feat: speed up admin clone import and enable Cache Components

- Clone import: defer FurnitureData.json writes and append all entries in a
  single batched write instead of one read-modify-write per item, removing
  the main serialization bottleneck for large batches.
- Clone import: raise SSE batch concurrency cap from 5 to 10 and bump the
  clone client/route default from 2 to 6.
- Add a flush hook to runSseBatch so callers can batch deferred work before
  batch_complete is emitted, and surface flush errors as an error event.
- Enable Next.js Cache Components (instant: false opt-out) and silence the
  related build warnings in next.config.ts.
- Switch isomorphic-dompurify to dompurify and refresh dependencies.
This commit is contained in:
openhands committed 2026-08-05 11:10:16 +02:00
1 parent ac9b3e3cb5
commit dc8fb8a6ed
254 files changed
+910 -551

No files matched your search

-2
View File
@@ -5,8 +5,6 @@
import { apiJson } from "@/lib/api";
import { siteSettings } from "@/lib/services/site-settings";
export const dynamic = "force-dynamic";
function truthy(value: string | null | undefined): boolean {
if (value === undefined || value === null) return false;
const s = value.trim().toLowerCase();
-1
View File
@@ -4,7 +4,6 @@ import { siteSettings } from "@/lib/services/site-settings";
// Radio player config: the subset of radio_* website_settings the front-end
// player needs (stream URL, name, autoplay, enabled, widget visibility) as a
// flat { key: value } map. No secrets live among these keys.
export const dynamic = "force-dynamic";
const CONFIG_KEYS = [
"radio_enabled",
-1
View File
@@ -6,7 +6,6 @@ import { siteSettings } from "@/lib/services/site-settings";
// Current on-air DJ. The DJ is set manually via the radio_current_dj_id setting
// (Manual DJ user ID). When set, resolve that user's username/look; otherwise
// there is no DJ on air. Mirrors the AtomCMS radio "on air" widget.
export const dynamic = "force-dynamic";
export async function GET(_req: Request) {
try {
-1
View File
@@ -4,7 +4,6 @@ import { siteSettings } from "@/lib/services/site-settings";
// Minimal radio_* settings an external page needs to embed the player: stream
// URL, display name, whether the radio is enabled, and autoplay. Returned as a
// flat { key: value } map. None of these keys are secrets.
export const dynamic = "force-dynamic";
const EMBED_KEYS = [
"radio_enabled",
-1
View File
@@ -4,7 +4,6 @@ import { siteSettings } from "@/lib/services/site-settings";
// Proxy for the configured radio "listeners" provider. The provider URL is
// stored in radio_listeners_api_url; we fetch it server-side with a short, hard
// timeout and reduce the response to a single listener count.
export const dynamic = "force-dynamic";
const FETCH_TIMEOUT_MS = 4000;
-1
View File
@@ -4,7 +4,6 @@ import { siteSettings } from "@/lib/services/site-settings";
// Proxy for the configured radio "now playing" provider. The provider URL is
// stored in radio_now_playing_api_url; we fetch it server-side (never exposing
// the URL or any provider key to the browser) with a short, hard timeout.
export const dynamic = "force-dynamic";
const FETCH_TIMEOUT_MS = 4000;
@@ -5,7 +5,6 @@ import { db, RadioListenerPoints, User } from "@/lib/db";
// Radio listener-points leaderboard: the top 20 users by total points, summed
// across radio_listener_points and joined to users for username/look. Public
// (no auth) — mirrors the AtomCMS radio leaderboard widget.
export const dynamic = "force-dynamic";
export async function GET(_req: Request) {
try {
-1
View File
@@ -5,7 +5,6 @@ import { db, RadioListenerPoints } from "@/lib/db";
// The Bearer-authed user's total radio listener points: the sum of all
// radio_listener_points.points rows for that user_id.
export const dynamic = "force-dynamic";
export async function GET(req: Request) {
const uid = await bearerUserId(req);
-1
View File
@@ -6,7 +6,6 @@ import { db, RadioShouts, User } from "@/lib/db";
// Latest 50 radio shouts with their author's username/look resolved. Mirrors the
// query behind the public /radio/shouts page (radio_shouts ordered by created_at
// desc, then joined to users by user_id).
export const dynamic = "force-dynamic";
// Max shout length (radio_shouts.message is TEXT; cap to keep posts sane).
const MAX_MESSAGE_LENGTH = 255;
-2
View File
@@ -1,7 +1,5 @@
import { fetchListeners, fetchNowPlaying } from "@/lib/services/radio";
export const dynamic = "force-dynamic";
/**
* Server-Sent Events stream of live radio state (AtomCMS's radio SSE endpoint).
* Pushes { nowPlaying, listeners } every ~10s so players/widgets get real-time