<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Zestor</title><link>https://ca7cdd17.zestor-docs.pages.dev/</link><description>Recent content on Zestor</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://ca7cdd17.zestor-docs.pages.dev/index.xml" rel="self" type="application/rss+xml"/><item><title>In-Memory Store (gomap)</title><link>https://ca7cdd17.zestor-docs.pages.dev/docs/implementations/gomap/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ca7cdd17.zestor-docs.pages.dev/docs/implementations/gomap/</guid><description>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store/gomap&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>gomap&lt;/code> package provides a high-performance in-memory implementation of the &lt;code>store.Store&lt;/code> interface using Go maps with &lt;code>sync.RWMutex&lt;/code> for thread safety.&lt;/p>
&lt;h2 id="features">Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Zero Dependencies&lt;/strong>: Pure Go, no external packages&lt;/li>
&lt;li>&lt;strong>Maximum Speed&lt;/strong>: Direct memory access, no serialization&lt;/li>
&lt;li>&lt;strong>Thread-Safe&lt;/strong>: &lt;code>RWMutex&lt;/code> for concurrent access&lt;/li>
&lt;li>&lt;strong>Full Watch Support&lt;/strong>: Real-time event notifications&lt;/li>
&lt;li>&lt;strong>Validation Hooks&lt;/strong>: Per-kind validation functions&lt;/li>
&lt;li>&lt;strong>Custom Comparison&lt;/strong>: Control when updates trigger events&lt;/li>
&lt;/ul>
&lt;h2 id="quick-start">Quick Start&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store/gomap&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">User&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Name&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Email&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">s&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">gomap&lt;/span>.&lt;span style="color:#a6e22e">NewMemStore&lt;/span>[&lt;span style="color:#a6e22e">User&lt;/span>](&lt;span style="color:#a6e22e">store&lt;/span>.&lt;span style="color:#a6e22e">StoreOptions&lt;/span>[&lt;span style="color:#a6e22e">User&lt;/span>]{})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">s&lt;/span>.&lt;span style="color:#a6e22e">Close&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// CRUD operations&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">s&lt;/span>.&lt;span style="color:#a6e22e">Set&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;users&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;alice&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">User&lt;/span>{&lt;span style="color:#a6e22e">Name&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;Alice&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">Email&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;alice@example.com&amp;#34;&lt;/span>})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">user&lt;/span>, &lt;span style="color:#a6e22e">ok&lt;/span>, &lt;span style="color:#a6e22e">_&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">s&lt;/span>.&lt;span style="color:#a6e22e">Get&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;users&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;alice&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">ok&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">user&lt;/span>.&lt;span style="color:#a6e22e">Name&lt;/span>) &lt;span style="color:#75715e">// Alice&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="configuration-options">Configuration Options&lt;/h2>
&lt;h3 id="basic-store">Basic Store&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">s&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">gomap&lt;/span>.&lt;span style="color:#a6e22e">NewMemStore&lt;/span>[&lt;span style="color:#a6e22e">User&lt;/span>](&lt;span style="color:#a6e22e">store&lt;/span>.&lt;span style="color:#a6e22e">StoreOptions&lt;/span>[&lt;span style="color:#a6e22e">User&lt;/span>]{})
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="with-validation">With Validation&lt;/h3>
&lt;p>Validate data before writes:&lt;/p></description></item><item><title>Installation</title><link>https://ca7cdd17.zestor-docs.pages.dev/docs/getting-started/installation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ca7cdd17.zestor-docs.pages.dev/docs/getting-started/installation/</guid><description>&lt;h2 id="requirements">Requirements&lt;/h2>
&lt;ul>
&lt;li>Go 1.21 or later&lt;/li>
&lt;/ul>
&lt;h2 id="install-via-go-modules">Install via Go Modules&lt;/h2>
&lt;p>Add Zestor to your project:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>go get github.com/zestor-dev/zestor
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="import">Import&lt;/h2>
&lt;p>Import the packages you need:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store/gomap&amp;#34;&lt;/span> &lt;span style="color:#75715e">// In-memory store&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For persistent storage with SQLite:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store/sqlite&amp;#34;&lt;/span> &lt;span style="color:#75715e">// SQLite store&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/codec&amp;#34;&lt;/span> &lt;span style="color:#75715e">// Serialization codecs&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="package-overview">Package Overview&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Package&lt;/th>
 &lt;th>Description&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>store&lt;/code>&lt;/td>
 &lt;td>Core interfaces, types, and options&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>store/gomap&lt;/code>&lt;/td>
 &lt;td>In-memory implementation&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>store/sqlite&lt;/code>&lt;/td>
 &lt;td>SQLite-backed persistent implementation&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>codec&lt;/code>&lt;/td>
 &lt;td>Serialization codecs (JSON, Protobuf, YAML)&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="verify-installation">Verify Installation&lt;/h2>
&lt;p>Create a simple test file:&lt;/p></description></item><item><title>store package</title><link>https://ca7cdd17.zestor-docs.pages.dev/docs/api/store/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ca7cdd17.zestor-docs.pages.dev/docs/api/store/</guid><description>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>store&lt;/code> package defines interfaces, types, and options for Zestor stores.&lt;/p>
&lt;hr>
&lt;h2 id="interfaces">Interfaces&lt;/h2>
&lt;h3 id="readert-any">Reader[T any]&lt;/h3>
&lt;p>Read-only access to the store.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Reader&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Get&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span>, &lt;span style="color:#a6e22e">key&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) (&lt;span style="color:#a6e22e">val&lt;/span> &lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#a6e22e">ok&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">List&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">filter&lt;/span> &lt;span style="color:#f92672">...&lt;/span>&lt;span style="color:#a6e22e">FilterFunc&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]) (&lt;span style="color:#66d9ef">map&lt;/span>[&lt;span style="color:#66d9ef">string&lt;/span>]&lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Count&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) (&lt;span style="color:#66d9ef">int&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Keys&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) ([]&lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Values&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) ([]&lt;span style="color:#a6e22e">KeyValue&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>], &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">GetAll&lt;/span>() (&lt;span style="color:#66d9ef">map&lt;/span>[&lt;span style="color:#66d9ef">string&lt;/span>]&lt;span style="color:#66d9ef">map&lt;/span>[&lt;span style="color:#66d9ef">string&lt;/span>]&lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="writert-any">Writer[T any]&lt;/h3>
&lt;p>Write access to the store.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Writer&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Set&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span>, &lt;span style="color:#a6e22e">key&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">value&lt;/span> &lt;span style="color:#a6e22e">T&lt;/span>) (&lt;span style="color:#a6e22e">created&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">SetFn&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span>, &lt;span style="color:#a6e22e">key&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">fn&lt;/span> &lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">v&lt;/span> &lt;span style="color:#a6e22e">T&lt;/span>) (&lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)) (&lt;span style="color:#a6e22e">changed&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">SetAll&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">values&lt;/span> &lt;span style="color:#66d9ef">map&lt;/span>[&lt;span style="color:#66d9ef">string&lt;/span>]&lt;span style="color:#a6e22e">T&lt;/span>) &lt;span style="color:#66d9ef">error&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Delete&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span>, &lt;span style="color:#a6e22e">key&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) (&lt;span style="color:#a6e22e">existed&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span>, &lt;span style="color:#a6e22e">prev&lt;/span> &lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="watchert-any">Watcher[T any]&lt;/h3>
&lt;p>Watch access to the store.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Watcher&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Watch&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">opts&lt;/span> &lt;span style="color:#f92672">...&lt;/span>&lt;span style="color:#a6e22e">WatchOption&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]) (&lt;span style="color:#a6e22e">r&lt;/span> &lt;span style="color:#f92672">&amp;lt;-&lt;/span>&lt;span style="color:#66d9ef">chan&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">Event&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>], &lt;span style="color:#a6e22e">cancel&lt;/span> &lt;span style="color:#66d9ef">func&lt;/span>(), &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="readwritert-any">ReadWriter[T any]&lt;/h3>
&lt;p>Combined read and write access.&lt;/p></description></item><item><title>Store &amp; Kinds</title><link>https://ca7cdd17.zestor-docs.pages.dev/docs/concepts/store/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ca7cdd17.zestor-docs.pages.dev/docs/concepts/store/</guid><description>&lt;h2 id="the-store-interface">The Store Interface&lt;/h2>
&lt;p>Zestor&amp;rsquo;s core is the &lt;code>Store&lt;/code> interface, which provides a complete set of operations for managing in-memory data:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Store&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Reader&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Writer&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Watcher&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Close&lt;/span>() &lt;span style="color:#66d9ef">error&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Dump&lt;/span>() &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The interface is &lt;strong>generic&lt;/strong> — you specify your data type &lt;code>T&lt;/code> when creating the store, and all operations are type-safe.&lt;/p>
&lt;h2 id="kinds-organizing-your-data">Kinds: Organizing Your Data&lt;/h2>
&lt;p>Data in Zestor is organized by &lt;strong>kinds&lt;/strong>. Think of kinds like tables in a database or collections in MongoDB.&lt;/p></description></item><item><title>Quick Start</title><link>https://ca7cdd17.zestor-docs.pages.dev/docs/getting-started/quickstart/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ca7cdd17.zestor-docs.pages.dev/docs/getting-started/quickstart/</guid><description>&lt;p>This guide walks you through building a simple application using Zestor.&lt;/p>
&lt;h2 id="create-a-store">Create a Store&lt;/h2>
&lt;p>First, define your data type and create a store. Zestor offers two implementations:&lt;/p>
&lt;h3 id="in-memory-store-gomap">In-Memory Store (gomap)&lt;/h3>
&lt;p>Best for: caching, testing, ephemeral data.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store/gomap&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">User&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Name&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Email&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Role&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Create a new in-memory store&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">s&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">gomap&lt;/span>.&lt;span style="color:#a6e22e">NewMemStore&lt;/span>[&lt;span style="color:#a6e22e">User&lt;/span>](&lt;span style="color:#a6e22e">store&lt;/span>.&lt;span style="color:#a6e22e">StoreOptions&lt;/span>[&lt;span style="color:#a6e22e">User&lt;/span>]{})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">s&lt;/span>.&lt;span style="color:#a6e22e">Close&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="sqlite-store-sqlite">SQLite Store (sqlite)&lt;/h3>
&lt;p>Best for: persistence, desktop apps, CLI tools.&lt;/p></description></item><item><title>SQLite Store</title><link>https://ca7cdd17.zestor-docs.pages.dev/docs/implementations/sqlite/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ca7cdd17.zestor-docs.pages.dev/docs/implementations/sqlite/</guid><description>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store/sqlite&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>sqlite&lt;/code> package provides a persistent SQLite-backed implementation of &lt;code>store.Store&lt;/code> using &lt;a href="https://pkg.go.dev/modernc.org/sqlite">modernc.org/sqlite&lt;/a> — a pure Go SQLite driver (no CGo required).&lt;/p>
&lt;h2 id="features">Features&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Persistent Storage&lt;/strong>: Data survives application restarts&lt;/li>
&lt;li>&lt;strong>ACID Transactions&lt;/strong>: Full transactional support&lt;/li>
&lt;li>&lt;strong>Single File&lt;/strong>: All data in one &lt;code>.db&lt;/code> file&lt;/li>
&lt;li>&lt;strong>WAL Mode&lt;/strong>: Write-Ahead Logging for better concurrency&lt;/li>
&lt;li>&lt;strong>Version Tracking&lt;/strong>: Automatic version incrementing&lt;/li>
&lt;li>&lt;strong>No-op Detection&lt;/strong>: Byte-level comparison prevents unnecessary updates&lt;/li>
&lt;li>&lt;strong>Pure Go&lt;/strong>: No CGo, cross-platform compatible&lt;/li>
&lt;/ul>
&lt;h2 id="quick-start">Quick Start&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/codec&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/zestor-dev/zestor/store/sqlite&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">User&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Name&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> &lt;span style="color:#e6db74">`json:&amp;#34;name&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Email&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> &lt;span style="color:#e6db74">`json:&amp;#34;email&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">s&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">sqlite&lt;/span>.&lt;span style="color:#a6e22e">New&lt;/span>[&lt;span style="color:#a6e22e">User&lt;/span>](&lt;span style="color:#a6e22e">sqlite&lt;/span>.&lt;span style="color:#a6e22e">Options&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">DSN&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;file:app.db?cache=shared&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Codec&lt;/span>: &lt;span style="color:#f92672">&amp;amp;&lt;/span>&lt;span style="color:#a6e22e">codec&lt;/span>.&lt;span style="color:#a6e22e">JSON&lt;/span>{},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Fatal&lt;/span>(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">s&lt;/span>.&lt;span style="color:#a6e22e">Close&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Same API as gomap&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">s&lt;/span>.&lt;span style="color:#a6e22e">Set&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;users&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;alice&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">User&lt;/span>{&lt;span style="color:#a6e22e">Name&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;Alice&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">Email&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;alice@example.com&amp;#34;&lt;/span>})
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">user&lt;/span>, &lt;span style="color:#a6e22e">ok&lt;/span>, &lt;span style="color:#a6e22e">_&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">s&lt;/span>.&lt;span style="color:#a6e22e">Get&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;users&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;alice&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">ok&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">user&lt;/span>.&lt;span style="color:#a6e22e">Name&lt;/span>) &lt;span style="color:#75715e">// Alice&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="configuration">Configuration&lt;/h2>
&lt;h3 id="options">Options&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Options&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">DSN&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> &lt;span style="color:#75715e">// SQLite connection string (required)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Codec&lt;/span> &lt;span style="color:#a6e22e">codec&lt;/span>.&lt;span style="color:#a6e22e">Codec&lt;/span> &lt;span style="color:#75715e">// Serialization codec (required)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">BusyTimeout&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Duration&lt;/span> &lt;span style="color:#75715e">// Lock wait timeout (optional)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">DisableWAL&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span> &lt;span style="color:#75715e">// Disable WAL mode (optional)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="dsn-examples">DSN Examples&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>DSN&lt;/th>
 &lt;th>Description&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>file:app.db&lt;/code>&lt;/td>
 &lt;td>Simple file database&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>file:app.db?cache=shared&lt;/code>&lt;/td>
 &lt;td>Shared cache (recommended)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>file:app.db?mode=rwc&lt;/code>&lt;/td>
 &lt;td>Read-write-create&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>file::memory:?cache=shared&lt;/code>&lt;/td>
 &lt;td>In-memory (testing)&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="full-configuration">Full Configuration&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">s&lt;/span>, &lt;span style="color:#a6e22e">_&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">sqlite&lt;/span>.&lt;span style="color:#a6e22e">New&lt;/span>[&lt;span style="color:#a6e22e">Config&lt;/span>](&lt;span style="color:#a6e22e">sqlite&lt;/span>.&lt;span style="color:#a6e22e">Options&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">DSN&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;file:config.db?cache=shared&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Codec&lt;/span>: &lt;span style="color:#f92672">&amp;amp;&lt;/span>&lt;span style="color:#a6e22e">codec&lt;/span>.&lt;span style="color:#a6e22e">JSON&lt;/span>{},
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">BusyTimeout&lt;/span>: &lt;span style="color:#ae81ff">5&lt;/span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Second&lt;/span>, &lt;span style="color:#75715e">// Wait up to 5s for locks&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">DisableWAL&lt;/span>: &lt;span style="color:#66d9ef">false&lt;/span>, &lt;span style="color:#75715e">// Keep WAL enabled (default)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>})
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="database-schema">Database Schema&lt;/h2>
&lt;p>The store automatically creates this schema on first use:&lt;/p></description></item><item><title>Watching &amp; Events</title><link>https://ca7cdd17.zestor-docs.pages.dev/docs/concepts/watching/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ca7cdd17.zestor-docs.pages.dev/docs/concepts/watching/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Zestor&amp;rsquo;s watch system lets you subscribe to changes in real-time. When data is created, updated, or deleted, watchers receive events through a channel.&lt;/p>
&lt;h2 id="basic-watching">Basic Watching&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Start watching the &amp;#34;users&amp;#34; kind&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">ch&lt;/span>, &lt;span style="color:#a6e22e">cancel&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">s&lt;/span>.&lt;span style="color:#a6e22e">Watch&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;users&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Fatal&lt;/span>(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">cancel&lt;/span>() &lt;span style="color:#75715e">// Always cancel when done&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Process events&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">for&lt;/span> &lt;span style="color:#a6e22e">event&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#66d9ef">range&lt;/span> &lt;span style="color:#a6e22e">ch&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%s: %s\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">event&lt;/span>.&lt;span style="color:#a6e22e">EventType&lt;/span>, &lt;span style="color:#a6e22e">event&lt;/span>.&lt;span style="color:#a6e22e">Name&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="event-types">Event Types&lt;/h2>
&lt;p>Three event types are emitted:&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Event&lt;/th>
 &lt;th>When&lt;/th>
 &lt;th>&lt;code>event.Object&lt;/code> contains&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>EventTypeCreate&lt;/code>&lt;/td>
 &lt;td>New key is set&lt;/td>
 &lt;td>The new value&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>EventTypeUpdate&lt;/code>&lt;/td>
 &lt;td>Existing key is modified&lt;/td>
 &lt;td>The new value&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>EventTypeDelete&lt;/code>&lt;/td>
 &lt;td>Key is deleted&lt;/td>
 &lt;td>The previous value&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">for&lt;/span> &lt;span style="color:#a6e22e">event&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#66d9ef">range&lt;/span> &lt;span style="color:#a6e22e">ch&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">switch&lt;/span> &lt;span style="color:#a6e22e">event&lt;/span>.&lt;span style="color:#a6e22e">EventType&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">case&lt;/span> &lt;span style="color:#a6e22e">store&lt;/span>.&lt;span style="color:#a6e22e">EventTypeCreate&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Created %s: %+v\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">event&lt;/span>.&lt;span style="color:#a6e22e">Name&lt;/span>, &lt;span style="color:#a6e22e">event&lt;/span>.&lt;span style="color:#a6e22e">Object&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">case&lt;/span> &lt;span style="color:#a6e22e">store&lt;/span>.&lt;span style="color:#a6e22e">EventTypeUpdate&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Updated %s: %+v\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">event&lt;/span>.&lt;span style="color:#a6e22e">Name&lt;/span>, &lt;span style="color:#a6e22e">event&lt;/span>.&lt;span style="color:#a6e22e">Object&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">case&lt;/span> &lt;span style="color:#a6e22e">store&lt;/span>.&lt;span style="color:#a6e22e">EventTypeDelete&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Deleted %s (was: %+v)\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">event&lt;/span>.&lt;span style="color:#a6e22e">Name&lt;/span>, &lt;span style="color:#a6e22e">event&lt;/span>.&lt;span style="color:#a6e22e">Object&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="event-structure">Event Structure&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Event&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">struct&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> &lt;span style="color:#75715e">// The kind (e.g., &amp;#34;users&amp;#34;)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Name&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> &lt;span style="color:#75715e">// The key (e.g., &amp;#34;alice&amp;#34;)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">EventType&lt;/span> &lt;span style="color:#a6e22e">EventType&lt;/span> &lt;span style="color:#75715e">// create, update, or delete&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Object&lt;/span> &lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#75715e">// The value (or previous value for delete)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="watch-options">Watch Options&lt;/h2>
&lt;h3 id="filter-by-event-type">Filter by Event Type&lt;/h3>
&lt;p>Only receive specific event types:&lt;/p></description></item><item><title>Interface Segregation</title><link>https://ca7cdd17.zestor-docs.pages.dev/docs/concepts/interfaces/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ca7cdd17.zestor-docs.pages.dev/docs/concepts/interfaces/</guid><description>&lt;h2 id="overview">Overview&lt;/h2>
&lt;p>Zestor follows the &lt;strong>Interface Segregation Principle&lt;/strong> by splitting its functionality into focused interfaces. This allows you to pass only the access level your code needs.&lt;/p>
&lt;h2 id="available-interfaces">Available Interfaces&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Reader provides read-only access&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Reader&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Get&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span>, &lt;span style="color:#a6e22e">key&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) (&lt;span style="color:#a6e22e">val&lt;/span> &lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#a6e22e">ok&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">List&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">filter&lt;/span> &lt;span style="color:#f92672">...&lt;/span>&lt;span style="color:#a6e22e">FilterFunc&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]) (&lt;span style="color:#66d9ef">map&lt;/span>[&lt;span style="color:#66d9ef">string&lt;/span>]&lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Count&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) (&lt;span style="color:#66d9ef">int&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Keys&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) ([]&lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Values&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) ([]&lt;span style="color:#a6e22e">KeyValue&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>], &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">GetAll&lt;/span>() (&lt;span style="color:#66d9ef">map&lt;/span>[&lt;span style="color:#66d9ef">string&lt;/span>]&lt;span style="color:#66d9ef">map&lt;/span>[&lt;span style="color:#66d9ef">string&lt;/span>]&lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Writer provides write access&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Writer&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Set&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span>, &lt;span style="color:#a6e22e">key&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">value&lt;/span> &lt;span style="color:#a6e22e">T&lt;/span>) (&lt;span style="color:#a6e22e">created&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">SetFn&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span>, &lt;span style="color:#a6e22e">key&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">fn&lt;/span> &lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">v&lt;/span> &lt;span style="color:#a6e22e">T&lt;/span>) (&lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)) (&lt;span style="color:#a6e22e">changed&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">SetAll&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">values&lt;/span> &lt;span style="color:#66d9ef">map&lt;/span>[&lt;span style="color:#66d9ef">string&lt;/span>]&lt;span style="color:#a6e22e">T&lt;/span>) &lt;span style="color:#66d9ef">error&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Delete&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span>, &lt;span style="color:#a6e22e">key&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>) (&lt;span style="color:#a6e22e">existed&lt;/span> &lt;span style="color:#66d9ef">bool&lt;/span>, &lt;span style="color:#a6e22e">prev&lt;/span> &lt;span style="color:#a6e22e">T&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Watcher provides watch access&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Watcher&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Watch&lt;/span>(&lt;span style="color:#a6e22e">kind&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">opts&lt;/span> &lt;span style="color:#f92672">...&lt;/span>&lt;span style="color:#a6e22e">WatchOption&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]) (&lt;span style="color:#a6e22e">r&lt;/span> &lt;span style="color:#f92672">&amp;lt;-&lt;/span>&lt;span style="color:#66d9ef">chan&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">Event&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>], &lt;span style="color:#a6e22e">cancel&lt;/span> &lt;span style="color:#66d9ef">func&lt;/span>(), &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// ReadWriter combines Reader and Writer&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">ReadWriter&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Reader&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Writer&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Store is the full interface&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Store&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>] &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Reader&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Writer&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Watcher&lt;/span>[&lt;span style="color:#a6e22e">T&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Close&lt;/span>() &lt;span style="color:#66d9ef">error&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Dump&lt;/span>() &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="why-interface-segregation">Why Interface Segregation?&lt;/h2>
&lt;h3 id="1-principle-of-least-privilege">1. Principle of Least Privilege&lt;/h3>
&lt;p>Pass only the access your code needs:&lt;/p></description></item><item><title>Codecs</title><link>https://ca7cdd17.zestor-docs.pages.dev/docs/concepts/codec/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ca7cdd17.zestor-docs.pages.dev/docs/concepts/codec/</guid><description>&lt;h2 id="what-is-a-codec">What is a Codec?&lt;/h2>
&lt;p>A &lt;strong>codec&lt;/strong> (coder/decoder) handles serialization and deserialization of your data types. Persistent stores like SQLite need codecs to convert Go structs to bytes for storage and back again when reading.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Codec&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Marshal&lt;/span>(&lt;span style="color:#a6e22e">v&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>) ([]&lt;span style="color:#66d9ef">byte&lt;/span>, &lt;span style="color:#66d9ef">error&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Unmarshal&lt;/span>(&lt;span style="color:#a6e22e">data&lt;/span> []&lt;span style="color:#66d9ef">byte&lt;/span>, &lt;span style="color:#a6e22e">v&lt;/span> &lt;span style="color:#66d9ef">any&lt;/span>) &lt;span style="color:#66d9ef">error&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="why-codecs-matter">Why Codecs Matter&lt;/h2>
&lt;p>In-memory stores like &lt;code>gomap&lt;/code> store your Go values directly — no serialization needed. But persistent stores must convert values to bytes:&lt;/p>
&lt;pre tabindex="0">&lt;code>┌──────────────┐ Marshal ┌──────────────┐
│ Go Struct │ ───────────────► │ []byte │ ───► Storage
│ {Name:&amp;#34;X&amp;#34;} │ │ [123,34...] │
└──────────────┘ └──────────────┘

┌──────────────┐ Unmarshal ┌──────────────┐
│ Go Struct │ ◄─────────────── │ []byte │ ◄─── Storage
│ {Name:&amp;#34;X&amp;#34;} │ │ [123,34...] │
└──────────────┘ └──────────────┘
&lt;/code>&lt;/pre>&lt;h2 id="available-codecs">Available Codecs&lt;/h2>
&lt;h3 id="json">JSON&lt;/h3>
&lt;p>The most common choice. Human-readable, widely supported.&lt;/p></description></item></channel></rss>