Thomas Camlong
ffed73ba8f
merge: incorporate latest dev changes into phase1-perf branch
...
Merge origin/dev to pick up service isolation (concurrently dev script,
turbopack aliases, instrumentation simplification), PostHog analytics,
color scheme, and other dev improvements while preserving all Phase 1
performance work (Suspense boundaries, cache components, Redis handler,
integration barrel diet, cache invalidation).
2026-08-07 21:36:48 +02:00
Thomas Camlong
33293ba1cf
refactor: simplify Phase 1 infrastructure code
...
- cache-invalidation: extract isExpectedRevalidateError helper
- integration-data-cache: flatten early-return chain, extract eviction
- redis-handler: extract StoredEntry type, readStreamBody, ensureConnected
- svg-purify: single getOwnPropertyDescriptor lookup per prop
- session-scoped-providers: simplify auth flow
- retryable-loader: use function declarations
- translation/request: replace spread-in-reduce with for loop
2026-08-07 21:04:42 +02:00
Thomas Camlong
67ac2bbc7c
fix: Redis expire guard, transferOwnership prev-owner, SVG regex
...
- Redis get() rejects legacy expire=0 entries and cleans them up
- transferOwnership invalidates previous owner in addition to new
- SVG regex uses non-greedy match and handles self-closing <svg />
- SVG fallback returns empty string instead of HTML wrapper
- Memory channel comment: FIFO eviction, not timestamp-based
2026-08-07 20:57:07 +02:00
Thomas Camlong
fbb2eddd87
fix: concurrent stale race, Redis expire leak, missing invalidation, UI Suspense
...
- Fix integration data cache: set pending synchronously before creating
fetch to prevent concurrent stale-revalidation from spawning duplicate
upstream calls
- Redis cache handler: skip persisting entries with expire=0 (dynamic
entries should not be stored in Redis)
- Add missing invalidation: user.changePassword, group.updateGroup,
group.transferOwnership
- Move SearchEngineOptimization inside Suspense in root layout
- Add Suspense fallback loader to root layout
- Move searchParams resolution inside Suspense in login page
2026-08-07 20:53:36 +02:00
Thomas Camlong
38ac8f3075
fix: concurrent cache miss, SVG output, narrowed error handling, format
...
- Fix integration data cache: check pending promise before TTL to
prevent returning undefined on concurrent cold-cache access
- Add concurrent-miss test (two parallel callers, one fetch)
- SVG sanitizer: extract <svg> from DOMPurify output to strip
residual HTML wrapper
- Narrow safeRevalidateTag catch: log unexpected errors, silence only
known "outside request scope" messages
- Run oxfmt across all packages (206 files formatted)
2026-08-07 20:48:17 +02:00
Thomas Camlong
b81b90875f
fix: revert DB driver to static imports, fix test regressions
...
- Revert createRequire() for DB drivers — require() can't resolve .ts
files in Vitest, breaking 49 test suites
- Make cache invalidation fail-safe via try-catch around revalidateTag
(throws outside Next.js context: tests, tasks service, websocket)
- Fix 6 integration test imports: barrel no longer exports concrete
classes, point tests at direct source paths
- Fix Redis cache handler lint errors: remove non-null assertions,
suppress __NEXT_BUILD_ID underscore warning
2026-08-07 20:43:07 +02:00
Thomas
b32ad82850
perf: cut cold route compilation and unblock preview images ( #6441 )
2026-08-07 20:24:26 +02:00
Thomas Camlong
67fcd69eb8
fix: inverted tag expiration in Redis handler + saveItemOptions board name
...
- Fix critical bug: tag expiration comparison was inverted (< should be >)
in Redis cache handler, which would prevent revalidateTag from clearing
stale entries
- Pass board name to invalidateBoardCache in saveItemOptions
- Add clarifying comment about two-tier invalidation helpers
2026-08-07 19:30:58 +02:00
Thomas Camlong
aeabfd3521
fix: requestMedia dual-layer cache invalidation
...
Mirror answerRequest pattern: invalidate both module-level integration
data cache and request-handler caches for media request list/stats.
2026-08-07 19:27:41 +02:00
Thomas Camlong
37930e44cc
perf: clean integration barrel — remove 46 concrete class re-exports
...
- Remove all concrete integration class re-exports from barrel
- Replace instanceof check with kind check in health-monitoring
- Document cache invalidation as preparatory (cacheTag follow-up)
2026-08-07 19:22:32 +02:00
Thomas Camlong
451dc3ce39
fix: address review #4 — board name invalidation, SVG tests, test gaps
...
- Pass board.name to all invalidateBoardCache calls (permission mutations)
- Align integration create invalidation with update/delete
- Add initial-fetch-failure test for integration-data-cache
- Expand SVG XSS test corpus (javascript:, xlink:href, @import, onbegin)
- Forbid <style> tags in SVG sanitizer to prevent CSS injection
- Fix duplicate export in packages/common/src/index.ts
2026-08-07 19:18:18 +02:00
Thomas Camlong
4361c8dbe2
fix: address Bugbot review #3 — mutation invalidation gaps
...
- Dual-layer cache invalidation on interact mutations
(dns-hole, media-requests, smart-home, indexer-manager, anchor-notes)
- importOldmarrConfig: invalidate created boards
- createBoard: invalidateUserCache when auto-setting homeBoardId
- group.savePositions: invalidate user caches for affected members
- integration.requestMedia: invalidate integration data cache
- user.delete: invalidate user cache
2026-08-07 19:14:02 +02:00
Thomas Camlong
0f8362c3da
fix: address Bugbot review #2 findings
...
- Invalidate integration data cache from widget interact mutations
(downloads, dns-hole, media-requests, indexer-manager, smart-home, anchor-notes)
- Redis handler getExpiration: fetch missing tags from Redis (multi-instance coherence)
- saveItemOptions: invalidate board cache after saving
- Remove unused cacheTags.app
- Fix integration data cache comment accuracy
2026-08-07 19:08:57 +02:00
Thomas Camlong
6b45aca5d5
fix: address Bugbot review findings
...
- Skip module-level integration cache for multi-instance (REDIS_IS_EXTERNAL)
- Add invalidateBoardCache to permission mutations (prevents future leak)
- Remove unused cacheTags.integrationData
- Replace KEYS with SCAN in Redis cache handler refreshTags()
- Document REDIS_CACHE_DB env var
2026-08-07 19:04:53 +02:00
Thomas Camlong
018f98e318
perf: implement Phase 1 homepage diet via Next.js Cache Components
...
P1-0: V8 heap cap (HOMARR_MAX_OLD_SPACE_SIZE, default 512MB)
P1-1: Module graph cuts
- Dynamic integration imports (55 static → lazy loaders)
- Conditional DB driver loading (only configured driver loaded)
- Replace jsdom with linkedom for SVG sanitization
- Delete eager widget barrel (55 import * as → 0)
- Extract createRetryableLoader to @homarr/common
P1-2: Enable cacheComponents + restructure root layout
- Suspense boundaries around session-dependent providers
- ColorSchemeScript replaces server-side cookie reads
- Board/manage/auth layouts wrapped in Suspense
P1-3: Cache read paths
- Cache tag registry + invalidation helpers
- Cache invalidation wired into all mutation routers
- Translation deep-merge memoized per locale
P1-4: Prerendered shells + loading.tsx files
P1-5: Shared integration data cache (60s TTL, stale-while-revalidate)
P1-6: Redis-backed Next.js cache handler (@homarr/next-cache-handler)
P1-7: Redis optional (memory channel fallback), TTL on pubSub:last:*,
Redis clients consolidated from 6 to 2
2026-08-07 18:59:47 +02:00
homarr-crowdin[bot]
85fcea3837
chore(lang): updated translations from crowdin ( #6500 )
2026-08-07 18:22:43 +02:00
Thomas
f76a0f240a
feat(apps): allow custom URI schemes in application links ( #6521 )
2026-08-06 21:52:56 +02:00
Thomas
55214ccbc5
fix(integrations): throw on total item-info failure to preserve stale-cache fallback ( #6522 )
2026-08-06 21:42:46 +02:00
Thomas
778533a62e
fix: revert regressions from recent integration/releases/app-href changes ( #6514 )
2026-08-03 17:37:53 +02:00
Thomas
b4fba47a23
fix(releases): add success flag to successful response for correct error detection ( #6512 )
2026-08-03 17:10:35 +02:00
Thomas
76ddfceb13
fix: restore auto-refresh for docker and notifications widgets ( #6511 )
2026-08-03 17:07:46 +02:00
Thomas
2f6b96e5ba
feat: restrict integrations management to integration-full-all permission ( #6509 )
2026-08-03 17:04:35 +02:00
Thomas
f1b7a5146a
fix: allow [homarr_base] template variables in app href validation ( #6508 )
2026-08-03 16:47:40 +02:00
Thomas Camlong
9f4b147f0e
fix legacy media server option mapping
2026-08-03 15:29:27 +02:00
Thomas Camlong
05292ae1f5
fix: map legacy media server options
2026-08-03 15:24:30 +02:00
Thomas Camlong
08af704c8a
Merge origin/dev into feat/build-performance
2026-08-03 15:21:23 +02:00
Thomas Camlong
de801f3f00
perf: optimize dashboard loading and builds
2026-08-02 15:58:16 +02:00
Thomas
d58a47b776
fix: restrict system health monitoring integrations ( #6505 )
2026-08-02 10:17:05 +02:00
Thomas
797bdd001f
fix: keep direct icon URLs visible ( #6504 )
2026-08-01 23:28:18 +02:00
Bergasha
49314533bf
feat(Media player widget): expands on Direct Play and Transcoding badges ( #6489 )
2026-08-01 23:21:13 +02:00
Thomas
27ca058088
feat(widgets): persist Beszel and Docker table layouts ( #6490 )
2026-08-01 23:20:09 +02:00
Thomas
edb56f3fcd
fix: accept direct icon URLs
...
Use valid direct HTTP(S) icon URLs without repository search.
2026-08-01 23:06:26 +02:00
homarr-crowdin[bot]
fcc5130068
chore(lang): update translations from crowdin ( #6457 )
2026-07-31 23:50:10 +02:00
Thomas
ade640dcea
test(navidrome): complete cleanup review ( #6494 )
...
* test(navidrome): hoist album fixture helper
* test(navidrome): address coderabbit cleanup feedback
2026-07-31 14:39:11 +02:00
Thomas
61128ddcc8
fix(navidrome): clean up audio stats integration ( #6493 )
2026-07-31 14:20:51 +02:00
Thomas
6a3cee8107
fix(navidrome): complete media server session data ( #6492 )
2026-07-31 13:53:06 +02:00
ajnart
d90e762e4b
fix: align Navidrome media sessions
2026-07-31 13:52:39 +02:00
ajnart
81a13d3b52
Merge remote-tracking branch 'origin/dev' into feat/build-performance
2026-07-31 13:38:16 +02:00
ajnart
388a74086e
fix: address Copilot cache review
2026-07-31 13:32:48 +02:00
Matt Van Horn
06d9c07d22
feat: expose Navidrome as a media-server (now-playing) integration ( #6070 )
2026-07-31 13:30:44 +02:00
ajnart
9963ba0274
fix: harden runtime isolation and regression tests
2026-07-30 00:38:34 +02:00
ajnart
fbb57c8f40
fix(docker): build runtime workspaces only
2026-07-29 06:57:06 +02:00
ajnart
0b9c4d6375
fix: address performance review feedback
2026-07-29 06:50:13 +02:00
ajnart
440626ba00
test(performance): add authenticated local benchmarks
2026-07-29 06:47:07 +02:00
ajnart
f8d8a09c56
perf(proxy): isolate settings database reads
2026-07-29 06:47:07 +02:00
ajnart
add6ee56ba
fix(updates): enforce a persisted daily check
2026-07-29 06:47:07 +02:00
ajnart
6b74078766
perf(widgets): lazy load the application graph
2026-07-29 06:47:07 +02:00
ajnart
4ca0b747bb
chore(next): upgrade preview and isolate dev services
2026-07-29 06:47:07 +02:00
Thomas
2885f7a297
fix(widgets): preserve data on integration failures ( #6484 )
2026-07-28 22:18:08 +02:00
Thomas
906c9f11fa
feat(widgets): rework downloads widget with mantine-datatable ( #6430 )
2026-07-28 21:50:09 +02:00