tangled
alpha
login
or
join now
nekomimi.pet
/
wisp.place-monorepo
88
fork
atom
Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
wisp.place
88
fork
atom
overview
issues
10
pulls
pipelines
supporters get 700MB
nekomimi.pet
2 weeks ago
6d6437e5
3e297fcd
1/2
deploy-wisp.yml
success
36s
test.yml
failed
29s
+75
-6
7 changed files
expand all
collapse all
unified
split
.gitignore
apps
firehose-service
src
lib
cache-writer.ts
db.ts
hosting-service
src
lib
db.ts
on-demand-cache.ts
build-cli.sh
packages
@wispplace
constants
src
index.ts
+1
.gitignore
···
1
1
.research/
2
2
+
binaries/
2
3
cache/
3
4
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
4
5
.env
+5
-4
apps/firehose-service/src/lib/cache-writer.ts
···
10
10
import { extractBlobCid, getPdsForDid } from '@wispplace/atproto-utils';
11
11
import { collectFileCidsFromEntries, countFilesInDirectory, normalizeFileCids } from '@wispplace/fs-utils';
12
12
import { shouldCompressMimeType } from '@wispplace/atproto-utils/compression';
13
13
-
import { MAX_BLOB_SIZE, MAX_FILE_COUNT, MAX_SITE_SIZE } from '@wispplace/constants';
13
13
+
import { MAX_BLOB_SIZE, MAX_FILE_COUNT, MAX_SITE_SIZE, MAX_SITE_SIZE_SUPPORTER } from '@wispplace/constants';
14
14
import { createLogger } from '@wispplace/observability';
15
15
import { writeFile, deleteFile, listFiles } from './storage';
16
16
-
import { getSiteCache, upsertSiteCache, deleteSiteCache, upsertSiteSettingsCache, deleteSiteSettingsCache, upsertSite, deleteSite } from './db';
16
16
+
import { getSiteCache, upsertSiteCache, deleteSiteCache, upsertSiteSettingsCache, deleteSiteSettingsCache, upsertSite, deleteSite, isSupporter } from './db';
17
17
import { rewriteHtmlPaths, isHtmlFile } from './html-rewriter';
18
18
import { gunzipSync } from 'zlib';
19
19
import { publishCacheInvalidation } from './cache-invalidation';
···
477
477
}
478
478
479
479
const totalSize = calculateTotalBlobSize(expandedRoot);
480
480
-
if (totalSize > MAX_SITE_SIZE) {
481
481
-
logger.error(`Site exceeds size limit: ${totalSize} > ${MAX_SITE_SIZE}`);
480
480
+
const sizeLimit = await isSupporter(did) ? MAX_SITE_SIZE_SUPPORTER : MAX_SITE_SIZE;
481
481
+
if (totalSize > sizeLimit) {
482
482
+
logger.error(`Site exceeds size limit: ${totalSize} > ${sizeLimit}`);
482
483
return;
483
484
}
484
485
+5
apps/firehose-service/src/lib/db.ts
···
162
162
await sql`DELETE FROM sites WHERE did = ${did} AND rkey = ${rkey}`;
163
163
}
164
164
165
165
+
export async function isSupporter(did: string): Promise<boolean> {
166
166
+
const rows = await sql`SELECT 1 FROM supporter WHERE did = ${did} LIMIT 1`;
167
167
+
return rows.length > 0;
168
168
+
}
169
169
+
165
170
export async function closeDatabase(): Promise<void> {
166
171
await sql.end({ timeout: 5 });
167
172
logger.info('[DB] Database connections closed');
+5
apps/hosting-service/src/lib/db.ts
···
206
206
`;
207
207
}
208
208
209
209
+
export async function isSupporter(did: string): Promise<boolean> {
210
210
+
const rows = await sql`SELECT 1 FROM supporter WHERE did = ${did} LIMIT 1`;
211
211
+
return rows.length > 0;
212
212
+
}
213
213
+
209
214
export { sql };
+28
-2
apps/hosting-service/src/lib/on-demand-cache.ts
···
14
14
import { extractBlobCid, getPdsForDid } from '@wispplace/atproto-utils';
15
15
import { shouldCompressMimeType } from '@wispplace/atproto-utils/compression';
16
16
import { collectFileCidsFromEntries, countFilesInDirectory } from '@wispplace/fs-utils';
17
17
-
import { MAX_BLOB_SIZE, MAX_FILE_COUNT, MAX_SITE_SIZE } from '@wispplace/constants';
17
17
+
import { MAX_BLOB_SIZE, MAX_FILE_COUNT, MAX_SITE_SIZE, MAX_SITE_SIZE_SUPPORTER } from '@wispplace/constants';
18
18
import { expandSubfsNodes } from './utils';
19
19
import { storage } from './storage';
20
20
-
import { upsertSiteCache, tryAcquireLock, releaseLock } from './db';
20
20
+
import { upsertSiteCache, tryAcquireLock, releaseLock, isSupporter } from './db';
21
21
import { enqueueRevalidate } from './revalidate-queue';
22
22
import { gunzipSync } from 'zlib';
23
23
import { createLogger } from '@wispplace/observability';
···
115
115
return false;
116
116
}
117
117
118
118
+
const totalSize = calculateTotalBlobSize(expandedRoot);
119
119
+
const sizeLimit = await isSupporter(did) ? MAX_SITE_SIZE_SUPPORTER : MAX_SITE_SIZE;
120
120
+
if (totalSize > sizeLimit) {
121
121
+
logger.error('Site exceeds size limit', { did, rkey, totalSize, sizeLimit });
122
122
+
return false;
123
123
+
}
124
124
+
118
125
// Collect files
119
126
const files = collectFileInfo(expandedRoot.entries);
120
127
···
159
166
} finally {
160
167
await releaseLock(lockKey);
161
168
}
169
169
+
}
170
170
+
171
171
+
function calculateTotalBlobSize(directory: Directory): number {
172
172
+
let totalSize = 0;
173
173
+
174
174
+
function sumBlobSizes(entries: Entry[]) {
175
175
+
for (const entry of entries) {
176
176
+
const node = entry.node;
177
177
+
if ('type' in node && node.type === 'directory' && 'entries' in node) {
178
178
+
sumBlobSizes(node.entries);
179
179
+
} else if ('type' in node && node.type === 'file' && 'blob' in node) {
180
180
+
const fileNode = node as File;
181
181
+
totalSize += (fileNode.blob as any)?.size || 0;
182
182
+
}
183
183
+
}
184
184
+
}
185
185
+
186
186
+
sumBlobSizes(directory.entries);
187
187
+
return totalSize;
162
188
}
163
189
164
190
function collectFileInfo(entries: Entry[], pathPrefix: string = ''): FileInfo[] {
+30
build-cli.sh
···
1
1
+
#!/usr/bin/env bash
2
2
+
set -e
3
3
+
4
4
+
OUTDIR="$(dirname "$0")/binaries"
5
5
+
ENTRY="./cli/index.ts"
6
6
+
7
7
+
mkdir -p "$OUTDIR"
8
8
+
9
9
+
echo "Building wispctl binaries..."
10
10
+
11
11
+
bun build --compile --minify --target=bun-darwin-arm64 "$ENTRY" --outfile "$OUTDIR/wisp-cli-aarch64-darwin"
12
12
+
echo " ✓ aarch64-darwin"
13
13
+
14
14
+
bun build --compile --minify --target=bun-darwin-x64 "$ENTRY" --outfile "$OUTDIR/wisp-cli-x86_64-darwin"
15
15
+
echo " ✓ x86_64-darwin"
16
16
+
17
17
+
bun build --compile --minify --target=bun-linux-arm64 "$ENTRY" --outfile "$OUTDIR/wisp-cli-aarch64-linux"
18
18
+
echo " ✓ aarch64-linux"
19
19
+
20
20
+
bun build --compile --minify --target=bun-linux-x64 "$ENTRY" --outfile "$OUTDIR/wisp-cli-x86_64-linux"
21
21
+
echo " ✓ x86_64-linux"
22
22
+
23
23
+
lipo -create -output "$OUTDIR/wisp-cli-darwin-universal" \
24
24
+
"$OUTDIR/wisp-cli-aarch64-darwin" \
25
25
+
"$OUTDIR/wisp-cli-x86_64-darwin"
26
26
+
echo " ✓ darwin-universal (lipo)"
27
27
+
28
28
+
echo ""
29
29
+
echo "Done. Binaries written to $OUTDIR:"
30
30
+
ls -lh "$OUTDIR"
+1
packages/@wispplace/constants/src/index.ts
···
14
14
15
15
// File size limits
16
16
export const MAX_SITE_SIZE = 300 * 1024 * 1024; // 300MB
17
17
+
export const MAX_SITE_SIZE_SUPPORTER = 700 * 1024 * 1024; // 700MB for supporters
17
18
export const MAX_FILE_SIZE = 200 * 1024 * 1024; // 200MB
18
19
export const MAX_FILE_COUNT = 1000;
19
20