chore: bumped evolu and refactored d7406a48
Steve · 2025-11-02 08:01 4 file(s) · +72 −48
bun.lock +16 −14
105 105
106 106
    "@eslint/config-array": ["@eslint/config-array@0.21.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="],
107 107
108 -
    "@eslint/config-helpers": ["@eslint/config-helpers@0.4.1", "", { "dependencies": { "@eslint/core": "^0.16.0" } }, "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw=="],
108 +
    "@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
109 109
110 -
    "@eslint/core": ["@eslint/core@0.16.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q=="],
110 +
    "@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
111 111
112 112
    "@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
113 113
114 -
    "@eslint/js": ["@eslint/js@9.38.0", "", {}, "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A=="],
114 +
    "@eslint/js": ["@eslint/js@9.39.0", "", {}, "sha512-BIhe0sW91JGPiaF1mOuPy5v8NflqfjIcDNpC+LbW9f609WVRX1rArrhi6Z2ymvrAry9jw+5POTj4t2t62o8Bmw=="],
115 115
116 116
    "@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
117 117
118 -
    "@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.0", "", { "dependencies": { "@eslint/core": "^0.16.0", "levn": "^0.4.1" } }, "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A=="],
118 +
    "@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
119 119
120 -
    "@evolu/common": ["@evolu/common@6.0.1-preview.19", "", { "dependencies": { "@noble/ciphers": "^1.3.0", "@noble/hashes": "^1.8.0", "@scure/bip39": "^1.6.0", "kysely": "^0.28.4", "msgpackr": "^1.11.5", "nanoid": "^3.3.11", "random": "^5.4.1" } }, "sha512-9xBsnr8wRBGxnC+Joj7jIHtUf2N9nONblYnWpXvpmRE+w2qJYBV7mmUNmbh8+0aSJYJwpPbkWt7qKNhO5oKWOQ=="],
120 +
    "@evolu/common": ["@evolu/common@6.0.1-preview.21", "", { "dependencies": { "@noble/ciphers": "^2.0.0", "@noble/hashes": "^2.0.0", "@scure/bip39": "^2.0.0", "kysely": "^0.28.4", "msgpackr": "^1.11.5", "random": "^5.4.1" } }, "sha512-FEg40ttU7N5YlRNYlsUwZDa56IvwHUnh8N+mqDCmiIGMcKfcJI+xIQp8/dBbjIQMzqaSlhqbv3bEfJenEmppQw=="],
121 121
122 -
    "@evolu/react": ["@evolu/react@9.0.1-preview.4", "", { "peerDependencies": { "@evolu/common": "^6.0.1-preview.18", "react": "^19.0.0" } }, "sha512-zSTFK+vlSXLr22MmtlKtlZoY9H+FPUpDduQWF0p2+mUZbMlCR0w/X8l+aw2z7+wFzHDGyHy+XzNUvQfEjdu7ZQ=="],
122 +
    "@evolu/react": ["@evolu/react@9.0.1-preview.5", "", { "peerDependencies": { "@evolu/common": "^6.0.1-preview.20", "react": ">=19" } }, "sha512-/HxQ3lpDnffxq9w/mLHc4r7dvqydaZ/8cHxp20AKUwZed+QTyRJ/NM0meFBAsmve0K5K7RmQz8+wC4Ux8BWQnQ=="],
123 123
124 -
    "@evolu/react-web": ["@evolu/react-web@1.0.1-preview.3", "", { "peerDependencies": { "@evolu/common": "^6.0.1-preview.18", "@evolu/web": "^1.0.1-preview.4", "react-dom": "^19.0.0" } }, "sha512-HXrwQaweuMMve4GAvmGa8rKw7OcQfrS+BV/5h7piNkqk29pPTdt9XK0D01SY9reAJgOdIfvgM8YAyd5GRXIstQ=="],
124 +
    "@evolu/react-web": ["@evolu/react-web@1.0.1-preview.4", "", { "dependencies": { "blo": "^2.0.0" }, "peerDependencies": { "@evolu/common": "^6.0.1-preview.20", "@evolu/web": "^1.0.1-preview.6", "react": ">=19", "react-dom": ">=19" } }, "sha512-XN8os6hqY8eQae2jPjYfmF12nKsVty9Jx9FF+bmA7iUXHR0rxE4hGu7x7zMg9DCCUjoRyNfx0JwIMklRMcn+XQ=="],
125 125
126 126
    "@evolu/web": ["@evolu/web@1.0.1-preview.5", "", { "dependencies": { "@sqlite.org/sqlite-wasm": "3.50.4-build1" }, "peerDependencies": { "@evolu/common": "^6.0.1-preview.18" } }, "sha512-3MHTpw7Dm7xgKjp1s9lymVNA+FbobhcsBabs3vohUv26sqF5bl4/tZeVrdORYL+mT9K3TPiGolzi19nZF2N+hQ=="],
127 127
165 165
166 166
    "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" } }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="],
167 167
168 -
    "@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="],
168 +
    "@noble/ciphers": ["@noble/ciphers@2.0.1", "", {}, "sha512-xHK3XHPUW8DTAobU+G0XT+/w+JLM7/8k1UFdB5xg/zTFPnFCobhftzw8wl4Lw2aq/Rvir5pxfZV5fEazmeCJ2g=="],
169 169
170 -
    "@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
170 +
    "@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="],
171 171
172 172
    "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
173 173
283 283
284 284
    "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.43", "", {}, "sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ=="],
285 285
286 -
    "@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="],
286 +
    "@scure/base": ["@scure/base@2.0.0", "", {}, "sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w=="],
287 287
288 -
    "@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="],
288 +
    "@scure/bip39": ["@scure/bip39@2.0.1", "", { "dependencies": { "@noble/hashes": "2.0.1", "@scure/base": "2.0.0" } }, "sha512-PsxdFj/d2AcJcZDX1FXN3dDgitDDTmwf78rKZq1a6c1P1Nan1X/Sxc7667zU3U+AN60g7SxxP0YCVw2H/hBycg=="],
289 289
290 290
    "@sqlite.org/sqlite-wasm": ["@sqlite.org/sqlite-wasm@3.50.4-build1", "", { "bin": { "sqlite-wasm": "bin/index.js" } }, "sha512-Qig2Wso7gPkU1PtXwFzndh+CTRzrIFxVGqv6eCetjU7YqxlHItj+GvQYwYTppCRgAPawtRN/4AJcEgB9xDHGug=="],
291 291
345 345
346 346
    "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
347 347
348 -
    "@types/node": ["@types/node@24.9.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg=="],
348 +
    "@types/node": ["@types/node@24.9.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA=="],
349 349
350 350
    "@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
351 351
396 396
    "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
397 397
398 398
    "baseline-browser-mapping": ["baseline-browser-mapping@2.8.20", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ=="],
399 +
400 +
    "blo": ["blo@2.0.0", "", {}, "sha512-VUUr1+vWisNSaHVswkbPbk1+GhygClKILkGchae7nsyuJ4ZVz5l1hEW4eR5F/ly/asM5vzigYGXjPnvrd//CVg=="],
399 401
400 402
    "brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
401 403
463 465
464 466
    "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
465 467
466 -
    "eslint": ["eslint@9.38.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.1", "@eslint/core": "^0.16.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.38.0", "@eslint/plugin-kit": "^0.4.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw=="],
468 +
    "eslint": ["eslint@9.39.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.39.0", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg=="],
467 469
468 470
    "eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="],
469 471
519 521
520 522
    "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
521 523
522 -
    "globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="],
524 +
    "globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="],
523 525
524 526
    "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
525 527
package.json +14 −14
10 10
    "preview": "vite preview"
11 11
  },
12 12
  "dependencies": {
13 -
    "@evolu/common": "^6.0.1-preview.19",
14 -
    "@evolu/react": "^9.0.1-preview.4",
15 -
    "@evolu/react-web": "^1.0.1-preview.3",
13 +
    "@evolu/common": "^6.0.1-preview.21",
14 +
    "@evolu/react": "^9.0.1-preview.5",
15 +
    "@evolu/react-web": "^1.0.1-preview.4",
16 16
    "@radix-ui/react-avatar": "^1.1.10",
17 17
    "@radix-ui/react-collapsible": "^1.1.12",
18 18
    "@radix-ui/react-dialog": "^1.1.15",
30 30
    "fast-xml-parser": "^5.3.0",
31 31
    "lucide-react": "^0.548.0",
32 32
    "next-themes": "^0.4.6",
33 -
    "react": "^19.1.1",
34 -
    "react-dom": "^19.1.1",
33 +
    "react": "^19.2.0",
34 +
    "react-dom": "^19.2.0",
35 35
    "react-markdown": "^10.1.0",
36 36
    "rehype-raw": "^7.0.0",
37 37
    "rehype-sanitize": "^6.0.0",
41 41
    "tailwindcss": "^4.1.16"
42 42
  },
43 43
  "devDependencies": {
44 -
    "@eslint/js": "^9.36.0",
45 -
    "@types/node": "^24.9.1",
46 -
    "@types/react": "^19.1.16",
47 -
    "@types/react-dom": "^19.1.9",
48 -
    "@vitejs/plugin-react": "^5.0.4",
49 -
    "eslint": "^9.36.0",
44 +
    "@eslint/js": "^9.39.0",
45 +
    "@types/node": "^24.9.2",
46 +
    "@types/react": "^19.2.2",
47 +
    "@types/react-dom": "^19.2.2",
48 +
    "@vitejs/plugin-react": "^5.1.0",
49 +
    "eslint": "^9.39.0",
50 50
    "eslint-plugin-react-hooks": "^5.2.0",
51 -
    "eslint-plugin-react-refresh": "^0.4.22",
52 -
    "globals": "^16.4.0",
51 +
    "eslint-plugin-react-refresh": "^0.4.24",
52 +
    "globals": "^16.5.0",
53 53
    "tw-animate-css": "^1.4.0",
54 54
    "typescript": "~5.9.3",
55 -
    "typescript-eslint": "^8.45.0",
55 +
    "typescript-eslint": "^8.46.2",
56 56
    "vite": "npm:rolldown-vite@7.1.14"
57 57
  },
58 58
  "overrides": {
src/components/app-sidebar.tsx +17 −16
96 96
	const hasRefreshedOnMount = React.useRef(false);
97 97
98 98
	const { hidden, isMobile, setOpenMobile } = useSidebar();
99 -
	const { insert, update } = useEvolu();
99 +
	const evolu = useEvolu();
100 100
	const allFeeds = useQuery(allFeedsQuery);
101 101
	const allReadStatuses = useQuery(allReadStatusesQuery);
102 102
	const allReadStatusesWithUnread = useQuery(allReadStatusesWithUnreadQuery);
161 161
162 162
			if (existingStatus) {
163 163
				// Update existing status to read
164 -
				update("readStatus", {
164 +
				evolu.update("readStatus", {
165 165
					id: existingStatus.id as any,
166 166
					isRead: 1,
167 167
				});
168 168
			} else if (post && post.feedId) {
169 169
				// Create new read status
170 -
				insert("readStatus", {
170 +
				evolu.insert("readStatus", {
171 171
					postId: postId,
172 172
					feedId: post.feedId,
173 173
					isRead: 1,
186 186
		[
187 187
			allReadStatusesWithUnread,
188 188
			feedPosts,
189 -
			insert,
190 -
			update,
189 +
			evolu,
191 190
			onPostSelect,
192 191
			isMobile,
193 192
			setOpenMobile,
204 203
205 204
			if (existingStatus && !existingStatus.isRead) {
206 205
				// Update existing status to read
207 -
				update("readStatus", {
206 +
				evolu.update("readStatus", {
208 207
					id: existingStatus.id as any,
209 208
					isRead: 1,
210 209
				});
211 210
				markedCount++;
212 211
			} else if (!existingStatus && post.feedId) {
213 212
				// Create new read status
214 -
				insert("readStatus", {
213 +
				evolu.insert("readStatus", {
215 214
					postId: post.id,
216 215
					feedId: post.feedId,
217 216
					isRead: 1,
222 221
		toast.success(
223 222
			`Marked ${markedCount} post${markedCount !== 1 ? "s" : ""} as read`,
224 223
		);
225 -
	}, [filteredPosts, allReadStatusesWithUnread, insert, update]);
224 +
	}, [filteredPosts, allReadStatusesWithUnread, evolu]);
226 225
227 226
	// Mark all visible posts as unread
228 227
	const handleMarkAllAsUnread = React.useCallback(() => {
234 233
235 234
			if (existingStatus && existingStatus.isRead) {
236 235
				// Update existing status to unread
237 -
				update("readStatus", {
236 +
				evolu.update("readStatus", {
238 237
					id: existingStatus.id as any,
239 238
					isRead: 0,
240 239
				});
241 240
				unmarkedCount++;
242 241
			} else if (!existingStatus && post.feedId) {
243 242
				// Create new unread status
244 -
				insert("readStatus", {
243 +
				evolu.insert("readStatus", {
245 244
					postId: post.id,
246 245
					feedId: post.feedId,
247 246
					isRead: 0,
252 251
		toast.success(
253 252
			`Marked ${unmarkedCount} post${unmarkedCount !== 1 ? "s" : ""} as unread`,
254 253
		);
255 -
	}, [filteredPosts, allReadStatusesWithUnread, insert, update]);
254 +
	}, [filteredPosts, allReadStatusesWithUnread, evolu]);
256 255
257 256
	const refreshFeeds = React.useCallback(async () => {
258 257
		if (allFeeds.length === 0) {
268 267
		try {
269 268
			for (const feed of allFeeds) {
270 269
				try {
270 +
					if (!feed.feedUrl) continue;
271 +
271 272
					let xmlData: string;
272 273
273 274
					// Try to fetch directly first
322 323
							continue;
323 324
						}
324 325
325 -
						insert("rssPost", {
326 +
						evolu.insert("rssPost", {
326 327
							title: post.title,
327 328
							author: isAtom
328 329
								? post.author?.name || feedData.title
343 344
					totalNewPosts += newPostsCount;
344 345
345 346
					// Update feed's dateUpdated
346 -
					update("rssFeed", {
347 +
					evolu.update("rssFeed", {
347 348
						id: feed.id as any,
348 349
						dateUpdated: new Date().toISOString(),
349 350
					});
364 365
			console.error("Error refreshing feeds:", error);
365 366
			toast.error("Failed to refresh feeds");
366 367
		}
367 -
	}, [allFeeds, allPosts, insert, update]);
368 +
	}, [allFeeds, allPosts, evolu]);
368 369
369 370
	// Run refresh on component mount (only once, even in strict mode)
370 371
	React.useEffect(() => {
478 479
				throw new Error("Unsupported feed format");
479 480
			}
480 481
481 -
			const result = insert("rssFeed", {
482 +
			const result = evolu.insert("rssFeed", {
482 483
				feedUrl: feedUrl,
483 484
				title: feedData.title,
484 485
				description: feedData.description || feedData.subtitle || "",
492 493
493 494
			// Process posts/entries
494 495
			for (const post of posts) {
495 -
				insert("rssPost", {
496 +
				evolu.insert("rssPost", {
496 497
					title: post.title,
497 498
					author: isAtom
498 499
						? post.author?.name || feedData.title
src/lib/evolu.ts +25 −4
1 -
import { createEvolu, getOrThrow, SimpleName } from "@evolu/common";
1 +
import * as Evolu from "@evolu/common";
2 2
import { evoluReactWebDeps } from "@evolu/react-web";
3 3
import { Schema, type RSSFeedId } from "./scheme.ts";
4 4
import { createUseEvolu } from "@evolu/react";
5 5
6 -
export const evolu = createEvolu(evoluReactWebDeps)(Schema, {
7 -
	name: getOrThrow(SimpleName.from("alcove")),
8 -
	syncUrl: "http://localhost:4000", // optional, defaults to wss://free.evoluhq.com
6 +
const service = "alcove";
7 +
8 +
// Initialize authentication
9 +
const authResult = await evoluReactWebDeps.localAuth.login(undefined, {
10 +
	service,
11 +
});
12 +
13 +
export const evolu = Evolu.createEvolu(evoluReactWebDeps)(Schema, {
14 +
	name: Evolu.SimpleName.orThrow(
15 +
		`${service}-${authResult?.owner?.id ?? "guest"}`,
16 +
	),
9 17
	reloadUrl: "/",
18 +
	encryptionKey: authResult?.owner?.encryptionKey,
19 +
	externalAppOwner: authResult?.owner,
20 +
	transports: [{ type: "WebSocket", url: "ws://localhost:4000" }],
10 21
});
11 22
12 23
export const useEvolu = createUseEvolu(evolu);
24 +
25 +
/**
26 +
 * Subscribe to unexpected Evolu errors (database, network, sync issues).
27 +
 */
28 +
evolu.subscribeError(() => {
29 +
	const error = evolu.getError();
30 +
	if (!error) return;
31 +
32 +
	console.error("Evolu error:", error);
33 +
});
13 34
14 35
export const allFeedsQuery = evolu.createQuery((db) =>
15 36
	db.selectFrom("rssFeed").selectAll(),