{"id":50744199,"url":"https://github.com/sravan27/silentdrop","last_synced_at":"2026-06-10T19:01:41.765Z","repository":{"id":363341246,"uuid":"1259332074","full_name":"sravan27/silentdrop","owner":"sravan27","description":"Does your JavaScript database silently return the wrong rows? Zero-dep MIT correctness checker. 8 merged PRs across 7 OSS sync engines.","archived":false,"fork":false,"pushed_at":"2026-06-08T12:46:02.000Z","size":13,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-08T14:24:06.588Z","etag":null,"topics":["conformance","correctness","data-loss","database","dexie","indexeddb","local-first","query-engine","sql","testing"],"latest_commit_sha":null,"homepage":"https://silentdrop-sravan.vercel.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sravan27.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-04T12:02:02.000Z","updated_at":"2026-06-08T12:49:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sravan27/silentdrop","commit_stats":null,"previous_names":["sravan27/silentdrop"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/sravan27/silentdrop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sravan27%2Fsilentdrop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sravan27%2Fsilentdrop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sravan27%2Fsilentdrop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sravan27%2Fsilentdrop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sravan27","download_url":"https://codeload.github.com/sravan27/silentdrop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sravan27%2Fsilentdrop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34165482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["conformance","correctness","data-loss","database","dexie","indexeddb","local-first","query-engine","sql","testing"],"created_at":"2026-06-10T19:01:40.714Z","updated_at":"2026-06-10T19:01:41.754Z","avatar_url":"https://github.com/sravan27.png","language":"JavaScript","funding_links":["https://buy.polar.sh/polar_cl_z0eLsPUJeMwrcNs4MQPAQbKIM3Rbdb8fLDgVj2RZcmr","https://buy.polar.sh/polar_cl_G0fuUHHZ1tg9E0oe7gluje9gs44l8FAqVnfwS2AJkbw"],"categories":["Misc"],"sub_categories":["Desktop"],"readme":"# silentdrop\n\n**Does your JavaScript database silently return the wrong rows?**\n\n→ **[silentdrop-sravan.vercel.app](https://silentdrop-sravan.vercel.app)** · the audit, the proof, and the booking page in one screen.\n\nClient‑side, embedded, and sync databases re‑implement SQL‑ish operators — `LIKE`,\ncase‑insensitive match, range comparison — in JavaScript. Subtle gaps between those\nJS implementations and the SQL semantics they're meant to mirror make queries\n**silently drop or over‑match rows**. No error. No crash. Just wrong data — the\nworst kind of bug.\n\nAs of this week I have shipped this exact bug class to **seven production databases**, 11 PRs in 8 days (8 merged, 1 open, 3 closed after an operator-direction call from a maintainer). Write-up: [9 silent-row-loss fixes in 7 days across 7 OSS databases](https://dev.to/sravan27/9-silent-row-loss-fixes-in-7-days-across-7-oss-databases-2nd-draft-56da).\n\n| Database | Bug | Status |\n|---|---|---|\n| PowerSync | LIKE/range, CAST, div-by-zero, json_each, NOT-NULL semantics | merged: `#643`, `#644`, `#645`, `#646`, `#647` + paid hardening sprint |\n| PowerSync | JOIN on aliased primary, silent zero-row sync | open: `#662` |\n| PowerSync | upper/lower/length/substring ASCII vs Unicode | closed by maintainer — preferred direction is Unicode-aware JS; client-side override scoped instead (`#663`, `#664`, `#665`) |\n| TanStack DB | upper/lower/ilike ASCII case fold | PR open (`db#1574`) |\n| Rocicorp's Zero | range/comparison | merged (`mono#6083`, `#6088`) |\n| InstantDB | `$like`/`$ilike` newline | merged (`instant#2714`) |\n| ElectricSQL | LIKE newline + escaped wildcards | PR open (`electric#4437`) |\n| Dexie | case‑fold drops rows | PR open (`Dexie.js#2306`) |\n\nPowerSync's full audit summary with reproductions: [discussions/668](https://github.com/orgs/powersync-ja/discussions/668).\n\n`silentdrop` packages that audit so you can run it against **your** database.\n\n## It catches real bugs\n\nRun it against Dexie (the dominant IndexedDB wrapper, ~2M downloads/week):\n\n```\n$ node examples/dexie.mjs\n\n  ✗  DIVERGENCE: ilike-casefold — Case-insensitive match must handle length-changing case folds\n     equalsIgnoreCase('straße') must match 'STRAßE'. Index walks that assume case\n     conversion is length-preserving (ß→SS, ﬁ→FI, İ) silently drop rows.\n     expected: [\"straße\",\"STRAßE\",\"Straße\",\"sTRAßE\"]\n     got:      [\"Straße\",\"sTRAßE\",\"straße\"]   \u003c-- 'STRAßE' silently dropped\n\n  ✗  DIVERGENCE: compare-nonbmp — Range comparison must order non-BMP characters by code point\n     A range query over astral characters (emoji, CJK ext.) drops rows, because\n     JS compares UTF-16 code units while SQL orders by code point.\n\n  ✗ 2 silent-data-loss divergences — these queries return wrong rows\n```\n\nBoth are genuine: the case‑fold one is reported as [Dexie #2306](https://github.com/dexie/Dexie.js/pull/2306).\n\n## What it checks\n\n- **`LIKE` across newlines** — `%` must span `\\n` (SQL semantics; RegExp without `dotAll` misses it)\n- **`LIKE` metacharacter literalness** — `LIKE 'a.b'` matches `a.b`, not `axb` (escaping)\n- **Case‑fold length changes** — `ß`→`SS`, ligatures, Turkish `İ` must not drop rows\n- **Non‑BMP ordering** — range comparison must order by code point, not UTF‑16 code unit\n\n## Usage\n\n```js\nimport { check, report } from \"silentdrop\";\n\n// Wire your DB's query operators (returns matching string values).\nconst adapter = {\n  async reset() { /* clear store */ },\n  async seed(values) { /* insert string values */ },\n  async like(pattern) { /* run a LIKE query, return matches (omit if unsupported) */ },\n  async ilike(needle) { /* case-insensitive equality */ },\n  async gt(bound) { /* values \u003e bound */ },\n};\n\nreport(await check(adapter));\n```\n\nSee [`examples/dexie.mjs`](examples/dexie.mjs) for a complete adapter.\n\n## Need the deep version?\n\n`silentdrop` catches the common cases automatically. If your database/sync layer is\ncorrectness‑critical and you want a **full manual hardening pass** — reduced repros +\nfixes + regression tests across the whole operator surface (the same work behind the\n5 databases above) — I do it as a fixed **$1,000 / 48‑hour sprint**, no‑find‑no‑charge:\n\n**→ https://buy.polar.sh/polar_cl_z0eLsPUJeMwrcNs4MQPAQbKIM3Rbdb8fLDgVj2RZcmr**\n\nSmaller scope? **$500 Diagnostic Fix** — one operator I find a divergence on, repro + fix + PR delivered:\n\n**→ https://buy.polar.sh/polar_cl_G0fuUHHZ1tg9E0oe7gluje9gs44l8FAqVnfwS2AJkbw**\n\nTrack record (June 2026): 8 silent-row-loss PRs at PowerSync (4 merged + 4 open), 2 each at Rocicorp Zero and Autumn (all merged), plus shipped fixes at InstantDB, ElectricSQL, Dexie, RxDB. Every bug is real and silent — no error, no log, just wrong rows.\n\n## License\n\nMIT © Sravan Sridhar · [github.com/sravan27](https://github.com/sravan27)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsravan27%2Fsilentdrop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsravan27%2Fsilentdrop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsravan27%2Fsilentdrop/lists"}