detached 4d548f3

chore(deps): integrate approved upstream foundations

commit
4d548f3f69cfbdc7fc18360aeb70966c0b334bd3
author
brice · · 2026-07-14 14:11 UTC
parent
41933ea
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
13 files · +482 -125
M go.mod +3 -3
@@ -6,10 +6,10 @@ require (
66 github.com/a-h/templ v0.3.1020
77 github.com/andybalholm/brotli v1.2.2
88 github.com/bnema/purego v0.11.0-bnema.4
9- github.com/bnema/purego-cef v0.13.3
9+ github.com/bnema/purego-cef v0.13.4-0.20260714140305-f0b7414af67e
1010 github.com/bnema/purego-cef2gtk v0.8.4
11- github.com/bnema/purego-pipewire v0.1.4
12- github.com/bnema/purego-sqlite v0.1.3
11+ github.com/bnema/purego-pipewire v0.1.5-0.20260714124450-6504b9cdf02a
12+ github.com/bnema/purego-sqlite v0.1.4-0.20260714131321-3614fe683b9c
1313 github.com/bnema/puregotk v0.7.0
1414 github.com/charmbracelet/bubbles v1.0.0
1515 github.com/charmbracelet/bubbletea v1.3.10
@@ -6,10 +6,10 @@ require (
6 github.com/a-h/templ v0.3.10206 github.com/a-h/templ v0.3.1020
7 github.com/andybalholm/brotli v1.2.27 github.com/andybalholm/brotli v1.2.2
8 github.com/bnema/purego v0.11.0-bnema.48 github.com/bnema/purego v0.11.0-bnema.4
9- github.com/bnema/purego-cef v0.13.39+ github.com/bnema/purego-cef v0.13.4-0.20260714140305-f0b7414af67e
10 github.com/bnema/purego-cef2gtk v0.8.410 github.com/bnema/purego-cef2gtk v0.8.4
11- github.com/bnema/purego-pipewire v0.1.411+ github.com/bnema/purego-pipewire v0.1.5-0.20260714124450-6504b9cdf02a
12- github.com/bnema/purego-sqlite v0.1.312+ github.com/bnema/purego-sqlite v0.1.4-0.20260714131321-3614fe683b9c
13 github.com/bnema/puregotk v0.7.013 github.com/bnema/puregotk v0.7.0
14 github.com/charmbracelet/bubbles v1.0.014 github.com/charmbracelet/bubbles v1.0.0
15 github.com/charmbracelet/bubbletea v1.3.1015 github.com/charmbracelet/bubbletea v1.3.10
M go.sum +6 -0 generated file: collapsed
A internal/infrastructure/persistence/sqlite/history_repo_benchmark_test.go +66 -0
@@ -0,0 +1,66 @@
1+package sqlite_test
2+
3+import (
4+ "fmt"
5+ "path/filepath"
6+ "testing"
7+
8+ "github.com/bnema/dumber/internal/domain/entity"
9+ "github.com/bnema/dumber/internal/domain/repository"
10+ "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite"
11+)
12+
13+// newHistoryBenchmarkRepository creates a representative local history corpus
14+// outside the measured operation. Sidebar reads use GetRecent and omnibox
15+// history suggestions use Search.
16+func newHistoryBenchmarkRepository(b *testing.B) (repository.HistoryRepository, func()) {
17+ b.Helper()
18+
19+ ctx := historyTestCtx()
20+ db, err := sqlite.NewConnection(ctx, filepath.Join(b.TempDir(), "dumber.db"))
21+ if err != nil {
22+ b.Fatal(err)
23+ }
24+
25+ repo := sqlite.NewHistoryRepository(db)
26+ for i := range 200 {
27+ entry := &entity.HistoryEntry{
28+ URL: fmt.Sprintf("https://example%d.test/dumber/history/%d", i%20, i),
29+ Title: fmt.Sprintf("Dumber history entry %d", i),
30+ }
31+ if err := repo.Save(ctx, entry); err != nil {
32+ _ = db.Close()
33+ b.Fatal(err)
34+ }
35+ }
36+
37+ return repo, func() { _ = db.Close() }
38+}
39+
40+func BenchmarkHistorySQLiteSidebarRecent(b *testing.B) {
41+ repo, closeDB := newHistoryBenchmarkRepository(b)
42+ defer closeDB()
43+ ctx := historyTestCtx()
44+
45+ b.ReportAllocs()
46+ b.ResetTimer()
47+ for range b.N {
48+ if _, err := repo.GetRecent(ctx, 50, 0); err != nil {
49+ b.Fatal(err)
50+ }
51+ }
52+}
53+
54+func BenchmarkHistorySQLiteOmniboxSearch(b *testing.B) {
55+ repo, closeDB := newHistoryBenchmarkRepository(b)
56+ defer closeDB()
57+ ctx := historyTestCtx()
58+
59+ b.ReportAllocs()
60+ b.ResetTimer()
61+ for range b.N {
62+ if _, err := repo.Search(ctx, "dumber history", 10); err != nil {
63+ b.Fatal(err)
64+ }
65+ }
66+}
@@ -0,0 +1,66 @@
1+package sqlite_test
2+
3+import (
4+ "fmt"
5+ "path/filepath"
6+ "testing"
7+
8+ "github.com/bnema/dumber/internal/domain/entity"
9+ "github.com/bnema/dumber/internal/domain/repository"
10+ "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite"
11+)
12+
13+// newHistoryBenchmarkRepository creates a representative local history corpus
14+// outside the measured operation. Sidebar reads use GetRecent and omnibox
15+// history suggestions use Search.
16+func newHistoryBenchmarkRepository(b *testing.B) (repository.HistoryRepository, func()) {
17+ b.Helper()
18+
19+ ctx := historyTestCtx()
20+ db, err := sqlite.NewConnection(ctx, filepath.Join(b.TempDir(), "dumber.db"))
21+ if err != nil {
22+ b.Fatal(err)
23+ }
24+
25+ repo := sqlite.NewHistoryRepository(db)
26+ for i := range 200 {
27+ entry := &entity.HistoryEntry{
28+ URL: fmt.Sprintf("https://example%d.test/dumber/history/%d", i%20, i),
29+ Title: fmt.Sprintf("Dumber history entry %d", i),
30+ }
31+ if err := repo.Save(ctx, entry); err != nil {
32+ _ = db.Close()
33+ b.Fatal(err)
34+ }
35+ }
36+
37+ return repo, func() { _ = db.Close() }
38+}
39+
40+func BenchmarkHistorySQLiteSidebarRecent(b *testing.B) {
41+ repo, closeDB := newHistoryBenchmarkRepository(b)
42+ defer closeDB()
43+ ctx := historyTestCtx()
44+
45+ b.ReportAllocs()
46+ b.ResetTimer()
47+ for range b.N {
48+ if _, err := repo.GetRecent(ctx, 50, 0); err != nil {
49+ b.Fatal(err)
50+ }
51+ }
52+}
53+
54+func BenchmarkHistorySQLiteOmniboxSearch(b *testing.B) {
55+ repo, closeDB := newHistoryBenchmarkRepository(b)
56+ defer closeDB()
57+ ctx := historyTestCtx()
58+
59+ b.ReportAllocs()
60+ b.ResetTimer()
61+ for range b.N {
62+ if _, err := repo.Search(ctx, "dumber history", 10); err != nil {
63+ b.Fatal(err)
64+ }
65+ }
66+}
M vendor/github.com/bnema/purego-cef/cef/bridge.go +8 -13 generated file: collapsed
M vendor/github.com/bnema/purego-pipewire/internal/core/player.go +5 -0 generated file: collapsed
M vendor/github.com/bnema/purego-pipewire/internal/core/player_rt.go +10 -6
@@ -163,6 +163,9 @@ func (p *player) fail(err error) {
163163 // queues the buffer back. If any step fails, it routes the error
164164 // through p.fail.
165165 func (p *player) onProcess() {
166+ // Drop native references before returning from each callback.
167+ defer p.pwView.clear()
168+
166169 ops := p.streamOps
167170 if ops == nil {
168171 return
@@ -180,24 +183,25 @@ func (p *player) onProcess() {
180183
181184 queueOnError := true
182185 defer func() {
183- if err := ops.QueueBuffer(sp, bufPtr); err != nil && queueOnError {
186+ err := ops.QueueBuffer(sp, bufPtr)
187+ if err != nil && queueOnError {
188+ // Clear before OnError can reenter player methods.
189+ p.pwView.clear()
184190 p.fail(fmt.Errorf("queue buffer: %w", err))
185191 }
186192 }()
187193
188- frames := p.config.FramesPerBuffer
189- view, err := newPWBufferView(bufPtr, p.config.Channels, frames)
190- if err != nil {
194+ if err := p.pwView.refresh(bufPtr); err != nil {
191195 queueOnError = false
192196 p.fail(fmt.Errorf("buffer view: %w", err))
193197 return
194198 }
195199
196- frames, err = p.processPCM(view.PCM())
200+ frames, err := p.processPCM(p.pwView.PCM())
197201 if err != nil {
198202 queueOnError = false
199203 return
200204 }
201205
202- view.Commit(frames)
206+ p.pwView.Commit(frames)
203207 }
@@ -163,6 +163,9 @@ func (p *player) fail(err error) {
163 // queues the buffer back. If any step fails, it routes the error163 // queues the buffer back. If any step fails, it routes the error
164 // through p.fail.164 // through p.fail.
165 func (p *player) onProcess() {165 func (p *player) onProcess() {
166+ // Drop native references before returning from each callback.
167+ defer p.pwView.clear()
168+
166 ops := p.streamOps169 ops := p.streamOps
167 if ops == nil {170 if ops == nil {
168 return171 return
@@ -180,24 +183,25 @@ func (p *player) onProcess() {
180 183
181 queueOnError := true184 queueOnError := true
182 defer func() {185 defer func() {
183- if err := ops.QueueBuffer(sp, bufPtr); err != nil && queueOnError {186+ err := ops.QueueBuffer(sp, bufPtr)
187+ if err != nil && queueOnError {
188+ // Clear before OnError can reenter player methods.
189+ p.pwView.clear()
184 p.fail(fmt.Errorf("queue buffer: %w", err))190 p.fail(fmt.Errorf("queue buffer: %w", err))
185 }191 }
186 }()192 }()
187 193
188- frames := p.config.FramesPerBuffer194+ if err := p.pwView.refresh(bufPtr); err != nil {
189- view, err := newPWBufferView(bufPtr, p.config.Channels, frames)
190- if err != nil {
191 queueOnError = false195 queueOnError = false
192 p.fail(fmt.Errorf("buffer view: %w", err))196 p.fail(fmt.Errorf("buffer view: %w", err))
193 return197 return
194 }198 }
195 199
196- frames, err = p.processPCM(view.PCM())200+ frames, err := p.processPCM(p.pwView.PCM())
197 if err != nil {201 if err != nil {
198 queueOnError = false202 queueOnError = false
199 return203 return
200 }204 }
201 205
202- view.Commit(frames)206+ p.pwView.Commit(frames)
203 }207 }
M vendor/github.com/bnema/purego-pipewire/internal/core/pwbuffer.go +66 -32 generated file: collapsed
M vendor/github.com/bnema/purego-sqlite/driver/driver.go +268 -63 generated file: collapsed
M vendor/github.com/bnema/purego-sqlite/internal/core/db.go +8 -0 generated file: collapsed
M vendor/github.com/bnema/purego-sqlite/internal/core/rows.go +13 -0 generated file: collapsed
M vendor/github.com/bnema/purego-sqlite/internal/loader/loader.go +23 -5 generated file: collapsed
M vendor/github.com/bnema/purego-sqlite/internal/ports/in/ports_gen.go +3 -0 generated file: collapsed
M vendor/modules.txt +3 -3 generated file: collapsed

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close