mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-12 08:45:38 +02:00
fix: Use images
This commit is contained in:
22
infra/cdn.ts
Normal file
22
infra/cdn.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { domain } from "./dns";
|
||||||
|
import { storage } from "./storage";
|
||||||
|
|
||||||
|
export const cdn = new sst.aws.Router("CDNRouter", {
|
||||||
|
routes: {
|
||||||
|
"/public": {
|
||||||
|
bucket: storage,
|
||||||
|
rewrite: {
|
||||||
|
regex: "^/public/([a-zA-Z0-9_-]+)$",
|
||||||
|
to: "/images/$1"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
domain: {
|
||||||
|
name: "cdn." + domain,
|
||||||
|
dns: sst.cloudflare.dns()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const outputs = {
|
||||||
|
cdn: cdn.url
|
||||||
|
}
|
||||||
@@ -1 +1,5 @@
|
|||||||
export const storage = new sst.aws.Bucket("Storage");
|
export const storage = new sst.aws.Bucket("Storage", {
|
||||||
|
access: "cloudfront"
|
||||||
|
});
|
||||||
|
|
||||||
|
export const zeroStorage = new sst.aws.Bucket("ZeroStorage");
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
// This is the website part where people play and connect
|
// This is the website part where people play and connect
|
||||||
import { api } from "./api";
|
import { api } from "./api";
|
||||||
|
import { cdn } from "./cdn";
|
||||||
import { auth } from "./auth";
|
import { auth } from "./auth";
|
||||||
import { zero } from "./zero";
|
import { zero } from "./zero";
|
||||||
import { domain } from "./dns";
|
import { domain } from "./dns";
|
||||||
@@ -16,6 +17,7 @@ new sst.aws.StaticSite("Web", {
|
|||||||
},
|
},
|
||||||
environment: {
|
environment: {
|
||||||
VITE_API_URL: api.url,
|
VITE_API_URL: api.url,
|
||||||
|
VITE_CDN_URL: cdn.url,
|
||||||
VITE_STAGE: $app.stage,
|
VITE_STAGE: $app.stage,
|
||||||
VITE_AUTH_URL: auth.url,
|
VITE_AUTH_URL: auth.url,
|
||||||
VITE_ZERO_URL: zero.url,
|
VITE_ZERO_URL: zero.url,
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { auth } from "./auth";
|
|||||||
import { domain } from "./dns";
|
import { domain } from "./dns";
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import { cluster } from "./cluster";
|
import { cluster } from "./cluster";
|
||||||
import { storage } from "./storage";
|
|
||||||
import { postgres } from "./postgres";
|
import { postgres } from "./postgres";
|
||||||
|
import { zeroStorage } from "./storage";
|
||||||
|
|
||||||
const connectionString = $interpolate`postgresql://${postgres.username}:${postgres.password}@${postgres.host}:${postgres.port}/${postgres.database}`;
|
const connectionString = $interpolate`postgresql://${postgres.username}:${postgres.password}@${postgres.host}:${postgres.port}/${postgres.database}`;
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ const zeroEnv = {
|
|||||||
? {
|
? {
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
ZERO_LITESTREAM_BACKUP_URL: $interpolate`s3://${storage.name}/zero/0`,
|
ZERO_LITESTREAM_BACKUP_URL: $interpolate`s3://${zeroStorage.name}/zero/0`,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ const replicationManager = !$dev
|
|||||||
capacity: "spot",
|
capacity: "spot",
|
||||||
architecture: "arm64",
|
architecture: "arm64",
|
||||||
image: zeroEnv.ZERO_IMAGE_URL,
|
image: zeroEnv.ZERO_IMAGE_URL,
|
||||||
link: [storage, postgres],
|
link: [zeroStorage, postgres],
|
||||||
health: {
|
health: {
|
||||||
command: ["CMD-SHELL", "curl -f http://localhost:4849/ || exit 1"],
|
command: ["CMD-SHELL", "curl -f http://localhost:4849/ || exit 1"],
|
||||||
interval: "5 seconds",
|
interval: "5 seconds",
|
||||||
@@ -123,7 +123,7 @@ const replicationManager = !$dev
|
|||||||
export const zero = new sst.aws.Service("Zero", {
|
export const zero = new sst.aws.Service("Zero", {
|
||||||
cluster,
|
cluster,
|
||||||
image: zeroEnv.ZERO_IMAGE_URL,
|
image: zeroEnv.ZERO_IMAGE_URL,
|
||||||
link: [storage, postgres],
|
link: [zeroStorage, postgres],
|
||||||
architecture: "arm64",
|
architecture: "arm64",
|
||||||
cpu: "0.5 vCPU",
|
cpu: "0.5 vCPU",
|
||||||
memory: "1 GB",
|
memory: "1 GB",
|
||||||
|
|||||||
54
packages/www/src/assets/service-worker.js
Normal file
54
packages/www/src/assets/service-worker.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
const CACHE_NAME = 'image-cache-v1';
|
||||||
|
const AUTH_TOKEN = 'Bearer YOUR_DYNAMIC_AUTH_TOKEN'; // Replace at runtime if needed
|
||||||
|
|
||||||
|
self.addEventListener('install', (event) => {
|
||||||
|
self.skipWaiting(); // Activate immediately
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
clients.claim(); // Take control of all clients
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', (event) => {
|
||||||
|
const req = event.request;
|
||||||
|
|
||||||
|
// Only intercept image requests
|
||||||
|
if (req.destination !== 'image') return;
|
||||||
|
|
||||||
|
// Only intercept our image requests
|
||||||
|
const url = new URL(req.url);
|
||||||
|
if (import.meta.env.VITE_CDN_URL !== url.origin) return;
|
||||||
|
|
||||||
|
event.respondWith(handleImageRequest(req));
|
||||||
|
});
|
||||||
|
|
||||||
|
async function handleImageRequest(request) {
|
||||||
|
const cache = await caches.open(CACHE_NAME);
|
||||||
|
|
||||||
|
const cachedResponse = await cache.match(request);
|
||||||
|
if (cachedResponse) return cachedResponse;
|
||||||
|
|
||||||
|
// Clone and modify the request with Authorization header
|
||||||
|
const modifiedRequest = new Request(request.url, {
|
||||||
|
method: request.method,
|
||||||
|
headers: {
|
||||||
|
...Object.fromEntries(request.headers.entries()),
|
||||||
|
Authorization: AUTH_TOKEN,
|
||||||
|
},
|
||||||
|
cache: 'no-store',
|
||||||
|
mode: 'same-origin',
|
||||||
|
credentials: 'same-origin',
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(modifiedRequest);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
await cache.put(request, response.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (err) {
|
||||||
|
return new Response('Image load failed', { status: 503 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,19 @@ if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
navigator.serviceWorker
|
||||||
|
.register('/src/assets/service-worker.js')
|
||||||
|
.then((reg) => {
|
||||||
|
console.log('[SW] Registered:', reg.scope);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('[SW] Registration failed:', err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render(
|
render(
|
||||||
() => (
|
() => (
|
||||||
<StorageProvider>
|
<StorageProvider>
|
||||||
|
|||||||
1
packages/www/src/sst-env.d.ts
vendored
1
packages/www/src/sst-env.d.ts
vendored
@@ -4,6 +4,7 @@
|
|||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
interface ImportMetaEnv {
|
interface ImportMetaEnv {
|
||||||
readonly VITE_API_URL: string
|
readonly VITE_API_URL: string
|
||||||
|
readonly VITE_CDN_URL: string
|
||||||
readonly VITE_STAGE: string
|
readonly VITE_STAGE: string
|
||||||
readonly VITE_AUTH_URL: string
|
readonly VITE_AUTH_URL: string
|
||||||
readonly VITE_ZERO_URL: string
|
readonly VITE_ZERO_URL: string
|
||||||
|
|||||||
8
sst-env.d.ts
vendored
8
sst-env.d.ts
vendored
@@ -24,6 +24,10 @@ declare module "sst" {
|
|||||||
"name": string
|
"name": string
|
||||||
"type": "sst.aws.Bus"
|
"type": "sst.aws.Bus"
|
||||||
}
|
}
|
||||||
|
"CDNRouter": {
|
||||||
|
"type": "sst.aws.Router"
|
||||||
|
"url": string
|
||||||
|
}
|
||||||
"Database": {
|
"Database": {
|
||||||
"clusterArn": string
|
"clusterArn": string
|
||||||
"database": string
|
"database": string
|
||||||
@@ -124,6 +128,10 @@ declare module "sst" {
|
|||||||
"type": "sst.aws.Service"
|
"type": "sst.aws.Service"
|
||||||
"url": string
|
"url": string
|
||||||
}
|
}
|
||||||
|
"ZeroStorage": {
|
||||||
|
"name": string
|
||||||
|
"type": "sst.aws.Bucket"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user