Skip to content

feat(sync-engine): define and inject pluggable StorageProvider interface for SyncQueue #35

@rohansaini-02

Description

@rohansaini-02

Problem

Currently, persistToStorage() and loadFromStorage() inside poc-sync-engine/src/SyncQueue.ts are empty placeholders:

private persistToStorage() {
}

private loadFromStorage() {
  this.queue = [];
}

To make the sync queue modular and reusable across both web (browser localStorage) and React Note (MMKV, SQLite, or WatermelonDB), we should decouple storage operations from the queue implementation.

However, async storage backends introduce initialization ordering concerns that cannot safely be handled inside the constructor, potentially creating race conditions if queue operations (like enqueue or peek) are called before storage hydration completes. Furthermore, introducing asynchronous persistence requires ensuring write ordering/concurrency remains deterministic, and that corrupted or invalid serialized state is handled gracefully.

Proposed Solution

  1. Define a generic IStorageProvider interface:
    export interface IStorageProvider {
    getItem(key: string): string | null | Promise<string | null>;
    setItem(key: string, value: string): void | Promise;
    }
  2. Accept a storage adapter implementation during initialization. To handle the asynchronous serialization lifecycle safely, possible approaches include:
    • Using a Static Factory Method (e.g., SyncQueue.create(storage)) to ensure hydration completes before returning the initialized instance.
    • Using an explicit asynchronous lifecycle method (e.g., .initialize() or .hydrate()).
  3. Safely deserialize the stored queue state (handling JSON parsing failures gracefully to avoid bricking queue initialization).
  4. Implement writes to the storage engine, ensuring that write ordering/concurrency remains deterministic for async storage operations.

Acceptance Criteria

  • SyncQueue depends on an injected IStorageProvider interface rather than environment-specific APIs.
  • Hydration is safe from constructor-level asynchronous race conditions.
  • Serialization/parsing logic gracefully handles corrupted or invalid payloads.
  • Queue writes to the storage provider are robust against concurrent state mutations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions