test(8.0): cover the native graph seam + make provider resolution factory-tolerant
The brain.graph.subgraph/export NATIVE routing (graphSubgraphNative / graphExportNative / hydrateNativeSubgraph + provider resolution) had ZERO brainy CI coverage — in production it's exercised only cross-layer against cor's engine, so a columnar return-shape or hydration-alignment drift would pass brainy CI silently. This registers a faithful MOCK GraphAccelerationProvider returning a columnar Subgraph built from the brain's REAL ints, locking the seam: - subgraph() routes native (traverse called) and hydrates node int->id, the nodeDepth column aligned to the node column, node type via batchGet, and edge verb-int->Relation via verbIntsToIds + getVerbsBatchCached. - node<->depth alignment is preserved when a node int does NOT resolve (deleted/unknown) — the unresolvable int is dropped, not collapsed (which would shift every later depth). This is the exact hydration risk the release audit flagged. - export() routes to the graph cursor, hydrates chunks, and ALWAYS closes the handle. Also fixes a latent contract bug found writing the test: graphAccelerationProvider() only accepted a ready instance, so a provider registered as a (storage)=>provider FACTORY (the convention graphIndex/metadataIndex/vector use) would fail the duck-test and the native path would silently never engage. Now resolves instance OR factory, cached. Covered by the factory-registration test.
This commit is contained in:
parent
89c4b7016c
commit
29410bc568
2 changed files with 206 additions and 2 deletions
|
|
@ -352,6 +352,12 @@ export class Brainy<T = any> implements BrainyInterface<T> {
|
|||
|
||||
// Plugin system
|
||||
private pluginRegistry = new PluginRegistry()
|
||||
/**
|
||||
* Resolved native graph-acceleration provider, cached on first `brain.graph.*`
|
||||
* access. `undefined` = not yet resolved; `null` = resolved, none registered
|
||||
* (use the TS fallback); otherwise the provider instance.
|
||||
*/
|
||||
private _graphAccelProvider: GraphAccelerationProvider | null | undefined = undefined
|
||||
|
||||
// Sub-APIs (lazy-loaded)
|
||||
private _nlp?: NaturalLanguageProcessor
|
||||
|
|
@ -3186,8 +3192,25 @@ export class Brainy<T = any> implements BrainyInterface<T> {
|
|||
|
||||
/** Resolve the optional native graph-acceleration provider (feature-detected). */
|
||||
private graphAccelerationProvider(): GraphAccelerationProvider | undefined {
|
||||
const provider = this.pluginRegistry.getProvider<unknown>('graphAcceleration')
|
||||
return isGraphAccelerationProvider(provider) ? provider : undefined
|
||||
if (this._graphAccelProvider !== undefined) {
|
||||
return this._graphAccelProvider ?? undefined
|
||||
}
|
||||
// Resolve the optional 'graphAcceleration' provider once and cache it. Accept
|
||||
// EITHER a ready instance OR a `(storage) => provider` factory (the convention
|
||||
// the graphIndex/metadataIndex/vector providers use) — a registered factory
|
||||
// would otherwise fail the isGraphAccelerationProvider duck-test and the native
|
||||
// path would silently never engage.
|
||||
const raw = this.pluginRegistry.getProvider<unknown>('graphAcceleration')
|
||||
let resolved: unknown = raw
|
||||
if (typeof raw === 'function' && !isGraphAccelerationProvider(raw)) {
|
||||
try {
|
||||
resolved = (raw as (storage: StorageAdapter) => unknown)(this.storage)
|
||||
} catch {
|
||||
resolved = undefined
|
||||
}
|
||||
}
|
||||
this._graphAccelProvider = isGraphAccelerationProvider(resolved) ? resolved : null
|
||||
return this._graphAccelProvider ?? undefined
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue