[{"data":1,"prerenderedAt":94},["ShallowReactive",2],{"api:\u002Fapi\u002Fconfig:en":3,"api:\u002Fapi\u002Fnotes:en":8,"api:\u002Fapi\u002Fprojects\u002Fnotes-search:en":32},{"email":4,"lang":5,"name":6,"role":7},"hello@ewsirdev.example","en","Ewsirdev","Web developer: websites, landing pages and Go services",[9,16,22,27],{"slug":10,"lang":5,"title":11,"date":12,"summary":13,"project":14,"minutes":15},"double-booking","Double booking: a transaction plus a partial UNIQUE index","2026-10-20","How booking-slots protects against two clients booking the same time at once, and how that protection is tested.","booking-slots",1,{"slug":17,"lang":5,"title":18,"date":12,"summary":19,"project":20,"minutes":21},"lease-and-fencing","Lease and fencing: how a queue neither loses a job nor lets a zombie finish it twice","A worker can crash, stall, or wake up after its job was taken by someone else. How the lease and the lease token in job-queue deal with that on SQLite.","job-queue",2,{"slug":23,"lang":5,"title":24,"date":12,"summary":25,"project":26,"minutes":21},"p95-nearest-rank","p95 in an uptime monitor: the nearest-rank method and what it does not hide","How uptime-monitor computes p50\u002Fp95 latency and uptime, why the nearest-rank method was chosen, and where those numbers can mislead.","uptime-monitor",{"slug":28,"lang":5,"title":29,"date":12,"summary":30,"project":31,"minutes":21},"websocket-from-scratch","WebSocket on the standard library: what really happens under new WebSocket()","Why realtime-rooms has its own RFC 6455 layer, which protocol violations it checks, and why a library is still the better choice for production.","realtime-rooms",{"slug":33,"title":34,"type":35,"stack":36,"description":49,"highlights":50,"run":55,"hue":56,"og":57,"shots":58,"case":66,"case_lang":5,"prev":88,"next":91},"notes-search","Card Index: notes with search","backend",[37,38,39,40,41,42,43,44,45,46,47,48],"Go","SQLite","FTS5","bm25","modernc.org\u002Fsqlite (no CGO)","REST API","Markdown (custom safe renderer)","SVG force-layout","Vanilla JS","embed","Docker","GitHub Actions","A Markdown notes base on Go and SQLite: [[wiki]] links with backlinks and a link graph, FTS5 full-text search (bm25, highlighting, simplified Russian morphology), version history with its own diff, autosave with conflict resolution, .md export and import.",[51,52,53,54],"FTS5 search with bm25 and highlighting","Wiki links, backlinks and a link graph","Version history with its own diff","A custom safe Markdown renderer with an XSS test","cd notes-search && set SEED_DEMO=1&& go run .\u002Fcmd\u002Fserver",160,"\u002Fog\u002Fen\u002Fnotes-search.jpg",{"desktop":59,"desktop_sm":60,"mobile":61,"dw":62,"dh":63,"mw":64,"mh":65},"\u002Fshots\u002Fnotes-search-desktop.webp","\u002Fshots\u002Fnotes-search-desktop-sm.webp","\u002Fshots\u002Fnotes-search-mobile.webp",1280,800,390,844,{"about":67,"features":70,"run":79,"notes":83},[68,69],"Card Index is a Markdown notes base on Go and SQLite. Notes are linked with [[wiki links]], with backlinks and a link graph, and search runs on SQLite FTS5 with bm25 ranking, match highlighting and simplified Russian morphology.","A single binary: the standard library and modernc.org\u002Fsqlite (no CGO), with a vanilla JS interface embedded through embed. Demo mode adds 12 notes about the project itself, each one honestly marked.",[71,72,73,74,75,76,77,78],"A custom safe Markdown renderer: the source is escaped as a whole, only the renderer creates tags from a closed set, and link schemes come from an allow-list; the XSS test runs about 30 payloads","Wiki links [[Title]] and [[Title|label]] with backlinks; a link to a note that does not exist yet comes alive when the note appears","An SVG link graph: a Fruchterman-Reingold layout in vanilla JS, draggable nodes, keyboard navigation","FTS5 search: bm25 with weights (title x8, tags x4, body x1), prefix search, highlighting done in Go code, a tag filter","Version history and a line-based diff on LCS between any two versions, with restore","Autosave with an optimistic list update, rollback on error and conflict resolution by rev (409)","Export everything as a zip of .md files with front matter; import a folder of .md files, single files or a zip","A REST API behind a Bearer token, dark and light themes, Docker and GitHub Actions",[80,81,82],"git clone \u003Crepository on request> notes-search","cd notes-search","SEED_DEMO=1 go run .\u002Fcmd\u002Fserver   # http:\u002F\u002Flocalhost:8089, token demo",[84,85,86,87],"The Russian morphology is simplified: it strips endings from a short list and adds prefix search. Fleeting vowels, alternations and irregular forms are not handled, and short words can produce false matches.","Renaming a note does not rewrite the old [[links]] in other notes. Markdown has no tables, images or footnotes.","One shared token, with no users or permissions. Conflicts are resolved wholesale (take theirs or overwrite); there is no line-by-line merge.","The graph is meant for hundreds of notes, not thousands. The -race tests run only in CI (there is no gcc locally).",{"slug":89,"title":90},"api-gateway","Sluice: API gateway",{"slug":92,"title":93},"landing-3d","OKSO T1: 3D landing page",1792697892726]