@memvid/sdk 2.0.113

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 (46) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +244 -0
  3. package/dist/__tests__/basic.test.d.ts +1 -0
  4. package/dist/__tests__/basic.test.js +41 -0
  5. package/dist/adapters/autogen.d.ts +23 -0
  6. package/dist/adapters/autogen.js +163 -0
  7. package/dist/adapters/basic.d.ts +1 -0
  8. package/dist/adapters/basic.js +11 -0
  9. package/dist/adapters/crewai.d.ts +23 -0
  10. package/dist/adapters/crewai.js +160 -0
  11. package/dist/adapters/google_adk.d.ts +25 -0
  12. package/dist/adapters/google_adk.js +158 -0
  13. package/dist/adapters/haystack.d.ts +1 -0
  14. package/dist/adapters/haystack.js +11 -0
  15. package/dist/adapters/langchain.d.ts +28 -0
  16. package/dist/adapters/langchain.js +156 -0
  17. package/dist/adapters/langgraph.d.ts +1 -0
  18. package/dist/adapters/langgraph.js +11 -0
  19. package/dist/adapters/llamaindex.d.ts +33 -0
  20. package/dist/adapters/llamaindex.js +195 -0
  21. package/dist/adapters/mcp.d.ts +1 -0
  22. package/dist/adapters/mcp.js +11 -0
  23. package/dist/adapters/openai.d.ts +26 -0
  24. package/dist/adapters/openai.js +169 -0
  25. package/dist/adapters/semantic_kernel.d.ts +1 -0
  26. package/dist/adapters/semantic_kernel.js +11 -0
  27. package/dist/adapters/vercel_ai.d.ts +27 -0
  28. package/dist/adapters/vercel_ai.js +148 -0
  29. package/dist/clip.d.ts +182 -0
  30. package/dist/clip.js +371 -0
  31. package/dist/embeddings.d.ts +156 -0
  32. package/dist/embeddings.js +289 -0
  33. package/dist/entities.d.ts +251 -0
  34. package/dist/entities.js +489 -0
  35. package/dist/error.d.ts +91 -0
  36. package/dist/error.js +203 -0
  37. package/dist/index.d.ts +53 -0
  38. package/dist/index.js +458 -0
  39. package/dist/noop.d.ts +2 -0
  40. package/dist/noop.js +55 -0
  41. package/dist/registry.d.ts +5 -0
  42. package/dist/registry.js +53 -0
  43. package/dist/types.d.ts +275 -0
  44. package/dist/types.js +2 -0
  45. package/index.node +0 -0
  46. package/package.json +81 -0
package/dist/index.js ADDED
@@ -0,0 +1,458 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MODEL_DIMENSIONS = exports.getEmbedder = exports.VoyageEmbeddings = exports.CohereEmbeddings = exports.OpenAIEmbeddings = exports.CorruptFileError = exports.VecIndexDisabledError = exports.FrameNotFoundError = exports.MemoryAlreadyBoundError = exports.ApiKeyRequiredError = exports.LockedError = exports.VerificationFailedError = exports.TimeIndexMissingError = exports.LexIndexDisabledError = exports.TicketReplayError = exports.TicketInvalidError = exports.CapacityExceededError = exports.MemvidError = exports.use = exports.GeminiEntities = exports.ClaudeEntities = exports.OpenAIEntities = exports.LocalNER = exports.getEntityExtractor = exports.GeminiClip = exports.OpenAIClip = exports.LocalClip = exports.getClipProvider = exports.entities = exports.clip = void 0;
37
+ exports.create = create;
38
+ exports.maskPii = maskPii;
39
+ const registry_1 = require("./registry");
40
+ const error_1 = require("./error");
41
+ // Adapter registrations (side effects)
42
+ require("./adapters/basic");
43
+ require("./adapters/langchain");
44
+ require("./adapters/llamaindex");
45
+ require("./adapters/crewai");
46
+ require("./adapters/vercel_ai");
47
+ require("./adapters/openai");
48
+ require("./adapters/autogen");
49
+ require("./adapters/haystack");
50
+ require("./adapters/langgraph");
51
+ require("./adapters/semantic_kernel");
52
+ require("./adapters/google_adk");
53
+ require("./adapters/mcp");
54
+ // Export CLIP and entities modules
55
+ exports.clip = __importStar(require("./clip"));
56
+ exports.entities = __importStar(require("./entities"));
57
+ // Re-export provider factories for convenience
58
+ var clip_1 = require("./clip");
59
+ Object.defineProperty(exports, "getClipProvider", { enumerable: true, get: function () { return clip_1.getClipProvider; } });
60
+ Object.defineProperty(exports, "LocalClip", { enumerable: true, get: function () { return clip_1.LocalClip; } });
61
+ Object.defineProperty(exports, "OpenAIClip", { enumerable: true, get: function () { return clip_1.OpenAIClip; } });
62
+ Object.defineProperty(exports, "GeminiClip", { enumerable: true, get: function () { return clip_1.GeminiClip; } });
63
+ var entities_1 = require("./entities");
64
+ Object.defineProperty(exports, "getEntityExtractor", { enumerable: true, get: function () { return entities_1.getEntityExtractor; } });
65
+ Object.defineProperty(exports, "LocalNER", { enumerable: true, get: function () { return entities_1.LocalNER; } });
66
+ Object.defineProperty(exports, "OpenAIEntities", { enumerable: true, get: function () { return entities_1.OpenAIEntities; } });
67
+ Object.defineProperty(exports, "ClaudeEntities", { enumerable: true, get: function () { return entities_1.ClaudeEntities; } });
68
+ Object.defineProperty(exports, "GeminiEntities", { enumerable: true, get: function () { return entities_1.GeminiEntities; } });
69
+ const addon = require("../index.node");
70
+ function normaliseApiKey(apikey) {
71
+ if (!apikey) {
72
+ return undefined;
73
+ }
74
+ if (typeof apikey === "string") {
75
+ return { default: apikey };
76
+ }
77
+ if ("provider" in apikey && "key" in apikey) {
78
+ return { [apikey.provider]: apikey.key };
79
+ }
80
+ const map = {};
81
+ for (const [provider, key] of Object.entries(apikey)) {
82
+ if (key) {
83
+ map[provider] = String(key);
84
+ }
85
+ }
86
+ return Object.keys(map).length > 0 ? map : undefined;
87
+ }
88
+ function normalisePutArgs(input) {
89
+ const payload = {
90
+ title: input.title,
91
+ label: input.label,
92
+ metadata: input.metadata,
93
+ text: input.text,
94
+ file: input.file,
95
+ uri: input.uri,
96
+ tags: input.tags,
97
+ labels: input.labels,
98
+ kind: input.kind,
99
+ track: input.track,
100
+ search_text: input.searchText,
101
+ enable_embedding: input.enableEmbedding,
102
+ auto_tag: input.autoTag,
103
+ extract_dates: input.extractDates,
104
+ vector_compression: input.vectorCompression,
105
+ };
106
+ return payload;
107
+ }
108
+ function normaliseFindOptions(opts) {
109
+ if (!opts) {
110
+ return undefined;
111
+ }
112
+ const payload = {
113
+ k: opts.k,
114
+ snippetChars: opts.snippetChars,
115
+ scope: opts.scope,
116
+ cursor: opts.cursor,
117
+ asOfFrame: opts.asOfFrame,
118
+ asOfTs: opts.asOfTs,
119
+ };
120
+ if (payload.k == null &&
121
+ payload.snippetChars == null &&
122
+ payload.scope == null &&
123
+ payload.cursor == null &&
124
+ payload.asOfFrame == null &&
125
+ payload.asOfTs == null) {
126
+ return undefined;
127
+ }
128
+ return payload;
129
+ }
130
+ function normaliseAskOptions(opts) {
131
+ if (!opts) {
132
+ return undefined;
133
+ }
134
+ const payload = {
135
+ k: opts.k,
136
+ mode: opts.mode,
137
+ snippetChars: opts.snippetChars,
138
+ scope: opts.scope,
139
+ since: opts.since,
140
+ until: opts.until,
141
+ contextOnly: opts.contextOnly,
142
+ model: opts.model,
143
+ llmContextChars: opts.llmContextChars,
144
+ modelApiKey: opts.modelApiKey,
145
+ asOfFrame: opts.asOfFrame,
146
+ asOfTs: opts.asOfTs,
147
+ };
148
+ if (payload.k == null &&
149
+ payload.mode == null &&
150
+ payload.snippetChars == null &&
151
+ payload.scope == null &&
152
+ payload.since == null &&
153
+ payload.until == null &&
154
+ payload.contextOnly == null &&
155
+ payload.model == null &&
156
+ payload.llmContextChars == null &&
157
+ payload.modelApiKey == null &&
158
+ payload.asOfFrame == null &&
159
+ payload.asOfTs == null) {
160
+ return undefined;
161
+ }
162
+ return payload;
163
+ }
164
+ function normaliseTimelineOptions(opts) {
165
+ if (!opts) {
166
+ return undefined;
167
+ }
168
+ const payload = {
169
+ limit: opts.limit,
170
+ since: opts.since,
171
+ until: opts.until,
172
+ reverse: opts.reverse,
173
+ asOfFrame: opts.asOfFrame,
174
+ asOfTs: opts.asOfTs,
175
+ };
176
+ if (payload.limit == null &&
177
+ payload.since == null &&
178
+ payload.until == null &&
179
+ payload.reverse == null &&
180
+ payload.asOfFrame == null &&
181
+ payload.asOfTs == null) {
182
+ return undefined;
183
+ }
184
+ return payload;
185
+ }
186
+ /**
187
+ * Helper to wrap async operations and convert native errors to MemvidError.
188
+ */
189
+ async function wrapAsync(fn) {
190
+ try {
191
+ return await fn();
192
+ }
193
+ catch (err) {
194
+ if (err instanceof Error) {
195
+ throw (0, error_1.wrapNativeError)(err);
196
+ }
197
+ throw err;
198
+ }
199
+ }
200
+ class MemvidImpl {
201
+ constructor(kind, core, attachments) {
202
+ this.kind = kind;
203
+ this.core = core;
204
+ this.tools = attachments.tools;
205
+ this.functions = attachments.functions;
206
+ this.nodes = attachments.nodes;
207
+ this.asQueryEngine = attachments.asQueryEngine ?? null;
208
+ }
209
+ async put(data) {
210
+ return wrapAsync(async () => {
211
+ // Set vector compression mode if requested
212
+ if (data.vectorCompression) {
213
+ await this.core.setVectorCompression(true);
214
+ }
215
+ return this.core.put(normalisePutArgs(data));
216
+ });
217
+ }
218
+ async putMany(requests, options) {
219
+ return wrapAsync(async () => {
220
+ // Convert to native format
221
+ const nativeRequests = requests.map((req) => ({
222
+ title: req.title,
223
+ text: req.text,
224
+ uri: req.uri,
225
+ labels: req.labels,
226
+ tags: req.tags,
227
+ metadata: req.metadata,
228
+ embedding: req.embedding,
229
+ }));
230
+ const nativeOptions = options
231
+ ? { compression_level: options.compressionLevel }
232
+ : undefined;
233
+ return this.core.putMany(nativeRequests, nativeOptions);
234
+ });
235
+ }
236
+ async find(query, opts) {
237
+ return wrapAsync(async () => {
238
+ const options = normaliseFindOptions(opts);
239
+ return this.core.find(query, options);
240
+ });
241
+ }
242
+ async ask(question, opts) {
243
+ return wrapAsync(async () => {
244
+ const options = normaliseAskOptions(opts);
245
+ const response = await this.core.ask(question, options);
246
+ // Apply PII masking if requested
247
+ if (opts?.maskPii) {
248
+ // Note: napi-rs converts snake_case to camelCase, so mask_pii becomes maskPii
249
+ const maskPiiFn = addon.maskPii;
250
+ // Mask the aggregated context
251
+ if (response.context) {
252
+ response.context = maskPiiFn(response.context);
253
+ }
254
+ // Mask the answer
255
+ if (response.answer) {
256
+ response.answer = maskPiiFn(response.answer);
257
+ }
258
+ // Mask answer_lines
259
+ if (response.answer_lines && Array.isArray(response.answer_lines)) {
260
+ response.answer_lines = response.answer_lines.map((line) => maskPiiFn(line));
261
+ }
262
+ // Mask text in each hit
263
+ if (response.hits && Array.isArray(response.hits)) {
264
+ for (const hit of response.hits) {
265
+ if (hit.text) {
266
+ hit.text = maskPiiFn(hit.text);
267
+ }
268
+ if (hit.chunk_text) {
269
+ hit.chunk_text = maskPiiFn(hit.chunk_text);
270
+ }
271
+ if (hit.snippet) {
272
+ hit.snippet = maskPiiFn(hit.snippet);
273
+ }
274
+ if (hit.tags && Array.isArray(hit.tags)) {
275
+ hit.tags = hit.tags.map((tag) => maskPiiFn(tag));
276
+ }
277
+ if (hit.labels && Array.isArray(hit.labels)) {
278
+ hit.labels = hit.labels.map((label) => maskPiiFn(label));
279
+ }
280
+ }
281
+ }
282
+ // Mask context_fragments
283
+ if (response.context_fragments && Array.isArray(response.context_fragments)) {
284
+ for (const fragment of response.context_fragments) {
285
+ if (fragment.text) {
286
+ fragment.text = maskPiiFn(fragment.text);
287
+ }
288
+ }
289
+ }
290
+ // Mask sources
291
+ if (response.sources && Array.isArray(response.sources)) {
292
+ for (const source of response.sources) {
293
+ if (source.snippet) {
294
+ source.snippet = maskPiiFn(source.snippet);
295
+ }
296
+ if (source.tags && Array.isArray(source.tags)) {
297
+ source.tags = source.tags.map((tag) => maskPiiFn(tag));
298
+ }
299
+ if (source.labels && Array.isArray(source.labels)) {
300
+ source.labels = source.labels.map((label) => maskPiiFn(label));
301
+ }
302
+ }
303
+ }
304
+ // Mask primary_source
305
+ if (response.primary_source) {
306
+ if (response.primary_source.snippet) {
307
+ response.primary_source.snippet = maskPiiFn(response.primary_source.snippet);
308
+ }
309
+ if (response.primary_source.tags && Array.isArray(response.primary_source.tags)) {
310
+ response.primary_source.tags = response.primary_source.tags.map((tag) => maskPiiFn(tag));
311
+ }
312
+ if (response.primary_source.labels && Array.isArray(response.primary_source.labels)) {
313
+ response.primary_source.labels = response.primary_source.labels.map((label) => maskPiiFn(label));
314
+ }
315
+ }
316
+ }
317
+ return response;
318
+ });
319
+ }
320
+ async timeline(opts) {
321
+ return wrapAsync(async () => {
322
+ const options = normaliseTimelineOptions(opts);
323
+ return this.core.timeline(options);
324
+ });
325
+ }
326
+ async stats() {
327
+ return wrapAsync(() => this.core.stats());
328
+ }
329
+ async seal() {
330
+ return wrapAsync(() => this.core.seal());
331
+ }
332
+ async enableLex() {
333
+ return wrapAsync(() => this.core.enableLex());
334
+ }
335
+ async setVectorCompression(enabled) {
336
+ return wrapAsync(() => this.core.setVectorCompression(enabled));
337
+ }
338
+ async applyTicket(ticket) {
339
+ return wrapAsync(() => this.core.applyTicket(ticket));
340
+ }
341
+ async getMemoryBinding() {
342
+ return wrapAsync(() => this.core.getMemoryBinding());
343
+ }
344
+ async unbindMemory() {
345
+ return wrapAsync(() => this.core.unbindMemory());
346
+ }
347
+ async getCapacity() {
348
+ return wrapAsync(() => this.core.getCapacity());
349
+ }
350
+ async currentTicket() {
351
+ return wrapAsync(() => this.core.currentTicket());
352
+ }
353
+ async syncTickets(memoryId, apiKey, apiUrl) {
354
+ return wrapAsync(() => this.core.syncTickets(memoryId, apiKey, apiUrl));
355
+ }
356
+ async putPdfTables(pdfPath, embedRows) {
357
+ return wrapAsync(() => this.core.putPdfTables(pdfPath, embedRows ?? true));
358
+ }
359
+ async listTables() {
360
+ return wrapAsync(() => this.core.listTables());
361
+ }
362
+ async getTable(tableId, format) {
363
+ return wrapAsync(() => this.core.getTable(tableId, format ?? "dict"));
364
+ }
365
+ }
366
+ const useImpl = (async (kind, filename, apiKey, options) => {
367
+ const normalised = normaliseApiKey(apiKey);
368
+ const mode = options?.mode ?? "open";
369
+ // Extract the API key string for the native layer
370
+ // Use the "default" key from normalized map, or the first available key
371
+ let apiKeyStr;
372
+ if (normalised) {
373
+ apiKeyStr = normalised.default ?? Object.values(normalised)[0];
374
+ }
375
+ let core;
376
+ try {
377
+ core = addon.openMemvid(filename, mode, true, true, apiKeyStr);
378
+ }
379
+ catch (err) {
380
+ if (err instanceof Error) {
381
+ throw (0, error_1.wrapNativeError)(err);
382
+ }
383
+ throw err;
384
+ }
385
+ const attachments = await (0, registry_1.resolve)(kind, core, normalised);
386
+ return new MemvidImpl(kind, core, attachments);
387
+ });
388
+ useImpl.verify = async (path, options) => {
389
+ const nativeOptions = options ? { deep: options.deep } : undefined;
390
+ return addon.verifyMemvid(path, nativeOptions);
391
+ };
392
+ useImpl.doctor = async (path, options) => {
393
+ if (!options) {
394
+ return addon.doctorMemvid(path, undefined);
395
+ }
396
+ const nativeOptions = {
397
+ rebuild_time_index: options.rebuildTimeIndex,
398
+ rebuild_lex_index: options.rebuildLexIndex,
399
+ rebuild_vec_index: options.rebuildVecIndex,
400
+ vacuum: options.vacuum,
401
+ dry_run: options.dryRun,
402
+ };
403
+ return addon.doctorMemvid(path, nativeOptions);
404
+ };
405
+ exports.use = useImpl;
406
+ exports.default = useImpl;
407
+ async function create(filename, kind = "basic", apiKey) {
408
+ return useImpl(kind, filename, apiKey, { mode: "create" });
409
+ }
410
+ // Re-export error classes for catch handling
411
+ var error_2 = require("./error");
412
+ Object.defineProperty(exports, "MemvidError", { enumerable: true, get: function () { return error_2.MemvidError; } });
413
+ Object.defineProperty(exports, "CapacityExceededError", { enumerable: true, get: function () { return error_2.CapacityExceededError; } });
414
+ Object.defineProperty(exports, "TicketInvalidError", { enumerable: true, get: function () { return error_2.TicketInvalidError; } });
415
+ Object.defineProperty(exports, "TicketReplayError", { enumerable: true, get: function () { return error_2.TicketReplayError; } });
416
+ Object.defineProperty(exports, "LexIndexDisabledError", { enumerable: true, get: function () { return error_2.LexIndexDisabledError; } });
417
+ Object.defineProperty(exports, "TimeIndexMissingError", { enumerable: true, get: function () { return error_2.TimeIndexMissingError; } });
418
+ Object.defineProperty(exports, "VerificationFailedError", { enumerable: true, get: function () { return error_2.VerificationFailedError; } });
419
+ Object.defineProperty(exports, "LockedError", { enumerable: true, get: function () { return error_2.LockedError; } });
420
+ Object.defineProperty(exports, "ApiKeyRequiredError", { enumerable: true, get: function () { return error_2.ApiKeyRequiredError; } });
421
+ Object.defineProperty(exports, "MemoryAlreadyBoundError", { enumerable: true, get: function () { return error_2.MemoryAlreadyBoundError; } });
422
+ Object.defineProperty(exports, "FrameNotFoundError", { enumerable: true, get: function () { return error_2.FrameNotFoundError; } });
423
+ Object.defineProperty(exports, "VecIndexDisabledError", { enumerable: true, get: function () { return error_2.VecIndexDisabledError; } });
424
+ Object.defineProperty(exports, "CorruptFileError", { enumerable: true, get: function () { return error_2.CorruptFileError; } });
425
+ // Re-export embeddings module
426
+ var embeddings_1 = require("./embeddings");
427
+ Object.defineProperty(exports, "OpenAIEmbeddings", { enumerable: true, get: function () { return embeddings_1.OpenAIEmbeddings; } });
428
+ Object.defineProperty(exports, "CohereEmbeddings", { enumerable: true, get: function () { return embeddings_1.CohereEmbeddings; } });
429
+ Object.defineProperty(exports, "VoyageEmbeddings", { enumerable: true, get: function () { return embeddings_1.VoyageEmbeddings; } });
430
+ Object.defineProperty(exports, "getEmbedder", { enumerable: true, get: function () { return embeddings_1.getEmbedder; } });
431
+ Object.defineProperty(exports, "MODEL_DIMENSIONS", { enumerable: true, get: function () { return embeddings_1.MODEL_DIMENSIONS; } });
432
+ /**
433
+ * Mask PII (Personally Identifiable Information) in text.
434
+ *
435
+ * Detects and replaces common PII patterns with placeholder tokens:
436
+ * - Email addresses → [EMAIL]
437
+ * - US Social Security Numbers → [SSN]
438
+ * - Phone numbers → [PHONE]
439
+ * - Credit card numbers → [CREDIT_CARD]
440
+ * - IPv4 addresses → [IP_ADDRESS]
441
+ * - API keys/tokens → [API_KEY]
442
+ *
443
+ * @param text - The text to mask
444
+ * @returns Text with PII replaced by placeholder tokens
445
+ *
446
+ * @example
447
+ * ```typescript
448
+ * import { maskPii } from 'memvid-sdk';
449
+ *
450
+ * const text = "Contact john@example.com at 555-123-4567";
451
+ * const masked = maskPii(text);
452
+ * console.log(masked); // "Contact [EMAIL] at [PHONE]"
453
+ * ```
454
+ */
455
+ function maskPii(text) {
456
+ // Note: napi-rs converts snake_case to camelCase
457
+ return addon.maskPii(text);
458
+ }
package/dist/noop.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export type NoOpFunction = (...args: unknown[]) => undefined;
2
+ export declare function createNoOp(message: string, key: string): NoOpFunction;
package/dist/noop.js ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNoOp = createNoOp;
4
+ const warned = new Set();
5
+ function createNoOp(message, key) {
6
+ const warn = () => {
7
+ if (!warned.has(key)) {
8
+ warned.add(key);
9
+ console.warn(message);
10
+ }
11
+ };
12
+ const base = () => {
13
+ warn();
14
+ return undefined;
15
+ };
16
+ const handler = {
17
+ apply: () => {
18
+ warn();
19
+ return undefined;
20
+ },
21
+ get: (_target, prop) => {
22
+ warn();
23
+ if (prop === Symbol.toPrimitive) {
24
+ return () => {
25
+ warn();
26
+ return 0;
27
+ };
28
+ }
29
+ if (prop === "valueOf") {
30
+ return () => {
31
+ warn();
32
+ return 0;
33
+ };
34
+ }
35
+ if (prop === "toString") {
36
+ return () => {
37
+ warn();
38
+ return "";
39
+ };
40
+ }
41
+ if (prop === Symbol.iterator) {
42
+ return function* iterator() {
43
+ warn();
44
+ };
45
+ }
46
+ return proxy;
47
+ },
48
+ has: () => {
49
+ warn();
50
+ return false;
51
+ },
52
+ };
53
+ const proxy = new Proxy(base, handler);
54
+ return proxy;
55
+ }
@@ -0,0 +1,5 @@
1
+ import type { AdapterBundle, ApiKeyMap, Kind, NativeMemvid } from "./types";
2
+ type Loader = (core: NativeMemvid, apiKey: ApiKeyMap | undefined) => Promise<AdapterBundle>;
3
+ export declare function register(kind: Kind, loader: Loader): void;
4
+ export declare function resolve(kind: Kind, core: NativeMemvid, apiKey: ApiKeyMap | undefined): Promise<AdapterBundle>;
5
+ export {};
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.register = register;
4
+ exports.resolve = resolve;
5
+ const noop_1 = require("./noop");
6
+ const loaders = new Map();
7
+ const cache = new Map();
8
+ function unsupported(kind) {
9
+ const key = kind.replace(/_/g, "-");
10
+ return {
11
+ tools: (0, noop_1.createNoOp)(`kind '${kind}' is not supported`, `memvid.adapters.${key}.tools`),
12
+ functions: [],
13
+ nodes: (0, noop_1.createNoOp)(`kind '${kind}' is not supported`, `memvid.adapters.${key}.nodes`),
14
+ asQueryEngine: null,
15
+ };
16
+ }
17
+ function failed(kind, error) {
18
+ const reason = error instanceof Error ? error.message : String(error);
19
+ const key = kind.replace(/_/g, "-");
20
+ return {
21
+ tools: (0, noop_1.createNoOp)(`failed to load adapter '${kind}': ${reason}`, `memvid.adapters.${key}.tools`),
22
+ functions: [],
23
+ nodes: (0, noop_1.createNoOp)(`failed to load adapter '${kind}': ${reason}`, `memvid.adapters.${key}.nodes`),
24
+ asQueryEngine: null,
25
+ };
26
+ }
27
+ function register(kind, loader) {
28
+ const normalised = kind.toLowerCase();
29
+ if (loaders.has(normalised)) {
30
+ throw new Error(`adapter '${kind}' already registered`);
31
+ }
32
+ loaders.set(normalised, loader);
33
+ }
34
+ async function resolve(kind, core, apiKey) {
35
+ const key = kind.toLowerCase();
36
+ if (cache.has(key)) {
37
+ return cache.get(key);
38
+ }
39
+ const loader = loaders.get(key);
40
+ if (!loader) {
41
+ const noop = unsupported(kind);
42
+ cache.set(key, noop);
43
+ return noop;
44
+ }
45
+ try {
46
+ const loaded = await loader(core, apiKey);
47
+ cache.set(key, loaded);
48
+ return loaded;
49
+ }
50
+ catch (error) {
51
+ return failed(kind, error);
52
+ }
53
+ }