mirror of
https://github.com/stablyai/orca.git
synced 2026-10-08 08:02:32 +00:00
* Bound AI Vault cache loading and cooperative atomic saves Preserve schema 3 caches across compatible releases while limiting bytes, JSON structure, and newest unique rows. Keep in-process entries authoritative and retain a valid prior snapshot when the newest row cannot fit. Credits @AmethystLiang for the original PR10708 cache bounds and cooperative persistence intent. * Use checked cache JSON properties in cooperative serialization Preserves lazy own-property access and all serializer bounds, yields and errors.
121 lines
3.5 KiB
TypeScript
121 lines
3.5 KiB
TypeScript
export type JsonTextStructureLimits = Readonly<{
|
|
structuralTokens: number
|
|
nestingDepth: number
|
|
}>
|
|
|
|
export class JsonTextStructureCapacityError extends Error {
|
|
constructor(
|
|
readonly resource: keyof JsonTextStructureLimits,
|
|
readonly limit: number
|
|
) {
|
|
super(
|
|
resource === 'structuralTokens'
|
|
? `JSON structure exceeds ${limit} tokens`
|
|
: `JSON nesting exceeds ${limit} levels`
|
|
)
|
|
this.name = 'JsonTextStructureCapacityError'
|
|
}
|
|
}
|
|
|
|
export function assertJsonTextStructureWithinLimits(
|
|
content: string,
|
|
limits: JsonTextStructureLimits
|
|
): void {
|
|
new JsonTextStructureValidator(limits).consume(content)
|
|
}
|
|
|
|
/** Carries string/escape and structure state across bounded chunks. */
|
|
export class JsonTextStructureValidator {
|
|
private structuralTokens = 0
|
|
private depth = 0
|
|
private maximumDepth = 0
|
|
private inString = false
|
|
private escaped = false
|
|
|
|
constructor(private readonly limits: JsonTextStructureLimits) {
|
|
assertLimit(limits.structuralTokens)
|
|
assertLimit(limits.nestingDepth)
|
|
}
|
|
|
|
consume(content: string): void {
|
|
let linearString = false
|
|
for (let index = 0; index < content.length; index += 1) {
|
|
const character = content[index]
|
|
if (this.inString) {
|
|
if (this.escaped) {
|
|
this.escaped = false
|
|
continue
|
|
}
|
|
if (!linearString) {
|
|
const quote = content.indexOf('"', index)
|
|
const end = quote === -1 ? content.length : quote
|
|
let backslashes = 0
|
|
for (let at = end - 1; at >= index && content[at] === '\\'; at -= 1) {
|
|
backslashes++
|
|
}
|
|
if (quote === -1) {
|
|
this.escaped = backslashes % 2 !== 0
|
|
return
|
|
}
|
|
index = quote
|
|
if (backslashes % 2 === 0) {
|
|
this.inString = false
|
|
} else {
|
|
// Escape-heavy strings scan linearly instead of repeating native searches.
|
|
linearString = true
|
|
}
|
|
continue
|
|
}
|
|
if (character === '\\') {
|
|
this.escaped = true
|
|
} else if (character === '"') {
|
|
this.inString = false
|
|
linearString = false
|
|
}
|
|
continue
|
|
}
|
|
if (character === '"') {
|
|
this.inString = true
|
|
continue
|
|
}
|
|
if (!isStructuralToken(character)) {
|
|
continue
|
|
}
|
|
this.structuralTokens++
|
|
if (this.structuralTokens > this.limits.structuralTokens) {
|
|
throw new JsonTextStructureCapacityError('structuralTokens', this.limits.structuralTokens)
|
|
}
|
|
if (character === '{' || character === '[') {
|
|
this.depth++
|
|
this.maximumDepth = Math.max(this.maximumDepth, this.depth)
|
|
if (this.depth > this.limits.nestingDepth) {
|
|
throw new JsonTextStructureCapacityError('nestingDepth', this.limits.nestingDepth)
|
|
}
|
|
} else if (character === '}' || character === ']') {
|
|
this.depth = Math.max(0, this.depth - 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
usage(): { structuralTokens: number; nestingDepth: number } {
|
|
return { structuralTokens: this.structuralTokens, nestingDepth: this.maximumDepth }
|
|
}
|
|
}
|
|
|
|
function assertLimit(value: number): void {
|
|
if (!Number.isSafeInteger(value) || value < 0) {
|
|
throw new RangeError('JSON structure limits must be non-negative safe integers')
|
|
}
|
|
}
|
|
|
|
function isStructuralToken(character: string | undefined): boolean {
|
|
return (
|
|
character === '{' ||
|
|
character === '}' ||
|
|
character === '[' ||
|
|
character === ']' ||
|
|
character === ',' ||
|
|
character === ':'
|
|
)
|
|
}
|