{"id":44728,"library":"diffable-objects","title":"diffable-objects","description":"A lightweight library for tracking and persisting state changes in Cloudflare Durable Objects using SQLite, version 0.1.1. It simplifies state management by automatically diffing property assignments and storing only mutations, reducing bandwidth and storage costs. Key differentiators from manual state handling include decorator-based or explicit state registration, configurable snapshot policies (e.g., every-change), and tight integration with Cloudflare Workers. The package is in early development with decorator support requiring wrangler@next. Ships TypeScript types and is designed for serverless environments.","status":"active","version":"0.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/zebp/diffable-objects","tags":["javascript","cloudflare","workers","durable-objects","sqlite","typescript"],"install":[{"cmd":"npm install diffable-objects","lang":"bash","label":"npm"},{"cmd":"yarn add diffable-objects","lang":"bash","label":"yarn"},{"cmd":"pnpm add diffable-objects","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for DurableObject base class and runtime APIs","package":"cloudflare:workers","optional":false}],"imports":[{"note":"Decorator for automatic state tracking; ESM-only, requires wrangler@next for decorator support","wrong":"const { diffable } = require('diffable-objects')","symbol":"diffable","correct":"import { diffable } from 'diffable-objects'"},{"note":"Function to register a property for explicit state tracking; named export, not default","wrong":"import state from 'diffable-objects'","symbol":"state","correct":"import { state } from 'diffable-objects'"},{"note":"DurableObject base class is from the Cloudflare workers runtime, not from this package","wrong":"import { DurableObject } from 'diffable-objects'","symbol":"DurableObject","correct":"import { DurableObject } from 'cloudflare:workers'"}],"quickstart":{"code":"import { DurableObject } from 'cloudflare:workers';\nimport { state } from 'diffable-objects';\n\nexport class MyObject extends DurableObject {\n  #myState = state(this.ctx, 'myState', { count: 0, items: [] });\n\n  increment() {\n    this.#myState.count++;\n  }\n\n  addItem(item: string) {\n    this.#myState.items.push(item);\n  }\n\n  getState() {\n    return this.#myState;\n  }\n}","lang":"typescript","description":"Demonstrates explicit state tracking with `state()`: creates a Durable Object with a tracked state object, mutates it, and retrieves it."},"warnings":[{"fix":"Use explicit `state()` function instead of `@diffable` decorator until wrangler@next is stable","message":"Decorator support requires wrangler@next and is experimental","severity":"breaking","affected_versions":">=0.1.0"},{"fix":"Always mutate `this.#state` directly; do not extract to a local variable and modify it","message":"State mutations must be done on the tracked object itself, not on a copy","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Use `snapshotPolicy: 'periodic'` with appropriate options","message":"Snapshot policy 'every-n-seconds' is deprecated in favor of 'periodic'","severity":"deprecated","affected_versions":">=0.1.0"},{"fix":"Pass `this.ctx` (the DurableObjectState) to `state()`","message":"The 'state' function requires 'this.ctx' to be the Durable Object's context, not the storage","severity":"gotcha","affected_versions":">=0.1.0"}],"env_vars":null,"search_vec":"'0.1.1':20 'assign':29 'automat':26 'bandwidth':35 'base':48 'chang':12,59 'cloudflar':14,64,88 'configur':53 'cost':38 'decor':47,73 'decorator-bas':46 'design':83 'develop':71 'dif':27 'diffabl':2 'diffable-object':1 'differenti':40 'durabl':15,91 'durable-object':90 'e.g':56 'earli':70 'environ':86 'everi':58 'every-chang':57 'explicit':50 'handl':44 'includ':45 'integr':62 'javascript':87 'key':39 'librari':6 'lightweight':5 'manag':24 'manual':42 'mutat':33 'next':77 'object':3,16,92 'packag':67 'persist':10 'polici':55 'properti':28 'reduc':34 'registr':52 'requir':75 'serverless':85 'ship':78 'simplifi':22 'snapshot':54 'sqlite':18,93 'state':11,23,43,51 'storag':37 'store':31 'support':74 'tight':61 'track':8 'type':80 'typescript':79,94 'use':17 'version':19 'worker':65,89 'wrangler':76","created_at":"2026-06-07T12:51:33.160235+00:00","updated_at":"2026-06-07T12:51:33.160235+00:00","problems":[{"fix":"Use explicit `state()` function instead of `@diffable`, or update wrangler to @next","cause":"Decorator not supported or not enabled in the current wrangler version","error":"TypeError: diffable is not a function"},{"fix":"Ensure code runs in a Cloudflare Worker with durable objects enabled","cause":"Running outside of Cloudflare Workers environment","error":"Error: Cannot find module 'cloudflare:workers'"},{"fix":"Verify that `state()` is called with `this.ctx` and that the Durable Object is properly bound","cause":"State not correctly passed or ctx is undefined","error":"TypeError: Cannot read properties of undefined (reading 'storage')"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/zebp/diffable-objects#readme","github":"https://github.com/zebp/diffable-objects","docs":null,"changelog":null,"pypi":null,"npm":"diffable-objects","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database","devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}