feat(plugin): every provider write surface carries the real committed generation
The provider contract (metadata addToIndex/removeFromIndex, vector addItem/removeItem, id-mapper getOrAssign/remove) gains an optional trailing generation — evaluated lazily at operation execute time (the graph surface's thunk pattern, generalized), threaded from all 17 construction sites: undefined during generation-0 bootstrap, the real committed generation everywhere else. Optional = additive: no existing provider or caller breaks; native delta logs that stamped literal zero start hearing truth. JS twins accept the parameter with parity notes. Pins: provider doubles capture and assert nonzero monotonic generations across add/update/remove on both surfaces.
This commit is contained in:
parent
3484107462
commit
2d532684b4
7 changed files with 583 additions and 63 deletions
|
|
@ -277,8 +277,35 @@ export interface MetadataIndexProvider {
|
|||
*/
|
||||
isMigrating?(): boolean
|
||||
|
||||
addToIndex(id: string, entityOrMetadata: any, skipFlush?: boolean, deferWrites?: boolean): Promise<void>
|
||||
removeFromIndex(id: string, metadata?: any): Promise<void>
|
||||
/**
|
||||
* @description Index one entity's metadata.
|
||||
* @param id - The entity's UUID.
|
||||
* @param entityOrMetadata - Entity structure or plain metadata bag.
|
||||
* @param skipFlush - Transactional atomicity: defer the flush to the commit seam.
|
||||
* @param deferWrites - Batch mode: buffer postings for a later flush.
|
||||
* @param generation - OPTIONAL (additive) — Brainy's commit generation for
|
||||
* this write: the SAME u64 counter {@link GraphIndexProvider.addVerb}
|
||||
* carries, resolved at operation-execute time. A provider with per-record
|
||||
* delta logs stamps it onto the durable record so its watermark
|
||||
* ("this projection reflects generation N") is derivable from real data —
|
||||
* never a literal 0. `undefined` means the caller genuinely has no commit
|
||||
* generation for this write (rebuild-from-canonical scans, bootstrap
|
||||
* writes before generation stamping activates); a provider must treat
|
||||
* that as "unstamped", not as generation 0. The built-in JS manager
|
||||
* accepts and ignores it (single live view, no per-record log).
|
||||
*/
|
||||
addToIndex(id: string, entityOrMetadata: any, skipFlush?: boolean, deferWrites?: boolean, generation?: bigint): Promise<void>
|
||||
/**
|
||||
* @description Remove one entity from the index.
|
||||
* @param id - The entity's UUID.
|
||||
* @param metadata - The entity's metadata (targets exact postings; absent → full scan).
|
||||
* @param generation - OPTIONAL (additive) — Brainy's commit generation for
|
||||
* this removal, same contract as {@link MetadataIndexProvider.addToIndex}:
|
||||
* a provider with per-record delta logs records the tombstone at this
|
||||
* generation (so as-of reads before it still see the entity); the JS
|
||||
* manager removes immediately and ignores it.
|
||||
*/
|
||||
removeFromIndex(id: string, metadata?: any, generation?: bigint): Promise<void>
|
||||
|
||||
getIds(field: string, value: any): Promise<string[]>
|
||||
/**
|
||||
|
|
@ -368,7 +395,14 @@ export interface MetadataIndexProvider {
|
|||
* the ceiling on the JS path), so `Number(bigint)` narrowing is lossless.
|
||||
*/
|
||||
getIdMapper(): {
|
||||
getOrAssign(uuid: string): number
|
||||
/**
|
||||
* Resolve-or-mint the entity's int. `generation` is OPTIONAL (additive):
|
||||
* Brainy's commit generation current at mint time, so a mapper with
|
||||
* per-record delta logs stamps the assignment record with a real
|
||||
* watermark instead of a literal 0. Ignored when the uuid is already
|
||||
* assigned (assignments are append-only) and by the JS mapper.
|
||||
*/
|
||||
getOrAssign(uuid: string, generation?: bigint): number
|
||||
getInt(uuid: string): number | undefined
|
||||
getUuid(intId: number): string | undefined
|
||||
}
|
||||
|
|
@ -1052,8 +1086,33 @@ export interface VectorIndexProvider {
|
|||
*/
|
||||
readonly name: string
|
||||
|
||||
addItem(item: VectorDocument): Promise<string>
|
||||
removeItem(id: string): Promise<boolean>
|
||||
/**
|
||||
* @description Insert one vector.
|
||||
* @param item - The vector document (`id` + `vector`).
|
||||
* @param generation - OPTIONAL (additive) — Brainy's commit generation for
|
||||
* this write: the SAME u64 counter the graph provider's
|
||||
* `addVerb(..., generation)` carries (and that `search`'s as-of
|
||||
* `options.generation` reads back), resolved at operation-execute time.
|
||||
* A provider with per-record delta logs / segment stamps records it so
|
||||
* its watermark reflects real data — never a literal 0. `undefined` =
|
||||
* the caller has no commit generation (rebuild-from-canonical, the
|
||||
* at-generation materializer's ephemeral reader); treat as "unstamped",
|
||||
* not generation 0. The built-in JS index accepts and ignores it (it
|
||||
* serves "now" only). The feature-detected `updateItem` capability (see
|
||||
* `src/transaction/operations/IndexOperations.ts`) carries the same
|
||||
* optional trailing generation.
|
||||
*/
|
||||
addItem(item: VectorDocument, generation?: bigint): Promise<string>
|
||||
/**
|
||||
* @description Remove one vector by id.
|
||||
* @param id - The entity's UUID.
|
||||
* @param generation - OPTIONAL (additive) — Brainy's commit generation for
|
||||
* this removal, same contract as {@link VectorIndexProvider.addItem}: a
|
||||
* provider with durable delete records stamps the tombstone at this
|
||||
* generation (as-of reads before it still see the vector); the JS index
|
||||
* removes immediately and ignores it.
|
||||
*/
|
||||
removeItem(id: string, generation?: bigint): Promise<boolean>
|
||||
search(
|
||||
queryVector: Vector,
|
||||
k?: number,
|
||||
|
|
@ -1199,10 +1258,29 @@ export interface EntityIdMapperProvider {
|
|||
* stays compatible — `restore()` falls back to `init()` when this is absent.
|
||||
*/
|
||||
rebuild?(): Promise<void>
|
||||
getOrAssign(uuid: string): number
|
||||
/**
|
||||
* @description Resolve-or-mint the entity's interned int (append-only:
|
||||
* once assigned, a uuid's int never changes and is never recycled).
|
||||
* @param uuid - The entity's UUID.
|
||||
* @param generation - OPTIONAL (additive) — Brainy's commit generation
|
||||
* current at mint time (the same u64 counter the graph/metadata write
|
||||
* surfaces carry). A mapper with per-record delta logs stamps the
|
||||
* assignment record with this real watermark instead of a literal 0.
|
||||
* Ignored when the uuid is already assigned, and by the JS mapper
|
||||
* (which keeps no per-record log).
|
||||
*/
|
||||
getOrAssign(uuid: string, generation?: bigint): number
|
||||
getUuid(intId: number): string | undefined
|
||||
getInt(uuid: string): number | undefined
|
||||
remove(uuid: string): boolean
|
||||
/**
|
||||
* @description Remove the uuid's mapping (the int stays reserved).
|
||||
* @param uuid - The entity's UUID.
|
||||
* @param generation - OPTIONAL (additive) — Brainy's commit generation for
|
||||
* this removal: a mapper with a per-key version chain tombstones the
|
||||
* mapping at this generation (as-of reads before it still resolve);
|
||||
* the JS mapper removes immediately and ignores it.
|
||||
*/
|
||||
remove(uuid: string, generation?: bigint): boolean
|
||||
flush(): Promise<void>
|
||||
clear(): Promise<void>
|
||||
getAllIntIds(): number[]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue