Skip to content

Releases: denislistiadi/syncraft-labs

v0.7.1 - Security Hardening, Modular Adapter Architecture & Docs Upgrade

Choose a tag to compare

@denislistiadi denislistiadi released this 15 Oct 13:11
806b9c9

Syncraft Labs v0.7.1 - Security Hardening, Modular Adapter Architecture & Docs Upgrade

This release delivers critical security hardening against prototype pollution vulnerabilities, modular architecture refactoring for React and Vue bindings (< 150 LOC per file), and an infrastructure upgrade to Astro v7 and Starlight v0.42 with client-side Mermaid diagram rendering. Fully backward compatible with zero breaking changes.

Breaking Changes

None. All public APIs, composables, hooks, and types remain 100% backward compatible.

Key Improvements

  • Security Hardening (Core):

    • Hardened applyPatches and proxy object/array handlers against prototype pollution attacks by strictly validating and rejecting __proto__, constructor, and prototype keys during state mutation.
    • Resolved transitive security vulnerabilities in package-lock.json via targeted dependency overrides.
  • Modular React Adapter Architecture (@syncraft-labs/react):

    • Decomposed monolithic use-sync.ts (352 lines) into focused, single-responsibility modules:
      • controller.ts (119 lines): Store lifecycle controller, registry WeakMap, and cleanup callbacks.
      • use-network.ts (36 lines): Online/offline event tracking and reconnect synchronization.
      • use-sync-suspense.ts (62 lines): Suspense-enabled hook variant.
      • use-sync.ts (146 lines): Main hook composable and backward-compatible re-exports.
    • Sanitized README syntax and typographical standards.
  • Modular Vue Adapter Architecture (@syncraft-labs/vue):

    • Decomposed monolithic use-sync.ts (271 lines) into focused, single-responsibility modules:
      • controller.ts (107 lines): Store lifecycle controller, registry WeakMap, and cleanup callbacks.
      • use-network.ts (43 lines): Composable for online/offline event tracking.
      • use-sync.ts (141 lines): Main composable and backward-compatible re-exports.
    • Aligned JSDoc comments to draft updater specifications and resolved duplicate closing template tags in README.
  • Documentation & Site Infrastructure (@syncraft-labs/docs):

    • Upgraded documentation site framework to Astro v7 and @astrojs/starlight v0.42.
    • Integrated astro-mermaid for client-side SVG diagram rendering across documentation pages.
    • Refactored PlaygroundInner.tsx into modular subcomponents (TaskHeader.tsx, TaskInput.tsx, TaskItem.tsx, TaskList.tsx) with isolated CSS modules.
    • Standardized generator scripts and metadata generation (llms.txt, llms-full.txt, and sitemap.xml).
  • CI Workflow Optimization:

    • Scoped package build and test matrix across Node 20 and Node 22, isolating Node 22 for Astro v7 documentation validation.

Pull Requests

  • PR #62: release: v0.7.1 - security hardening, modular adapter decomposition, and docs upgrade

Upgrade

npm install @syncraft-labs/core@0.7.1 @syncraft-labs/react@0.7.1 @syncraft-labs/vue@0.7.1

v0.7.0 — Observability, Devtools & Fine-Grained Reactivity

Choose a tag to compare

@denislistiadi denislistiadi released this 12 Oct 10:28

Syncraft Labs v0.7.0 — Observability, Devtools & Fine-Grained Reactivity

This release introduces explicit lifecycle event hooks for network synchronization, browser devtools inspection support, selector-based fine-grained reactivity, atomic IndexedDB transactions, and redirectable structured logging. Fully backward compatible — zero breaking changes.

Breaking Changes

None.

Key Features and Improvements

  • Lifecycle Event Hooks (#20, PR #60):

    • Added onSyncStart, onSyncSuccess, and onSyncError to BaseControllerOptions across React and Vue adapters to track background sync runs without subscribing to internal state mutations.
    • Added onRollback(error, previousState) callback to SyncStoreConfig and useSync, allowing applications to alert users and trigger telemetry when local persistence fails and optimistic draft states are reverted.
  • DevTools Inspection Hook (#21, PR #60):

    • Automatically registers active SyncStore singleton instances into window.__SYNCRAFT_DEVTOOLS__.stores (Map<string, SyncStore<any>>) in browser runtimes.
    • Enables browser developer extensions and console debugging scripts to inspect store snapshots and monitor queued outbox mutations.
    • Automatically cleans up and unregisters stores on destroy().
  • Selector-Based Reactivity & Fine-Grained Subscriptions (PR #59):

    • Added optional selector?: (state: T | undefined) => R parameter to useSync configuration in both @syncraft-labs/react and @syncraft-labs/vue.
    • Memoizes selected state slices, preventing unnecessary component re-renders when unrelated branches of a large state tree mutate.
    • Vue adapter migrated component listener cleanup to onScopeDispose to eliminate subscription memory leaks during SSR and Suspense boundary teardown.
  • Atomic IndexedDB Transactions & Retry Circuit Breaker (PR #58):

    • Consolidated state writes and outbox appends into a single atomic IndexedDB readwrite transaction block (persistState), eliminating outbox/state mismatch race conditions.
    • Background synchronization loops now detect non-retryable HTTP 4xx Client Errors and immediately halt polling to prevent infinite exponential backoff loops.
  • Structured & Redirectable Logging (#22, PR #60):

    • Added injectable logger?: SyncraftLogger interface (warn, error, optional info, debug) to SyncStoreConfig and adapter options.
    • Replaced hardcoded console calls throughout core storage, controller pipelines, and shape validators, enabling seamless routing to application logging frameworks and remote monitoring sinks.
  • Infrastructure & Security:

    • Migrated npm package publication to Trusted Publishers using tokenless OpenID Connect (OIDC) authentication.
    • Integrated Driftgraph architecture gatekeeper (denislistiadi/driftgraph@v1) into CI to maintain architectural modularity and guard against cyclic dependencies.

Closed Issues and Pull Requests

  • Issue #20 — Lifecycle event hooks (PR #60)
  • Issue #21 — Devtools inspection hook (PR #60)
  • Issue #22 — Structured, redirectable logging (PR #60)
  • PR #58 — fix(core): refactor persistence layer for atomic transactions
  • PR #59 — feat(bindings): implement selector-based reactivity and improve unmount cleanup
  • PR #60 — feat(core): add lifecycle event hooks and devtools inspection hook
  • PR #57 — ci: integrate driftgraph architecture gatekeeper

Upgrade

npm install @syncraft-labs/core@0.7.0 @syncraft-labs/react@0.7.0 @syncraft-labs/vue@0.7.0

v0.6.0 — Conflict Resolution & Sync Robustness

Choose a tag to compare

@denislistiadi denislistiadi released this 15 Sep 15:06

Syncraft Labs v0.6.0 — Conflict Resolution & Sync Robustness

This release introduces pluggable conflict resolution strategies, cross-browser storage quota recovery, and the publication of RFC-001 outlining Syncraft's long-term CRDT architecture. Fully backward compatible — zero breaking changes.

Breaking Changes

None.

Key Features and Improvements

  • Pluggable Conflict Resolution (#17):

    • Pure resolveConflict engine supporting "lastWriteWins" (default) and "custom" three-way merge algorithms (base, local, remote).
    • Added applyRemoteState(remote) on BaseStoreController for applying WebSocket broadcasts, server-sent events, or polling updates while automatically reconciling pending local outbox patches.
    • Fully integrated into React (useSync) and Vue (useSync) composables.
    • Dedicated guide available in docs: /guides/conflict-resolution/.
  • Storage Quota Handling & Recovery (#19):

    • Cross-browser isQuotaExceededError() utility detecting WebKit QuotaExceededError, Gecko NS_ERROR_DOM_QUOTA_REACHED, and legacy error variants.
    • withQuotaGuard storage interceptor: automatically rolls back optimistic in-memory drafts upon disk quota exhaustion, emits typed SyncraftError (source: "store", retryable: false), and triggers the new onQuotaExceeded callback for telemetry and alert dialogs.
    • Dedicated guide available in docs: /guides/storage-quota/.
  • RFC-001: CRDT Evaluation & Architectural Roadmap (#18):

    • Published comprehensive analysis evaluating State-based and Operation-based CRDTs (Yjs, Automerge) vs JSON Patches.
    • Formally established Syncraft's core design commitment: retain lightweight JSON Patches (<2 KB) as default, deferring CRDTs to an optional post-v1.0 plugin architecture (@syncraft-labs/crdt-yjs).
    • Removed misleading "crdt" keyword from package metadata.
  • Official Documentation Changelog:

    • Added dedicated Changelog Page in official docs tracking release history and upgrade paths from v0.6.0 down to v0.1.0.

Closed Issues and Pull Requests

  • Issue #17 — Pluggable conflict resolution strategy (PR #52)
  • Issue #18 — Evaluate optional CRDT backend (PR #53)
  • Issue #19 — Storage quota handling (PR #54)

Upgrade

npm install @syncraft-labs/core@0.6.0 @syncraft-labs/react@0.6.0 @syncraft-labs/vue@0.6.0

v0.5.0 — Collections, Correctness & Adapter Hardening

Choose a tag to compare

@denislistiadi denislistiadi released this 08 Sep 17:46

Syncraft Labs v0.5.0 — Collections, Correctness & Adapter Hardening

This release adds native Map and Set support to the draft engine, explicit
unsupported-type detection, a full adapter reliability overhaul (deduped sync
loops, race-free reconnects, coherent error contracts), and patch-correctness
proofs via property-based testing. Fully backward compatible — no breaking
changes.

Breaking Changes

None.

Key Features and Improvements

  • Map & Set in drafts (#13): Map (set, delete, clear) and Set
    (add, delete, clear) inside produce now generate granular patches
    reusing replace / add / remove with $entries and $values path
    conventions (keys/values restricted to string | number). hybridClone
    preserves Date / Map / Set through applyPatches.
  • Unsupported-type detection (#14): new validateStateShape() and
    isUnsupportedType() utilities return explicit errors carrying the property
    path and constructor name (Date degrades to a dev-mode warning guiding
    toward ISO strings or timestamps). Enforced in createSyncStore,
    produceWithPatches, hydrate(), and BroadcastChannel sync with zero
    production overhead.
  • Adapter reliability overhaul (#38, #39, #40, #41): singleton
    StoreController per store key deduplicates hydration, fetcher calls, and
    background sync loops across components sharing a key; in-flight sync mutex
    plus single-snapshot compactOutbox close the outbox re-read window and
    reconnect interleaving; clarified contracts — update() is fire-and-forget
    into error state while refetch() throws — with SyncraftError /
    toSyncraftError() normalization; fixed the useSyncSuspense infinite-throw
    loop on hydration rejection (errors cached and thrown once to Error
    Boundaries), with a dedicated suspense suite.
  • Patch-correctness proofs (#15): general property-based suite asserting
    applyPatches(base, patches) === nextState plus inverse reversibility over
    1,000 randomized iterations per run (5 properties × 200). Fixed
    markChanged parent propagation for repeated mutations to the same path and
    added Map / Set parent-copy guards.
  • Cheaper array copies (#16): shallowCopy uses target.slice(), covered
    by benchmarks and decision record ADR-001 (custom persistent structures
    deferred; collection mode recommended past ~100k items).
  • Leaner engine: core modularized into produce/, guards/, storage/,
    types/, store/, controller/ behind barrel files (≤200 lines/file);
    React and Vue extend a shared BaseStoreController, removing duplicated
    controller logic.
  • Governance & hygiene: SECURITY.md plus SYNCRAFT-SEC-2026-001 advisory
    pages; brace-expansion advisory resolved (2.1.4); the sole runtime
    dependency (idb) carries zero advisories.

Closed Issues and Pull Requests

  • Issue #13 — Map & Set support in draft state (PR #48)
  • Issue #14 — Explicit detection for unsupported types (PR #37)
  • Issue #15 — General property-based test suite (PR #49)
  • Issue #16 — Structural sharing for large arrays (PR #50)
  • Issues #38, #39, #40, #41 — adapter dedup, sync races, error contracts,
    suspense handling (PR #46)
  • Security policy and advisory docs (PR #47)
  • Dependency bumps: js-yaml, postcss, fast-uri (PRs #42–#44)

Upgrade

npm install @syncraft-labs/core@0.5.0 @syncraft-labs/react@0.5.0 @syncraft-labs/vue@0.5.0

v0.4.2

Choose a tag to compare

@denislistiadi denislistiadi released this 22 Aug 16:33

Security Release: Version 0.4.2

CRITICAL SECURITY WARNING

Version 0.4.1 of this package was compromised by a supply-chain attack associated with the PolinRider malware campaign. The compromised version contained heavily obfuscated malicious code hidden via extensive whitespace padding designed to act as an information stealer and persistent backdoor.

Version 0.4.1 has been strictly deprecated. If you have installed or depended on version 0.4.1, you must treat your environment as potentially compromised.


Urgent Action Required for Users

If your project currently pulls or allows version 0.4.1, please execute the following remediation steps immediately:

  1. Purge Cache and Lockfiles:

    npm cache clean --force
    rm -rf node_modules package-lock.json yarn.lock
  2. Force Update to Safe Version:
    Update your package.json dependency line to strictly require version 0.4.2 or higher:

    "@syncraft-labs/core": "^0.4.2"
    "@syncraft-labs/react": "^0.4.2"
    "@syncraft-labs/vue": "^0.4.2"
  3. Safe Reinstallation:
    Reinstall your dependencies using the --ignore-scripts flag to prevent any latent malicious installation hooks from executing:

    npm install --ignore-scripts
    # OR
    yarn install --ignore-scripts
  4. Credential Rotation:
    As PolinRider targets environment variables and access tokens, we strongly recommend rotating all environment secrets, API keys, and deployment tokens that were active on machines where 0.4.1 was installed.


What Was Fixed in 0.4.2?

  • Malware Eviction: Completely removed the injected obfuscated PolinRider payloads from all core assets and codebase builds.
  • Build Integrity Audit: Validated the release build from an isolated, verified clean environment.
  • Account Security Hardening: Rotated all internal NPM publishing tokens and enforced mandatory Two-Factor Authentication (2FA) for Publishing to secure future releases against unauthorized access.

We apologize for the disruption and appreciate the community members who promptly flagged this anomaly.

v0.4.0 — Storage & Data Integrity Foundation

Choose a tag to compare

@denislistiadi denislistiadi released this 20 Aug 17:50

Syncraft Labs v0.4.0 — Storage & Data Integrity Foundation

This release marks the completion of Milestone 1, focusing on storage performance, data integrity, dev-mode immutability safety, and robust outbox queue handling for enterprise local-first applications.

Breaking Changes

  • Core: OutboxEntry<T> no longer contains a snapshot field. Outbox entries now store only patches and inversePatches, resulting in a >80% reduction in IndexedDB storage footprint for large datasets. Applications that previously accessed entry.snapshot in custom pusher functions should use store.getSnapshot() or the new applyPatches() utility.

Key Features and Improvements

  • Granular Collection Storage (storageMode: "collection"): Added support for per-entity storage partitioning in IndexedDB when managing collections (Record<string, Entity>). Updating single records only writes the affected entity to storage rather than rewriting the entire dataset. Configurable via storageMode: "collection" and idField.
  • Patch-Based Outbox & applyPatches: Transitioned the outbox queue to store lightweight JSON patches and inverse patches. Exported the standalone applyPatches<T>(baseState, patches) utility for applying Immer-style RFC 6902 patches.
  • Outbox Compaction (compactOutbox): Added automatic compaction in React and Vue integrations before background push cycles. Merges consecutive mutations targeting the same path using a last-write-wins strategy to reduce network bandwidth and pusher request count. Also exposed as store.compactOutbox() and standalone compactOutbox().
  • Configurable Outbox Overflow Strategies: Introduced overflowStrategy ("reject", "dropOldest", or "forceFlush") and onOverflow callback in store and hook configurations, preventing unbounded outbox growth during prolonged offline periods.
  • Development-Mode Deep Freeze (deepFreeze): Added automatic recursive Object.freeze() on in-memory state returned by store.getSnapshot(), store.get(), store.hydrate(), and subscribers in development environments (NODE_ENV !== "production"). Detects and prevents accidental direct mutations outside store.set() with zero runtime overhead in production builds.
  • Circular Reference Detection (assertNoCycles): Integrated cycle detection during proxy draft traversal, state assignments, and hydration. Correctly distinguishes true circular references from acyclic diamond/DAG structures and throws explicit descriptive errors with property paths.
  • Documentation and SEO: Synchronized API reference tables across all package READMEs and the official documentation site, and added Google Search Console site verification.

Closed Issues and Pull Requests

  • Issue #7: Granular/keyed storage for large state (PR #30)
  • Issue #8: Outbox: store patches, not full snapshots (PR #31)
  • Issue #9: Outbox compaction (PR #32)
  • Issue #10: Explicit outbox overflow strategy (PR #33)
  • Issue #11: Deep freeze state in development mode (PR #34)
  • Issue #12: Circular reference detection (PR #35)

v0.3.0

Choose a tag to compare

@denislistiadi denislistiadi released this 01 Aug 18:37
3abeddc

What's New

Changed

  • Core: Replaced immer dependency with a custom, lightweight proxy-based implementation to reduce bundle size and improve enterprise integration.
  • Types: Changed the generic state constraint in createSyncStore and hooks from T extends object to T extends Record<string, unknown> | any[] (enforced via types vs interfaces for stricter plain-object adherence) to prevent runtime persistence failures with non-serializable objects like Map or Set in IndexedDB.
  • Docs: Migrated documentation site from Docusaurus to Astro Starlight to resolve indexing issues with zero-JS static output, and updated all content to reflect v0.3.0 API changes.

v0.2.1

Choose a tag to compare

@denislistiadi denislistiadi released this 20 Jul 16:19
0cc7def

What's New

Changed

  • Docs: Restructured the Docusaurus documentation site with dedicated Core Concepts and Getting Started pages.
  • Docs: Added 7 comprehensive Production Guides (SSR, Architecture, Error Handling, Sync Strategies, Cross-Tab Sync, and Testing).
  • Docs: Revamped README.md for all packages with professional layouts, badges, and SEO metadata.

Fixed

  • Docs: Resolved broken links on the documentation site during Docusaurus builds.

v0.2.0

Choose a tag to compare

@denislistiadi denislistiadi released this 13 Jul 07:15
bd63f95

What's New

Added

  • React: Added <SyncraftProvider> and useStoreRegistry() hooks to enforce a Context-based Store Registry. This guarantees isolated state across requests and completely prevents state/data leaks in Server-Side Rendering (SSR) environments like Next.js and Remix.
  • Vue: Added createSyncraft() plugin to provide a reactive store registry at the application level via app.provide and inject. This makes the library fully compatible with Nuxt.js and other Vue SSR architectures.
  • Docs: Added useSyncSuspense usage guide and Provider configurations in documentation.

Changed

  • BREAKING (React): useSync and useSyncSuspense now throw an error if used outside a <SyncraftProvider>. You must wrap your application root with <SyncraftProvider>.
  • BREAKING (Vue): useSync now throws an error if the Vue app has not installed the Syncraft plugin. You must run app.use(createSyncraft()) in your main entry file.
  • Internal: Refactored the core singleton logic to no longer rely on a global module-level Map. The registry is now safely bound to the component tree context.

Fixed

  • Fatal data leakage bug where state from one user could bleed into another user's request during Server-Side Rendering (SSR).

v0.1.1

Choose a tag to compare

@denislistiadi denislistiadi released this 10 Jul 12:11

What's Changed

Changed

  • Refactored documentation structure to simplify content to Intro, React, and Vue guides.
  • Merged the standalone Vite playground application directly into the Docusaurus documentation as a custom page (/playground).
  • Migrated playground styles from Tailwind CSS to CSS Modules for better compatibility with Docusaurus.
  • Updated documentation navigation, sidebar, and footer to reflect the new structure.

Removed

  • Removed standalone apps/playground workspace.
  • Removed unused Docusaurus template components (HomepageFeatures, markdown-page.mdx).
  • Removed core.md, contributing.md, and publishing.md from the documentation sidebar (content is preserved in intro.md or root repository files).