A simple, clean, fast browser for the AtmosphereConf(2026) VODs
1import { defineConfig } from 'vite'
2import react from '@vitejs/plugin-react'
3import { VitePWA } from 'vite-plugin-pwa'
4import { fileURLToPath } from 'node:url'
5
6// https://vite.dev/config/
7export default defineConfig({
8 resolve: {
9 alias: {
10 '@': fileURLToPath(new URL('./src', import.meta.url)),
11 },
12 },
13 plugins: [
14 react(),
15 VitePWA({
16 registerType: 'autoUpdate',
17 includeAssets: ['favicon.svg'],
18 manifest: {
19 name: 'Streamplace VOD Client',
20 short_name: 'Streamplace VOD',
21 description:
22 'A minimalist glassy video browser for Streamplace and AtmosphereConf VODs.',
23 theme_color: '#000000',
24 background_color: '#000000',
25 display: 'standalone',
26 start_url: '/',
27 icons: [
28 {
29 src: '/favicon.svg',
30 sizes: 'any',
31 type: 'image/svg+xml',
32 purpose: 'any maskable',
33 },
34 ],
35 },
36 workbox: {
37 globPatterns: ['**/*.{js,css,html,svg,png,ico,woff2}'],
38 runtimeCaching: [
39 {
40 urlPattern: /^https:\/\/plc\.directory\/.*/i,
41 handler: 'NetworkFirst',
42 options: {
43 cacheName: 'plc-directory',
44 networkTimeoutSeconds: 8,
45 expiration: {
46 maxEntries: 16,
47 maxAgeSeconds: 60 * 60 * 24,
48 },
49 },
50 },
51 {
52 urlPattern:
53 /^https:\/\/bsky\.network\/xrpc\/com\.atproto\.sync\.listReposByCollection.*/i,
54 handler: 'NetworkFirst',
55 options: {
56 cacheName: 'relay-collection-discovery',
57 networkTimeoutSeconds: 8,
58 expiration: {
59 maxEntries: 16,
60 maxAgeSeconds: 60 * 15,
61 },
62 },
63 },
64 {
65 urlPattern:
66 /^https:\/\/[^/]+\/xrpc\/com\.atproto\.repo\.listRecords.*/i,
67 handler: 'NetworkFirst',
68 options: {
69 cacheName: 'list-records',
70 networkTimeoutSeconds: 8,
71 expiration: {
72 maxEntries: 24,
73 maxAgeSeconds: 60 * 15,
74 },
75 },
76 },
77 {
78 urlPattern:
79 /^https:\/\/public\.api\.bsky\.app\/xrpc\/app\.bsky\.actor\.getProfile.*/i,
80 handler: 'NetworkFirst',
81 options: {
82 cacheName: 'bsky-profiles',
83 networkTimeoutSeconds: 6,
84 expiration: {
85 maxEntries: 160,
86 maxAgeSeconds: 60 * 60,
87 },
88 },
89 },
90 {
91 urlPattern:
92 /^https:\/\/vod-beta\.stream\.place\/xrpc\/place\.stream\.playback\.getVideoPlaylist.*/i,
93 handler: 'NetworkFirst',
94 options: {
95 cacheName: 'playlists',
96 networkTimeoutSeconds: 6,
97 expiration: {
98 maxEntries: 48,
99 maxAgeSeconds: 60 * 60,
100 },
101 },
102 },
103 {
104 urlPattern: /^\/api\/search.*/i,
105 handler: 'NetworkFirst',
106 options: {
107 cacheName: 'semantic-search',
108 networkTimeoutSeconds: 5,
109 expiration: {
110 maxEntries: 40,
111 maxAgeSeconds: 60 * 5,
112 },
113 },
114 },
115 ],
116 },
117 }),
118 ],
119})