88// scan cache — round-trips through one human-readable JSON file.
99
1010export const BACKUP_FORMAT = 'repolens-backup' ;
11- export const BACKUP_VERSION = 1 ;
11+ export const BACKUP_VERSION = 2 ;
1212
1313// Upper bounds on how much a single import may write, so a hostile or corrupt
1414// file can't pin the IndexedDB write lock or blow the storage quota. Anything
1515// past these is dropped with a surfaced warning (never silently).
16- export const MAX_ROWS = { repos : 5000 , nodes : 20000 , edges : 50000 , cache : 5000 , collections : 2000 , decisions : 5000 } ;
16+ export const MAX_ROWS = { repos : 5000 , nodes : 20000 , edges : 50000 , cache : 5000 , collections : 2000 , decisions : 5000 , snapshots : 5000 } ;
17+
18+ // Per-repo snapshot ring-buffer cap (mirrors SNAPSHOT_CAP in snapshots.js); each
19+ // imported snapshots row is trimmed to its most recent SNAP_CAP entries.
20+ const SNAP_CAP = 30 ;
1721
1822const arr = ( x ) => ( Array . isArray ( x ) ? x : [ ] ) ;
1923const rowHasRepo = ( r ) => ! ! ( r && r . id != null && r . payload && r . payload . repoId ) ;
@@ -22,10 +26,11 @@ const edgeOk = (e) => !!(e && e.id != null && e.source != null && e.target != nu
2226const cacheOk = ( c ) => ! ! ( c && c . repoId && c . platform ) ;
2327const collectionOk = ( c ) => ! ! ( c && c . id != null && c . payload && typeof c . payload . name === 'string' ) ;
2428const decisionOk = ( d ) => ! ! ( d && d . id != null && d . payload && d . payload . repoId && d . payload . decision ) ;
29+ const snapshotOk = ( r ) => ! ! ( r && r . id != null && r . repoId && Array . isArray ( r . snaps ) ) ;
2530
2631/** Empty normalized shape — the safe fallback when a file can't be parsed. */
2732function emptyValue ( ) {
28- return { repos : [ ] , nodes : [ ] , edges : [ ] , cache : [ ] , collections : [ ] , decisions : [ ] } ;
33+ return { repos : [ ] , nodes : [ ] , edges : [ ] , cache : [ ] , collections : [ ] , decisions : [ ] , snapshots : [ ] } ;
2934}
3035
3136/**
@@ -34,19 +39,14 @@ function emptyValue() {
3439 * @param {{ repos?: object[], nodes?: object[], edges?: object[], cache?: object[], exportedAt?: string } } [parts]
3540 * @returns {object }
3641 */
37- export function buildBackup ( { repos, nodes, edges, cache, collections, decisions, exportedAt } = { } ) {
38- const r = arr ( repos ) , n = arr ( nodes ) , e = arr ( edges ) , c = arr ( cache ) , col = arr ( collections ) , dec = arr ( decisions ) ;
42+ export function buildBackup ( { repos, nodes, edges, cache, collections, decisions, snapshots , exportedAt } = { } ) {
43+ const r = arr ( repos ) , n = arr ( nodes ) , e = arr ( edges ) , c = arr ( cache ) , col = arr ( collections ) , dec = arr ( decisions ) , snap = arr ( snapshots ) ;
3944 return {
4045 format : BACKUP_FORMAT ,
4146 version : BACKUP_VERSION ,
4247 exportedAt : exportedAt || new Date ( ) . toISOString ( ) ,
43- counts : { repos : r . length , nodes : n . length , edges : e . length , cache : c . length , collections : col . length , decisions : dec . length } ,
44- repos : r ,
45- nodes : n ,
46- edges : e ,
47- cache : c ,
48- collections : col ,
49- decisions : dec ,
48+ counts : { repos : r . length , nodes : n . length , edges : e . length , cache : c . length , collections : col . length , decisions : dec . length , snapshots : snap . length } ,
49+ repos : r , nodes : n , edges : e , cache : c , collections : col , decisions : dec , snapshots : snap ,
5050 } ;
5151}
5252
@@ -87,6 +87,7 @@ export function validateBackup(obj) {
8787 cache : clamp ( 'cache' , arr ( obj . cache ) . filter ( cacheOk ) ) ,
8888 collections : clamp ( 'collections' , arr ( obj . collections ) . filter ( collectionOk ) ) ,
8989 decisions : clamp ( 'decisions' , arr ( obj . decisions ) . filter ( decisionOk ) ) ,
90+ snapshots : clamp ( 'snapshots' , arr ( obj . snapshots ) . filter ( snapshotOk ) . map ( ( r ) => ( { ...r , snaps : arr ( r . snaps ) . slice ( - SNAP_CAP ) } ) ) ) ,
9091 } ;
9192 return { ok : errors . length === 0 , errors, warnings, value } ;
9293}
@@ -99,7 +100,7 @@ export function validateBackup(obj) {
99100 */
100101export function summarizeBackup ( obj ) {
101102 const { value } = validateBackup ( obj ) ;
102- return { repos : value . repos . length , nodes : value . nodes . length , edges : value . edges . length , cache : value . cache . length , collections : value . collections . length , decisions : value . decisions . length } ;
103+ return { repos : value . repos . length , nodes : value . nodes . length , edges : value . edges . length , cache : value . cache . length , collections : value . collections . length , decisions : value . decisions . length , snapshots : value . snapshots . length } ;
103104}
104105
105106/**
0 commit comments