Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changesets

Add a changeset for every user-visible change. On `main`, the release workflow
creates a version PR; merging that PR updates the changelog and publishes the
new package to npm.
5 changes: 5 additions & 0 deletions .changeset/breezy-cooks-make.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rushdb/javascript-sdk": major
---

Direct mode for 3.0 rust native engine (rc)
9 changes: 9 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.0.4/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
5 changes: 5 additions & 0 deletions .changeset/direct-engine-sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rushdb/javascript-sdk': minor
---

Add direct mode for the standalone RushDB engine, including record replacement, deletion by ID, and single-record lookups.
32 changes: 32 additions & 0 deletions .changeset/direct-mode-cloud-boundary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
'@rushdb/javascript-sdk': minor
---

Direct mode (a standalone engine) and RushDB Cloud are one SDK with one code path.

- In direct mode every method is answered from the engine: records (including `find` with
`orderBy`, `select` and `groupBy`, `upsert`, `set`, `findOne`/`findUniq`, `findById` of several
ids), relationships, labels, properties, JSON and CSV import, CSV export, text indexes and keyword
search, external vector indexes, vector and hybrid search with a `queryVector`, raw openCypher, the
schema and transactions. Nothing is ever sent to RushDB Cloud: before, a method without direct
support sent the engine token to `api.rushdb.com`.
- The Cloud-only features (managed embeddings, `ai.search`, `relationships.patterns.*`,
`settings.get`) throw `CloudOnlyError` before sending anything. `CLOUD_ONLY_METHODS`,
`CLOUD_ONLY_FORMS` and `isCloudOnlyMethod` list them.
- In a transaction, direct mode stages record creates, `update`, `set`, `deleteById`, `attach`,
`importJson` and `importCsv` (records are named by id; the engine resolves them inside the
transaction). Writes the engine cannot stage (bulk deletes, `detach`, upserts and merge imports,
inline vectors) throw `DirectModeError` instead of running outside the transaction; the engine
refuses a merge import or inline vectors in a staged import.
- `records.detach` without `typeOrTypes` removes relationships of every type, and without
`direction` removes them both ways, as RushDB 2.x on Neo4j did. `records.attach` and
`relationships.createMany` without a type create `__RUSHDB__RELATION__DEFAULT__` relationships,
as before, instead of `RELATED_TO`.
- `direct: true` without `engineUrl` throws instead of falling back to RushDB Cloud. New `scope`
option for a multitenant engine; the unused `engineToken` option is gone.
- Fixed: direct mode never sent the request body, so every call failed against a real engine.
- Fixed in both modes: `records.findById([...ids])` posted to the create endpoint; it now searches
by id.
- The package declares `exports`: under Node, `import` gets an ES module build (`dist/index.node.mjs`)
whose default export is the `RushDB` class; before, an ESM `import RushDB from` received the
CommonJS module object.
9 changes: 9 additions & 0 deletions .changeset/hybrid-fusion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@rushdb/javascript-sdk': minor
---

Hybrid search fusion controls. `fusion: 'dbsf'` fuses each leg's scores normalized by its own
distribution (mean ± 3σ, as Qdrant defines DBSF) instead of ranks (`rrf`, the default, with
`rrfK`). Each leg takes a `weight` (its share of the fused score) and a `prefetchLimit` (hits it
ranks before fusion, 1–10,000). On `vectorSearch`, the top-level `weight`/`prefetchLimit` are the
vector leg's and `text.weight`/`text.prefetchLimit` the text leg's; the result reports `fusion`.
9 changes: 9 additions & 0 deletions .changeset/named-embedding-indexes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@rushdb/javascript-sdk': minor
---

Embedding indexes have names. A name is unique within a project, defaults to
`<label>.<property>.<model>.<dimensions>.<similarity>`, and is returned when indexes are listed.
Search (`index`), inline vectors (`index`), stats, vector upsert and delete accept an index's name
as well as its id. The dashboard asks for the name in a second step when creating an index,
prefilled with the default.
22 changes: 22 additions & 0 deletions .changeset/remove-neo4j-remnants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
'@rushdb/javascript-sdk': patch
---

The RushDB engine is the only data store; what remained of the Neo4j-backed platform is removed.

- Projects no longer carry a `customDb` (bring-your-own Neo4j) connection: the `projects.custom_db`
column is dropped (migration `0010_drop_project_custom_db`), `GET /sdk/settings` no longer
returns `customDb`, `DELETE /projects/:id` no longer takes `shouldStoreCustomDbData`, and the
dashboard drops the "External Instance" badge. Every project is metered the same way.
- `POST /query/raw` returns `{ records }` (the always-empty `summary` is gone). Raw queries are
openCypher run by the engine, which must have the `cypher` language enabled.
- A write sent with `x-transaction-id` defers its side effects (recount, schema refresh,
relationship automation) to `POST /tx/:txId/commit`, and a failed request inside a transaction
rolls the transaction back. Both checks keyed off a Neo4j transaction object that was no longer
attached, so neither ran.
- `RUSHDB_TRANSACTION_TIMEOUT_MS` no longer falls back to `NEO4J_TRANSACTION_TIMEOUT_MS`.
- The CLI `db-restore` command now recounts the project after the restore; it never ran before.
- Deploy templates (Compose, Helm, Fly) run the engine with `--multitenant --languages cypher`,
which Core requires: it scopes every request to its project. Heroku's `app.json` sets
`RUST_ENGINE_URL` / `RUST_ENGINE_TOKEN`, the variables Core reads.
- SDK: `serverSettings` drops `customDB` / `managedDB`; doc comments no longer mention Neo4j.
11 changes: 11 additions & 0 deletions .changeset/text-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@rushdb/javascript-sdk': minor
---

Keyword (BM25) search. Text indexes cover one property of a label, or every string of it (`*`),
and are declared, listed and dropped through `/text-indexes` (`db.textIndexes`, MCP
`createTextIndex` / `listTextIndexes` / `deleteTextIndex`), with a default name of
`<label>.<property>.text`. `POST /search/text` (`db.records.textSearch`, MCP `textSearch`) ranks
matching records among those `labels` and `where` select, and `total` counts every match. A
vector search with a `text` leg becomes a hybrid search the engine fuses. The dashboard lists and
creates text indexes on the Search Indexes page and adds a Keyword search mode to Records.
Empty file modified .eslintrc
100644 → 100755
Empty file.
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 10.1.0
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm build
- run: pnpm types:check
- run: pnpm test
- run: npm pack --dry-run
39 changes: 39 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Release

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: write
pull-requests: write
id-token: write

concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: pnpm/action-setup@v4
with:
version: 10.1.0
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Upgrade npm for trusted publishing
run: npm install -g npm@^11.5.1
- run: pnpm install --frozen-lockfile
- uses: changesets/action@v1
with:
version: pnpm changeset version
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .gitignore
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ coverage
.rollup.cache
cjs
esm
packages/javascript-sdk/types
/types
Empty file modified .npmignore
100644 → 100755
Empty file.
Empty file modified CHANGELOG.md
100644 → 100755
Empty file.
Empty file modified CONTRIBUTING.md
100644 → 100755
Empty file.
Empty file modified LICENSE
100644 → 100755
Empty file.
58 changes: 56 additions & 2 deletions README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -172,14 +172,67 @@ const relationships = await db.relationships.find({

---

## RushDB Cloud or a self-hosted engine

The SDK works with RushDB in one of two ways:

| | RushDB Cloud | Self-hosted RushDB engine (direct mode) |
| --- | --- | --- |
| What you run | nothing: the managed service at [app.rushdb.com](https://app.rushdb.com) | one `rushdbd` binary, on your own infrastructure |
| Connect with | an API key | the engine URL and the engine token |

The engine is what you can self-host. RushDB Cloud runs that engine for you and adds the dashboard,
managed embeddings and the AI features (natural-language search, relationship-pattern suggestions),
which exist only in RushDB Cloud.

```typescript
// RushDB Cloud
const db = new RushDB('RUSHDB_API_KEY')

// A self-hosted engine
const db = new RushDB('ENGINE_TOKEN', {
direct: true,
engineUrl: 'http://127.0.0.1:3000',
scope: 'tenant-1' // only for an engine started with --multitenant
})
```

What each offers:

| Feature | Cloud | Self-hosted engine |
| --- | :---: | :---: |
| Records: create, read, update, set, upsert, delete, `find` with `where`, `orderBy`, `select`, `groupBy` | ✓ | ✓ |
| Relationships: `attach`/`detach`, `relationships.createMany`/`deleteMany`/`find` | ✓ | ✓ |
| Labels, properties, property values | ✓ | ✓ |
| Import JSON and CSV, export CSV | ✓ | ✓ |
| Text indexes and keyword search (`records.textSearch`) | ✓ | ✓ |
| External vector indexes; vector and hybrid search with a `queryVector` you supply | ✓ | ✓ |
| Raw openCypher (`query.raw`; the engine needs `--languages cypher`) | ✓ | ✓ |
| Schema (`ai.getSchema`, `ai.getSchemaMarkdown`) | ✓ | ✓ |
| Transactions | ✓ | record creates, updates, sets, deletes by id, attaches and imports are staged; other writes refuse a transaction |
| Managed embeddings: managed indexes, `records.vectorSearch` by text `query` | ✓ | — |
| Natural-language search (`ai.search`) | ✓ | — |
| Relationship-pattern suggestions (`relationships.patterns.*`) | ✓ | — |
| Project settings (`settings.get`), dashboard, projects, team access, MCP over HTTP with OAuth | ✓ | — |

In direct mode a Cloud-only method throws `CloudOnlyError` (with `method` and `reason`) before
sending anything, and no request ever goes to RushDB Cloud. A write the engine cannot stage into a
transaction throws `DirectModeError`, also before sending anything. The list is available in code:

```typescript
import { CLOUD_ONLY_METHODS, CloudOnlyError, isCloudOnlyMethod } from '@rushdb/javascript-sdk'
```

---

## SDK configuration

```typescript
import RushDB from '@rushdb/javascript-sdk'

const db = new RushDB('RUSHDB_API_KEY', {
// Override for self-hosted or staging
url: 'http://your-rushdb-server.com/api/v1',
// A different RushDB Cloud API endpoint (default: https://api.rushdb.com/api/v1)
url: 'https://api.rushdb.com/api/v1',
timeout: 30000
})
```
Expand All @@ -191,6 +244,7 @@ Key options:
- `timeout` — request timeout in ms (default: 10000)
- `httpClient` — custom HTTP client for advanced use
- `options.allowForceDelete` — allow deleting all records without criteria (default: false)
- `direct`, `engineUrl`, `scope` — direct mode against a standalone engine (see above)

Full config reference: [docs.rushdb.com/typescript-sdk/introduction#sdk-configuration-options](https://docs.rushdb.com/typescript-sdk/introduction#sdk-configuration-options)

Expand Down
5 changes: 5 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Security policy

Please do not report vulnerabilities in public issues. Report them to
security@rushdb.com with a minimal reproduction, affected version, impact, and
any available mitigation.
Loading
Loading