falkordb 6.6.2 → 6.8.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.
package/README.md CHANGED
@@ -32,12 +32,10 @@ npm install falkordb
32
32
  import { FalkorDB } from 'falkordb';
33
33
 
34
34
  const db = await FalkorDB.connect({
35
+ host: 'localhost',
36
+ port: 6379,
35
37
  username: 'myUsername',
36
- password: 'myPassword',
37
- socket: {
38
- host: 'localhost',
39
- port: 6379
40
- }
38
+ password: 'myPassword'
41
39
  })
42
40
 
43
41
  console.log('Connected to FalkorDB')
@@ -62,6 +60,50 @@ db.close()
62
60
 
63
61
  To learn more about Cypher query language check: https://docs.falkordb.com/cypher/
64
62
 
63
+ ### Connection Options
64
+
65
+ `host` and `port` are the shorthand for a plain TCP connection and default to `localhost:6379`.
66
+ You can also pass a connection URL:
67
+
68
+ ```typescript
69
+ const db = await FalkorDB.connect({ url: 'falkor://localhost:6379' })
70
+ ```
71
+
72
+ For anything beyond host and port — TLS, connection timeouts, keep-alive — use `socket`, which is
73
+ passed to the underlying [node-redis](https://github.com/redis/node-redis) client:
74
+
75
+ ```typescript
76
+ const db = await FalkorDB.connect({
77
+ socket: {
78
+ host: 'localhost',
79
+ port: 6379,
80
+ tls: true,
81
+ connectTimeout: 5000
82
+ }
83
+ })
84
+ ```
85
+
86
+ `url` sets the connection address, so it overrides the top-level `host` and `port`. Other
87
+ `socket` settings such as TLS and timeouts still apply alongside it. When both are given,
88
+ `socket.host` and `socket.port` take precedence over the top-level `host` and `port`.
89
+
90
+ #### `.stubs()`
91
+
92
+ Lists the graphs that are currently offloaded to disk ("stubs"). `db.list()` already includes
93
+ offloaded graphs, so `stubs()` is how you tell which of the listed graphs are not loaded in memory.
94
+
95
+ `GRAPH.STUBS` is provided by the FalkorDB Enterprise graph-offloading module, so on deployments
96
+ without that module the call rejects with an "unknown command" error — treat that as
97
+ "offloading is not supported here".
98
+
99
+ On a cluster the replies of all master nodes are combined. If only some masters fail, the
100
+ partial result is returned and the failures are logged; the call rejects only when every
101
+ master fails.
102
+
103
+ ```typescript
104
+ const offloaded = await db.stubs();
105
+ ```
106
+
65
107
  #### `.close()`
66
108
 
67
109
  Forcibly close a client's connection to FalkorDB immediately. Calling `close` will not send further pending commands to the Redis server, or wait for or parse outstanding responses.
@@ -8,6 +8,14 @@ import { UdfListReply } from "../commands/UDF_LIST";
8
8
  export interface Client {
9
9
  init(falkordb: FalkorDB): Promise<void>;
10
10
  list(): Promise<Array<string>>;
11
+ /**
12
+ * Lists the graphs that are currently offloaded to disk ("stubs").
13
+ *
14
+ * `GRAPH.STUBS` is provided by the FalkorDB Enterprise graph-offloading
15
+ * module, so it rejects with an "unknown command" error on deployments where
16
+ * that module is not loaded.
17
+ */
18
+ stubs(): Promise<Array<string>>;
11
19
  configGet(configKey: string): Promise<(string | number)[] | (string | number)[][]>;
12
20
  configSet(configKey: string, value: number | string): Promise<void>;
13
21
  info(section?: string): Promise<(string | string[])[]>;
@@ -41,6 +41,7 @@ export declare class Cluster implements Client {
41
41
  delete(graph: string): Promise<void>;
42
42
  explain(graph: string, query: string): Promise<string[]>;
43
43
  list(): Promise<Array<string>>;
44
+ stubs(): Promise<Array<string>>;
44
45
  configGet(configKey: string): Promise<(string | number)[] | (string | number)[][]>;
45
46
  configSet(configKey: string, value: number | string): Promise<void>;
46
47
  info(section?: string): Promise<(string | string[])[]>;
@@ -59,6 +59,30 @@ class Cluster {
59
59
  }
60
60
  return result;
61
61
  }
62
+ async stubs() {
63
+ const replies = await Promise.allSettled(this.#client.masters.map(async (master) => {
64
+ return (await this.#client.nodeClient(master)).falkordb.stubs();
65
+ }));
66
+ const result = [];
67
+ const errors = [];
68
+ for (const reply of replies) {
69
+ if (reply.status === "fulfilled") {
70
+ result.push(...reply.value);
71
+ }
72
+ else {
73
+ errors.push(reply.reason);
74
+ }
75
+ }
76
+ // Only surface a failure when every master failed - e.g. when the
77
+ // graph-offloading module is missing cluster-wide ("unknown command").
78
+ if (errors.length > 0 && errors.length === replies.length) {
79
+ throw errors[0];
80
+ }
81
+ if (errors.length > 0) {
82
+ console.error("Some nodes failed to respond:", errors);
83
+ }
84
+ return result;
85
+ }
62
86
  async configGet(configKey) {
63
87
  return this.#client.falkordb.configGet(configKey);
64
88
  }
@@ -21,6 +21,7 @@ export declare class NullClient implements Client {
21
21
  getConnection(): Promise<SingleGraphConnection>;
22
22
  init(_falkordb: FalkorDB): Promise<void>;
23
23
  list(): Promise<Array<string>>;
24
+ stubs(): Promise<Array<string>>;
24
25
  configGet(_configKey: string): Promise<(string | number)[] | (string | number)[][]>;
25
26
  configSet(_configKey: string, _value: number | string): Promise<void>;
26
27
  info(_section?: string): Promise<(string | string[])[]>;
@@ -22,6 +22,9 @@ class NullClient {
22
22
  list() {
23
23
  throw new Error("Method not implemented.");
24
24
  }
25
+ stubs() {
26
+ throw new Error("Method not implemented.");
27
+ }
25
28
  configGet(_configKey) {
26
29
  throw new Error("Method not implemented.");
27
30
  }
@@ -35,6 +35,7 @@ export declare class Single implements Client {
35
35
  explain(graph: string, query: string): Promise<string[]>;
36
36
  profile<_T>(graph: string, query: string): Promise<string[]>;
37
37
  list(): Promise<string[]>;
38
+ stubs(): Promise<string[]>;
38
39
  configGet(configKey: string): Promise<(string | number)[] | (string | number)[][]>;
39
40
  configSet(configKey: string, value: number | string): Promise<void>;
40
41
  info(section?: string): Promise<(string | string[])[]>;
@@ -28,6 +28,9 @@ class Single {
28
28
  async list() {
29
29
  return this.client.falkordb.list();
30
30
  }
31
+ async stubs() {
32
+ return this.client.falkordb.stubs();
33
+ }
31
34
  async configGet(configKey) {
32
35
  return this.client.falkordb.configGet(configKey);
33
36
  }
@@ -0,0 +1,5 @@
1
+ import { CommandParser } from '@redis/client';
2
+ export declare const IS_READ_ONLY = true;
3
+ export declare function parseCommand(parser: CommandParser): void;
4
+ export declare function transformArguments(): Array<string>;
5
+ export declare function transformReply(reply: unknown): Array<string>;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IS_READ_ONLY = void 0;
4
+ exports.parseCommand = parseCommand;
5
+ exports.transformArguments = transformArguments;
6
+ exports.transformReply = transformReply;
7
+ exports.IS_READ_ONLY = true;
8
+ function parseCommand(parser) {
9
+ parser.push('GRAPH.STUBS');
10
+ }
11
+ function transformArguments() {
12
+ return ['GRAPH.STUBS'];
13
+ }
14
+ function transformReply(reply) {
15
+ return reply;
16
+ }
@@ -8,6 +8,7 @@ import * as PROFILE from './PROFILE';
8
8
  import * as QUERY from './QUERY';
9
9
  import * as RO_QUERY from './RO_QUERY';
10
10
  import * as SLOWLOG from './SLOWLOG';
11
+ import * as STUBS from './STUBS';
11
12
  import * as CONSTRAINT_CREATE from './CONSTRAINT_CREATE';
12
13
  import * as CONSTRAINT_DROP from './CONSTRAINT_DROP';
13
14
  import * as COPY from './COPY';
@@ -40,6 +41,8 @@ declare const _default: {
40
41
  roQuery: typeof RO_QUERY;
41
42
  SLOWLOG: typeof SLOWLOG;
42
43
  slowLog: typeof SLOWLOG;
44
+ STUBS: typeof STUBS;
45
+ stubs: typeof STUBS;
43
46
  CONSTRAINT_CREATE: typeof CONSTRAINT_CREATE;
44
47
  constraintCreate: typeof CONSTRAINT_CREATE;
45
48
  CONSTRAINT_DROP: typeof CONSTRAINT_DROP;
@@ -11,6 +11,7 @@ const PROFILE = require("./PROFILE");
11
11
  const QUERY = require("./QUERY");
12
12
  const RO_QUERY = require("./RO_QUERY");
13
13
  const SLOWLOG = require("./SLOWLOG");
14
+ const STUBS = require("./STUBS");
14
15
  const CONSTRAINT_CREATE = require("./CONSTRAINT_CREATE");
15
16
  const CONSTRAINT_DROP = require("./CONSTRAINT_DROP");
16
17
  const COPY = require("./COPY");
@@ -42,6 +43,8 @@ exports.default = {
42
43
  roQuery: RO_QUERY,
43
44
  SLOWLOG,
44
45
  slowLog: SLOWLOG,
46
+ STUBS,
47
+ stubs: STUBS,
45
48
  CONSTRAINT_CREATE,
46
49
  constraintCreate: CONSTRAINT_CREATE,
47
50
  CONSTRAINT_DROP,
@@ -46,6 +46,16 @@ export interface FalkorDBOptions {
46
46
  * Socket connection properties
47
47
  */
48
48
  socket?: SocketOptions;
49
+ /**
50
+ * Server hostname, shorthand for `socket.host`.
51
+ * Ignored when `url` or `socket.host` is provided.
52
+ */
53
+ host?: string;
54
+ /**
55
+ * Server port, shorthand for `socket.port`.
56
+ * Ignored when `url` or `socket.port` is provided.
57
+ */
58
+ port?: number;
49
59
  /**
50
60
  * ACL username ([see ACL guide](https://redis.io/topics/acl))
51
61
  */
@@ -82,6 +92,15 @@ export default class FalkorDB extends EventEmitter {
82
92
  selectGraph(graphId: string): Graph;
83
93
  get connection(): Promise<SingleGraphConnection>;
84
94
  list(): Promise<string[]>;
95
+ /**
96
+ * Lists the graphs that are currently offloaded to disk ("stubs").
97
+ *
98
+ * `GRAPH.STUBS` is provided by the FalkorDB Enterprise graph-offloading
99
+ * module, so this rejects with an "unknown command" error on deployments
100
+ * where that module is not loaded. Callers that support both editions
101
+ * should treat such a rejection as "no offloading support".
102
+ */
103
+ stubs(): Promise<string[]>;
85
104
  configGet(configKey: string): Promise<(string | number)[] | (string | number)[][]>;
86
105
  configSet(configKey: string, value: number | string): Promise<void>;
87
106
  info(section?: string): Promise<(string | string[])[]>;
@@ -21,7 +21,18 @@ async function clientFactory(client) {
21
21
  class FalkorDB extends events_1.EventEmitter {
22
22
  #client = new nullClient_1.NullClient();
23
23
  static async connect(options) {
24
- const redisOption = (options ?? {});
24
+ const { host, port, ...rest } = options ?? {};
25
+ const redisOption = rest;
26
+ // Support the top-level `host`/`port` shorthand used by the other FalkorDB
27
+ // clients by folding them into the socket options node-redis expects.
28
+ // Explicit `socket` values win, and `url` takes precedence over both.
29
+ if (!redisOption.url && (host !== undefined || port !== undefined)) {
30
+ redisOption.socket = {
31
+ ...(host !== undefined && { host }),
32
+ ...(port !== undefined && { port }),
33
+ ...redisOption.socket,
34
+ };
35
+ }
25
36
  // If the URL is provided, and the protocol is `falkor` replaces it with `redis` for the underline redis client
26
37
  // e.g. falkor://localhost:6379 -> redis://localhost:6379
27
38
  if (redisOption.url && redisOption.url.startsWith('falkor')) {
@@ -53,6 +64,17 @@ class FalkorDB extends events_1.EventEmitter {
53
64
  async list() {
54
65
  return this.#client.list();
55
66
  }
67
+ /**
68
+ * Lists the graphs that are currently offloaded to disk ("stubs").
69
+ *
70
+ * `GRAPH.STUBS` is provided by the FalkorDB Enterprise graph-offloading
71
+ * module, so this rejects with an "unknown command" error on deployments
72
+ * where that module is not loaded. Callers that support both editions
73
+ * should treat such a rejection as "no offloading support".
74
+ */
75
+ async stubs() {
76
+ return this.#client.stubs();
77
+ }
56
78
  async configGet(configKey) {
57
79
  return this.#client.configGet(configKey);
58
80
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "falkordb",
3
- "version": "6.6.2",
3
+ "version": "6.8.0",
4
4
  "description": "A FalkorDB javascript library",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
@@ -33,19 +33,19 @@
33
33
  "falkordb"
34
34
  ],
35
35
  "engines": {
36
- "node": ">=20.0.0"
36
+ "node": ">=22"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@tsconfig/node20": "^20.1.4",
40
- "@types/jest": "^29.5.14",
40
+ "@types/jest": "^30.0.0",
41
41
  "@types/lodash": "^4.17.13",
42
- "@types/node": "^25.0.2",
42
+ "@types/node": "^26.2.0",
43
43
  "@typescript-eslint/eslint-plugin": "^8.18.2",
44
44
  "@typescript-eslint/parser": "^8.18.2",
45
45
  "eslint": "^10.0.1",
46
46
  "gh-pages": "^6.2.0",
47
47
  "jest": "^30.2.0",
48
- "release-it": "^19.0.3",
48
+ "release-it": "^21.0.2",
49
49
  "ts-jest": "^29.4.6",
50
50
  "typescript": "^5.9.3"
51
51
  },