@ibgib/node-gib 0.0.2

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 (127) hide show
  1. package/.ibgibignore +30 -0
  2. package/CHANGELOG.md +18 -0
  3. package/README.md +16 -0
  4. package/dist/assumptions.respec.d.mts +2 -0
  5. package/dist/assumptions.respec.d.mts.map +1 -0
  6. package/dist/assumptions.respec.mjs +41 -0
  7. package/dist/assumptions.respec.mjs.map +1 -0
  8. package/dist/common/prompt-functions.d.mts +89 -0
  9. package/dist/common/prompt-functions.d.mts.map +1 -0
  10. package/dist/common/prompt-functions.mjs +418 -0
  11. package/dist/common/prompt-functions.mjs.map +1 -0
  12. package/dist/constants.d.mts +3 -0
  13. package/dist/constants.d.mts.map +1 -0
  14. package/dist/constants.mjs +3 -0
  15. package/dist/constants.mjs.map +1 -0
  16. package/dist/foo.d.mts +2 -0
  17. package/dist/foo.d.mts.map +1 -0
  18. package/dist/foo.mjs +19 -0
  19. package/dist/foo.mjs.map +1 -0
  20. package/dist/helpers.d.mts +2 -0
  21. package/dist/helpers.d.mts.map +1 -0
  22. package/dist/helpers.mjs +3 -0
  23. package/dist/helpers.mjs.map +1 -0
  24. package/dist/respec-gib.node.d.mts +2 -0
  25. package/dist/respec-gib.node.d.mts.map +1 -0
  26. package/dist/respec-gib.node.mjs +213 -0
  27. package/dist/respec-gib.node.mjs.map +1 -0
  28. package/dist/spec-helper.node.respec.d.mts +13 -0
  29. package/dist/spec-helper.node.respec.d.mts.map +1 -0
  30. package/dist/spec-helper.node.respec.mjs +50 -0
  31. package/dist/spec-helper.node.respec.mjs.map +1 -0
  32. package/dist/types.d.mts +2 -0
  33. package/dist/types.d.mts.map +1 -0
  34. package/dist/types.mjs +2 -0
  35. package/dist/types.mjs.map +1 -0
  36. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace-helper.d.mts +35 -0
  37. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace-helper.d.mts.map +1 -0
  38. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace-helper.mjs +267 -0
  39. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace-helper.mjs.map +1 -0
  40. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.d.mts +98 -0
  41. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.d.mts.map +1 -0
  42. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.mjs +160 -0
  43. package/dist/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.mjs.map +1 -0
  44. package/dist/witness/space/node-filesystem-space/node-filesystem-space-helper.d.mts +42 -0
  45. package/dist/witness/space/node-filesystem-space/node-filesystem-space-helper.d.mts.map +1 -0
  46. package/dist/witness/space/node-filesystem-space/node-filesystem-space-helper.mjs +312 -0
  47. package/dist/witness/space/node-filesystem-space/node-filesystem-space-helper.mjs.map +1 -0
  48. package/dist/witness/space/node-filesystem-space/node-filesystem-space-types.d.mts +84 -0
  49. package/dist/witness/space/node-filesystem-space/node-filesystem-space-types.d.mts.map +1 -0
  50. package/dist/witness/space/node-filesystem-space/node-filesystem-space-types.mjs +65 -0
  51. package/dist/witness/space/node-filesystem-space/node-filesystem-space-types.mjs.map +1 -0
  52. package/dist/witness/space/node-filesystem-space/node-filesystem-space-v1.d.mts +77 -0
  53. package/dist/witness/space/node-filesystem-space/node-filesystem-space-v1.d.mts.map +1 -0
  54. package/dist/witness/space/node-filesystem-space/node-filesystem-space-v1.mjs +672 -0
  55. package/dist/witness/space/node-filesystem-space/node-filesystem-space-v1.mjs.map +1 -0
  56. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-constants.d.mts +5 -0
  57. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-constants.d.mts.map +1 -0
  58. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-constants.mjs +5 -0
  59. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-constants.mjs.map +1 -0
  60. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-types.d.mts +30 -0
  61. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-types.d.mts.map +1 -0
  62. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-types.mjs +38 -0
  63. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-types.mjs.map +1 -0
  64. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-v1.d.mts +64 -0
  65. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-v1.d.mts.map +1 -0
  66. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-v1.mjs +353 -0
  67. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-v1.mjs.map +1 -0
  68. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_createAndInit.node-indexed-filesystem-space-v1.respec.d.mts +2 -0
  69. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_createAndInit.node-indexed-filesystem-space-v1.respec.d.mts.map +1 -0
  70. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_createAndInit.node-indexed-filesystem-space-v1.respec.mjs +52 -0
  71. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_createAndInit.node-indexed-filesystem-space-v1.respec.mjs.map +1 -0
  72. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_persistTransformResult.node-indexed-filesystem-space-v1.respec.d.mts +2 -0
  73. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_persistTransformResult.node-indexed-filesystem-space-v1.respec.d.mts.map +1 -0
  74. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_persistTransformResult.node-indexed-filesystem-space-v1.respec.mjs +53 -0
  75. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_persistTransformResult.node-indexed-filesystem-space-v1.respec.mjs.map +1 -0
  76. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_putGetDelete.node-indexed-filesystem-space-v1.respec.d.mts +2 -0
  77. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_putGetDelete.node-indexed-filesystem-space-v1.respec.d.mts.map +1 -0
  78. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_putGetDelete.node-indexed-filesystem-space-v1.respec.mjs +59 -0
  79. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_putGetDelete.node-indexed-filesystem-space-v1.respec.mjs.map +1 -0
  80. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-indexed-filesystem-space-v1.respec.d.mts +2 -0
  81. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-indexed-filesystem-space-v1.respec.d.mts.map +1 -0
  82. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-indexed-filesystem-space-v1.respec.mjs +55 -0
  83. package/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-indexed-filesystem-space-v1.respec.mjs.map +1 -0
  84. package/dist/witness/space/node-filesystem-space/respec/testSpace_createAndInit.node-filesystem-space-v1.respec.d.mts +2 -0
  85. package/dist/witness/space/node-filesystem-space/respec/testSpace_createAndInit.node-filesystem-space-v1.respec.d.mts.map +1 -0
  86. package/dist/witness/space/node-filesystem-space/respec/testSpace_createAndInit.node-filesystem-space-v1.respec.mjs +67 -0
  87. package/dist/witness/space/node-filesystem-space/respec/testSpace_createAndInit.node-filesystem-space-v1.respec.mjs.map +1 -0
  88. package/dist/witness/space/node-filesystem-space/respec/testSpace_persistTransformResult.node-filesystem-space-v1.respec.d.mts +2 -0
  89. package/dist/witness/space/node-filesystem-space/respec/testSpace_persistTransformResult.node-filesystem-space-v1.respec.d.mts.map +1 -0
  90. package/dist/witness/space/node-filesystem-space/respec/testSpace_persistTransformResult.node-filesystem-space-v1.respec.mjs +67 -0
  91. package/dist/witness/space/node-filesystem-space/respec/testSpace_persistTransformResult.node-filesystem-space-v1.respec.mjs.map +1 -0
  92. package/dist/witness/space/node-filesystem-space/respec/testSpace_putGetDelete.node-filesystem-space-v1.respec.d.mts +2 -0
  93. package/dist/witness/space/node-filesystem-space/respec/testSpace_putGetDelete.node-filesystem-space-v1.respec.d.mts.map +1 -0
  94. package/dist/witness/space/node-filesystem-space/respec/testSpace_putGetDelete.node-filesystem-space-v1.respec.mjs +68 -0
  95. package/dist/witness/space/node-filesystem-space/respec/testSpace_putGetDelete.node-filesystem-space-v1.respec.mjs.map +1 -0
  96. package/dist/witness/space/node-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-filesystem-space-v1.respec.d.mts +2 -0
  97. package/dist/witness/space/node-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-filesystem-space-v1.respec.d.mts.map +1 -0
  98. package/dist/witness/space/node-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-filesystem-space-v1.respec.mjs +69 -0
  99. package/dist/witness/space/node-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-filesystem-space-v1.respec.mjs.map +1 -0
  100. package/generate-version-file.js +29 -0
  101. package/package.json +41 -0
  102. package/src/assumptions.respec.mts +51 -0
  103. package/src/common/prompt-functions.mts +429 -0
  104. package/src/constants.mts +2 -0
  105. package/src/foo.mts +13 -0
  106. package/src/helpers.mts +5 -0
  107. package/src/respec-gib.node.mts +201 -0
  108. package/src/spec-helper.node.respec.mts +50 -0
  109. package/src/types.mts +0 -0
  110. package/src/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace-helper.mts +290 -0
  111. package/src/witness/space/metaspace/metaspace-nodespace/metaspace-nodespace.mts +166 -0
  112. package/src/witness/space/node-filesystem-space/node-filesystem-space-helper.mts +298 -0
  113. package/src/witness/space/node-filesystem-space/node-filesystem-space-types.mts +150 -0
  114. package/src/witness/space/node-filesystem-space/node-filesystem-space-v1.mts +672 -0
  115. package/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-constants.mts +6 -0
  116. package/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-types.mts +68 -0
  117. package/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-v1.mts +403 -0
  118. package/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_createAndInit.node-indexed-filesystem-space-v1.respec.mts +68 -0
  119. package/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_persistTransformResult.node-indexed-filesystem-space-v1.respec.mts +70 -0
  120. package/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_putGetDelete.node-indexed-filesystem-space-v1.respec.mts +72 -0
  121. package/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-indexed-filesystem-space-v1.respec.mts +72 -0
  122. package/src/witness/space/node-filesystem-space/respec/testSpace_createAndInit.node-filesystem-space-v1.respec.mts +87 -0
  123. package/src/witness/space/node-filesystem-space/respec/testSpace_persistTransformResult.node-filesystem-space-v1.respec.mts +88 -0
  124. package/src/witness/space/node-filesystem-space/respec/testSpace_putGetDelete.node-filesystem-space-v1.respec.mts +88 -0
  125. package/src/witness/space/node-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-filesystem-space-v1.respec.mts +90 -0
  126. package/tsconfig.json +17 -0
  127. package/tsconfig.test.json +10 -0
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @module node-indexed-filesystem-space-types
3
+ */
4
+
5
+ import { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
6
+ import {
7
+ NodeFilesystemSpaceData_V1,
8
+ NodeFilesystemSpaceRel8ns_V1,
9
+ } from '../node-filesystem-space-types.mjs';
10
+ import { DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS, IBGIB_SPACE_NAME_DEFAULT, ZERO_SPACE_ID } from '@ibgib/core-gib/dist/witness/space/space-constants.mjs';
11
+ import {
12
+ DEFAULT_LONG_PATH_LENGTH, IBGIB_BASE_DIR, IBGIB_BASE_SUBPATH,
13
+ IBGIB_BIN_SUBPATH, IBGIB_DNA_SUBPATH, IBGIB_ENCODING, IBGIB_IBGIBS_SUBPATH,
14
+ IBGIB_LONG_SUBPATH, IBGIB_META_SUBPATH, IBGIB_SPACE_SUBPATH_DEFAULT
15
+ } from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-constants.mjs';
16
+ import { DEFAULT_INDEXED_FILESYSTEM_SPACE_DESCRIPTION } from './node-indexed-filesystem-space-constants.mjs';
17
+
18
+ /**
19
+ * Data for indexed filesystem space.
20
+ */
21
+ export interface NodeIndexedFilesystemSpaceData_V1 extends NodeFilesystemSpaceData_V1 {
22
+ }
23
+
24
+ /**
25
+ * Rel8ns for indexed filesystem space.
26
+ */
27
+ export interface NodeIndexedFilesystemSpaceRel8ns_V1 extends NodeFilesystemSpaceRel8ns_V1 {
28
+ }
29
+
30
+ /**
31
+ * IbGib representing the indexed filesystem space.
32
+ * Does not descend from a NodeFilesystemSpace ibgib type, just the base IbGib_V1.
33
+ */
34
+ export interface NodeIndexedFilesystemSpaceIbGib_V1
35
+ extends IbGib_V1<NodeIndexedFilesystemSpaceData_V1, NodeIndexedFilesystemSpaceRel8ns_V1> {
36
+ }
37
+
38
+ /**
39
+ * Used in bootstrapping.
40
+ *
41
+ * If you change this, please bump the version
42
+ *
43
+ * (but of course won't be the end of the world when this doesn't happen).
44
+ */
45
+ export const DEFAULT_NODE_INDEXED_FILESYSTEM_SPACE_DATA_V1: NodeIndexedFilesystemSpaceData_V1 = {
46
+ version: '2',
47
+ uuid: ZERO_SPACE_ID,
48
+ name: IBGIB_SPACE_NAME_DEFAULT,
49
+ classname: 'NodeIndexedFilesystemSpace_V1',
50
+ baseDir: IBGIB_BASE_DIR,
51
+ encoding: IBGIB_ENCODING,
52
+ baseSubPath: IBGIB_BASE_SUBPATH,
53
+ spaceSubPath: IBGIB_SPACE_SUBPATH_DEFAULT,
54
+ ibgibsSubPath: IBGIB_IBGIBS_SUBPATH,
55
+ metaSubPath: IBGIB_META_SUBPATH,
56
+ binSubPath: IBGIB_BIN_SUBPATH,
57
+ dnaSubPath: IBGIB_DNA_SUBPATH,
58
+ longSubPath: IBGIB_LONG_SUBPATH,
59
+ mitigateLongPaths: false,
60
+ longPathLength: DEFAULT_LONG_PATH_LENGTH,
61
+ persistOptsAndResultIbGibs: false,
62
+ validateIbGibAddrsMatchIbGibs: false,
63
+ longPollingIntervalMs: DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS,
64
+ allowPrimitiveArgs: false,
65
+ catchAllErrors: true,
66
+ description: DEFAULT_INDEXED_FILESYSTEM_SPACE_DESCRIPTION,
67
+ trace: false,
68
+ }
@@ -0,0 +1,403 @@
1
+ import { existsSync, mkdirSync } from 'node:fs';
2
+ import { writeFile, rm, readFile, readdir } from 'node:fs/promises';
3
+ import { default as pathUtils, join } from 'path';
4
+
5
+ import { clone, extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
6
+ import { getIbAndGib, getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';
7
+ import { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';
8
+ import { IbGib_V1, IbGibRel8ns_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';
9
+ import { toDto, isBinary, } from '@ibgib/core-gib/dist/common/other/ibgib-helper.mjs';
10
+ import {
11
+ PutIbGibFileOpts, PutIbGibFileResult, GetIbGibFileOpts, GetIbGibFileResult,
12
+ DeleteIbGibFileOpts, DeleteIbGibFilesResult,
13
+ } from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-types.mjs';
14
+ import { isMetaStone, parseMetaStoneIb } from '@ibgib/core-gib/dist/common/meta-stone/meta-stone-helper.mjs';
15
+
16
+ import { GLOBAL_LOG_A_LOT } from '../../../../constants.mjs';
17
+ import { NodeFilesystemSpace_V1 } from '../node-filesystem-space-v1.mjs';
18
+ import { DEFAULT_NODE_FILESYSTEM_SPACE_DATA_V1, NodeFilesystemSpaceData_V1, NodeFilesystemSpaceRel8ns_V1 } from '../node-filesystem-space-types.mjs';
19
+ import { DEFAULT_NODE_INDEXED_FILESYSTEM_SPACE_DATA_V1 } from './node-indexed-filesystem-space-types.mjs';
20
+
21
+ const logalot = GLOBAL_LOG_A_LOT;
22
+
23
+ const INDEX_DIR_NAME = '.idx';
24
+ const MAP_EXTENSION = '.map';
25
+
26
+ /**
27
+ * Mapping from Full IbGib Address -> Short Filename
28
+ */
29
+ interface IndexMap {
30
+ [addr: string]: string;
31
+ }
32
+
33
+ /**
34
+ * Robust filesystem space that uses a distributed index folder strategy (.idx)
35
+ * to avoid Windows MAX_PATH issues while maintaining TJP grouping.
36
+ */
37
+ export class NodeIndexedFilesystemSpace_V1<
38
+ TData extends NodeFilesystemSpaceData_V1 = NodeFilesystemSpaceData_V1,
39
+ TRel8ns extends NodeFilesystemSpaceRel8ns_V1 = NodeFilesystemSpaceRel8ns_V1
40
+ > extends NodeFilesystemSpace_V1<TData, TRel8ns> {
41
+
42
+ protected override lc: string = `[${NodeIndexedFilesystemSpace_V1.name}]`;
43
+
44
+ /**
45
+ * in case the caller tries to override the classname. This should be overridden in any descendant classes
46
+ */
47
+ get classname(): string { return NodeIndexedFilesystemSpace_V1.name; }
48
+
49
+ /**
50
+ * Factory static method to create the space with the given
51
+ * `dto` param's ibGib properties.
52
+ *
53
+ * We do this because when we persist this space (and its settings
54
+ * located in `data`), we do not save the actual class instantiation
55
+ * but just the ibgib properties. Use this factory method to
56
+ * create a new space instance and rehydrate from that saved dto.
57
+ *
58
+ * ## notes
59
+ *
60
+ * * DTO stands for data transfer object.
61
+ *
62
+ * @param dto space ibGib dto that we're going to load from
63
+ * @returns newly created space built upon `dto`
64
+ */
65
+ static async createFromDto<
66
+ TData extends NodeFilesystemSpaceData_V1 = NodeFilesystemSpaceData_V1,
67
+ TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1
68
+ >(dto: IbGib_V1<TData, TRel8ns>): Promise<NodeFilesystemSpace_V1<TData, TRel8ns>> {
69
+ const lc = `[${NodeIndexedFilesystemSpace_V1.name}][${this.createFromDto.name}]`;
70
+ if (logalot) { console.log(`${lc}`); }
71
+ const space = new NodeIndexedFilesystemSpace_V1<TData, TRel8ns>(dto.data); // shouldn't have to do this
72
+ await space.initialized;
73
+ await space.loadIbGibDto(dto);
74
+ return space;
75
+ }
76
+
77
+ constructor(
78
+ // /**
79
+ // * Default predicate value when putting an unknown ibGib.
80
+ // *
81
+ // * ## notes
82
+ // *
83
+ // * So when a repo witnesses another ibGib, it either defaults to
84
+ // * storing that ibGib or not storing that ibGib. This is what that
85
+ // * is referring to. If it's optimistic, then it stores any ibGib by
86
+ // * default and it passes its put predicate.
87
+ // */
88
+ // public optimisticPut: boolean = true,
89
+ initialData?: TData,
90
+ initialRel8ns?: TRel8ns,
91
+ ) {
92
+ super(initialData ?? clone(DEFAULT_NODE_INDEXED_FILESYSTEM_SPACE_DATA_V1), initialRel8ns);
93
+ const lc = `${this.lc}[ctor]`;
94
+
95
+ // try {
96
+ // if (logalot) { console.log(`${lc} starting...`); }
97
+ // this.initialize();
98
+ // } catch (error) {
99
+ // console.error(`${lc} ${extractErrorMsg(error)}`);
100
+ // throw error;
101
+ // } finally {
102
+ // if (logalot) { console.log(`${lc} complete.`); }
103
+ // }
104
+ }
105
+
106
+ /**
107
+ * Overrides the path building to be "Index Aware".
108
+ * In this implementation, the "path" returned is the bucket directory.
109
+ * The actual filename is resolved via the index.
110
+ */
111
+ protected override async buildPath(opts: any): Promise<string> {
112
+ const { addr, isDna, isBin, addrIsForAMetaStone } = opts;
113
+ const { ib, gib } = getIbAndGib({ ibGibAddr: addr });
114
+
115
+ // Primitive ibgibs do not need bucket indexing, delegate to original un-indexed logic
116
+ if (gib === 'gib') {
117
+ return super.buildPath(opts);
118
+ }
119
+
120
+ let subPath = '';
121
+ if (isDna) { subPath = this.data!.dnaSubPath!; }
122
+ else if (isBin) { subPath = this.data!.binSubPath!; }
123
+ else if (addrIsForAMetaStone || isMetaStone({ addr })) { subPath = this.data!.metaSubPath!; }
124
+ else { subPath = this.data!.ibgibsSubPath!; }
125
+
126
+ return this.buildPath_withSubPath({ addr, subPath });
127
+ }
128
+
129
+ protected async buildPath_withSubPath(opts: { addr: string, subPath: string }): Promise<string> {
130
+ const { addr, subPath } = opts;
131
+ const { ib, gib } = getIbAndGib({ ibGibAddr: addr });
132
+
133
+ // Deterministic Bucket based on first 6 chars of gib (or ib if gib is primitive)
134
+ let hashBase = (gib && gib !== 'gib') ? gib : ib;
135
+
136
+ // Special handling for metastones: group by target TJP
137
+ if (isMetaStone({ addr })) {
138
+ hashBase = parseMetaStoneIb({ ib }).tjpGib;
139
+ } else {
140
+ const gibInfo = getGibInfo({ ibGibAddr: addr });
141
+ if (gibInfo.tjpGib) {
142
+ hashBase = gibInfo.tjpGib;
143
+ }
144
+ }
145
+
146
+ const bucket1 = hashBase.substring(0, 3).toUpperCase();
147
+ const bucket2 = hashBase.substring(3, 6).toUpperCase();
148
+
149
+ // Root/Space/SubPath/B1/B2
150
+ return pathUtils.join(
151
+ this.data!.baseSubPath!,
152
+ this.data!.spaceSubPath!,
153
+ subPath,
154
+ bucket1,
155
+ bucket2
156
+ );
157
+ }
158
+
159
+ /**
160
+ * Resolves the actual filename for an address using the index.
161
+ */
162
+ protected async resolveFilename(bucketPath: string, addr: string): Promise<string | undefined> {
163
+ const mapFilePath = this.getMapFilePath(bucketPath, addr);
164
+ if (!existsSync(mapFilePath)) { return undefined; }
165
+
166
+ try {
167
+ const content = await readFile(mapFilePath, 'utf8');
168
+ const map: IndexMap = JSON.parse(content);
169
+ return map[addr];
170
+ } catch (error) {
171
+ console.error(`${this.lc} Error reading map file ${mapFilePath}: ${extractErrorMsg(error)}`);
172
+ return undefined;
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Updates the index with a new mapping.
178
+ */
179
+ protected async updateIndex(bucketPath: string, addr: string, filename: string): Promise<void> {
180
+ const indexDir = join(bucketPath, INDEX_DIR_NAME);
181
+ if (!existsSync(indexDir)) {
182
+ mkdirSync(indexDir, { recursive: true });
183
+ }
184
+
185
+ const mapFilePath = this.getMapFilePath(bucketPath, addr);
186
+ let map: IndexMap = {};
187
+
188
+ if (existsSync(mapFilePath)) {
189
+ try {
190
+ const content = await readFile(mapFilePath, 'utf8');
191
+ map = JSON.parse(content);
192
+ } catch (error) {
193
+ console.warn(`${this.lc} Map file ${mapFilePath} corrupted, overwriting. (W: 4129bd5e921d4d8e87491d9e2a84423)`);
194
+ }
195
+ }
196
+
197
+ map[addr] = filename;
198
+ await writeFile(mapFilePath, JSON.stringify(map, null, 2));
199
+ }
200
+
201
+ protected getMapFilePath(bucketPath: string, addr: string): string {
202
+ const { gib } = getIbAndGib({ ibGibAddr: addr });
203
+ // Use next 4 chars of hash for map filename distribution
204
+ const mapName = (gib.length > 10 ? gib.substring(6, 10) : 'default').toUpperCase();
205
+ return join(bucketPath, INDEX_DIR_NAME, `${mapName}${MAP_EXTENSION}`);
206
+ }
207
+
208
+ protected override async putFile(opts: PutIbGibFileOpts): Promise<PutIbGibFileResult> {
209
+ const lc = `${this.lc}[putFile]`;
210
+ const { ibGib, isDna } = opts;
211
+ if (!ibGib) { throw new Error('ibGib required'); }
212
+
213
+ const addr = getIbGibAddr({ ibGib });
214
+ const { gib } = getIbAndGib({ ibGibAddr: addr });
215
+
216
+ // Primitive ibgibs bypass indexing completely
217
+ if (gib === 'gib') {
218
+ return super.putFile(opts);
219
+ }
220
+
221
+ const bucketPath = join(this.data!.baseDir, await this.buildPath({
222
+ addr, isDna, isBin: isBinary({ addr }), addrIsForAMetaStone: isMetaStone({ addr })
223
+ }));
224
+
225
+ if (!existsSync(bucketPath)) {
226
+ mkdirSync(bucketPath, { recursive: true });
227
+ }
228
+
229
+ // 1. Resolve or Generate Filename
230
+ let filename = await this.resolveFilename(bucketPath, addr);
231
+ if (!filename) {
232
+ // Generate a random but safe filename
233
+ const randomId = Math.random().toString(36).substring(2, 8);
234
+ filename = `${randomId}.json`;
235
+ }
236
+
237
+ const fullPath = join(bucketPath, filename);
238
+
239
+ // 2. Write Data
240
+ try {
241
+ const data = JSON.stringify(toDto({ ibGib }), null, 2);
242
+ await writeFile(fullPath, data, this.data!.encoding as BufferEncoding);
243
+
244
+ // 3. Update Index
245
+ await this.updateIndex(bucketPath, addr, filename);
246
+ return { success: true };
247
+ } catch (error) {
248
+ return { success: false, errorMsg: extractErrorMsg(error) };
249
+ }
250
+ }
251
+
252
+ protected override async getFile(opts: GetIbGibFileOpts): Promise<GetIbGibFileResult> {
253
+ const lc = `${this.lc}[getFile]`;
254
+ const addr = opts.addr;
255
+ if (!addr) { throw new Error('addr required'); }
256
+
257
+ const { ib, gib } = getIbAndGib({ ibGibAddr: addr });
258
+
259
+ // Primitive ibgibs bypass indexing completely
260
+ if (gib === 'gib') {
261
+ return super.getFile(opts);
262
+ }
263
+
264
+ const isBin = isBinary({ addr });
265
+ const addrIsMetaStone = isMetaStone({ addr });
266
+
267
+ // Build list of subpaths to try
268
+ const subPathsToTry: string[] = [];
269
+
270
+ if (opts.isDna) {
271
+ subPathsToTry.push(this.data!.dnaSubPath!);
272
+ } else if (isBin) {
273
+ subPathsToTry.push(this.data!.binSubPath!);
274
+ } else if (addrIsMetaStone) {
275
+ subPathsToTry.push(this.data!.metaSubPath!);
276
+ } else {
277
+ // Might be DNA if not explicitly told, check dna first as optimization if ib is a transform
278
+ const { ib } = getIbAndGib({ ibGibAddr: addr });
279
+ const knownTransformIbs = ['fork', 'mut8', 'rel8', 'plan'];
280
+ const addrMightBeDna = knownTransformIbs.some(x => x === ib || x.startsWith(ib + ' '));
281
+
282
+ if (addrMightBeDna) {
283
+ subPathsToTry.push(this.data!.dnaSubPath!);
284
+ }
285
+ subPathsToTry.push(this.data!.ibgibsSubPath!);
286
+ if (!addrMightBeDna) {
287
+ subPathsToTry.push(this.data!.dnaSubPath!);
288
+ }
289
+ }
290
+
291
+ for (const subPath of subPathsToTry) {
292
+ const relBucketPath = await this.buildPath_withSubPath({ addr, subPath });
293
+ const bucketPath = join(this.data!.baseDir, relBucketPath);
294
+ const filename = await this.resolveFilename(bucketPath, addr);
295
+ if (filename) {
296
+ const fullPath = join(bucketPath, filename);
297
+ if (existsSync(fullPath)) {
298
+ try {
299
+ const content = await readFile(fullPath, 'utf8');
300
+ const ibGib = JSON.parse(content) as IbGib_V1;
301
+ return { success: true, ibGib };
302
+ } catch (error) {
303
+ if (logalot) { console.error(`${lc} error reading ${fullPath}: ${extractErrorMsg(error)}`); }
304
+ }
305
+ }
306
+ }
307
+ }
308
+
309
+ return { success: true };
310
+ }
311
+
312
+ protected override async deleteFile(opts: DeleteIbGibFileOpts): Promise<DeleteIbGibFilesResult> {
313
+ const addr = opts.addr;
314
+ if (!addr) { throw new Error('addr required'); }
315
+
316
+ const { gib } = getIbAndGib({ ibGibAddr: addr });
317
+
318
+ // Primitive ibgibs bypass indexing completely
319
+ if (gib === 'gib') {
320
+ return super.deleteFile(opts);
321
+ }
322
+
323
+ const bucketPath = join(this.data!.baseDir, await this.buildPath({
324
+ addr, isDna: opts.isDna, isBin: isBinary({ addr }), addrIsForAMetaStone: isMetaStone({ addr })
325
+ }));
326
+
327
+ const filename = await this.resolveFilename(bucketPath, addr);
328
+ if (!filename) { return { success: true }; }
329
+
330
+ const fullPath = join(bucketPath, filename);
331
+ try {
332
+ if (existsSync(fullPath)) {
333
+ await rm(fullPath);
334
+ }
335
+
336
+ // Remove from index
337
+ const mapFilePath = this.getMapFilePath(bucketPath, addr);
338
+ if (existsSync(mapFilePath)) {
339
+ const content = await readFile(mapFilePath, 'utf8');
340
+ const map: IndexMap = JSON.parse(content);
341
+ delete map[addr];
342
+ if (Object.keys(map).length === 0) {
343
+ await rm(mapFilePath);
344
+ } else {
345
+ await writeFile(mapFilePath, JSON.stringify(map, null, 2));
346
+ }
347
+ }
348
+ return { success: true };
349
+ } catch (error) {
350
+ return { success: false, errorMsg: extractErrorMsg(error) };
351
+ }
352
+ }
353
+
354
+ /**
355
+ * Overrides getMetaStoneAddrs to look in the bucketed directory.
356
+ */
357
+ protected override async getMetaStoneAddrs(opts: {
358
+ ibGibAddr: string,
359
+ tjpGib: string,
360
+ fnFilterIb?: (ib: string) => boolean,
361
+ }): Promise<string[]> {
362
+ const { ibGibAddr, tjpGib, fnFilterIb } = opts;
363
+ const lc = `${this.lc}[getMetaStoneAddrs]`;
364
+
365
+ // Get the bucket path for metastones for this TJP
366
+ const relBucketPath = await this.buildPath({
367
+ addr: ibGibAddr,
368
+ addrIsForAMetaStone: true
369
+ });
370
+ const bucketPath = join(this.data!.baseDir, relBucketPath);
371
+
372
+ if (!existsSync(bucketPath)) { return []; }
373
+
374
+ const indexDir = join(bucketPath, INDEX_DIR_NAME);
375
+ if (!existsSync(indexDir)) { return []; }
376
+
377
+ const metaStoneAddrs: string[] = [];
378
+
379
+ try {
380
+ const mapFiles = (await readdir(indexDir)).filter(f => f.endsWith(MAP_EXTENSION));
381
+
382
+ for (const mapFile of mapFiles) {
383
+ const content = await readFile(join(indexDir, mapFile), 'utf8');
384
+ const map: IndexMap = JSON.parse(content);
385
+ for (const addr of Object.keys(map)) {
386
+ if (isMetaStone({ addr })) {
387
+ const { ib } = getIbAndGib({ ibGibAddr: addr });
388
+ const metaStoneInfo = parseMetaStoneIb({ ib });
389
+ if (metaStoneInfo.tjpGib === tjpGib) {
390
+ if (!fnFilterIb || fnFilterIb(ib)) {
391
+ metaStoneAddrs.push(addr);
392
+ }
393
+ }
394
+ }
395
+ }
396
+ }
397
+ } catch (error) {
398
+ if (logalot) { console.error(`${lc} error reading metastone index: ${extractErrorMsg(error)}`); }
399
+ }
400
+
401
+ return metaStoneAddrs;
402
+ }
403
+ }
@@ -0,0 +1,68 @@
1
+ import { rm } from 'node:fs/promises';
2
+
3
+ import {
4
+ respecfully,
5
+ } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
6
+ const maam = `[${import.meta.url}]`, sir = maam;
7
+
8
+ import {
9
+ testSpace_createAndInit,
10
+ } from '@ibgib/core-gib/dist/witness/space/space-respec-helper.mjs';
11
+ import {
12
+ getCurrentFilename, specGetBaseDir, specGetBaseSubPath, specGetSpaceDescription,
13
+ specGetSpaceId, specGetSpaceName
14
+ } from '@ibgib/core-gib/dist/spec-helper.node.respec.mjs';
15
+ import { NodeIndexedFilesystemSpace_V1 } from '../node-indexed-filesystem-space-v1.mjs';
16
+ import { IBGIB_ENCODING } from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-constants.mjs';
17
+ import { NodeFilesystemSpaceData_V1 } from '../../node-filesystem-space-types.mjs';
18
+
19
+ const logalot = false;
20
+ const TEST_BASE_DIR_ROOT = (await getCurrentFilename(import.meta.url)).replace('testSpace_', '').substring(0, 18) + '_troot';
21
+ const lc = `[${TEST_BASE_DIR_ROOT}]`;
22
+
23
+ const fnGetInitialRel8ns = () => {
24
+ return Promise.resolve(undefined);
25
+ };
26
+
27
+ const fnGetSpace = async (initialData: any, initialRel8ns: any) => {
28
+ const space = new NodeIndexedFilesystemSpace_V1(initialData, initialRel8ns);
29
+ return space;
30
+ };
31
+
32
+ await respecfully(sir, `[${NodeIndexedFilesystemSpace_V1.name} specs]`, async () => {
33
+
34
+ console.log('---'); // output buffer
35
+ console.log('---'); // output buffer
36
+ await testSpace_createAndInit({
37
+ respecfulTitle: sir,
38
+ fnGetInitialSpaceData: async () => {
39
+ const uuid = await specGetSpaceId();
40
+ return {
41
+ version: '1',
42
+ classname: NodeIndexedFilesystemSpace_V1.name,
43
+ uuid,
44
+ name: specGetSpaceName(uuid),
45
+ description: specGetSpaceDescription(uuid),
46
+ baseDir: specGetBaseDir(TEST_BASE_DIR_ROOT, uuid, logalot, lc),
47
+ baseSubPath: specGetBaseSubPath(TEST_BASE_DIR_ROOT, uuid, logalot, lc),
48
+ binSubPath: 'bin',
49
+ dnaSubPath: 'dna',
50
+ encoding: IBGIB_ENCODING,
51
+ ibgibsSubPath: 'ibgibs',
52
+ metaSubPath: 'meta',
53
+ spaceSubPath: 'space',
54
+ allowPrimitiveArgs: false,
55
+ catchAllErrors: false,
56
+ longPollingIntervalMs: 500,
57
+ persistOptsAndResultIbGibs: false,
58
+ trace: false,
59
+ validateIbGibAddrsMatchIbGibs: false,
60
+ } satisfies NodeFilesystemSpaceData_V1;
61
+ },
62
+ fnGetInitialSpaceRel8ns: fnGetInitialRel8ns,
63
+ fnGetSpace,
64
+ })
65
+ console.log('---'); // output buffer
66
+ console.log('---'); // output buffer
67
+
68
+ });
@@ -0,0 +1,70 @@
1
+ import { rm } from 'node:fs/promises';
2
+
3
+ import {
4
+ respecfully,
5
+ respecfullyDear,
6
+ } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
7
+ const maam = `[${import.meta.url}]`, sir = maam;
8
+
9
+ import {
10
+ testSpace_persistTransformResult,
11
+ } from '@ibgib/core-gib/dist/witness/space/space-respec-helper.mjs';
12
+ import {
13
+ getCurrentFilename, specGetBaseDir, specGetBaseSubPath, specGetSpaceDescription,
14
+ specGetSpaceId, specGetSpaceName
15
+ } from '@ibgib/core-gib/dist/spec-helper.node.respec.mjs';
16
+ import { NodeIndexedFilesystemSpace_V1 } from '../node-indexed-filesystem-space-v1.mjs';
17
+ import { IBGIB_ENCODING } from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-constants.mjs';
18
+ import { NodeFilesystemSpaceData_V1 } from '../../node-filesystem-space-types.mjs';
19
+
20
+ const logalot = false;
21
+ const TEST_BASE_DIR_ROOT = (await getCurrentFilename(import.meta.url)).replace('testSpace_', '').substring(0, 18) + '_troot';
22
+ const lc = `[${TEST_BASE_DIR_ROOT}]`;
23
+
24
+ const fnGetInitialRel8ns = () => {
25
+ return Promise.resolve(undefined);
26
+ };
27
+
28
+ const fnGetSpace = async (initialData: any, initialRel8ns: any) => {
29
+ const space = new NodeIndexedFilesystemSpace_V1(initialData, initialRel8ns);
30
+ return space;
31
+ };
32
+
33
+ await respecfully(sir, `[${NodeIndexedFilesystemSpace_V1.name} specs]`, async () => {
34
+
35
+ console.log('---'); // output buffer
36
+ console.log('---'); // output buffer
37
+ await testSpace_persistTransformResult({
38
+ respecfulTitle: sir,
39
+ // shortcircuitRespec: true,
40
+ fnGetInitialSpaceData: async () => {
41
+ const uuid = await specGetSpaceId();
42
+ return {
43
+ version: '1',
44
+ classname: NodeIndexedFilesystemSpace_V1.name,
45
+ uuid,
46
+ name: specGetSpaceName(uuid),
47
+ description: specGetSpaceDescription(uuid),
48
+ baseDir: specGetBaseDir(TEST_BASE_DIR_ROOT, uuid, logalot, lc),
49
+ baseSubPath: specGetBaseSubPath(TEST_BASE_DIR_ROOT, uuid, logalot, lc),
50
+ binSubPath: 'bin',
51
+ dnaSubPath: 'dna',
52
+ encoding: IBGIB_ENCODING,
53
+ ibgibsSubPath: 'ibgibs',
54
+ metaSubPath: 'meta',
55
+ spaceSubPath: 'space',
56
+ allowPrimitiveArgs: false,
57
+ catchAllErrors: false,
58
+ longPollingIntervalMs: 500,
59
+ persistOptsAndResultIbGibs: false,
60
+ trace: false,
61
+ validateIbGibAddrsMatchIbGibs: false,
62
+ } satisfies NodeFilesystemSpaceData_V1;
63
+ },
64
+ fnGetInitialSpaceRel8ns: fnGetInitialRel8ns,
65
+ fnGetSpace,
66
+ })
67
+ console.log('---'); // output buffer
68
+ console.log('---'); // output buffer
69
+
70
+ });
@@ -0,0 +1,72 @@
1
+ import { rm } from 'node:fs/promises';
2
+
3
+ import {
4
+ respecfully,
5
+ } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
6
+ const maam = `[${import.meta.url}]`, sir = maam;
7
+
8
+ import { testSpace_putGetDelete, } from '@ibgib/core-gib/dist/witness/space/space-respec-helper.mjs';
9
+ import {
10
+ getCurrentFilename, specGetBaseDir, specGetBaseSubPath,
11
+ specGetSpaceDescription, specGetSpaceId, specGetSpaceName
12
+ } from '@ibgib/core-gib/dist/spec-helper.node.respec.mjs';
13
+ import { IBGIB_ENCODING } from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-constants.mjs';
14
+
15
+ import { NodeIndexedFilesystemSpace_V1 } from '../node-indexed-filesystem-space-v1.mjs';
16
+
17
+ const logalot = false;
18
+ const TEST_BASE_DIR_ROOT = (await getCurrentFilename(import.meta.url)).replace('testSpace_', '').substring(0, 18) + '_troot';
19
+ const lc = `[${TEST_BASE_DIR_ROOT}]`;
20
+
21
+ const fnGetInitialRel8ns = () => {
22
+ return Promise.resolve(undefined);
23
+ };
24
+
25
+ const fnGetSpace = async (initialData: any, initialRel8ns: any) => {
26
+ const space = new NodeIndexedFilesystemSpace_V1(initialData, initialRel8ns);
27
+ return space;
28
+ };
29
+
30
+ await respecfully(sir, `[${lc} respecs]`, async () => {
31
+ // Clean up after tests
32
+ // lastOfAll(sir, async () => {
33
+ // await rm(TEST_BASE_DIR_ROOT, {
34
+ // recursive: true,
35
+ // force: true,
36
+ // });
37
+ // });
38
+
39
+ console.log('---'); // output buffer
40
+ console.log('---'); // output buffer
41
+ await testSpace_putGetDelete({
42
+ respecfulTitle: sir,
43
+ fnGetInitialSpaceData: async () => {
44
+ const uuid = await specGetSpaceId();
45
+ return {
46
+ version: '1',
47
+ classname: 'NodeIndexedFilesystemSpace_V1',
48
+ uuid,
49
+ name: specGetSpaceName(uuid),
50
+ description: specGetSpaceDescription(uuid),
51
+ baseDir: specGetBaseDir(TEST_BASE_DIR_ROOT, uuid, logalot, lc),
52
+ baseSubPath: specGetBaseSubPath(TEST_BASE_DIR_ROOT, uuid, logalot, lc),
53
+ binSubPath: 'bin',
54
+ dnaSubPath: 'dna',
55
+ encoding: IBGIB_ENCODING,
56
+ ibgibsSubPath: 'ibgibs',
57
+ metaSubPath: 'meta',
58
+ spaceSubPath: 'space',
59
+ allowPrimitiveArgs: false,
60
+ catchAllErrors: false,
61
+ longPollingIntervalMs: 500,
62
+ persistOptsAndResultIbGibs: false,
63
+ trace: false,
64
+ validateIbGibAddrsMatchIbGibs: false,
65
+ };
66
+ },
67
+ fnGetInitialSpaceRel8ns: fnGetInitialRel8ns,
68
+ fnGetSpace,
69
+ });
70
+ console.log('---'); // output buffer
71
+ console.log('---'); // output buffer
72
+ });