Skip to content

Conversation

@konard
Copy link
Member

@konard konard commented Jan 16, 2026

Summary

Implements issue #13 - StorageBackend interface/trait that enables pluggable storage backends. This abstraction allows switching between memory, link-cli, and custom backends via configuration without code changes.

Fixes #13

JavaScript Changes

New Files

  • js/src/backends/types.ts - TypeScript type definitions for StorageBackend interface
  • js/src/backends/registry.js - Backend registry and MemoryBackendAdapter implementation
  • js/src/backends/registry.d.ts - TypeScript declarations for registry
  • js/tests/backend-registry.test.js - Comprehensive test suite (30 tests)

StorageBackend Interface

interface StorageBackend {
  // Lifecycle
  connect(): Promise<void>;
  disconnect(): Promise<void>;
  isConnected(): boolean;

  // Core operations
  save(link: Link): Promise<LinkId>;
  load(id: LinkId): Promise<Link | null>;
  delete(id: LinkId): Promise<boolean>;
  query(pattern: LinkPattern): Promise<Link[]>;

  // Batch operations
  saveBatch(links: readonly Link[]): Promise<LinkId[]>;
  deleteBatch(ids: readonly LinkId[]): Promise<boolean[]>;

  // Metadata
  getCapabilities(): BackendCapabilities;
  getStats(): BackendStats;
}

Usage Example (JavaScript)

import { BackendRegistry, MemoryBackendAdapter } from 'links-queue';

// Use built-in memory backend
const backend = BackendRegistry.create({ type: 'memory' });
await backend.connect();

// Register custom backend
BackendRegistry.register('custom', MyCustomBackend);
const customBackend = BackendRegistry.create({ type: 'custom', options: {...} });

Rust Changes

New Files

  • rust/src/backends/traits.rs - StorageBackend trait and types
  • rust/src/backends/memory_backend.rs - MemoryBackend implementation
  • rust/src/backends/registry.rs - BackendRegistry and StorageBackendDyn trait

StorageBackend Trait

pub trait StorageBackend<T: LinkType>: Send + Sync {
    // Lifecycle
    fn connect(&mut self) -> impl Future<Output = BackendResult<T, ()>> + Send;
    fn disconnect(&mut self) -> impl Future<Output = BackendResult<T, ()>> + Send;
    fn is_connected(&self) -> bool;

    // Core operations
    fn save(&mut self, link: Link<T>) -> impl Future<Output = BackendResult<T, T>> + Send;
    fn load(&self, id: T) -> impl Future<Output = BackendResult<T, Option<Link<T>>>> + Send;
    fn delete(&mut self, id: T) -> impl Future<Output = BackendResult<T, bool>> + Send;
    fn query(&self, pattern: &LinkPattern<T>) -> impl Future<Output = BackendResult<T, Vec<Link<T>>>> + Send;

    // Metadata
    fn capabilities(&self) -> BackendCapabilities;
    fn stats(&self) -> BackendStats;
}

Usage Example (Rust)

use links_queue::{BackendRegistry, BackendConfig, StorageBackend, MemoryBackend};

// Create backend via registry
let mut registry = BackendRegistry::<u64>::new();
let mut backend = registry.create(&BackendConfig::memory())?;
backend.connect_dyn().await?;

// Or use MemoryBackend directly
let mut backend = MemoryBackend::<u64>::new();
backend.connect().await?;

Features

Both Implementations

  • ✅ Connect/disconnect lifecycle management
  • ✅ Track operation statistics (reads, writes, deletes, queries)
  • ✅ Report backend capabilities and durability levels
  • ✅ Switching between backends via configuration
  • ✅ API parity between JS and Rust

BackendCapabilities

  • supportsTransactions - Whether the backend supports atomic transactions
  • supportsBatchOperations - Whether batch operations are native (vs. simulated)
  • durabilityLevel - 'none' | 'fsync' | 'replicated'
  • maxLinkSize - Maximum link size in bytes (0 for unlimited)
  • supportsPatternQueries - Whether pattern queries are native (vs. scanning)

BackendStats

  • totalLinks - Total number of links stored
  • usedSpace - Approximate storage space used
  • operations - Read/write/delete/query counters
  • connectedAt - Connection timestamp
  • uptimeMs - Uptime in milliseconds

Test Plan

  • JavaScript tests pass (135 tests including 30 new backend registry tests)
  • Rust tests pass (109 tests)
  • All doctests pass
  • ESLint passes with no warnings
  • Clippy passes with no warnings
  • Prettier formatting verified

Version Changes

  • JavaScript: Added changeset for minor version bump (0.3.0 → 0.4.0)
  • Rust: Bumped to 0.2.0

🤖 Generated with Claude Code

Adding CLAUDE.md with task information for AI processing.
This file will be removed when the task is complete.

Issue: #13
@konard konard self-assigned this Jan 16, 2026
Implements issue #13 - StorageBackend interface/trait enabling pluggable storage backends

JavaScript changes:
- Add StorageBackend interface with lifecycle, CRUD, batch, and metadata operations
- Add BackendCapabilities and BackendStats types for backend introspection
- Add MemoryBackendAdapter wrapping MemoryLinkStore with StorageBackend interface
- Add BackendRegistry for registering and creating backends by configuration
- Add comprehensive tests for backend registry and adapter (30 tests)
- Add changeset for minor version bump

Rust changes:
- Add StorageBackend trait with async lifecycle, CRUD, and batch operations
- Add BackendCapabilities, BackendStats, and DurabilityLevel types
- Add MemoryBackend implementing StorageBackend trait
- Add StorageBackendDyn for object-safe trait objects
- Add BackendRegistry for factory-based backend creation
- Bump version to 0.2.0 for the new feature

Both implementations:
- Support connect/disconnect lifecycle management
- Track operation statistics (reads, writes, deletes, queries)
- Report backend capabilities and durability levels
- Enable switching between backends via configuration
- Maintain API parity between JS and Rust

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@konard konard changed the title [WIP] [Phase 3] Define StorageBackend interface/trait (API Contract) [Phase 3] Implement StorageBackend interface/trait for pluggable backends Jan 17, 2026
@konard konard marked this pull request as ready for review January 17, 2026 00:13
konard and others added 5 commits January 17, 2026 01:16
Use .ts and .d.ts extensions instead of .js for type imports
to resolve Deno type-checking errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The ILink export was using `export type { Link as ILink } from './types.js'`
which caused Deno to fail with "Cannot find module types.js".
Changed to a simple type alias: `export type ILink = Link;`

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Changed JSDoc imports from '../types.js' to '../index.js' in registry.js
- Updated registry.d.ts to import Link types from '../types.ts' to match
  the StorageBackend interface, fixing the type mismatch error
- Fixed prettier formatting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove beforeEach from JS tests for Deno compatibility
  (Deno's node:test doesn't support beforeEach)
- Use createConnectedBackend() helper and inline reset() calls instead
- Fix Rust formatting with cargo fmt
- Fix useless comparison warning (u64 >= 0)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@konard
Copy link
Member Author

konard commented Jan 17, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $19.315999 USD
  • Calculated by Anthropic: $13.966840 USD
  • Difference: $-5.349159 (-27.69%)
    📎 Log file uploaded as Gist (2156KB)
    🔗 View complete solution draft log

Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Member Author

konard commented Jan 17, 2026

Ensure all changes are correct, consistent and fully meet the requirements.

@konard konard marked this pull request as draft January 17, 2026 09:44
@konard
Copy link
Member Author

konard commented Jan 17, 2026

🤖 AI Work Session Started

Starting automated work session at 2026-01-17T09:44:47.038Z

The PR has been converted to draft mode while work is in progress.

This comment marks the beginning of an AI work session. Please wait working session to finish, and provide your feedback.

Resolves conflicts by keeping both backend exports (from this branch)
and queue exports (from main).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@konard konard marked this pull request as ready for review January 17, 2026 09:50
@konard
Copy link
Member Author

konard commented Jan 17, 2026

🤖 AI Work Session Completed

Changes in this session:

  • ✅ Resolved merge conflicts with main branch (merged queue interfaces)
  • ✅ Verified all changes meet issue [Phase 3] Define StorageBackend interface/trait (API Contract) #13 requirements:
    • TypeScript interface definitions in js/src/backends/types.ts
    • Rust trait definitions in rust/src/backends/traits.rs
    • Backend registry/factory implementations for both JS and Rust
    • Documentation with custom backend examples
    • API parity between JS and Rust implementations
  • ✅ All tests passing locally (165 JS tests, 166 Rust tests including doctests)
  • ✅ Both CI pipelines passing
  • ✅ Merge status is CLEAN

The PR is ready for review.

@konard
Copy link
Member Author

konard commented Jan 17, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $2.336479 USD
  • Calculated by Anthropic: $1.484051 USD
  • Difference: $-0.852427 (-36.48%)
    📎 Log file uploaded as Gist (451KB)
    🔗 View complete solution draft log

Now working session is ended, feel free to review and add any feedback on the solution draft.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Phase 3] Define StorageBackend interface/trait (API Contract)

2 participants