Files
orca/src/shared/mobile-file-directory-limit.ts
NeilandOrca 879aad7dd6 oom(foundation): bound shared readers/limits + add BoundedMap primitive (#10299)
* oom(01): A1-shared-readers — reintroduce #10179 subset

Files: 18 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(02): A2-shared-image-media — reintroduce #10179 subset

Files: 7 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(03): A3-shared-fs-listing — reintroduce #10179 subset

Files: 21 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(04): A4-shared-remote-relay — reintroduce #10179 subset

Files: 8 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(05): A5-shared-misc — reintroduce #10179 subset

Files: 28 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

* oom(06): B-shared-wiring — reintroduce #10179 subset

Files: 81 applied, 0 deleted (from 6eb70d8370)

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-07-24 21:36:57 -07:00

44 lines
1.4 KiB
TypeScript

// Why: normal repositories stay complete while pathological fan-out/name payloads fail before retention.
export const MOBILE_FILE_DIRECTORY_MAX_ENTRIES = 10_000
export const MOBILE_FILE_DIRECTORY_MAX_RETAINED_BYTES = 4 * 1024 * 1024
export const MOBILE_FILE_DIRECTORY_LIMIT_MESSAGE =
'This folder is too large to show safely on mobile (limit: 10,000 items or a 4 MB listing).'
type NamedDirectoryEntry = { name: string }
export type MobileFileDirectoryLimitState = {
entries: number
retainedBytes: number
}
export function createMobileFileDirectoryLimitState(): MobileFileDirectoryLimitState {
return { entries: 0, retainedBytes: 0 }
}
export function trackMobileFileDirectoryEntry(
state: MobileFileDirectoryLimitState,
entry: NamedDirectoryEntry
): void {
state.entries += 1
state.retainedBytes += estimateMobileDirectoryEntryBytes(entry)
if (
state.entries > MOBILE_FILE_DIRECTORY_MAX_ENTRIES ||
state.retainedBytes > MOBILE_FILE_DIRECTORY_MAX_RETAINED_BYTES
) {
throw new Error(MOBILE_FILE_DIRECTORY_LIMIT_MESSAGE)
}
}
export function assertMobileFileDirectoryWithinLimit(
entries: readonly NamedDirectoryEntry[]
): void {
const state = createMobileFileDirectoryLimitState()
for (const entry of entries) {
trackMobileFileDirectoryEntry(state, entry)
}
}
export function estimateMobileDirectoryEntryBytes(entry: NamedDirectoryEntry): number {
return entry.name.length * 2 + 64
}