@ibgib/vcs-gib 0.0.6 → 0.0.18

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 (185) hide show
  1. package/README.md +24 -2
  2. package/VCS_CLI_USER_GUIDE.md +2 -2
  3. package/dist/AUTO-GENERATED-version.d.mts +1 -1
  4. package/dist/AUTO-GENERATED-version.d.mts.map +1 -1
  5. package/dist/AUTO-GENERATED-version.mjs +1 -1
  6. package/dist/AUTO-GENERATED-version.mjs.map +1 -1
  7. package/dist/bootstrap/node-bootstrap.d.mts.map +1 -1
  8. package/dist/bootstrap/node-bootstrap.mjs +9 -0
  9. package/dist/bootstrap/node-bootstrap.mjs.map +1 -1
  10. package/dist/bootstrap/{node-bootstrap.respec.node.d.mts → node-bootstrap.respec.d.mts} +1 -1
  11. package/dist/bootstrap/node-bootstrap.respec.d.mts.map +1 -0
  12. package/dist/bootstrap/{node-bootstrap.respec.node.mjs → node-bootstrap.respec.mjs} +1 -1
  13. package/dist/bootstrap/node-bootstrap.respec.mjs.map +1 -0
  14. package/dist/cli/cli-arg-parser.d.mts +3 -0
  15. package/dist/cli/cli-arg-parser.d.mts.map +1 -1
  16. package/dist/cli/cli-arg-parser.mjs +13 -1
  17. package/dist/cli/cli-arg-parser.mjs.map +1 -1
  18. package/dist/cli/{cli-arg-parser.respec.node.d.mts → cli-arg-parser.respec.d.mts} +1 -1
  19. package/dist/cli/cli-arg-parser.respec.d.mts.map +1 -0
  20. package/dist/cli/{cli-arg-parser.respec.node.mjs → cli-arg-parser.respec.mjs} +1 -1
  21. package/dist/cli/cli-arg-parser.respec.mjs.map +1 -0
  22. package/dist/cli/cli-constants.d.mts +6 -0
  23. package/dist/cli/cli-constants.d.mts.map +1 -1
  24. package/dist/cli/cli-constants.mjs +24 -0
  25. package/dist/cli/cli-constants.mjs.map +1 -1
  26. package/dist/cli/{cli-e2e.respec.node.d.mts → cli-e2e.respec.d.mts} +1 -1
  27. package/dist/cli/cli-e2e.respec.d.mts.map +1 -0
  28. package/dist/cli/{cli-e2e.respec.node.mjs → cli-e2e.respec.mjs} +2 -2
  29. package/dist/cli/cli-e2e.respec.mjs.map +1 -0
  30. package/dist/cli/commands/add-cmd.d.mts.map +1 -1
  31. package/dist/cli/commands/add-cmd.mjs +35 -30
  32. package/dist/cli/commands/add-cmd.mjs.map +1 -1
  33. package/dist/cli/commands/{branch-checkout-cmd.respec.node.d.mts → branch-checkout-cmd.respec.d.mts} +1 -1
  34. package/dist/cli/commands/branch-checkout-cmd.respec.d.mts.map +1 -0
  35. package/dist/cli/commands/{branch-checkout-cmd.respec.node.mjs → branch-checkout-cmd.respec.mjs} +172 -8
  36. package/dist/cli/commands/branch-checkout-cmd.respec.mjs.map +1 -0
  37. package/dist/cli/commands/branch-cmd.d.mts +2 -1
  38. package/dist/cli/commands/branch-cmd.d.mts.map +1 -1
  39. package/dist/cli/commands/branch-cmd.mjs +59 -8
  40. package/dist/cli/commands/branch-cmd.mjs.map +1 -1
  41. package/dist/cli/commands/checkout-cmd.d.mts.map +1 -1
  42. package/dist/cli/commands/checkout-cmd.mjs +38 -18
  43. package/dist/cli/commands/checkout-cmd.mjs.map +1 -1
  44. package/dist/cli/commands/commit-cmd.d.mts.map +1 -1
  45. package/dist/cli/commands/commit-cmd.mjs +26 -23
  46. package/dist/cli/commands/commit-cmd.mjs.map +1 -1
  47. package/dist/cli/commands/{commit-log-cmd.respec.node.d.mts → commit-log-cmd.respec.d.mts} +1 -1
  48. package/dist/cli/commands/commit-log-cmd.respec.d.mts.map +1 -0
  49. package/dist/cli/commands/{commit-log-cmd.respec.node.mjs → commit-log-cmd.respec.mjs} +1 -1
  50. package/dist/cli/commands/commit-log-cmd.respec.mjs.map +1 -0
  51. package/dist/cli/commands/{init-cmd.respec.node.d.mts → init-cmd.respec.d.mts} +1 -1
  52. package/dist/cli/commands/init-cmd.respec.d.mts.map +1 -0
  53. package/dist/cli/commands/{init-cmd.respec.node.mjs → init-cmd.respec.mjs} +1 -1
  54. package/dist/cli/commands/init-cmd.respec.mjs.map +1 -0
  55. package/dist/cli/commands/merge-cmd.d.mts +23 -0
  56. package/dist/cli/commands/merge-cmd.d.mts.map +1 -0
  57. package/dist/cli/commands/merge-cmd.mjs +224 -0
  58. package/dist/cli/commands/merge-cmd.mjs.map +1 -0
  59. package/dist/cli/commands/reset-cmd.d.mts +21 -0
  60. package/dist/cli/commands/reset-cmd.d.mts.map +1 -0
  61. package/dist/cli/commands/reset-cmd.mjs +93 -0
  62. package/dist/cli/commands/reset-cmd.mjs.map +1 -0
  63. package/dist/cli/commands/reset-restore-cmd.respec.d.mts +7 -0
  64. package/dist/cli/commands/reset-restore-cmd.respec.d.mts.map +1 -0
  65. package/dist/cli/commands/reset-restore-cmd.respec.mjs +185 -0
  66. package/dist/cli/commands/reset-restore-cmd.respec.mjs.map +1 -0
  67. package/dist/cli/commands/restore-cmd.d.mts +22 -0
  68. package/dist/cli/commands/restore-cmd.d.mts.map +1 -0
  69. package/dist/cli/commands/restore-cmd.mjs +115 -0
  70. package/dist/cli/commands/restore-cmd.mjs.map +1 -0
  71. package/dist/cli/commands/{status-add-cmd.respec.node.d.mts → status-add-cmd.respec.d.mts} +1 -1
  72. package/dist/cli/commands/status-add-cmd.respec.d.mts.map +1 -0
  73. package/dist/cli/commands/{status-add-cmd.respec.node.mjs → status-add-cmd.respec.mjs} +25 -1
  74. package/dist/cli/commands/status-add-cmd.respec.mjs.map +1 -0
  75. package/dist/cli/vcs-cli-main.d.mts.map +1 -1
  76. package/dist/cli/vcs-cli-main.mjs +36 -3
  77. package/dist/cli/vcs-cli-main.mjs.map +1 -1
  78. package/dist/engine/branch/branch-graph-helper.d.mts +12 -3
  79. package/dist/engine/branch/branch-graph-helper.d.mts.map +1 -1
  80. package/dist/engine/branch/branch-graph-helper.mjs +50 -18
  81. package/dist/engine/branch/branch-graph-helper.mjs.map +1 -1
  82. package/dist/engine/branch/branch-space-helper.d.mts +1 -0
  83. package/dist/engine/branch/branch-space-helper.d.mts.map +1 -1
  84. package/dist/engine/branch/branch-space-helper.mjs +1 -0
  85. package/dist/engine/branch/branch-space-helper.mjs.map +1 -1
  86. package/dist/engine/branch/{branch-space.respec.node.d.mts → branch-space.respec.d.mts} +1 -1
  87. package/dist/engine/branch/branch-space.respec.d.mts.map +1 -0
  88. package/dist/engine/branch/{branch-space.respec.node.mjs → branch-space.respec.mjs} +12 -7
  89. package/dist/engine/branch/branch-space.respec.mjs.map +1 -0
  90. package/dist/engine/diff/{line-diff-helper.respec.node.d.mts → line-diff-helper.respec.d.mts} +1 -1
  91. package/dist/engine/diff/line-diff-helper.respec.d.mts.map +1 -0
  92. package/dist/engine/diff/{line-diff-helper.respec.node.mjs → line-diff-helper.respec.mjs} +1 -1
  93. package/dist/engine/diff/line-diff-helper.respec.mjs.map +1 -0
  94. package/dist/engine/filter/{glob-helper.respec.node.d.mts → glob-helper.respec.d.mts} +1 -1
  95. package/dist/engine/filter/glob-helper.respec.d.mts.map +1 -0
  96. package/dist/engine/filter/{glob-helper.respec.node.mjs → glob-helper.respec.mjs} +1 -1
  97. package/dist/engine/filter/glob-helper.respec.mjs.map +1 -0
  98. package/dist/engine/index/index-helper.d.mts +35 -0
  99. package/dist/engine/index/index-helper.d.mts.map +1 -1
  100. package/dist/engine/index/index-helper.mjs +241 -0
  101. package/dist/engine/index/index-helper.mjs.map +1 -1
  102. package/dist/engine/item/item-helper.d.mts +29 -3
  103. package/dist/engine/item/item-helper.d.mts.map +1 -1
  104. package/dist/engine/item/item-helper.mjs +234 -56
  105. package/dist/engine/item/item-helper.mjs.map +1 -1
  106. package/dist/engine/item/item.respec.d.mts +7 -0
  107. package/dist/engine/item/item.respec.d.mts.map +1 -0
  108. package/dist/engine/item/item.respec.mjs +75 -0
  109. package/dist/engine/item/item.respec.mjs.map +1 -0
  110. package/dist/engine/merge/b2tfs-3way-merge-strategy.d.mts +38 -0
  111. package/dist/engine/merge/b2tfs-3way-merge-strategy.d.mts.map +1 -0
  112. package/dist/engine/merge/b2tfs-3way-merge-strategy.mjs +593 -0
  113. package/dist/engine/merge/b2tfs-3way-merge-strategy.mjs.map +1 -0
  114. package/dist/engine/merge/b2tfs-merge-strategy.respec.d.mts +7 -0
  115. package/dist/engine/merge/b2tfs-merge-strategy.respec.d.mts.map +1 -0
  116. package/dist/engine/merge/b2tfs-merge-strategy.respec.mjs +335 -0
  117. package/dist/engine/merge/b2tfs-merge-strategy.respec.mjs.map +1 -0
  118. package/dist/respec-gib.node.mjs +1 -1
  119. package/dist/respec-gib.node.mjs.map +1 -1
  120. package/dist/{vcs-gib.respec.node.d.mts → vcs-gib.respec.d.mts} +1 -1
  121. package/dist/vcs-gib.respec.d.mts.map +1 -0
  122. package/dist/{vcs-gib.respec.node.mjs → vcs-gib.respec.mjs} +1 -1
  123. package/dist/vcs-gib.respec.mjs.map +1 -0
  124. package/package.json +3 -3
  125. package/src/AUTO-GENERATED-version.mts +1 -1
  126. package/src/bootstrap/node-bootstrap.mts +6 -0
  127. package/src/cli/cli-arg-parser.mts +15 -0
  128. package/src/cli/cli-constants.mts +27 -0
  129. package/src/cli/{cli-e2e.respec.node.mts → cli-e2e.respec.mts} +2 -2
  130. package/src/cli/commands/add-cmd.mts +41 -29
  131. package/src/cli/commands/{branch-checkout-cmd.respec.node.mts → branch-checkout-cmd.respec.mts} +190 -8
  132. package/src/cli/commands/branch-cmd.mts +78 -8
  133. package/src/cli/commands/checkout-cmd.mts +48 -23
  134. package/src/cli/commands/commit-cmd.mts +35 -26
  135. package/src/cli/commands/merge-cmd.mts +289 -0
  136. package/src/cli/commands/reset-cmd.mts +128 -0
  137. package/src/cli/commands/reset-restore-cmd.respec.mts +222 -0
  138. package/src/cli/commands/restore-cmd.mts +155 -0
  139. package/src/cli/commands/{status-add-cmd.respec.node.mts → status-add-cmd.respec.mts} +27 -0
  140. package/src/cli/vcs-cli-main.mts +36 -3
  141. package/src/engine/branch/branch-graph-helper.mts +66 -18
  142. package/src/engine/branch/branch-space-helper.mts +6 -0
  143. package/src/engine/branch/{branch-space.respec.node.mts → branch-space.respec.mts} +12 -6
  144. package/src/engine/index/index-helper.mts +324 -0
  145. package/src/engine/item/item-helper.mts +284 -58
  146. package/src/engine/item/item.respec.mts +92 -0
  147. package/src/engine/merge/b2tfs-3way-merge-strategy.mts +725 -0
  148. package/src/engine/merge/b2tfs-merge-strategy.respec.mts +438 -0
  149. package/src/respec-gib.node.mts +2 -2
  150. package/tsconfig.tsbuildinfo +1 -1
  151. package/dist/bootstrap/node-bootstrap.respec.node.d.mts.map +0 -1
  152. package/dist/bootstrap/node-bootstrap.respec.node.mjs.map +0 -1
  153. package/dist/cli/cli-arg-parser.respec.node.d.mts.map +0 -1
  154. package/dist/cli/cli-arg-parser.respec.node.mjs.map +0 -1
  155. package/dist/cli/cli-e2e.respec.node.d.mts.map +0 -1
  156. package/dist/cli/cli-e2e.respec.node.mjs.map +0 -1
  157. package/dist/cli/commands/branch-checkout-cmd.respec.node.d.mts.map +0 -1
  158. package/dist/cli/commands/branch-checkout-cmd.respec.node.mjs.map +0 -1
  159. package/dist/cli/commands/commit-log-cmd.respec.node.d.mts.map +0 -1
  160. package/dist/cli/commands/commit-log-cmd.respec.node.mjs.map +0 -1
  161. package/dist/cli/commands/init-cmd.respec.node.d.mts.map +0 -1
  162. package/dist/cli/commands/init-cmd.respec.node.mjs.map +0 -1
  163. package/dist/cli/commands/status-add-cmd.respec.node.d.mts.map +0 -1
  164. package/dist/cli/commands/status-add-cmd.respec.node.mjs.map +0 -1
  165. package/dist/engine/branch/branch-space.respec.node.d.mts.map +0 -1
  166. package/dist/engine/branch/branch-space.respec.node.mjs.map +0 -1
  167. package/dist/engine/diff/line-diff-helper.respec.node.d.mts.map +0 -1
  168. package/dist/engine/diff/line-diff-helper.respec.node.mjs.map +0 -1
  169. package/dist/engine/filter/glob-helper.respec.node.d.mts.map +0 -1
  170. package/dist/engine/filter/glob-helper.respec.node.mjs.map +0 -1
  171. package/dist/vcs-gib.respec.node.d.mts.map +0 -1
  172. package/dist/vcs-gib.respec.node.mjs.map +0 -1
  173. package/test_runs/001-hello-node/20260728_090100_0001-flow-core-main.md +0 -39
  174. package/test_runs/001-hello-node/20260728_090200_0003-flow-branching-worktree.md +0 -54
  175. package/test_runs/001-hello-node/20260728_090300_0002-flow-selective-add.md +0 -45
  176. package/test_runs/001-hello-node/20260728_142100_0007-flow-edge-cases.md +0 -44
  177. package/test_runs/001-hello-node/20260728_142400_0005-flow-hardcoded-ignores.md +0 -36
  178. package/tools/pack-for-test.mjs +0 -73
  179. /package/src/bootstrap/{node-bootstrap.respec.node.mts → node-bootstrap.respec.mts} +0 -0
  180. /package/src/cli/{cli-arg-parser.respec.node.mts → cli-arg-parser.respec.mts} +0 -0
  181. /package/src/cli/commands/{commit-log-cmd.respec.node.mts → commit-log-cmd.respec.mts} +0 -0
  182. /package/src/cli/commands/{init-cmd.respec.node.mts → init-cmd.respec.mts} +0 -0
  183. /package/src/engine/diff/{line-diff-helper.respec.node.mts → line-diff-helper.respec.mts} +0 -0
  184. /package/src/engine/filter/{glob-helper.respec.node.mts → glob-helper.respec.mts} +0 -0
  185. /package/src/{vcs-gib.respec.node.mts → vcs-gib.respec.mts} +0 -0
@@ -7,21 +7,215 @@
7
7
 
8
8
  import fs from 'node:fs/promises';
9
9
  import path from 'node:path';
10
+ import crypto from 'node:crypto';
10
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 { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
17
+ import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
18
+ import { TransformResult } from '@ibgib/ts-gib/dist/types.mjs';
11
19
  import { MetaspaceService } from '@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs';
12
20
  import { IbGibSpaceAny } from '@ibgib/core-gib/dist/witness/space/space-base-v1.mjs';
13
21
  import { getIbGibsFromCache_fallbackToSpaces } from '@ibgib/core-gib/dist/common/other/ibgib-helper.mjs';
14
22
  import { putInSpace, persistTransformResult, getFromSpace } from '@ibgib/core-gib/dist/witness/space/space-helper.mjs';
15
23
 
16
24
  import { parseSpaceQualifiedIbGibAddr } from '../index/index-helper.mjs';
25
+ import { B2TFS_ITEM_ATOM, getB2tFSItemIb } from './item-atom-helper.mjs';
17
26
  import { GLOBAL_LOG_A_LOT } from '../../vcs-gib-constants.mjs';
18
27
  import {
19
- B2tFSItemIbGib_V1, B2TFS_CHILD_ITEM_REL8N_NAME, BINARY_REL8N_NAME, B2tFSItemDiffInfo
28
+ B2tFSItemIbGib_V1, B2tFSItemData_V1, B2tFSItemRel8ns_V1, B2TFS_CHILD_ITEM_REL8N_NAME, BINARY_REL8N_NAME, B2tFSItemDiffInfo
20
29
  } from './item-types.mjs';
21
30
 
22
31
  const lcFile = `[item-helper]`;
23
32
  const logalot = GLOBAL_LOG_A_LOT;
24
33
 
34
+ export interface CreateB2tFSItemIbGibOpts {
35
+ fsType: 'file' | 'folder';
36
+ name: string;
37
+ data?: Partial<B2tFSItemData_V1>;
38
+ rel8ns?: Partial<B2tFSItemRel8ns_V1>;
39
+ }
40
+
41
+ export interface EvolveB2tFSItemIbGibOpts {
42
+ existingItem: B2tFSItemIbGib_V1;
43
+ dataToUpdate?: Partial<B2tFSItemData_V1>;
44
+ rel8nsToUpdate?: Partial<B2tFSItemRel8ns_V1>;
45
+ rel8nsToRemove?: Partial<B2tFSItemRel8ns_V1>;
46
+ }
47
+
48
+ /**
49
+ * Creates a brand-new B2tFSItemIbGib_V1 node using Factory_V1.firstGen with TJP, DNA, and nCounter.
50
+ * Used ONLY for brand-new files or folders.
51
+ */
52
+ export async function createB2tFSItemIbGib({
53
+ fsType,
54
+ name,
55
+ data,
56
+ rel8ns,
57
+ }: CreateB2tFSItemIbGibOpts): Promise<TransformResult<IbGib_V1>> {
58
+ const lc = `${lcFile}[${createB2tFSItemIbGib.name}]`;
59
+ try {
60
+ if (logalot) {
61
+ console.log(`${lc} starting... (I: 8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d)`);
62
+ }
63
+
64
+ if (!fsType || !name) {
65
+ throw new Error(`fsType and name are required (E: 9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e)`);
66
+ }
67
+
68
+ const nameHash = data?.nameHash || crypto.createHash('sha256').update(name).digest('hex');
69
+ const uuid = data?.uuid || (await getUUID());
70
+ const diffTransactionId = data?.diffTransactionId || (await getUUID());
71
+
72
+ let fileNameSansExt: string | undefined;
73
+ let fileExt: string | undefined;
74
+ if (fsType === 'file') {
75
+ fileNameSansExt = path.parse(name).name;
76
+ fileExt = path.parse(name).ext.replace(/^\./, '');
77
+ }
78
+
79
+ const itemData: B2tFSItemData_V1 = {
80
+ name,
81
+ nameHash,
82
+ fsType,
83
+ diffTransactionId,
84
+ uuid,
85
+ classname: 'B2tFSItemIbGib_V1',
86
+ ...(fsType === 'file' ? { fileNameSansExt, fileExt } : {}),
87
+ ...data,
88
+ };
89
+
90
+ const ib = getB2tFSItemIb(fsType, name, nameHash);
91
+
92
+ const res = await Factory_V1.firstGen({
93
+ parentIbGib: Factory_V1.primitive({ ib: B2TFS_ITEM_ATOM }),
94
+ ib,
95
+ data: itemData,
96
+ rel8ns: rel8ns as any,
97
+ tjp: { timestamp: true, uuid: true },
98
+ dna: true,
99
+ nCounter: true,
100
+ });
101
+
102
+ if (logalot) {
103
+ console.log(`${lc} Created new B2tFSItemIbGib: ${res.newIbGib.ib}^${res.newIbGib.gib} (I: 0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f)`);
104
+ }
105
+
106
+ return res;
107
+ } catch (error) {
108
+ console.error(`${lc} ${extractErrorMsg(error)} (E: 1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a)`);
109
+ throw error;
110
+ } finally {
111
+ if (logalot) {
112
+ console.log(`${lc} complete. (I: 2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b)`);
113
+ }
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Evolves an existing B2tFSItemIbGib_V1 node using mut8 (for data/hash updates)
119
+ * and rel8 (for binary/child link updates) with DNA, nCounter, and timeline tracking.
120
+ * Populates rel8ns.past and rel8ns.ancestor, preserving the item's TJP to generate
121
+ * composite two-part timeline gib addresses (<tjpGib>^<punctiliarGib>).
122
+ */
123
+ export async function evolveB2tFSItemIbGib({
124
+ existingItem,
125
+ dataToUpdate,
126
+ rel8nsToUpdate,
127
+ rel8nsToRemove,
128
+ }: EvolveB2tFSItemIbGibOpts): Promise<TransformResult<IbGib_V1>> {
129
+ const lc = `${lcFile}[${evolveB2tFSItemIbGib.name}]`;
130
+ try {
131
+ if (logalot) {
132
+ console.log(`${lc} starting... (I: 3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c)`);
133
+ }
134
+
135
+ if (!existingItem || !existingItem.ib || !existingItem.gib) {
136
+ throw new Error(`existingItem with valid ib and gib is required (E: 4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d)`);
137
+ }
138
+
139
+ let currentItem: B2tFSItemIbGib_V1 = existingItem;
140
+ const dnas: IbGib_V1[] = [];
141
+ const intermediateIbGibs: IbGib_V1[] = [];
142
+
143
+ // Ensure rel8ns.ancestor is populated if missing
144
+ if (!currentItem.rel8ns?.ancestor || currentItem.rel8ns.ancestor.length === 0) {
145
+ currentItem = {
146
+ ...currentItem,
147
+ rel8ns: {
148
+ ...(currentItem.rel8ns || {}),
149
+ ancestor: [`${B2TFS_ITEM_ATOM}^gib`],
150
+ },
151
+ };
152
+ }
153
+
154
+ const hasDataChanges = dataToUpdate && Object.keys(dataToUpdate).length > 0;
155
+ const hasRel8nsChanges = (rel8nsToUpdate && Object.keys(rel8nsToUpdate).length > 0) ||
156
+ (rel8nsToRemove && Object.keys(rel8nsToRemove).length > 0);
157
+
158
+ // If neither data nor rel8ns explicitly specified, update diffTransactionId to evolve timeline
159
+ const patchData: Partial<B2tFSItemData_V1> = {
160
+ ...(dataToUpdate || {}),
161
+ diffTransactionId: dataToUpdate?.diffTransactionId || (await getUUID()),
162
+ };
163
+
164
+ // Pass 1: mut8 for data/hash updates
165
+ const resMut8 = await mut8({
166
+ src: currentItem,
167
+ dataToAddOrPatch: patchData,
168
+ dna: true,
169
+ nCounter: true,
170
+ });
171
+
172
+ currentItem = resMut8.newIbGib as B2tFSItemIbGib_V1;
173
+ if (resMut8.dnas) { dnas.push(...resMut8.dnas); }
174
+
175
+ // Pass 2: rel8 for binary/child link updates if rel8ns specified
176
+ if (hasRel8nsChanges) {
177
+ intermediateIbGibs.push(currentItem);
178
+
179
+ const resRel8 = await rel8({
180
+ src: currentItem,
181
+ rel8nsToAddByAddr: rel8nsToUpdate as any,
182
+ rel8nsToRemoveByAddr: rel8nsToRemove as any,
183
+ dna: true,
184
+ nCounter: true,
185
+ });
186
+
187
+ currentItem = resRel8.newIbGib as B2tFSItemIbGib_V1;
188
+ if (resRel8.dnas) { dnas.push(...resRel8.dnas); }
189
+ }
190
+
191
+ // Verify rel8ns.ancestor exists on evolved item
192
+ if (!currentItem.rel8ns?.ancestor || currentItem.rel8ns.ancestor.length === 0) {
193
+ currentItem.rel8ns = {
194
+ ...(currentItem.rel8ns || {}),
195
+ ancestor: [`${B2TFS_ITEM_ATOM}^gib`],
196
+ };
197
+ }
198
+
199
+ if (logalot) {
200
+ console.log(`${lc} Evolved B2tFSItemIbGib: ${currentItem.ib}^${currentItem.gib} (I: 5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e)`);
201
+ }
202
+
203
+ return {
204
+ newIbGib: currentItem,
205
+ intermediateIbGibs: intermediateIbGibs.length > 0 ? intermediateIbGibs : undefined,
206
+ dnas: dnas.length > 0 ? dnas : undefined,
207
+ };
208
+ } catch (error) {
209
+ console.error(`${lc} ${extractErrorMsg(error)} (E: 6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f)`);
210
+ throw error;
211
+ } finally {
212
+ if (logalot) {
213
+ console.log(`${lc} complete. (I: 7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a)`);
214
+ }
215
+ }
216
+ }
217
+
218
+
25
219
  function getSpacesArray(metaAny: any): IbGibSpaceAny[] {
26
220
  if (!metaAny || !metaAny.spaces) {
27
221
  return [];
@@ -141,69 +335,86 @@ export async function getIbGibWithMetaspaceFallback({
141
335
  /**
142
336
  * Projects a B2tFS item graph back onto the physical filesystem directory.
143
337
  */
144
- export async function writeB2tFSItemToFS(opts: {
338
+ export async function writeB2tFSItemToFS({
339
+ item,
340
+ destPath,
341
+ space,
342
+ metaspace,
343
+ }: {
145
344
  item: B2tFSItemIbGib_V1;
146
345
  destPath: string;
147
346
  space: IbGibSpaceAny;
148
347
  metaspace: MetaspaceService;
149
348
  }): Promise<void> {
150
349
  const lc = `${lcFile}[${writeB2tFSItemToFS.name}]`;
151
- const { item, destPath, space, metaspace } = opts;
350
+ try {
351
+ if (logalot) {
352
+ console.log(`${lc} starting... (I: 7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d)`);
353
+ }
152
354
 
153
- if (!item || !item.data) {
154
- throw new Error(`Invalid B2tFS item provided (E: 32a09c81b29e4d58)`);
155
- }
355
+ if (!item || !item.data) {
356
+ throw new Error(`Invalid B2tFS item provided (E: 32a09c81b29e4d5867198204b12541a5)`);
357
+ }
156
358
 
157
- const { fsType, name } = item.data;
158
- const targetPath = path.join(destPath, name);
359
+ const { fsType, name } = item.data;
360
+ const targetPath = path.join(destPath, name);
159
361
 
160
- if (fsType === 'folder') {
161
- await fs.mkdir(targetPath, { recursive: true });
162
- const childAddrs = item.rel8ns?.[B2TFS_CHILD_ITEM_REL8N_NAME] || [];
362
+ if (fsType === 'folder') {
363
+ await fs.mkdir(targetPath, { recursive: true });
364
+ const childAddrs = item.rel8ns?.[B2TFS_CHILD_ITEM_REL8N_NAME] || [];
163
365
 
164
- for (const childAddr of childAddrs) {
165
- const childItem = await getIbGibWithMetaspaceFallback({
166
- addr: childAddr,
167
- space,
168
- metaspace,
169
- }) as B2tFSItemIbGib_V1;
366
+ for (const childAddr of childAddrs) {
367
+ const childItem = await getIbGibWithMetaspaceFallback({
368
+ addr: childAddr,
369
+ space,
370
+ metaspace,
371
+ }) as B2tFSItemIbGib_V1;
170
372
 
171
- if (childItem) {
172
- await writeB2tFSItemToFS({
173
- item: childItem,
174
- destPath: targetPath,
373
+ if (childItem) {
374
+ await writeB2tFSItemToFS({
375
+ item: childItem,
376
+ destPath: targetPath,
377
+ space,
378
+ metaspace,
379
+ });
380
+ }
381
+ }
382
+ } else if (fsType === 'file') {
383
+ await fs.mkdir(path.dirname(targetPath), { recursive: true });
384
+ const binAddrs = item.rel8ns?.[BINARY_REL8N_NAME] || [];
385
+ const latestBinAddr = binAddrs.at(-1);
386
+
387
+ if (latestBinAddr) {
388
+ const binIbGib = await getIbGibWithMetaspaceFallback({
389
+ addr: latestBinAddr,
175
390
  space,
176
391
  metaspace,
177
392
  });
178
- }
179
- }
180
- } else if (fsType === 'file') {
181
- const binAddrs = item.rel8ns?.[BINARY_REL8N_NAME] || [];
182
- const latestBinAddr = binAddrs.at(-1);
183
393
 
184
- if (latestBinAddr) {
185
- const binIbGib = await getIbGibWithMetaspaceFallback({
186
- addr: latestBinAddr,
187
- space,
188
- metaspace,
189
- });
394
+ if (binIbGib && binIbGib.data) {
395
+ let fileData: Uint8Array;
396
+ if (typeof binIbGib.data === 'string') {
397
+ fileData = Buffer.from(binIbGib.data, 'base64');
398
+ } else if (binIbGib.data instanceof Uint8Array || Buffer.isBuffer(binIbGib.data)) {
399
+ fileData = binIbGib.data as Uint8Array;
400
+ } else if (typeof binIbGib.data === 'object') {
401
+ const vals = Object.values(binIbGib.data as object);
402
+ fileData = new Uint8Array(vals);
403
+ } else {
404
+ fileData = new Uint8Array(0);
405
+ }
190
406
 
191
- if (binIbGib && binIbGib.data) {
192
- let fileData: Uint8Array;
193
- if (typeof binIbGib.data === 'string') {
194
- fileData = Buffer.from(binIbGib.data, 'base64');
195
- } else if (binIbGib.data instanceof Uint8Array || Buffer.isBuffer(binIbGib.data)) {
196
- fileData = binIbGib.data as Uint8Array;
197
- } else if (typeof binIbGib.data === 'object') {
198
- const vals = Object.values(binIbGib.data as object);
199
- fileData = new Uint8Array(vals);
200
- } else {
201
- fileData = new Uint8Array(0);
407
+ await fs.writeFile(targetPath, fileData);
202
408
  }
203
-
204
- await fs.writeFile(targetPath, fileData);
205
409
  }
206
410
  }
411
+ } catch (error) {
412
+ console.error(`${lc} ${extractErrorMsg(error)} (E: 8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d)`);
413
+ throw error;
414
+ } finally {
415
+ if (logalot) {
416
+ console.log(`${lc} complete. (I: 9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e)`);
417
+ }
207
418
  }
208
419
  }
209
420
 
@@ -212,28 +423,43 @@ export async function writeB2tFSItemToFS(opts: {
212
423
  * 1. Persists all child and parent transform results to space.
213
424
  * 2. Registers new IbGib pointers with metaspace to advance timeline tips.
214
425
  */
215
- export async function applyB2tFSItemDiff(opts: {
426
+ export async function applyB2tFSItemDiff({
427
+ diff,
428
+ space,
429
+ metaspace,
430
+ }: {
216
431
  diff: B2tFSItemDiffInfo;
217
432
  space: IbGibSpaceAny;
218
433
  metaspace: MetaspaceService;
219
434
  }): Promise<void> {
220
435
  const lc = `${lcFile}[${applyB2tFSItemDiff.name}]`;
221
- const { diff, space, metaspace } = opts;
436
+ try {
437
+ if (logalot) {
438
+ console.log(`${lc} starting... (I: 0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d)`);
439
+ }
222
440
 
223
- if (diff.childDiffs && diff.childDiffs.length > 0) {
224
- for (const childDiff of diff.childDiffs) {
225
- await applyB2tFSItemDiff({ diff: childDiff, space, metaspace });
441
+ if (diff.childDiffs && diff.childDiffs.length > 0) {
442
+ for (const childDiff of diff.childDiffs) {
443
+ await applyB2tFSItemDiff({ diff: childDiff, space, metaspace });
444
+ }
226
445
  }
227
- }
228
446
 
229
- const results = diff.transformResults || [];
230
- for (const tr of results) {
231
- await persistTransformResult({ resTransform: tr, space });
232
- }
447
+ const results = diff.transformResults || [];
448
+ for (const tr of results) {
449
+ await persistTransformResult({ resTransform: tr, space });
450
+ }
233
451
 
234
- for (const tr of results) {
235
- if (tr.newIbGib) {
236
- await metaspace.registerNewIbGib({ ibGib: tr.newIbGib });
452
+ for (const tr of results) {
453
+ if (tr.newIbGib) {
454
+ await metaspace.registerNewIbGib({ ibGib: tr.newIbGib });
455
+ }
456
+ }
457
+ } catch (error) {
458
+ console.error(`${lc} ${extractErrorMsg(error)} (E: 1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e)`);
459
+ throw error;
460
+ } finally {
461
+ if (logalot) {
462
+ console.log(`${lc} complete. (I: 2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f)`);
237
463
  }
238
464
  }
239
465
  }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * @module item.respec.node
3
+ *
4
+ * Unit tests for createB2tFSItemIbGib and evolveB2tFSItemIbGib timeline transforms.
5
+ */
6
+
7
+ import {
8
+ respecfully, ifWe, iReckon
9
+ } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
10
+ import { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
11
+ import { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';
12
+
13
+ import { createB2tFSItemIbGib, evolveB2tFSItemIbGib } from './item-helper.mjs';
14
+ import { B2tFSItemIbGib_V1 } from './item-types.mjs';
15
+
16
+ const lc = `[apps/vcs-gib/src/engine/item/item.respec.node.mts]`;
17
+
18
+ await respecfully(lc, `B2tFS Item Timeline Transforms`, async () => {
19
+
20
+ await respecfully(lc, `createB2tFSItemIbGib`, async () => {
21
+ await ifWe(lc, `creates brand-new file item with TJP and DNA`, async () => {
22
+ const res = await createB2tFSItemIbGib({
23
+ fsType: 'file',
24
+ name: 'test.txt',
25
+ data: {
26
+ fileHash: 'hash_abc_123',
27
+ },
28
+ });
29
+
30
+ const item = res.newIbGib as B2tFSItemIbGib_V1;
31
+ iReckon(lc, item).isGonnaBeTruthy();
32
+ iReckon(lc, item.data?.name).willEqual('test.txt');
33
+ iReckon(lc, item.data?.fileHash).willEqual('hash_abc_123');
34
+ iReckon(lc, item.rel8ns?.ancestor).isGonnaBeTruthy();
35
+ iReckon(lc, item.rel8ns?.tjp).isGonnaBeTruthy();
36
+
37
+ const gibInfo = getGibInfo({ gib: item.gib });
38
+ iReckon(lc, gibInfo.tjpGib).isGonnaBeTruthy();
39
+ iReckon(lc, gibInfo.punctiliarHash).isGonnaBeTruthy();
40
+ });
41
+
42
+ await ifWe(lc, `creates brand-new folder item`, async () => {
43
+ const res = await createB2tFSItemIbGib({
44
+ fsType: 'folder',
45
+ name: 'src',
46
+ });
47
+
48
+ const item = res.newIbGib as B2tFSItemIbGib_V1;
49
+ iReckon(lc, item).isGonnaBeTruthy();
50
+ iReckon(lc, item.data?.fsType).willEqual('folder');
51
+ iReckon(lc, item.data?.name).willEqual('src');
52
+ });
53
+ });
54
+
55
+ await respecfully(lc, `evolveB2tFSItemIbGib`, async () => {
56
+ await ifWe(lc, `evolves existing item via mut8/rel8, generating two-part timeline gib and rel8ns.past`, async () => {
57
+ const createRes = await createB2tFSItemIbGib({
58
+ fsType: 'file',
59
+ name: 'config.json',
60
+ data: {
61
+ fileHash: 'hash_v1',
62
+ },
63
+ });
64
+
65
+ const initialItem = createRes.newIbGib as B2tFSItemIbGib_V1;
66
+ const initialAddr = getIbGibAddr({ ibGib: initialItem });
67
+ const initialGibInfo = getGibInfo({ gib: initialItem.gib });
68
+
69
+ // Evolve item with updated fileHash
70
+ const evolveRes = await evolveB2tFSItemIbGib({
71
+ existingItem: initialItem,
72
+ dataToUpdate: {
73
+ fileHash: 'hash_v2',
74
+ },
75
+ });
76
+
77
+ const evolvedItem = evolveRes.newIbGib as B2tFSItemIbGib_V1;
78
+ const evolvedAddr = getIbGibAddr({ ibGib: evolvedItem });
79
+ const evolvedGibInfo = getGibInfo({ gib: evolvedItem.gib });
80
+
81
+ iReckon(lc, evolvedItem.data?.fileHash).willEqual('hash_v2');
82
+ iReckon(lc, evolvedItem.rel8ns?.past).includes(initialAddr);
83
+ iReckon(lc, evolvedItem.rel8ns?.ancestor).isGonnaBeTruthy();
84
+ iReckon(lc, evolvedItem.rel8ns?.tjp).willEqual(initialItem.rel8ns?.tjp);
85
+
86
+ // Verify two-part composite timeline gib address
87
+ iReckon(lc, evolvedGibInfo.tjpGib).willEqual(initialGibInfo.tjpGib);
88
+ iReckon(lc, evolvedGibInfo.punctiliarHash).isGonnaBeTruthy();
89
+ iReckon(lc, evolvedGibInfo.punctiliarHash !== initialGibInfo.punctiliarHash).isGonnaBeTrue();
90
+ });
91
+ });
92
+ });