refactor: rename BackupData → PortableGraph (the type is interchange, not a backup)
Parity with the 8.0 rename, backported to the 7.x line. The brain.data() export()/import() document type was BackupData, but it is the portable, versioned interchange representation of a graph (entities + relations + optional vectors), NOT a backup — exported for transport between instances, versions, and products. The actual backup is the native snapshot, so "Backup*" mis-signalled. Rename every developer-visible symbol, JSDoc, comment and doc: - BackupData→PortableGraph, BackupEntity→PortableGraphEntity, BackupRelation→PortableGraphRelation, BACKUP_FORMAT[_VERSION]→ PORTABLE_GRAPH_FORMAT[_VERSION], internal toBackup* helpers→toPortableGraph*. - src/api/DataAPI.ts, src/index.ts, src/cli/commands/core.ts, docs, and the test (renamed data-backup.test.ts → data-portable-graph.test.ts). The on-the-wire `format` tag is also renamed 'brainy-backup' → 'brainy-portable-graph': the export/import format was introduced in 7.32.0 and has not been adopted by any consumer, so there are no stored documents to stay compatible with — a clean rename beats carrying a legacy tag forward. No deprecated aliases (nothing to alias). 1505 unit green; build clean; data-portable-graph.test.ts 20/20.
This commit is contained in:
parent
5e7379dc41
commit
89036deb20
9 changed files with 98 additions and 95 deletions
|
|
@ -1765,18 +1765,18 @@ await brain.import('https://api.example.com/data.json')
|
|||
|
||||
---
|
||||
|
||||
### Export & Import (portable backup)
|
||||
### Export & Import (portable graph)
|
||||
|
||||
`brain.data()` exposes a portable graph backup/restore API. `export(selector?, options?)`
|
||||
serializes part or all of the graph to a versioned, portable `BackupData` document;
|
||||
`import(backup, options?)` restores it (dedup-by-id merge by default, re-embedding when
|
||||
`brain.data()` exposes a portable graph graph/restore API. `export(selector?, options?)`
|
||||
serializes part or all of the graph to a versioned, portable `PortableGraph` document;
|
||||
`import(graph, options?)` restores it (dedup-by-id merge by default, re-embedding when
|
||||
vectors are absent).
|
||||
|
||||
```typescript
|
||||
const data = await brain.data()
|
||||
|
||||
// Whole brain → a portable BackupData document
|
||||
const backup = await data.export()
|
||||
// Whole brain → a portable PortableGraph document
|
||||
const graph = await data.export()
|
||||
|
||||
// Just one workbench's members, with vectors, then restore elsewhere (merge by id)
|
||||
const subset = await data.export({ ids }, { includeVectors: true })
|
||||
|
|
|
|||
|
|
@ -457,14 +457,14 @@ await brain.storage.withLock('resource-id', async () => {
|
|||
|
||||
### Export Data
|
||||
```typescript
|
||||
// Export the whole brain to a portable BackupData document
|
||||
const backup = await brain.data().then(d => d.export(undefined, { includeVectors: true }))
|
||||
// Export the whole brain to a portable PortableGraph document
|
||||
const graph = await brain.data().then(d => d.export(undefined, { includeVectors: true }))
|
||||
```
|
||||
|
||||
### Import Data
|
||||
```typescript
|
||||
// Restore a BackupData document (dedup-by-id merge by default)
|
||||
await brain.data().then(d => d.import(backup, { onConflict: 'merge' }))
|
||||
// Restore a PortableGraph document (dedup-by-id merge by default)
|
||||
await brain.data().then(d => d.import(graph, { onConflict: 'merge' }))
|
||||
```
|
||||
|
||||
See the [Export & Import guide](../guides/export-and-import.md) for partial exports
|
||||
|
|
@ -479,7 +479,7 @@ const newBrain = new Brainy({ storage: { type: 's3' } })
|
|||
await oldBrain.init()
|
||||
await newBrain.init()
|
||||
|
||||
// Transfer all data via a portable backup
|
||||
// Transfer all data via a portable graph
|
||||
const data = await oldBrain.data().then(d => d.export(undefined, { includeVectors: true }))
|
||||
await newBrain.data().then(d => d.import(data))
|
||||
```
|
||||
|
|
|
|||
|
|
@ -546,7 +546,7 @@ const appComponent = await brain.findOne({ type: 'ReactComponent', name: 'App' }
|
|||
const imports = await brain.getRelated(appComponent.id, 'Imports')
|
||||
console.log(`App component imports:`, imports.map(c => c.name))
|
||||
|
||||
// Export the analyzed component graph as a portable BackupData document
|
||||
// Export the analyzed component graph as a portable PortableGraph document
|
||||
const graph = await brain.data().then(d => d.export({ type: 'ReactComponent' }))
|
||||
console.log(`Exported ${graph.stats.entityCount} components, ${graph.stats.relationCount} edges`)
|
||||
```
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ public: true
|
|||
category: guides
|
||||
template: guide
|
||||
order: 9
|
||||
description: Export part or all of a brain to a portable, versioned BackupData document and import it back — by id, collection, connected neighbourhood, VFS subtree, predicate, or the whole brain. Covers vectors, edge policy, conflict handling, and id remapping.
|
||||
description: Export part or all of a brain to a portable, versioned PortableGraph document and import it back — by id, collection, connected neighbourhood, VFS subtree, predicate, or the whole brain. Covers vectors, edge policy, conflict handling, and id remapping.
|
||||
next:
|
||||
- guides/subtypes-and-facets
|
||||
- api/README
|
||||
|
|
@ -15,19 +15,19 @@ next:
|
|||
|
||||
`brain.data()` exposes a **portable graph export/import** API. One method serializes a
|
||||
graph — an item, a collection, a connected neighbourhood, a VFS subtree, a predicate
|
||||
match, or the whole brain — into a single versioned JSON document (`BackupData`); the
|
||||
match, or the whole brain — into a single versioned JSON document (`PortableGraph`); the
|
||||
inverse restores it.
|
||||
|
||||
```typescript
|
||||
const data = await brain.data()
|
||||
|
||||
const backup = await data.export() // whole brain → BackupData
|
||||
await data.import(backup) // restore (merge by id, re-embed if no vectors)
|
||||
const graph = await data.export() // whole brain → PortableGraph
|
||||
await data.import(graph) // restore (merge by id, re-embed if no vectors)
|
||||
```
|
||||
|
||||
It is **portable** (human-readable JSON), **versioned** (`formatVersion`, so a 7.x export
|
||||
imports cleanly into 8.0), and **current-state** (the entities and edges as they are now —
|
||||
no generation history). Use it for portable artifacts, partial backups, cross-environment
|
||||
no generation history). Use it for portable artifacts, partial graphs, cross-environment
|
||||
moves, and version upgrades.
|
||||
|
||||
## When to use which
|
||||
|
|
@ -38,13 +38,13 @@ moves, and version upgrades.
|
|||
| To ingest a CSV / PDF / Excel / JSON **file** as new entities | `brain.import(file)` — see [Import Anything](./import-anything.md) |
|
||||
|
||||
The two are different operations that happen to share a verb: `import(file)` parses a
|
||||
foreign document into new entities; `data().import(backup)` restores a graph this API
|
||||
foreign document into new entities; `data().import(graph)` restores a graph this API
|
||||
exported.
|
||||
|
||||
## Exporting
|
||||
|
||||
```typescript
|
||||
export(selector?, options?): Promise<BackupData>
|
||||
export(selector?, options?): Promise<PortableGraph>
|
||||
```
|
||||
|
||||
### Selectors — *what* to export
|
||||
|
|
@ -96,17 +96,17 @@ const tree = await data.export({ vfsPath: '/docs' }, { includeContent: true })
|
|||
## Importing
|
||||
|
||||
```typescript
|
||||
import(backup, options?): Promise<ImportResult>
|
||||
import(graph, options?): Promise<ImportResult>
|
||||
```
|
||||
|
||||
```typescript
|
||||
const result = await brain.data().then(d => d.import(backup, { onConflict: 'merge' }))
|
||||
const result = await brain.data().then(d => d.import(graph, { onConflict: 'merge' }))
|
||||
// → { imported, merged, skipped, reembedded, blobsWritten, errors }
|
||||
```
|
||||
|
||||
| Option | Default | Effect |
|
||||
|--------|---------|--------|
|
||||
| `onConflict` | `'merge'` | `'merge'` (update existing id in place — assemble many backups), `'replace'` (delete + recreate), or `'skip'`. |
|
||||
| `onConflict` | `'merge'` | `'merge'` (update existing id in place — assemble many graphs), `'replace'` (delete + recreate), or `'skip'`. |
|
||||
| `reembed` | `'auto'` | `'auto'` (use the carried vector, else re-embed from `data`) or `'never'` (require a carried vector; record an error if absent). |
|
||||
| `remapIds` | — | Rewrite every id on the way in, e.g. to clone a template subgraph under fresh ids. |
|
||||
|
||||
|
|
@ -115,15 +115,15 @@ exported documents that share entity ids — re-importing an id merges rather th
|
|||
|
||||
```typescript
|
||||
// Clone a subgraph under fresh ids (a copy, not a move)
|
||||
const remap = new Map(backup.entities.map(e => [e.id, crypto.randomUUID()]))
|
||||
await data.import(backup, { remapIds: id => remap.get(id) ?? id })
|
||||
const remap = new Map(graph.entities.map(e => [e.id, crypto.randomUUID()]))
|
||||
await data.import(graph, { remapIds: id => remap.get(id) ?? id })
|
||||
```
|
||||
|
||||
## The `BackupData` format
|
||||
## The `PortableGraph` format
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"format": "brainy-backup",
|
||||
"format": "brainy-portable-graph",
|
||||
"formatVersion": 1, // import gates on this (cross-version migration)
|
||||
"brainyVersion": "7.32.0",
|
||||
"createdAt": "2026-06-16T…Z",
|
||||
|
|
@ -154,7 +154,7 @@ of each entity; `metadata` holds **only** custom user fields — mirroring the i
|
|||
|
||||
## Cross-version (7.x → 8.0)
|
||||
|
||||
Because the document is shared and versioned, a backup written by 7.x imports into 8.0:
|
||||
Because the document is shared and versioned, a graph written by 7.x imports into 8.0:
|
||||
`formatVersion` is read forward, `subtype` is carried so 8.0 re-types correctly, and the
|
||||
same 384-dimension model on both lines means `includeVectors:false` re-embeds identically
|
||||
(or `true` carries vectors verbatim). The format is **current-state** — if you need a
|
||||
|
|
|
|||
|
|
@ -540,11 +540,11 @@ export async function generateStaticProps() {
|
|||
})
|
||||
await brain.init()
|
||||
|
||||
// Build a search index — export the whole brain as a portable BackupData document
|
||||
const backup = await brain.data().then(d => d.export())
|
||||
// Build a search index — export the whole brain as a portable PortableGraph document
|
||||
const graph = await brain.data().then(d => d.export())
|
||||
|
||||
return {
|
||||
props: { searchIndex: backup.entities }
|
||||
props: { searchIndex: graph.entities }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue