@ouim/vectoriadb-server 0.1.5 → 0.1.6

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/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@ouim/vectoriadb-server",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "start": "node index.js",
8
- "demo": "node demo.js"
8
+ "demo": "node demo.js",
9
+ "test": "node --test"
9
10
  },
10
11
  "dependencies": {
11
12
  "@huggingface/transformers": "^3.8.1",
@@ -0,0 +1,46 @@
1
+ import test from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import VectoriaDBServer from '../vectoriadb-server.js'
4
+
5
+ test('server deserializes serialized options.filter (object form) into a function', async () => {
6
+ const server = new VectoriaDBServer()
7
+
8
+ // stub the underlying VectoriaDB method (`search`) to inspect received args
9
+ server._vectoria = {
10
+ async search(...args) {
11
+ // find an arg that contains a `filter` property
12
+ const opt = args.find(a => a && typeof a === 'object' && Object.prototype.hasOwnProperty.call(a, 'filter'))
13
+ assert(opt, 'expected an options object containing `filter`')
14
+ assert.equal(typeof opt.filter, 'function', 'options.filter should be a function after deserialization')
15
+
16
+ // sanity-check the deserialized function works
17
+ const sample = { owner: 'team' }
18
+ assert.equal(opt.filter(sample), true)
19
+
20
+ return { ok: true }
21
+ },
22
+ }
23
+
24
+ // capture emitted responses from the "socket"
25
+ let emitted = null
26
+ const mockSocket = { emit: (evt, payload) => (emitted = { evt, payload }) }
27
+
28
+ const payload = {
29
+ id: 't-filter-1',
30
+ method: 'search',
31
+ params: [
32
+ {
33
+ // serialized filter object as sent by the client SDK
34
+ filter: { __isFnString: true, fn: 'function(m){ return !!(m && m.owner === "team") }' },
35
+ },
36
+ ],
37
+ }
38
+
39
+ await server._handleRequest(mockSocket, payload)
40
+
41
+ assert(emitted, 'expected socket.emit to be called')
42
+ assert.equal(emitted.evt, 'response')
43
+ assert.equal(emitted.payload.id, payload.id)
44
+ assert.deepEqual(emitted.payload.result, { ok: true })
45
+ assert.equal(emitted.payload.error, null)
46
+ })
@@ -148,15 +148,21 @@ export default class VectoriaDBServer {
148
148
  // Allow passing serialized functions from client: convert stringified functions back to real functions
149
149
  const reparsedParams = params.map(p => {
150
150
  if (p && typeof p === 'object') {
151
- // detect serialized function marker
151
+ // Top-level serialized function (client forwarded a function as a param)
152
152
  if (p.__isFnString && typeof p.fn === 'string') {
153
153
  // create function from string - executed in server process (trusted usage only)
154
154
  // eslint-disable-next-line no-new-func
155
155
  const fn = new Function('return (' + p.fn + ')')()
156
156
  return fn
157
157
  }
158
- // also support options.filter as a string directly
159
- if (typeof p.filter === 'string' && p.filter.trim().startsWith('function')) {
158
+
159
+ // Support serialized `filter` nested inside an `options` object:
160
+ // - { filter: { __isFnString: true, fn: 'function(m) { ... }' } }
161
+ // - or `filter` as a raw function string
162
+ if (p.filter && typeof p.filter === 'object' && p.filter.__isFnString && typeof p.filter.fn === 'string') {
163
+ // eslint-disable-next-line no-new-func
164
+ p.filter = new Function('return (' + p.filter.fn + ')')()
165
+ } else if (typeof p.filter === 'string' && p.filter.trim().startsWith('function')) {
160
166
  // eslint-disable-next-line no-new-func
161
167
  p.filter = new Function('return (' + p.filter + ')')()
162
168
  }