@ibgib/vcs-gib 0.0.6 → 0.0.17
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.
- package/README.md +24 -2
- package/VCS_CLI_USER_GUIDE.md +2 -2
- package/dist/AUTO-GENERATED-version.d.mts +1 -1
- package/dist/AUTO-GENERATED-version.d.mts.map +1 -1
- package/dist/AUTO-GENERATED-version.mjs +1 -1
- package/dist/AUTO-GENERATED-version.mjs.map +1 -1
- package/dist/bootstrap/node-bootstrap.d.mts.map +1 -1
- package/dist/bootstrap/node-bootstrap.mjs +6 -0
- package/dist/bootstrap/node-bootstrap.mjs.map +1 -1
- package/dist/cli/cli-arg-parser.d.mts +3 -0
- package/dist/cli/cli-arg-parser.d.mts.map +1 -1
- package/dist/cli/cli-arg-parser.mjs +13 -1
- package/dist/cli/cli-arg-parser.mjs.map +1 -1
- package/dist/cli/cli-constants.d.mts +5 -0
- package/dist/cli/cli-constants.d.mts.map +1 -1
- package/dist/cli/cli-constants.mjs +23 -0
- package/dist/cli/cli-constants.mjs.map +1 -1
- package/dist/cli/cli-e2e.respec.node.mjs +1 -1
- package/dist/cli/cli-e2e.respec.node.mjs.map +1 -1
- package/dist/cli/commands/add-cmd.d.mts.map +1 -1
- package/dist/cli/commands/add-cmd.mjs +33 -28
- package/dist/cli/commands/add-cmd.mjs.map +1 -1
- package/dist/cli/commands/branch-checkout-cmd.respec.node.mjs +70 -0
- package/dist/cli/commands/branch-checkout-cmd.respec.node.mjs.map +1 -1
- package/dist/cli/commands/branch-cmd.d.mts +2 -1
- package/dist/cli/commands/branch-cmd.d.mts.map +1 -1
- package/dist/cli/commands/branch-cmd.mjs +57 -6
- package/dist/cli/commands/branch-cmd.mjs.map +1 -1
- package/dist/cli/commands/checkout-cmd.d.mts.map +1 -1
- package/dist/cli/commands/checkout-cmd.mjs +23 -11
- package/dist/cli/commands/checkout-cmd.mjs.map +1 -1
- package/dist/cli/commands/commit-cmd.d.mts.map +1 -1
- package/dist/cli/commands/commit-cmd.mjs +24 -21
- package/dist/cli/commands/commit-cmd.mjs.map +1 -1
- package/dist/cli/commands/reset-cmd.d.mts +21 -0
- package/dist/cli/commands/reset-cmd.d.mts.map +1 -0
- package/dist/cli/commands/reset-cmd.mjs +93 -0
- package/dist/cli/commands/reset-cmd.mjs.map +1 -0
- package/dist/cli/commands/reset-restore-cmd.respec.node.d.mts +7 -0
- package/dist/cli/commands/reset-restore-cmd.respec.node.d.mts.map +1 -0
- package/dist/cli/commands/reset-restore-cmd.respec.node.mjs +185 -0
- package/dist/cli/commands/reset-restore-cmd.respec.node.mjs.map +1 -0
- package/dist/cli/commands/restore-cmd.d.mts +22 -0
- package/dist/cli/commands/restore-cmd.d.mts.map +1 -0
- package/dist/cli/commands/restore-cmd.mjs +115 -0
- package/dist/cli/commands/restore-cmd.mjs.map +1 -0
- package/dist/cli/commands/status-add-cmd.respec.node.mjs +24 -0
- package/dist/cli/commands/status-add-cmd.respec.node.mjs.map +1 -1
- package/dist/cli/vcs-cli-main.d.mts.map +1 -1
- package/dist/cli/vcs-cli-main.mjs +29 -3
- package/dist/cli/vcs-cli-main.mjs.map +1 -1
- package/dist/engine/branch/branch-graph-helper.d.mts +12 -3
- package/dist/engine/branch/branch-graph-helper.d.mts.map +1 -1
- package/dist/engine/branch/branch-graph-helper.mjs +50 -18
- package/dist/engine/branch/branch-graph-helper.mjs.map +1 -1
- package/dist/engine/branch/branch-space-helper.d.mts +1 -0
- package/dist/engine/branch/branch-space-helper.d.mts.map +1 -1
- package/dist/engine/branch/branch-space-helper.mjs +1 -0
- package/dist/engine/branch/branch-space-helper.mjs.map +1 -1
- package/dist/engine/branch/branch-space.respec.node.mjs +11 -6
- package/dist/engine/branch/branch-space.respec.node.mjs.map +1 -1
- package/dist/engine/index/index-helper.d.mts +35 -0
- package/dist/engine/index/index-helper.d.mts.map +1 -1
- package/dist/engine/index/index-helper.mjs +241 -0
- package/dist/engine/index/index-helper.mjs.map +1 -1
- package/dist/engine/item/item-helper.d.mts +29 -3
- package/dist/engine/item/item-helper.d.mts.map +1 -1
- package/dist/engine/item/item-helper.mjs +234 -56
- package/dist/engine/item/item-helper.mjs.map +1 -1
- package/dist/engine/item/item.respec.node.d.mts +7 -0
- package/dist/engine/item/item.respec.node.d.mts.map +1 -0
- package/dist/engine/item/item.respec.node.mjs +75 -0
- package/dist/engine/item/item.respec.node.mjs.map +1 -0
- package/package.json +3 -3
- package/src/AUTO-GENERATED-version.mts +1 -1
- package/src/bootstrap/node-bootstrap.mts +2 -0
- package/src/cli/cli-arg-parser.mts +15 -0
- package/src/cli/cli-constants.mts +26 -0
- package/src/cli/cli-e2e.respec.node.mts +2 -2
- package/src/cli/commands/add-cmd.mts +36 -26
- package/src/cli/commands/branch-checkout-cmd.respec.node.mts +79 -0
- package/src/cli/commands/branch-cmd.mts +75 -6
- package/src/cli/commands/checkout-cmd.mts +25 -14
- package/src/cli/commands/commit-cmd.mts +30 -23
- package/src/cli/commands/reset-cmd.mts +128 -0
- package/src/cli/commands/reset-restore-cmd.respec.node.mts +222 -0
- package/src/cli/commands/restore-cmd.mts +155 -0
- package/src/cli/commands/status-add-cmd.respec.node.mts +27 -0
- package/src/cli/vcs-cli-main.mts +29 -3
- package/src/engine/branch/branch-graph-helper.mts +66 -18
- package/src/engine/branch/branch-space-helper.mts +6 -0
- package/src/engine/branch/branch-space.respec.node.mts +12 -6
- package/src/engine/index/index-helper.mts +324 -0
- package/src/engine/item/item-helper.mts +284 -58
- package/src/engine/item/item.respec.node.mts +92 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/test_runs/001-hello-node/20260728_090100_0001-flow-core-main.md +0 -39
- package/test_runs/001-hello-node/20260728_090200_0003-flow-branching-worktree.md +0 -54
- package/test_runs/001-hello-node/20260728_090300_0002-flow-selective-add.md +0 -45
- package/test_runs/001-hello-node/20260728_142100_0007-flow-edge-cases.md +0 -44
- package/test_runs/001-hello-node/20260728_142400_0005-flow-hardcoded-ignores.md +0 -36
- package/tools/pack-for-test.mjs +0 -73
|
@@ -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(
|
|
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
|
-
|
|
350
|
+
try {
|
|
351
|
+
if (logalot) {
|
|
352
|
+
console.log(`${lc} starting... (I: 7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d)`);
|
|
353
|
+
}
|
|
152
354
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
355
|
+
if (!item || !item.data) {
|
|
356
|
+
throw new Error(`Invalid B2tFS item provided (E: 32a09c81b29e4d5867198204b12541a5)`);
|
|
357
|
+
}
|
|
156
358
|
|
|
157
|
-
|
|
158
|
-
|
|
359
|
+
const { fsType, name } = item.data;
|
|
360
|
+
const targetPath = path.join(destPath, name);
|
|
159
361
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
362
|
+
if (fsType === 'folder') {
|
|
363
|
+
await fs.mkdir(targetPath, { recursive: true });
|
|
364
|
+
const childAddrs = item.rel8ns?.[B2TFS_CHILD_ITEM_REL8N_NAME] || [];
|
|
163
365
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
436
|
+
try {
|
|
437
|
+
if (logalot) {
|
|
438
|
+
console.log(`${lc} starting... (I: 0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d)`);
|
|
439
|
+
}
|
|
222
440
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
447
|
+
const results = diff.transformResults || [];
|
|
448
|
+
for (const tr of results) {
|
|
449
|
+
await persistTransformResult({ resTransform: tr, space });
|
|
450
|
+
}
|
|
233
451
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
+
});
|