Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
508f9bd
refactor(nodedb): split trait_impl into focused submodules
farhan-syah May 15, 2026
610ee3d
feat(graph): add collection parameter to all graph operations
farhan-syah May 15, 2026
9637028
fix(sync): replace encode_or_empty with fallible try_encode
farhan-syah May 15, 2026
a868b49
fix(engines): adapt to updated upstream crate APIs
farhan-syah May 15, 2026
43580b9
ci(wasm): add browser tests and npm publish pipeline
farhan-syah May 15, 2026
b89367b
chore: bump version to 0.1.0-beta.1 and add community files
farhan-syah May 15, 2026
73e10fa
refactor(tests): split monolithic common/mod.rs into focused helper m…
farhan-syah May 15, 2026
a55d4ae
feat(query): add LiteError::Unsupported and guard unsupported scan mo…
farhan-syah May 15, 2026
37c63e6
test(sync): add sync interop and CRDT semantics test suites
farhan-syah May 15, 2026
e75c4a0
test: add SQL matrix, SQL parity, sync load, and FFI coverage
farhan-syah May 15, 2026
4550adb
docs: add sync protocol spec, SQL support matrix, and update public docs
farhan-syah May 15, 2026
111414e
chore: add tokio-postgres dep, nextest groups for new test suites, an…
farhan-syah May 15, 2026
eb1ab15
feat(storage): add bounded range scan to StorageEngineSync
farhan-syah May 15, 2026
e831309
feat(kv): add TTL support with inline deadline encoding
farhan-syah May 15, 2026
ec41bea
feat(graph): isolate CSR indices per collection
farhan-syah May 15, 2026
a15c034
feat(engine): persist FTS and spatial indices across restarts
farhan-syah May 15, 2026
12c9427
feat(sync): add outbound queues for columnar, vector, FTS, spatial, a…
farhan-syah May 15, 2026
2278cc5
refactor(sync): split transport monolith into focused modules
farhan-syah May 15, 2026
3845b94
feat(sync): wire vector outbound and complete array sync delegate
farhan-syah May 15, 2026
d589705
feat(query): make query engine async and add engine-aware DML dispatch
farhan-syah May 15, 2026
10fa20c
test: expand engine gate, SQL parity, persistence, and sync interop c…
farhan-syah May 15, 2026
6cd4734
test(sync): add vector and timeseries sync interop suites; update docs
farhan-syah May 15, 2026
6e1ee76
temp
farhan-syah May 16, 2026
f1c04a9
refactor: split NodeDbLite core and vector search into focused modules
farhan-syah May 16, 2026
33d0a51
feat(vector): add codec sidecar infrastructure for quantized reranking
farhan-syah May 16, 2026
e5e09dc
feat(query): extract vector op and write dispatch into dedicated modules
farhan-syah May 16, 2026
632910a
feat(array): implement Project, Aggregate, Elementwise, and Compact ops
farhan-syah May 17, 2026
d9b49b7
feat(query): add document, kv, crdt, and meta op handler modules
farhan-syah May 17, 2026
bf596be
refactor(query): split physical visitor adapter into per-op-family mo…
farhan-syah May 17, 2026
9f38434
feat(engine): add CRDT list/version ops and timeseries explicit-cutof…
farhan-syah May 17, 2026
ad794e4
feat(engine/strict): add bitemporal history tracking to strict engine
farhan-syah May 17, 2026
c7614d6
feat(engine/graph): add bitemporal edge history for graph collections
farhan-syah May 17, 2026
c8623a7
feat(engine/columnar): add bitemporal flag and segment tombstoning
farhan-syah May 17, 2026
37e9da9
feat(query/kv): implement kv materialize scan and windowed sorted ind…
farhan-syah May 17, 2026
c07473f
feat(query/document): implement UpdateFromJoin, Merge, and Materializ…
farhan-syah May 17, 2026
c6fb2a0
feat(query/columnar): add columnar op dispatch module
farhan-syah May 17, 2026
8d6c1f0
feat(query/meta): implement distributed meta-ops and temporal purge h…
farhan-syah May 17, 2026
527ccc3
refactor(query): extract shared msgpack payload helpers
farhan-syah May 17, 2026
b02deb6
feat(engine): add BM25ScoreScan support and spatial inverse entry map
farhan-syah May 17, 2026
892cfb2
feat(core): wire spatial and CSR indices into the query engine
farhan-syah May 17, 2026
ebecc71
feat(query): add graph, spatial, timeseries, and query op modules
farhan-syah May 17, 2026
0744c78
feat(query/physical_visitor): implement graph, spatial, timeseries, a…
farhan-syah May 17, 2026
6f0923b
refactor(query/visitor): decompose monolithic adapter into focused vi…
farhan-syah May 17, 2026
266e2c9
refactor(query): replace Unsupported errors with unreachable in Origi…
farhan-syah May 17, 2026
d88681d
test: update SQL parity tests to reflect newly implemented operations
farhan-syah May 17, 2026
c80635f
feat(query/filter): split filters into primitive and expression predi…
farhan-syah May 17, 2026
3f9a1d1
test: update filter tests and remove stale SQL support doc
farhan-syah May 17, 2026
7f43909
refactor(storage): migrate from redb to pagedb as the storage substrate
farhan-syah May 23, 2026
afe2e98
refactor(query): drop residual StorageEngineSync trait bounds
farhan-syah May 23, 2026
9892952
feat(storage): per-engine segment storage for vector, array, fts, col…
farhan-syah May 23, 2026
d0b4e2f
refactor(storage): remove redb backend; wire WASM/OPFS through pagedb
farhan-syah May 23, 2026
5fecd63
perf(kv): hot-path read cache + lock-free overlay check + stack-buffe…
farhan-syah May 24, 2026
04d5838
feat(graph): implement Personalized PageRank with teleport distribution
farhan-syah May 24, 2026
a565ffe
feat(document): bitemporal storage for embedded document collections
farhan-syah May 24, 2026
a422fb7
feat(graph): implement graph_pagerank on NodeDbLite with personalization
farhan-syah May 24, 2026
04d8bba
chore(lite): clippy cleanup and fix lock held across await in put_schema
farhan-syah May 24, 2026
5440d5e
fix(lite): restore FTS, graph, and vector indexes across process rest…
farhan-syah May 24, 2026
cf8cecd
feat(sql): bind parametrized SELECT placeholders end-to-end
farhan-syah May 25, 2026
f3085e5
fix(query): make bitemporal collections visible to SELECT without flush
farhan-syah May 25, 2026
a97fc43
refactor(runtime): consolidate wall-clock helpers into runtime::now_m…
farhan-syah Jun 10, 2026
2f30739
refactor(history): split document history ops into focused sub-modules
farhan-syah Jun 10, 2026
12bee3d
feat(sync): add SyncGate trait for per-document local-only control
farhan-syah Jun 10, 2026
0920dab
feat(vector,fts): add allowed_ids filter to vector_search and text_se…
farhan-syah Jun 10, 2026
9e95e95
feat(document): add batch document+vector ingest via document_put_wit…
farhan-syah Jun 10, 2026
35ca6f8
refactor: finish migration to runtime::now_millis across remaining mo…
farhan-syah Jun 10, 2026
d221be2
feat(storage): add at-rest encryption for pagedb storage
farhan-syah Jun 12, 2026
5aa0448
feat(config,core): add auto-flush background task and outbound queue …
farhan-syah Jun 12, 2026
ee750a8
feat(sync): replace in-memory outbound queues with durable storage-ba…
farhan-syah Jun 12, 2026
23e0147
refactor(sync): split SyncDelegate impl into focused submodules
farhan-syah Jun 12, 2026
047f9bf
feat(sync): add producer fencing, token refresh backoff, and stale-ti…
farhan-syah Jun 12, 2026
847821f
feat(sync): implement delete-on-ack transport with idempotent frame s…
farhan-syah Jun 12, 2026
70135e3
feat(engine): add memory-pressure backpressure guards and wire durabl…
farhan-syah Jun 12, 2026
0bd7e6a
feat(wasm,runtime): complete WASM runtime stubs and add crate-level d…
farhan-syah Jun 12, 2026
9e60ef9
test: add encryption, auto-flush, and dedup tests; wire nextest setup…
farhan-syah Jun 12, 2026
1499bc8
chore: update FFI bindings, WASM API, examples, docs, and dependency …
farhan-syah Jun 12, 2026
cfe63f0
fix(sync): update array sync module for new wire types and Encryption…
farhan-syah Jun 12, 2026
0113012
fix: adapt to updated core crate APIs across CRDT, FTS, and query engine
farhan-syah Jul 2, 2026
c1a505c
feat(sync,query): surface real schema for synced collections in SQL c…
farhan-syah Jul 2, 2026
f72b6d7
feat(sync): announce collection schema before first outbound delta
farhan-syah Jul 2, 2026
9a1ed2c
fix(sync): register synced collections under Origin's default database
farhan-syah Jul 2, 2026
f561395
test(sync): assert plain document scan returns synced rows
farhan-syah Jul 2, 2026
6cc5bd5
chore: ignore .claude directory
farhan-syah Jul 2, 2026
73c50ea
test(sync): remove duplicate plain document scan assertion
farhan-syah Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 19 additions & 0 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
#
# Run with: cargo nextest run -p nodedb-lite

experimental = ["setup-scripts"]

[scripts.setup.build-origin]
command = { command-line = "scripts/ensure-origin.sh", relative-to = "workspace-root" }
slow-timeout = { period = "600s", terminate-after = 1 }
capture-stderr = true

[profile.default]
# Hard ceiling per test. Anything above this is a bug, not a slow test.
slow-timeout = { period = "30s", terminate-after = 4 }
Expand Down Expand Up @@ -39,10 +46,18 @@ binary(/concurrency/)
| binary(/e2e/)
| binary(/integration/)
| binary(/compensation/)
| binary(/sync_interop/)
| binary(/sync_load/)
| binary(/sql_parity/)
| binary(/definition_sync_interop/)
'''
test-group = 'heavy'
threads-required = 'num-test-threads'

[[profile.default.scripts]]
filter = 'binary(/sync_interop/) | binary(/sync_load/) | binary(/definition_sync_interop/) | binary(/sql_parity/)'
setup = 'build-origin'

[test-groups]
heavy = { max-threads = 1 }

Expand All @@ -52,3 +67,7 @@ fail-fast = false

[profile.ci.junit]
path = "junit.xml"

[[profile.ci.scripts]]
filter = 'binary(/sync_interop/) | binary(/sync_load/) | binary(/definition_sync_interop/) | binary(/sql_parity/)'
setup = 'build-origin'
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# CI — thin wrapper that calls the reusable test workflow.

name: CI

on:
pull_request:
branches: [main]
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:
workflow_call:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
test:
if: github.event.pull_request.draft == false
name: Test Suite
uses: ./.github/workflows/test.yml
249 changes: 249 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
name: Release
run-name: Release ${{ github.ref_name }}

on:
push:
tags:
- "v*"

concurrency:
group: release
cancel-in-progress: false

permissions:
contents: read

env:
CARGO_TERM_COLOR: always

jobs:
# ── Validate tag ─────────────────────────────────────────────────────────────
validate-version:
name: Validate Version Tag
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
is_full_release: ${{ steps.version.outputs.is_full_release }}
steps:
- uses: actions/checkout@v6

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Validate tag against Cargo.toml
id: version
run: |
TAG="${GITHUB_REF_NAME}"
TAG_VERSION="${TAG#v}"

CARGO_VERSION=$(cargo metadata --no-deps --format-version=1 \
| jq -r '.packages[] | select(.name == "nodedb-lite") | .version')
CARGO_BASE=$(echo "$CARGO_VERSION" | grep -oP '^\d+\.\d+\.\d+')

echo "Tag version: $TAG_VERSION"
echo "Cargo.toml version: $CARGO_VERSION"
echo "Cargo.toml base: $CARGO_BASE"

if [[ ! "$TAG_VERSION" =~ ^([0-9]+\.[0-9]+\.[0-9]+)(-[a-zA-Z]+\.[0-9]+)?$ ]]; then
echo "::error::Invalid tag format '$TAG'. Expected: vX.Y.Z or vX.Y.Z-label.N"
exit 1
fi

TAG_BASE="${BASH_REMATCH[1]}"

if [[ "$TAG_BASE" != "$CARGO_BASE" ]]; then
echo "::error::Base version mismatch! Tag '$TAG_BASE' != Cargo.toml '$CARGO_BASE'"
exit 1
fi

# Full release = no hyphen suffix (v0.1.0, not v0.1.0-beta.1)
if [[ "$TAG_VERSION" == *-* ]]; then
echo "is_full_release=false" >> "$GITHUB_OUTPUT"
else
echo "is_full_release=true" >> "$GITHUB_OUTPUT"
fi

echo "version=$TAG_VERSION" >> "$GITHUB_OUTPUT"

# ── CI gate ──────────────────────────────────────────────────────────────────
ci:
name: CI Gate
needs: validate-version
uses: ./.github/workflows/ci.yml

# ── WASM gate ────────────────────────────────────────────────────────────────
wasm:
name: WASM Gate
needs: validate-version
uses: ./.github/workflows/wasm.yml

# ── Publish crates to crates.io ──────────────────────────────────────────────
# Requires secret: CARGO_REGISTRY_TOKEN
# Tier 1: nodedb-lite (no internal Lite deps).
# Tier 2: nodedb-lite-ffi, nodedb-lite-wasm (both depend on nodedb-lite).
# is_published / wait_for polling mirrors the nodedb workspace pattern so
# a re-run after a failed publish never double-publishes an already-indexed
# crate.
publish-crates:
name: Publish to crates.io
needs: [validate-version, ci, wasm]
runs-on: ubuntu-latest
environment: crates.io
permissions:
contents: read
steps:
- uses: actions/checkout@v6

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
cmake clang libclang-dev pkg-config protobuf-compiler perl

- name: Set version from tag
run: |
VERSION="${{ needs.validate-version.outputs.version }}"
CURRENT=$(cargo metadata --no-deps --format-version=1 \
| jq -r '.packages[] | select(.name == "nodedb-lite") | .version')
if [[ "$VERSION" != "$CURRENT" ]]; then
sed -i "0,/^version = \".*\"/s//version = \"$VERSION\"/" Cargo.toml

# For pre-release versions, pin internal dep requirements so
# semver "0.1.0" doesn't fail to match "0.1.0-beta.1".
if [[ "$VERSION" == *-* ]]; then
sed -i -E 's/(nodedb-lite = \{ [^}]*version = )"[^"]*"/\1"='"$VERSION"'"/' Cargo.toml
echo "Updated internal dep versions to =$VERSION"
fi

echo "Updated workspace version: $CURRENT -> $VERSION"
else
echo "Version already matches, no change needed"
fi

- name: Publish crates
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
TIER1="nodedb-lite"
TIER2="nodedb-lite-ffi nodedb-lite-wasm"

is_published() {
curl -sf \
-H "User-Agent: nodedb-lite-ci (github.com/NodeDB-Lab/nodedb-lite)" \
"https://crates.io/api/v1/crates/$1/$2" > /dev/null 2>&1
}

wait_for() {
local crate="$1" version="$2"
echo -n " Waiting for $crate@$version..."
for i in $(seq 1 30); do
if is_published "$crate" "$version"; then
echo " ready"
return 0
fi
sleep 5
done
echo " timed out!"
return 1
}

publish_tier() {
local tier_name="$1"; shift
local crates=("$@")
local need_wait=()

echo "::group::Tier: $tier_name"
for crate in "${crates[@]}"; do
VERSION=$(cargo metadata --no-deps --format-version=1 \
| jq -r --arg name "$crate" '.packages[] | select(.name == $name) | .version')
if is_published "$crate" "$VERSION"; then
echo " $crate@$VERSION already published — skipping"
else
echo " Publishing $crate@$VERSION..."
cargo publish -p "$crate" --allow-dirty --no-verify
need_wait+=("$crate:$VERSION")
fi
done

for entry in "${need_wait[@]}"; do
wait_for "${entry%%:*}" "${entry##*:}"
done
echo "::endgroup::"
}

publish_tier "1 (no internal Lite deps)" $TIER1
publish_tier "2 (depends on nodedb-lite)" $TIER2

# ── Publish npm package ──────────────────────────────────────────────────────
# Requires secret: NPM_TOKEN
publish-npm:
name: Publish to npm
needs: [validate-version, ci, wasm, publish-crates]
runs-on: ubuntu-latest
environment: npm
permissions:
contents: read
steps:
- uses: actions/checkout@v6

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown

- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org

- name: Build WASM release
run: wasm-pack build --target web --release nodedb-lite-wasm

- name: Rewrite pkg/package.json metadata
working-directory: nodedb-lite-wasm/pkg
run: |
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
pkg.name = '@nodedb/lite';
pkg.version = '${{ needs.validate-version.outputs.version }}';
pkg.license = 'Apache-2.0';
pkg.repository = { type: 'git', url: 'https://github.com/NodeDB-Lab/nodedb-lite' };
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"

- name: Publish to npm
working-directory: nodedb-lite-wasm/pkg
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
if [[ "${{ needs.validate-version.outputs.is_full_release }}" == "true" ]]; then
npm publish --access public
else
npm publish --access public --tag beta
fi

# ── Create GitHub Release ─────────────────────────────────────────────────────
github-release:
name: Create GitHub Release
needs: [validate-version, publish-crates, publish-npm]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.validate-version.outputs.version }}
name: NodeDB Lite ${{ needs.validate-version.outputs.version }}
generate_release_notes: true
draft: false
prerelease: ${{ contains(needs.validate-version.outputs.version, '-') }}
80 changes: 80 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Reusable test workflow: fmt, clippy, native test suite, and wasm32 check.
#
# Called by:
# - ci.yml (PR checks)
# - release.yml (pre-publish gate)
#
# Lite is a separate workspace from Origin. It consumes the nodedb-* shared
# crates from crates.io. Local development uses `.cargo/config.toml`
# [patch.crates-io] to resolve to a sibling Origin checkout; CI uses the
# published versions.

name: Test

on:
workflow_call:

permissions:
contents: read

env:
CARGO_TERM_COLOR: always

jobs:
lint:
name: Lint & Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
with:
shared-key: lite-workspace
- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
cmake clang libclang-dev pkg-config protobuf-compiler perl
- name: Check formatting
run: cargo fmt --all -- --check
- name: Run clippy
run: cargo clippy --workspace --all-targets --profile ci -- -D warnings
- name: Check wasm32 target
run: cargo check -p nodedb-lite-wasm --target wasm32-unknown-unknown

test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
shared-key: lite-workspace
- name: Install system deps
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
cmake clang libclang-dev pkg-config protobuf-compiler perl
- name: Install cargo-nextest
uses: taiki-e/install-action@v2
with:
tool: nextest
- name: Run tests
run: |
cargo nextest run \
--workspace \
--cargo-profile ci --profile ci \
--no-fail-fast
- name: Upload JUnit report
if: always()
uses: actions/upload-artifact@v4
with:
name: junit-report
path: target/nextest/ci/junit.xml
if-no-files-found: ignore
Loading
Loading