superb-memory 0.0.0-stage → 0.2.5

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/index.d.ts ADDED
@@ -0,0 +1,58 @@
1
+ export declare class MemoryDBError extends Error {
2
+ status: number;
3
+ constructor(status: number, message: string);
4
+ }
5
+
6
+ export interface MemoryDBOptions {
7
+ url?: string;
8
+ token?: string;
9
+ timeout?: number;
10
+ }
11
+
12
+ export interface Record {
13
+ id: string;
14
+ kind: string;
15
+ content: string;
16
+ data?: Record<string, unknown> | null;
17
+ collection?: string;
18
+ version: number;
19
+ user: string;
20
+ workspace: string;
21
+ source: string;
22
+ layer?: string;
23
+ parent?: string;
24
+ metadata?: Record<string, string>;
25
+ created: string;
26
+ deleted: boolean;
27
+ }
28
+
29
+ export declare class MemoryDB {
30
+ constructor(urlOrOptions?: string | MemoryDBOptions, maybeOptions?: MemoryDBOptions);
31
+ static fromURL(connectionString: string): MemoryDB;
32
+ request(method: string, path: string, body?: unknown, headers?: Record<string, string>): Promise<any>;
33
+ health(): Promise<any>;
34
+ search(query: { text?: string; vector?: number[]; kind?: string; source?: string; embedding_model?: string; agent?: string; limit?: number }): Promise<{ results: { record: Record; score: number }[] }>;
35
+ ingest(payload: { source: string; messages: { role: string; content: string }[]; facts?: unknown[]; extract?: boolean; context?: string; tools?: unknown[] }): Promise<{ results: Record[] }>;
36
+ queueIngest(payload: object): Promise<Record>;
37
+ transaction(changes: { record: object; expected: number }[], idempotencyKey?: string): Promise<{ results: Record[] }>;
38
+ memories: {
39
+ create(record: object): Promise<Record>;
40
+ list(opts?: { kind?: string; source?: string; q?: string; limit?: number }): Promise<{ results: { record: Record; score: number }[] }>;
41
+ get(pk: string): Promise<Record>;
42
+ history(pk: string): Promise<{ results: Record[] }>;
43
+ delete(pk: string, version: number): Promise<Record>;
44
+ };
45
+ collections: {
46
+ list(): Promise<Record[]>;
47
+ create(name: string, schema: object): Promise<Record>;
48
+ };
49
+ documents(name: string): {
50
+ create(data: object, idempotencyKey?: string): Promise<Record>;
51
+ get(pk: string): Promise<Record>;
52
+ query(q?: object): Promise<{ results: Record[]; total: number; plan: string; next_cursor?: string }>;
53
+ update(pk: string, opts: { version?: number; set?: object; unset?: string[] }): Promise<Record>;
54
+ delete(pk: string, version: number): Promise<Record>;
55
+ };
56
+ }
57
+
58
+ export default MemoryDB;
package/index.mjs ADDED
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Dependency-free MemoryDB client for Node 18+ (native fetch).
3
+ * Accepts either ({url, token}) or a memorydb://TOKEN@host:port connection string,
4
+ * matching the Python/Go clients and the MEMORYDB_URL environment variable.
5
+ */
6
+ const DEFAULT_PORT = 8080;
7
+
8
+ export function parseConnectionString(cs) {
9
+ const u = new URL(cs);
10
+ if (u.protocol !== 'memorydb:' && u.protocol !== 'memorydbs:') {
11
+ throw new Error('connection string must start with memorydb:// or memorydbs://');
12
+ }
13
+ const token = decodeURIComponent(u.username);
14
+ if (!token) throw new Error('connection string must carry the token: memorydb://TOKEN@host:port');
15
+ const scheme = u.protocol === 'memorydbs:' ? 'https' : 'http';
16
+ const host = u.hostname || '127.0.0.1';
17
+ const port = u.port || String(DEFAULT_PORT);
18
+ return { url: `${scheme}://${host}:${port}`, token };
19
+ }
20
+
21
+ export class MemoryDBError extends Error {
22
+ constructor(status, message) {
23
+ super(message);
24
+ this.status = status;
25
+ }
26
+ }
27
+
28
+ export class MemoryDB {
29
+ constructor(urlOrOptions = 'http://127.0.0.1:8080', maybeOptions = {}) {
30
+ let url, token, timeout = 35000;
31
+ if (typeof urlOrOptions === 'string' && urlOrOptions.startsWith('memorydb')) {
32
+ ({ url, token } = parseConnectionString(urlOrOptions));
33
+ } else if (typeof urlOrOptions === 'object') {
34
+ ({ url, token, timeout = 35000 } = urlOrOptions);
35
+ } else {
36
+ url = urlOrOptions;
37
+ token = maybeOptions.token;
38
+ timeout = maybeOptions.timeout ?? timeout;
39
+ }
40
+ if (!token) token = process.env.MEMORYDB_TOKEN;
41
+ if (!url) url = process.env.MEMORYDB_URL;
42
+ if (url && url.startsWith('memorydb')) ({ url, token } = parseConnectionString(url));
43
+ if (!token) throw new Error('pass token=, a memorydb:// connection string, or set MEMORYDB_TOKEN');
44
+ this.base = url.replace(/\/+$/, '') + '/api/v1/';
45
+ this.token = token;
46
+ this.timeout = timeout;
47
+ this.documents = (name) => new DocumentManager(this, name);
48
+ this.memories = new MemoryManager(this);
49
+ this.collections = new CollectionManager(this);
50
+ }
51
+
52
+ static fromURL(cs) {
53
+ return new MemoryDB(cs);
54
+ }
55
+
56
+ async request(method, path, body, headers = {}) {
57
+ const controller = new AbortController();
58
+ const timer = setTimeout(() => controller.abort(), this.timeout);
59
+ try {
60
+ const res = await fetch(this.base + path, {
61
+ method,
62
+ headers: { Authorization: `Bearer ${this.token}`, 'Content-Type': 'application/json', ...headers },
63
+ body: body === undefined ? undefined : JSON.stringify(body),
64
+ signal: controller.signal,
65
+ });
66
+ const data = await res.json().catch(() => ({}));
67
+ if (!res.ok) throw new MemoryDBError(res.status, data.error || `HTTP ${res.status}`);
68
+ return data;
69
+ } finally {
70
+ clearTimeout(timer);
71
+ }
72
+ }
73
+
74
+ health() { return this.request('GET', 'health/'); }
75
+ search(query) { return this.request('POST', 'search/', { limit: 10, ...query }); }
76
+ ingest(payload) { return this.request('POST', 'ingest/', payload); }
77
+ queueIngest(payload) { return this.request('POST', 'jobs/', payload); }
78
+ transaction(changes, idempotencyKey) {
79
+ return this.request('POST', 'transactions/', { changes }, idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {});
80
+ }
81
+ }
82
+
83
+ class MemoryManager {
84
+ constructor(client) { this.client = client; }
85
+ create(record) { return this.client.request('POST', 'memories/', record); }
86
+ list({ kind = '', source = '', q = '', limit = 50 } = {}) {
87
+ const params = new URLSearchParams({ kind, source, q, limit: String(limit) });
88
+ return this.client.request('GET', 'memories/?' + params);
89
+ }
90
+ get(pk) { return this.client.request('GET', `memories/${encodeURIComponent(pk)}/`); }
91
+ history(pk) { return this.client.request('GET', `memories/${encodeURIComponent(pk)}/history/`); }
92
+ delete(pk, version) {
93
+ return this.client.request('DELETE', `memories/${encodeURIComponent(pk)}/`, undefined, { 'If-Match': String(version) });
94
+ }
95
+ }
96
+
97
+ class CollectionManager {
98
+ constructor(client) { this.client = client; }
99
+ list() { return this.client.request('GET', 'collections/').then((d) => d.results); }
100
+ create(name, schema) { return this.client.request('POST', 'collections/', { name, schema }); }
101
+ }
102
+
103
+ class DocumentManager {
104
+ constructor(client, name) {
105
+ if (!/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(name)) throw new Error('invalid collection name');
106
+ this.client = client;
107
+ this.path = `documents/${encodeURIComponent(name)}/`;
108
+ }
109
+ create(data, idempotencyKey) {
110
+ return this.client.request('POST', this.path, { data }, idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {});
111
+ }
112
+ get(pk) { return this.client.request('GET', this.path + encodeURIComponent(pk) + '/'); }
113
+ query(q = {}) { return this.client.request('POST', 'query/' + this.path.slice('documents/'.length), q); }
114
+ update(pk, { version, set = {}, unset = [] }) {
115
+ return this.client.request('PATCH', this.path + encodeURIComponent(pk) + '/', { version, set, unset });
116
+ }
117
+ delete(pk, version) {
118
+ return this.client.request('DELETE', this.path + encodeURIComponent(pk) + '/', undefined, { 'If-Match': String(version) });
119
+ }
120
+ }
121
+
122
+ export default MemoryDB;
package/package.json CHANGED
@@ -1,6 +1,18 @@
1
1
  {
2
2
  "name": "superb-memory",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.5",
4
+ "description": "Dependency-free Node client for the MemoryDB Go document and agent-memory database",
5
+ "type": "module",
6
+ "main": "index.mjs",
7
+ "types": "index.d.ts",
8
+ "exports": { ".": { "types": "./index.d.ts", "import": "./index.mjs" } },
9
+ "engines": { "node": ">=18" },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/humaniods/MemoryDB.git",
13
+ "directory": "sdk/node"
14
+ },
15
+ "files": ["index.mjs", "index.d.ts"],
16
+ "license": "MIT",
17
+ "scripts": { "test": "node test.mjs" }
18
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.