refactor(quartz): encapsulate interning as InternedEventStore decorator

Replaces the ctor-injected interner inside SQLiteEventStore /
QueryBuilder / EventStore / FsEventStore with a standalone
InternedEventStore decorator in nip01Core/cache/.

Composition is now explicit at the call site:

  val sqlite = EventStore(...)
  val cached = InternedEventStore(sqlite)
  val observable = ObservableEventStore(cached)

Each layer has one job: EventStore persists, InternedEventStore
canonicalises read results, ObservableEventStore publishes the bus.
Stores no longer carry an interner field; passing one through three
layers of constructor params is gone.

InternedEventStore wraps every IEventStore.query variant (list +
streaming, single filter + multi) and pipes results through
interner.intern. Writes (insert, transaction, delete*,
deleteExpiredEvents) and counts pass through untouched.

assertQuery test helpers generalized from EventStore /
SQLiteEventStore to IEventStore so the decorator works with the
existing fixtures.

BaseDBTest reverts to plain EventStore — the basic store tests
don't read through the projection / interning layer, so they don't
need decoration. Tests that DO want canonical-instance reads can
wrap explicitly: `InternedEventStore(eventStore)`.

7/7 interner + 240/240 store + projection tests still pass.

https://claude.ai/code/session_01Jny85MTu1ynKgFBgysfWu5
This commit is contained in:
Claude
2026-04-30 14:30:48 +00:00
parent 03e9c9d2b2
commit 3fc4781d12
7 changed files with 102 additions and 40 deletions
@@ -22,9 +22,10 @@ package com.vitorpamplona.quartz.nip01Core.store.sqlite
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
import com.vitorpamplona.quartz.nip01Core.store.IEventStore
import kotlin.test.assertEquals
suspend fun <T : Event> EventStore.assertQuery(
suspend fun <T : Event> IEventStore.assertQuery(
expected: T?,
filter: Filter,
) {
@@ -40,7 +41,7 @@ suspend fun <T : Event> EventStore.assertQuery(
}
}
suspend fun <T : Event> EventStore.assertQuery(
suspend fun <T : Event> IEventStore.assertQuery(
expected: List<T>,
filter: Filter,
) {
@@ -20,7 +20,6 @@
*/
package com.vitorpamplona.quartz.nip01Core.store.sqlite
import com.vitorpamplona.quartz.nip01Core.cache.EventInterner
import com.vitorpamplona.quartz.utils.Secp256k1Instance
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -64,12 +63,6 @@ open class BaseDBTest {
EventStore(
dbName = null,
indexStrategy = indexStrategy,
// Each store gets its own interner so
// parallel forEachDB runs don't share a
// canonical Event for the same id —
// tests sign with random sigs that
// would otherwise cross-pollinate.
interner = EventInterner(),
)
}
}