import { readFileSync } from "node:fs";
import { visualizer } from "rollup-plugin-visualizer";
import { defineConfig, type Plugin } from "vite";
import { VitePWA } from "vite-plugin-pwa";
const VERSION: string = JSON.parse(readFileSync(new URL("./version.json", import.meta.url), "utf8")).version;
// dist/version.json lets a running app ask "what version is live right now?"
// (it is deliberately NOT precached — see globPatterns — so the fetch hits the network)
const emitVersion: Plugin = {
name: "emit-version",
generateBundle() {
this.emitFile({ type: "asset", fileName: "version.json", source: JSON.stringify({ version: VERSION }) });
},
};
// base './' is load-bearing: the app is served both at https://cautpartener.ro/
// and from IPFS gateway paths like /ipfs/<cid>/ — all asset URLs must be relative.
export default defineConfig({
base: "./",
resolve: {
alias: {
// @orbitdb/core (+ lru, abstract-level) import node:events — use the
// browser EventEmitter package instead of vite's empty external shim
events: "events/events.js",
},
},
build: {
target: "es2022",
// the libp2p stack is big by nature; keep first paint light with dynamic
// splits — watch stats.html before shipping size changes
chunkSizeWarningLimit: 900,
},
define: { __APP_VERSION__: JSON.stringify(VERSION) },
plugins: [
emitVersion,
// outside dist/ on purpose: dist is published wholesale (deploy step +
// IPFS mirror) and the visualizer report doesn't belong on the site
visualizer({ filename: "stats.html", gzipSize: true }),
VitePWA({
registerType: "prompt",
includeAssets: ["icons/apple-touch-icon.png"],
manifest: {
name: "Caut Partener",
short_name: "CautPartener",
description: "Rețea socială peer-to-peer, criptată integral — fără servere, fără conturi centrale.",
lang: "ro",
start_url: "./",
scope: "./",
display: "standalone",
background_color: "#131118",
theme_color: "#131118",
icons: [
{ src: "icons/icon-192.png", sizes: "192x192", type: "image/png" },
{ src: "icons/icon-512.png", sizes: "512x512", type: "image/png" },
{ src: "icons/icon-512-maskable.png", sizes: "512x512", type: "image/png", purpose: "maskable" },
],
},
workbox: {
globPatterns: ["**/*.{js,css,html,png,svg,webmanifest}"],
maximumFileSizeToCacheInBytes: 4 * 1024 * 1024, // p2p chunks exceed workbox's 2 MiB default
navigateFallback: "index.html",
// prompt-mode update flow: the new SW must claim open pages, else
// controllerchange never fires on first-visit pages and the one-tap
// update banner can't reload into the new version
clientsClaim: true,
skipWaiting: false,
},
}),
],
});