@ibgib/vcs-gib 0.0.30 → 0.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/dist/AUTO-GENERATED-version.d.mts +1 -1
  2. package/dist/AUTO-GENERATED-version.mjs +1 -1
  3. package/dist/bootstrap/node-bootstrap.mjs +1 -1
  4. package/dist/bootstrap/node-bootstrap.mjs.map +1 -1
  5. package/dist/cli/commands/add-cmd.d.mts +2 -3
  6. package/dist/cli/commands/add-cmd.d.mts.map +1 -1
  7. package/dist/cli/commands/add-cmd.mjs +30 -283
  8. package/dist/cli/commands/add-cmd.mjs.map +1 -1
  9. package/dist/cli/commands/branch-cmd.d.mts +8 -8
  10. package/dist/cli/commands/branch-cmd.d.mts.map +1 -1
  11. package/dist/cli/commands/branch-cmd.mjs +45 -176
  12. package/dist/cli/commands/branch-cmd.mjs.map +1 -1
  13. package/dist/cli/commands/checkout-cmd.d.mts +2 -4
  14. package/dist/cli/commands/checkout-cmd.d.mts.map +1 -1
  15. package/dist/cli/commands/checkout-cmd.mjs +31 -110
  16. package/dist/cli/commands/checkout-cmd.mjs.map +1 -1
  17. package/dist/cli/commands/commit-cmd.d.mts +7 -8
  18. package/dist/cli/commands/commit-cmd.d.mts.map +1 -1
  19. package/dist/cli/commands/commit-cmd.mjs +40 -390
  20. package/dist/cli/commands/commit-cmd.mjs.map +1 -1
  21. package/dist/cli/commands/generate-comment-cmd.d.mts.map +1 -1
  22. package/dist/cli/commands/generate-comment-cmd.mjs +5 -2
  23. package/dist/cli/commands/generate-comment-cmd.mjs.map +1 -1
  24. package/dist/cli/commands/init-cmd.d.mts +2 -2
  25. package/dist/cli/commands/init-cmd.d.mts.map +1 -1
  26. package/dist/cli/commands/init-cmd.mjs +20 -70
  27. package/dist/cli/commands/init-cmd.mjs.map +1 -1
  28. package/dist/cli/commands/log-cmd.d.mts +2 -3
  29. package/dist/cli/commands/log-cmd.d.mts.map +1 -1
  30. package/dist/cli/commands/log-cmd.mjs +42 -271
  31. package/dist/cli/commands/log-cmd.mjs.map +1 -1
  32. package/dist/cli/commands/merge-cmd.d.mts +3 -17
  33. package/dist/cli/commands/merge-cmd.d.mts.map +1 -1
  34. package/dist/cli/commands/merge-cmd.mjs +32 -218
  35. package/dist/cli/commands/merge-cmd.mjs.map +1 -1
  36. package/dist/cli/commands/reset-cmd.d.mts +1 -1
  37. package/dist/cli/commands/reset-cmd.d.mts.map +1 -1
  38. package/dist/cli/commands/reset-cmd.mjs +17 -19
  39. package/dist/cli/commands/reset-cmd.mjs.map +1 -1
  40. package/dist/cli/commands/restore-cmd.d.mts +8 -7
  41. package/dist/cli/commands/restore-cmd.d.mts.map +1 -1
  42. package/dist/cli/commands/restore-cmd.mjs +44 -62
  43. package/dist/cli/commands/restore-cmd.mjs.map +1 -1
  44. package/dist/cli/commands/status-cmd.d.mts +2 -2
  45. package/dist/cli/commands/status-cmd.d.mts.map +1 -1
  46. package/dist/cli/commands/status-cmd.mjs +63 -62
  47. package/dist/cli/commands/status-cmd.mjs.map +1 -1
  48. package/dist/cli/vcs-projection-helper.d.mts +23 -0
  49. package/dist/cli/vcs-projection-helper.d.mts.map +1 -0
  50. package/dist/cli/vcs-projection-helper.mjs +91 -0
  51. package/dist/cli/vcs-projection-helper.mjs.map +1 -0
  52. package/dist/test/test-helpers.d.mts +2 -2
  53. package/dist/test/test-helpers.d.mts.map +1 -1
  54. package/package.json +3 -3
  55. package/src/AUTO-GENERATED-version.mts +1 -1
  56. package/src/bootstrap/node-bootstrap.mts +1 -1
  57. package/src/cli/cli-e2e.respec.mts +4 -4
  58. package/src/cli/commands/add-cmd.mts +32 -347
  59. package/src/cli/commands/branch-cmd.mts +56 -225
  60. package/src/cli/commands/checkout-cmd.mts +34 -138
  61. package/src/cli/commands/commit-cmd.mts +46 -473
  62. package/src/cli/commands/commit-log-cmd.respec.mts +11 -7
  63. package/src/cli/commands/generate-comment-cmd.mts +6 -2
  64. package/src/cli/commands/init-cmd.mts +20 -73
  65. package/src/cli/commands/log-cmd.mts +41 -331
  66. package/src/cli/commands/merge-cmd.mts +32 -252
  67. package/src/cli/commands/reset-cmd.mts +17 -19
  68. package/src/cli/commands/restore-cmd.mts +52 -72
  69. package/src/cli/commands/status-add-cmd.respec.mts +3 -3
  70. package/src/cli/commands/status-cmd.mts +68 -63
  71. package/src/cli/vcs-projection-helper.mts +112 -0
  72. package/src/engine/branch/branch-space.respec.mts +5 -5
  73. package/src/engine/merge/b2tfs-sync-comments.respec.mts +4 -4
  74. package/src/test/test-helpers.mts +2 -2
  75. package/src/vcs-gib.respec.mts +11 -8
  76. package/tsconfig.test.tsbuildinfo +1 -1
  77. package/tsconfig.tsbuildinfo +1 -1
  78. package/dist/engine/branch/branch-graph-helper.d.mts +0 -28
  79. package/dist/engine/branch/branch-graph-helper.d.mts.map +0 -1
  80. package/dist/engine/branch/branch-graph-helper.mjs +0 -81
  81. package/dist/engine/branch/branch-graph-helper.mjs.map +0 -1
  82. package/dist/engine/branch/branch-helper.d.mts +0 -40
  83. package/dist/engine/branch/branch-helper.d.mts.map +0 -1
  84. package/dist/engine/branch/branch-helper.mjs +0 -78
  85. package/dist/engine/branch/branch-helper.mjs.map +0 -1
  86. package/dist/engine/branch/branch-space-helper.d.mts +0 -23
  87. package/dist/engine/branch/branch-space-helper.d.mts.map +0 -1
  88. package/dist/engine/branch/branch-space-helper.mjs +0 -78
  89. package/dist/engine/branch/branch-space-helper.mjs.map +0 -1
  90. package/dist/engine/branch/branch-types.d.mts +0 -26
  91. package/dist/engine/branch/branch-types.d.mts.map +0 -1
  92. package/dist/engine/branch/branch-types.mjs +0 -7
  93. package/dist/engine/branch/branch-types.mjs.map +0 -1
  94. package/dist/engine/diff/line-diff-helper.d.mts +0 -76
  95. package/dist/engine/diff/line-diff-helper.d.mts.map +0 -1
  96. package/dist/engine/diff/line-diff-helper.mjs +0 -144
  97. package/dist/engine/diff/line-diff-helper.mjs.map +0 -1
  98. package/dist/engine/filter/glob-helper.d.mts +0 -51
  99. package/dist/engine/filter/glob-helper.d.mts.map +0 -1
  100. package/dist/engine/filter/glob-helper.mjs +0 -132
  101. package/dist/engine/filter/glob-helper.mjs.map +0 -1
  102. package/dist/engine/index/index-helper.d.mts +0 -113
  103. package/dist/engine/index/index-helper.d.mts.map +0 -1
  104. package/dist/engine/index/index-helper.mjs +0 -533
  105. package/dist/engine/index/index-helper.mjs.map +0 -1
  106. package/dist/engine/index/index-types.d.mts +0 -63
  107. package/dist/engine/index/index-types.d.mts.map +0 -1
  108. package/dist/engine/index/index-types.mjs +0 -7
  109. package/dist/engine/index/index-types.mjs.map +0 -1
  110. package/dist/engine/item/item-atom-helper.d.mts +0 -20
  111. package/dist/engine/item/item-atom-helper.d.mts.map +0 -1
  112. package/dist/engine/item/item-atom-helper.mjs +0 -30
  113. package/dist/engine/item/item-atom-helper.mjs.map +0 -1
  114. package/dist/engine/item/item-helper.d.mts +0 -94
  115. package/dist/engine/item/item-helper.d.mts.map +0 -1
  116. package/dist/engine/item/item-helper.mjs +0 -424
  117. package/dist/engine/item/item-helper.mjs.map +0 -1
  118. package/dist/engine/item/item-types.d.mts +0 -128
  119. package/dist/engine/item/item-types.d.mts.map +0 -1
  120. package/dist/engine/item/item-types.mjs +0 -16
  121. package/dist/engine/item/item-types.mjs.map +0 -1
  122. package/dist/engine/merge/b2tfs-3way-graft-strategy.d.mts +0 -74
  123. package/dist/engine/merge/b2tfs-3way-graft-strategy.d.mts.map +0 -1
  124. package/dist/engine/merge/b2tfs-3way-graft-strategy.mjs +0 -570
  125. package/dist/engine/merge/b2tfs-3way-graft-strategy.mjs.map +0 -1
  126. package/dist/engine/merge/b2tfs-3way-graft-types.d.mts +0 -34
  127. package/dist/engine/merge/b2tfs-3way-graft-types.d.mts.map +0 -1
  128. package/dist/engine/merge/b2tfs-3way-graft-types.mjs +0 -2
  129. package/dist/engine/merge/b2tfs-3way-graft-types.mjs.map +0 -1
  130. package/dist/engine/status/status-helper.d.mts +0 -90
  131. package/dist/engine/status/status-helper.d.mts.map +0 -1
  132. package/dist/engine/status/status-helper.mjs +0 -286
  133. package/dist/engine/status/status-helper.mjs.map +0 -1
  134. package/src/engine/branch/branch-graph-helper.mts +0 -117
  135. package/src/engine/branch/branch-helper.mts +0 -112
  136. package/src/engine/branch/branch-space-helper.mts +0 -110
  137. package/src/engine/branch/branch-types.mts +0 -29
  138. package/src/engine/diff/line-diff-helper.mts +0 -210
  139. package/src/engine/diff/line-diff-helper.respec.mts +0 -84
  140. package/src/engine/filter/glob-helper.mts +0 -165
  141. package/src/engine/filter/glob-helper.respec.mts +0 -94
  142. package/src/engine/index/index-helper.mts +0 -705
  143. package/src/engine/index/index-types.mts +0 -66
  144. package/src/engine/item/item-atom-helper.mts +0 -30
  145. package/src/engine/item/item-helper.mts +0 -544
  146. package/src/engine/item/item-types.mts +0 -137
  147. package/src/engine/item/item.respec.mts +0 -92
  148. package/src/engine/merge/b2tfs-3way-graft-strategy.mts +0 -630
  149. package/src/engine/merge/b2tfs-3way-graft-strategy.respec.mts +0 -346
  150. package/src/engine/merge/b2tfs-3way-graft-types.mts +0 -34
  151. package/src/engine/status/status-helper.mts +0 -383
@@ -1,66 +0,0 @@
1
- /**
2
- * @module index-types
3
- *
4
- * Space-qualified address and B2tFS index type definitions.
5
- */
6
-
7
- import { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
8
- import { IbGibData_V1, IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
9
-
10
- /**
11
- * Format: v:1^spaceId:<spaceId>^<ibGibAddr>
12
- */
13
- export type SpaceQualifiedIbGibAddr = string;
14
-
15
- export interface B2tFSStagedItemRecord {
16
- itemAddr: string;
17
- binAddr?: string;
18
- fileHash?: string;
19
- fsType: 'file' | 'folder';
20
- stagedAt: string;
21
- }
22
-
23
- export interface B2tFSIndexData_V1 extends IbGibData_V1 {
24
- /**
25
- * Space UUID containing this index
26
- */
27
- mySpaceId: string;
28
- /**
29
- * Currently active branch space UUID
30
- */
31
- activeSpaceId: string;
32
- /**
33
- * Active branch name (e.g. 'main')
34
- */
35
- activeBranch?: string;
36
- /**
37
- * Space UUID from which this space forked
38
- */
39
- ancestorSpaceId?: string;
40
- /**
41
- * Soft references to branch TJPs: $@branch = [SpaceQualifiedIbGibAddr, ...]
42
- */
43
- '$@branch'?: SpaceQualifiedIbGibAddr[];
44
- /**
45
- * Staged paths lookup table
46
- */
47
- stagedPaths?: { [relPath: string]: B2tFSStagedItemRecord };
48
- /**
49
- * Staged candidate item addresses
50
- */
51
- staged_item?: IbGibAddr[];
52
- }
53
-
54
- export interface B2tFSIndexRel8ns_V1 extends IbGibRel8ns_V1 {
55
- /**
56
- * Local branch TJP address for this space
57
- */
58
- branch_tjp?: IbGibAddr[];
59
- /**
60
- * Active or registered branch IbGib addresses
61
- */
62
- branch?: IbGibAddr[];
63
- }
64
-
65
- export interface B2tFSIndexIbGib_V1 extends IbGib_V1<B2tFSIndexData_V1, B2tFSIndexRel8ns_V1> {
66
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * @module item-atom-helper
3
- *
4
- * Helper functions enforcing canonical space-delimited `ib` atom formulas.
5
- *
6
- * Formula: `[atom] [fsType] [saferName] [saferNameVersion] [nameHash]`
7
- * Example: `b2tfs_item file index_mts v1 a745323851634de188beaebdcb85cbb9`
8
- */
9
-
10
- export const B2TFS_ITEM_ATOM = 'b2tfs_item';
11
- export const B2TFS_ITEM_SAFER_NAME_VERSION_V1 = 'v1';
12
-
13
- export function getB2tFSItemSaferName(rawName: string): string {
14
- if (!rawName) { return 'unnamed'; }
15
- // Clean to alphanumeric and underscores/dashes/dots
16
- const safe = rawName.replace(/[^a-zA-Z0-9_\-\.]/g, '_');
17
- return safe.slice(0, 32);
18
- }
19
-
20
- /**
21
- * Returns canonical `ib` metadata string for a B2tFS item.
22
- *
23
- * @param fsType 'file' or 'folder'
24
- * @param name raw file/folder name
25
- * @param nameHash SHA-256 hash of name
26
- */
27
- export function getB2tFSItemIb(fsType: 'file' | 'folder', name: string, nameHash: string): string {
28
- const saferName = getB2tFSItemSaferName(name);
29
- return `${B2TFS_ITEM_ATOM} ${fsType} ${saferName} ${B2TFS_ITEM_SAFER_NAME_VERSION_V1} ${nameHash}`;
30
- }
@@ -1,544 +0,0 @@
1
- /**
2
- * @module item-helper
3
- *
4
- * B2tFS Item Helper functions: graph diff generation, filesystem projection materialization,
5
- * and two-pass transform application.
6
- */
7
-
8
- import fs from 'node:fs/promises';
9
- import path from 'node:path';
10
- import crypto from 'node:crypto';
11
-
12
- import { extractErrorMsg, getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
13
- import { Factory_V1 } from '@ibgib/ts-gib/dist/V1/factory.mjs';
14
- import { mut8 } from '@ibgib/ts-gib/dist/V1/transforms/mut8.mjs';
15
- import { rel8 } from '@ibgib/ts-gib/dist/V1/transforms/rel8.mjs';
16
- import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
17
- import { TransformResult, IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';
18
- import { MetaspaceService } from '@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs';
19
- import { IbGibSpaceAny } from '@ibgib/core-gib/dist/witness/space/space-base-v1.mjs';
20
- import { isIbGib } from '@ibgib/core-gib/dist/common/other/ibgib-helper.mjs';
21
- import { persistTransformResult, getFromSpace } from '@ibgib/core-gib/dist/witness/space/space-helper.mjs';
22
- import { reifyDependencyGraph } from '@ibgib/core-gib/dist/common/other/graph-helper.mjs';
23
-
24
- import { GLOBAL_LOG_A_LOT } from '../../vcs-gib-constants.mjs';
25
- import { parseSpaceQualifiedIbGibAddr } from '../index/index-helper.mjs';
26
- import { B2TFS_ITEM_ATOM, getB2tFSItemIb } from './item-atom-helper.mjs';
27
- import {
28
- B2tFSItemIbGib_V1, B2tFSItemData_V1, B2tFSItemRel8ns_V1,
29
- B2TFS_CHILD_ITEM_REL8N_NAME, BINARY_REL8N_NAME, B2tFSItemDiffInfo
30
- } from './item-types.mjs';
31
-
32
- const logalot = GLOBAL_LOG_A_LOT;
33
- const lcFile = `[item-helper]`;
34
-
35
- export function isB2tFSItemIbGib(x: any): x is B2tFSItemIbGib_V1 {
36
- if (!x) { return false; }
37
- if (!isIbGib(x)) { return false; }
38
- return x.ib.startsWith(B2TFS_ITEM_ATOM) || x.data?.classname === 'B2tFSItemIbGib_V1';
39
- }
40
-
41
- export interface CreateB2tFSItemIbGibOpts {
42
- fsType: 'file' | 'folder';
43
- name: string;
44
- data?: Partial<B2tFSItemData_V1>;
45
- rel8ns?: Partial<B2tFSItemRel8ns_V1>;
46
- }
47
-
48
- export interface EvolveB2tFSItemIbGibOpts {
49
- existingItem: B2tFSItemIbGib_V1;
50
- dataToUpdate?: Partial<B2tFSItemData_V1>;
51
- rel8nsToUpdate?: Partial<B2tFSItemRel8ns_V1>;
52
- rel8nsToRemove?: Partial<B2tFSItemRel8ns_V1>;
53
- }
54
-
55
- /**
56
- * Creates a brand-new B2tFSItemIbGib_V1 node using Factory_V1.firstGen with TJP, DNA, and nCounter.
57
- * Used ONLY for brand-new files or folders.
58
- */
59
- export async function createB2tFSItemIbGib({
60
- fsType,
61
- name,
62
- data,
63
- rel8ns,
64
- }: CreateB2tFSItemIbGibOpts): Promise<TransformResult<IbGib_V1>> {
65
- const lc = `${lcFile}[${createB2tFSItemIbGib.name}]`;
66
- try {
67
- if (logalot) {
68
- console.log(`${lc} starting... (I: 8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d)`);
69
- }
70
-
71
- if (!fsType || !name) {
72
- throw new Error(`fsType and name are required (E: 9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e)`);
73
- }
74
-
75
- const nameHash = data?.nameHash || crypto.createHash('sha256').update(name).digest('hex');
76
- const uuid = data?.uuid || (await getUUID());
77
- const diffTransactionId = data?.diffTransactionId || (await getUUID());
78
-
79
- let fileNameSansExt: string | undefined;
80
- let fileExt: string | undefined;
81
- if (fsType === 'file') {
82
- fileNameSansExt = path.parse(name).name;
83
- fileExt = path.parse(name).ext.replace(/^\./, '');
84
- }
85
-
86
- const itemData: B2tFSItemData_V1 = {
87
- name,
88
- nameHash,
89
- fsType,
90
- diffTransactionId,
91
- uuid,
92
- classname: 'B2tFSItemIbGib_V1',
93
- ...(fsType === 'file' ? { fileNameSansExt, fileExt } : {}),
94
- ...data,
95
- };
96
-
97
- const ib = getB2tFSItemIb(fsType, name, nameHash);
98
-
99
- const res = await Factory_V1.firstGen({
100
- parentIbGib: Factory_V1.primitive({ ib: B2TFS_ITEM_ATOM }),
101
- ib,
102
- data: itemData,
103
- rel8ns: rel8ns as any,
104
- tjp: { timestamp: true, uuid: true },
105
- dna: true,
106
- nCounter: true,
107
- });
108
-
109
- if (logalot) {
110
- console.log(`${lc} Created new B2tFSItemIbGib: ${res.newIbGib.ib}^${res.newIbGib.gib} (I: 0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f)`);
111
- }
112
-
113
- return res;
114
- } catch (error) {
115
- console.error(`${lc} ${extractErrorMsg(error)} (E: 1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a)`);
116
- throw error;
117
- } finally {
118
- if (logalot) {
119
- console.log(`${lc} complete. (I: 2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b)`);
120
- }
121
- }
122
- }
123
-
124
- /**
125
- * Evolves an existing B2tFSItemIbGib_V1 node using mut8 (for data/hash updates)
126
- * and rel8 (for binary/child link updates) with DNA, nCounter, and timeline tracking.
127
- * Populates rel8ns.past and rel8ns.ancestor, preserving the item's TJP to generate
128
- * composite two-part timeline gib addresses (<tjpGib>^<punctiliarGib>).
129
- */
130
- export async function evolveB2tFSItemIbGib({
131
- existingItem,
132
- dataToUpdate,
133
- rel8nsToUpdate,
134
- rel8nsToRemove,
135
- }: EvolveB2tFSItemIbGibOpts): Promise<TransformResult<IbGib_V1>> {
136
- const lc = `${lcFile}[${evolveB2tFSItemIbGib.name}]`;
137
- try {
138
- if (logalot) {
139
- console.log(`${lc} starting... (I: 3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c)`);
140
- }
141
-
142
- if (!existingItem || !existingItem.ib || !existingItem.gib) {
143
- throw new Error(`existingItem with valid ib and gib is required (E: 4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d)`);
144
- }
145
-
146
- let currentItem: B2tFSItemIbGib_V1 = existingItem;
147
- const dnas: IbGib_V1[] = [];
148
- const intermediateIbGibs: IbGib_V1[] = [];
149
-
150
- // Ensure rel8ns.ancestor is populated if missing
151
- if (!currentItem.rel8ns?.ancestor || currentItem.rel8ns.ancestor.length === 0) {
152
- currentItem = {
153
- ...currentItem,
154
- rel8ns: {
155
- ...(currentItem.rel8ns || {}),
156
- ancestor: [`${B2TFS_ITEM_ATOM}^gib`],
157
- },
158
- };
159
- }
160
-
161
- const hasDataChanges = dataToUpdate && Object.keys(dataToUpdate).length > 0;
162
- const hasRel8nsChanges = (rel8nsToUpdate && Object.keys(rel8nsToUpdate).length > 0) ||
163
- (rel8nsToRemove && Object.keys(rel8nsToRemove).length > 0);
164
-
165
- // If neither data nor rel8ns explicitly specified, update diffTransactionId to evolve timeline
166
- const patchData: Partial<B2tFSItemData_V1> = {
167
- ...(dataToUpdate || {}),
168
- diffTransactionId: dataToUpdate?.diffTransactionId || (await getUUID()),
169
- };
170
-
171
- // Pass 1: mut8 for data/hash updates
172
- const resMut8 = await mut8({
173
- src: currentItem,
174
- dataToAddOrPatch: patchData,
175
- dna: true,
176
- nCounter: patchData.n ? false : true, // if we manually set data.n, turn nCounter off
177
- });
178
-
179
- currentItem = resMut8.newIbGib as B2tFSItemIbGib_V1;
180
- if (resMut8.dnas) { dnas.push(...resMut8.dnas); }
181
-
182
- // Pass 2: rel8 for binary/child link updates if rel8ns specified
183
- if (hasRel8nsChanges) {
184
- intermediateIbGibs.push(currentItem);
185
-
186
- const resRel8 = await rel8({
187
- src: currentItem,
188
- rel8nsToAddByAddr: rel8nsToUpdate as any,
189
- rel8nsToRemoveByAddr: rel8nsToRemove as any,
190
- dna: true,
191
- nCounter: true,
192
- });
193
-
194
- currentItem = resRel8.newIbGib as B2tFSItemIbGib_V1;
195
- if (resRel8.dnas) { dnas.push(...resRel8.dnas); }
196
- }
197
-
198
- // Verify rel8ns.ancestor exists on evolved item
199
- if (!currentItem.rel8ns?.ancestor || currentItem.rel8ns.ancestor.length === 0) {
200
- currentItem.rel8ns = {
201
- ...(currentItem.rel8ns || {}),
202
- ancestor: [`${B2TFS_ITEM_ATOM}^gib`],
203
- };
204
- }
205
-
206
- if (logalot) {
207
- console.log(`${lc} Evolved B2tFSItemIbGib: ${currentItem.ib}^${currentItem.gib} (I: 5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e)`);
208
- }
209
-
210
- return {
211
- newIbGib: currentItem,
212
- intermediateIbGibs: intermediateIbGibs.length > 0 ? intermediateIbGibs : undefined,
213
- dnas: dnas.length > 0 ? dnas : undefined,
214
- };
215
- } catch (error) {
216
- console.error(`${lc} ${extractErrorMsg(error)} (E: 6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f)`);
217
- throw error;
218
- } finally {
219
- if (logalot) {
220
- console.log(`${lc} complete. (I: 7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a)`);
221
- }
222
- }
223
- }
224
-
225
-
226
- function getSpacesArray(metaAny: any): IbGibSpaceAny[] {
227
- if (!metaAny || !metaAny.spaces) {
228
- return [];
229
- }
230
- if (metaAny.spaces instanceof Map) {
231
- return Array.from(metaAny.spaces.values());
232
- }
233
- if (Array.isArray(metaAny.spaces)) {
234
- return metaAny.spaces;
235
- }
236
- if (typeof metaAny.spaces === 'object') {
237
- return Object.values(metaAny.spaces);
238
- }
239
- return [];
240
- }
241
-
242
- async function fetchFromSpaceSilently(spaceToQuery: IbGibSpaceAny, addrToGet: string): Promise<any> {
243
- try {
244
- const resGet = await getFromSpace({ space: spaceToQuery, addrs: [addrToGet] });
245
- if (resGet) {
246
- const found = resGet.ibGibs?.find(x => !!x) || (resGet.rawResultIbGib as any)?.ibGibs?.find((x: any) => !!x);
247
- if (found) {
248
- return found;
249
- }
250
- }
251
- } catch {
252
- // Suppress missing address error
253
- }
254
- return undefined;
255
- }
256
-
257
- /**
258
- * Retrieves an ibgib node by address, searching space first, then falling back to metaspace spaces if available.
259
- */
260
- export async function getIbGibWithMetaspaceFallback({
261
- addr,
262
- space,
263
- metaspace,
264
- }: {
265
- addr: string;
266
- space: IbGibSpaceAny;
267
- metaspace?: MetaspaceService;
268
- }): Promise<any> {
269
- const parsedSq = parseSpaceQualifiedIbGibAddr(addr);
270
- const targetAddr = parsedSq ? parsedSq.ibGibAddr : addr;
271
-
272
- if (parsedSq && metaspace) {
273
- try {
274
- const spaceList = (await metaspace.getLocalUserSpaces({ lock: false })) || [];
275
- let targetSpace = spaceList.find(s =>
276
- s?.data?.uuid === parsedSq.spaceId ||
277
- s?.data?.spaceId === parsedSq.spaceId ||
278
- s?.data?.name === parsedSq.spaceId ||
279
- s?.ib === parsedSq.spaceId ||
280
- s?.data?.spaceSubPath === parsedSq.spaceId
281
- );
282
-
283
- if (!targetSpace) {
284
- try {
285
- targetSpace = await metaspace.getLocalUserSpace({ localSpaceId: parsedSq.spaceId, lock: false });
286
- } catch {
287
- // Suppress lookup error
288
- }
289
- }
290
-
291
- if (targetSpace) {
292
- const found = await fetchFromSpaceSilently(targetSpace, targetAddr);
293
- if (found) {
294
- return found;
295
- }
296
- }
297
- } catch {
298
- // Suppress space lookup errors
299
- }
300
- }
301
-
302
- const primaryFound = await fetchFromSpaceSilently(space, targetAddr);
303
- if (primaryFound) {
304
- return primaryFound;
305
- }
306
-
307
- if (metaspace) {
308
- let spaceList: IbGibSpaceAny[] = [];
309
- try {
310
- spaceList = (await metaspace.getLocalUserSpaces({ lock: false })) || [];
311
- } catch {
312
- // Ignore bootstrap lookup error
313
- }
314
-
315
- const metaAny = metaspace as any;
316
-
317
- // Try zero space if distinct
318
- if (metaspace.zeroSpace && metaspace.zeroSpace !== space) {
319
- const zeroFound = await fetchFromSpaceSilently(metaspace.zeroSpace, targetAddr);
320
- if (zeroFound) {
321
- return zeroFound;
322
- }
323
- }
324
-
325
- if (metaAny.activeSpace && metaAny.activeSpace !== space && metaAny.activeSpace !== metaspace.zeroSpace) {
326
- const activeFound = await fetchFromSpaceSilently(metaAny.activeSpace, targetAddr);
327
- if (activeFound) {
328
- return activeFound;
329
- }
330
- }
331
-
332
- for (const s of spaceList) {
333
- if (s && s !== space && s !== metaAny.activeSpace && s !== metaspace.zeroSpace) {
334
- const sFound = await fetchFromSpaceSilently(s, targetAddr);
335
- if (sFound) {
336
- return sFound;
337
- }
338
- }
339
- }
340
- }
341
-
342
- return undefined;
343
- }
344
-
345
- /**
346
- * Projects a B2tFS item graph back onto the physical filesystem directory.
347
- */
348
- export async function writeB2tFSItemToFS({
349
- item,
350
- destPath,
351
- space,
352
- metaspace,
353
- }: {
354
- item: B2tFSItemIbGib_V1;
355
- destPath: string;
356
- space: IbGibSpaceAny;
357
- metaspace: MetaspaceService;
358
- }): Promise<void> {
359
- const lc = `${lcFile}[${writeB2tFSItemToFS.name}]`;
360
- try {
361
- if (logalot) {
362
- console.log(`${lc} starting... (I: 7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d)`);
363
- }
364
-
365
- if (!item || !item.data) {
366
- throw new Error(`Invalid B2tFS item provided (E: 32a09c81b29e4d5867198204b12541a5)`);
367
- }
368
-
369
- const { fsType, name } = item.data;
370
- const targetPath = path.join(destPath, name);
371
-
372
- if (fsType === 'folder') {
373
- await fs.mkdir(targetPath, { recursive: true });
374
- const childAddrs = item.rel8ns?.[B2TFS_CHILD_ITEM_REL8N_NAME] || [];
375
-
376
- for (const childAddr of childAddrs) {
377
- const childItem = await getIbGibWithMetaspaceFallback({
378
- addr: childAddr,
379
- space,
380
- metaspace,
381
- }) as B2tFSItemIbGib_V1;
382
-
383
- if (childItem) {
384
- await writeB2tFSItemToFS({
385
- item: childItem,
386
- destPath: targetPath,
387
- space,
388
- metaspace,
389
- });
390
- }
391
- }
392
- } else if (fsType === 'file') {
393
- await fs.mkdir(path.dirname(targetPath), { recursive: true });
394
- const binAddrs = item.rel8ns?.[BINARY_REL8N_NAME] || [];
395
- const latestBinAddr = binAddrs.at(-1);
396
-
397
- if (latestBinAddr) {
398
- const binIbGib = await getIbGibWithMetaspaceFallback({
399
- addr: latestBinAddr,
400
- space,
401
- metaspace,
402
- });
403
-
404
- if (binIbGib && binIbGib.data) {
405
- let fileData: Uint8Array;
406
- if (typeof binIbGib.data === 'string') {
407
- fileData = Buffer.from(binIbGib.data, 'base64');
408
- } else if (binIbGib.data instanceof Uint8Array || Buffer.isBuffer(binIbGib.data)) {
409
- fileData = binIbGib.data as Uint8Array;
410
- } else if (typeof binIbGib.data === 'object') {
411
- const vals = Object.values(binIbGib.data as object);
412
- fileData = new Uint8Array(vals);
413
- } else {
414
- fileData = new Uint8Array(0);
415
- }
416
-
417
- await fs.writeFile(targetPath, fileData);
418
- }
419
- }
420
- }
421
- } catch (error) {
422
- console.error(`${lc} ${extractErrorMsg(error)} (E: 8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d)`);
423
- throw error;
424
- } finally {
425
- if (logalot) {
426
- console.log(`${lc} complete. (I: 9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e)`);
427
- }
428
- }
429
- }
430
-
431
- /**
432
- * Executes two-pass application of diff transform results:
433
- * 1. Persists all child and parent transform results to space.
434
- * 2. Registers new IbGib pointers with metaspace to advance timeline tips.
435
- */
436
- export async function applyB2tFSItemDiff({
437
- diff,
438
- space,
439
- metaspace,
440
- }: {
441
- diff: B2tFSItemDiffInfo;
442
- space: IbGibSpaceAny;
443
- metaspace: MetaspaceService;
444
- }): Promise<void> {
445
- const lc = `${lcFile}[${applyB2tFSItemDiff.name}]`;
446
- try {
447
- if (logalot) {
448
- console.log(`${lc} starting... (I: 0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d)`);
449
- }
450
-
451
- if (diff.childDiffs && diff.childDiffs.length > 0) {
452
- for (const childDiff of diff.childDiffs) {
453
- await applyB2tFSItemDiff({ diff: childDiff, space, metaspace });
454
- }
455
- }
456
-
457
- const results = diff.transformResults || [];
458
- for (const tr of results) {
459
- await persistTransformResult({ resTransform: tr, space });
460
- }
461
-
462
- for (const tr of results) {
463
- if (tr.newIbGib) {
464
- await metaspace.registerNewIbGib({ ibGib: tr.newIbGib });
465
- }
466
- }
467
- } catch (error) {
468
- console.error(`${lc} ${extractErrorMsg(error)} (E: 1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e)`);
469
- throw error;
470
- } finally {
471
- if (logalot) {
472
- console.log(`${lc} complete. (I: 2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f)`);
473
- }
474
- }
475
- }
476
-
477
- // #region reifyB2tFSHierarchy
478
-
479
- export interface ReifyB2tFSHierarchyOpts {
480
- /** Root B2tFS item (folder or file). Either rootItem or rootItemAddr required. */
481
- rootItem?: B2tFSItemIbGib_V1;
482
- /** Address of root B2tFS item. Either rootItem or rootItemAddr required. */
483
- rootItemAddr?: IbGibAddr;
484
- /** Space containing the branch items and updated timeline tips. */
485
- space: IbGibSpaceAny;
486
- /** Metaspace service instance for lookups and registrations. */
487
- metaspace: MetaspaceService;
488
- }
489
-
490
- export interface ReifyB2tFSHierarchyResult {
491
- /** The reified root B2tFS item (evolved if any descendants changed, or unchanged if no descendants changed). */
492
- reifiedRootItem: B2tFSItemIbGib_V1;
493
- /** True if one or more folder/file nodes in the hierarchy evolved to new tips. */
494
- hasChanges: boolean;
495
- /** Map of old address -> new address for every node that evolved in this reification run. */
496
- reifiedAddrsMap: { [oldAddr: string]: string };
497
- /** All newly evolved and persisted intermediate/root folder items created during reification. */
498
- evolvedItems: B2tFSItemIbGib_V1[];
499
- }
500
-
501
- /**
502
- * Reifies a B2tFS filesystem item hierarchy (folders and files) bottom-up.
503
- *
504
- * Traverses `b2tfs_child` relationship edges. If any child timeline advanced
505
- * in `space` (e.g. during a 3-way merge or parallel commit), the parent folders
506
- * are evolved in-place using `rel8` with the updated child tip addresses.
507
- */
508
- export async function reifyB2tFSHierarchy({
509
- rootItem,
510
- rootItemAddr,
511
- space,
512
- metaspace,
513
- }: ReifyB2tFSHierarchyOpts): Promise<ReifyB2tFSHierarchyResult> {
514
- const lc = `${lcFile}[${reifyB2tFSHierarchy.name}]`;
515
- try {
516
- if (logalot) {
517
- console.log(`${lc} starting... (I: 3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a)`);
518
- }
519
-
520
- const res = await reifyDependencyGraph({
521
- ibGib: rootItem,
522
- ibGibAddr: rootItemAddr,
523
- onlyRel8nNames: [B2TFS_CHILD_ITEM_REL8N_NAME],
524
- space,
525
- metaspace,
526
- });
527
-
528
- return {
529
- reifiedRootItem: res.reifiedIbGib as B2tFSItemIbGib_V1,
530
- hasChanges: res.hasChanges,
531
- reifiedAddrsMap: res.reifiedAddrsMap,
532
- evolvedItems: res.evolvedIbGibs as B2tFSItemIbGib_V1[],
533
- };
534
- } catch (error) {
535
- console.error(`${lc} ${extractErrorMsg(error)} (E: 4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b)`);
536
- throw error;
537
- } finally {
538
- if (logalot) {
539
- console.log(`${lc} complete. (I: 5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c)`);
540
- }
541
- }
542
- }
543
-
544
- // #endregion reifyB2tFSHierarchy