feat(files): add per-channel storage quota [CI]
ci/woodpecker/pr/web-build Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful

This commit is contained in:
justme committed 2026-10-14 20:42:08 +08:00
1 parent 441ed0e5f0
commit a6f078d009
19 files changed
+172 -15

No files matched your search

@@ -55,6 +55,7 @@ export async function applyChannelRecord(resource: SavedResource, session: Chann
const signedEvent = await objectEventProjection(resource, session, event.item.itemId);
if (signedEvent?.kind === 'chat.edit' && signedEvent.targetItemId)
publishWorkspace(resource.id, { t: 'removed', id: signedEvent.targetItemId });
if (signedEvent?.kind.startsWith('file.')) void loadWorkspace(resource.id).catch(() => {});
const control = readResourceRecord(event.item);
if (control !== false) {
if (control && control.t === 'file-catalog') {
@@ -108,6 +109,7 @@ export async function applyChannelRecord(resource: SavedResource, session: Chann
fileCatalogs.delete(`${resource.id}:${event.itemId}`);
blobs.delete(`${resource.id}:${event.itemId}`);
publishWorkspace(resource.id, { t: 'removed', id: event.itemId });
void loadWorkspace(resource.id).catch(() => {});
break;
case 'rejected':
showRejected(resource.id, event);
@@ -3,6 +3,7 @@ import { active, getSession } from './sessions';
import { apiFetch, type ApiError } from './http';
import { publishWorkspace } from './presentation';
import { channelMetadata, processChannelBytes, syncChannel } from './channelEvents';
import { loadWorkspace } from './workspaceStructure';
import { flushOutbox } from './transfer';
import { socketStream, sseStream, delay, type StreamConsumer } from './transports';
import { errorMessage } from '../errors';
@@ -31,7 +32,11 @@ export async function connectChannel(id: string): Promise<void> {
const stream: StreamConsumer = {
cursor: 0,
async record(bytes) { stream.cursor = Math.max(stream.cursor, await processChannelBytes(resource, session, bytes)); },
async control(value) { if (value.t === 'settings' || value.t === 'seats') await channelMetadata(resource, session); },
async control(value) {
if (value.t === 'settings') {
await Promise.all([channelMetadata(resource, session), loadWorkspace(id)]);
} else if (value.t === 'seats') await channelMetadata(resource, session);
},
online() { if (!signal.aborted) publishWorkspace(id, { t: 'connection', state: 'online' }); },
};
let initialized = false;