zen-fs-config 0.4.0 → 0.4.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.
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +32 -18
- package/dist/index.mjs +32 -18
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -399,7 +399,13 @@ declare class ConfigRepo implements IConfigRepo {
|
|
|
399
399
|
readMetaFile<T>(path: string): Promise<T | null>;
|
|
400
400
|
/** Path for a single backend descriptor: .meta/backends/{id}.json */
|
|
401
401
|
backendFilePath(id: string): string;
|
|
402
|
-
/**
|
|
402
|
+
/**
|
|
403
|
+
* Read all backend descriptors from .meta/backends/*.json.
|
|
404
|
+
*
|
|
405
|
+
* If duplicate backends are detected (same type + options but different id),
|
|
406
|
+
* only the first one (sorted by id) is kept and the rest are removed
|
|
407
|
+
* (including their version sidecar files).
|
|
408
|
+
*/
|
|
403
409
|
readAllBackendDescriptors(): Promise<BackendDescriptor[]>;
|
|
404
410
|
/** Write a single backend descriptor as .meta/backends/{id}.json */
|
|
405
411
|
writeBackendDescriptor(desc: BackendDescriptor): Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -399,7 +399,13 @@ declare class ConfigRepo implements IConfigRepo {
|
|
|
399
399
|
readMetaFile<T>(path: string): Promise<T | null>;
|
|
400
400
|
/** Path for a single backend descriptor: .meta/backends/{id}.json */
|
|
401
401
|
backendFilePath(id: string): string;
|
|
402
|
-
/**
|
|
402
|
+
/**
|
|
403
|
+
* Read all backend descriptors from .meta/backends/*.json.
|
|
404
|
+
*
|
|
405
|
+
* If duplicate backends are detected (same type + options but different id),
|
|
406
|
+
* only the first one (sorted by id) is kept and the rest are removed
|
|
407
|
+
* (including their version sidecar files).
|
|
408
|
+
*/
|
|
403
409
|
readAllBackendDescriptors(): Promise<BackendDescriptor[]>;
|
|
404
410
|
/** Write a single backend descriptor as .meta/backends/{id}.json */
|
|
405
411
|
writeBackendDescriptor(desc: BackendDescriptor): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -485,7 +485,6 @@ var BACKENDS_DIR = `${META_DIR}/backends`;
|
|
|
485
485
|
var CONFLICTS_DIR = `${META_DIR}/.conflicts`;
|
|
486
486
|
var DELETIONS_DIR = `${META_DIR}/.deleted`;
|
|
487
487
|
var NODES_DIR = "/nodes";
|
|
488
|
-
var NODE_ID_FILE = `${NODES_DIR}/.node-id`;
|
|
489
488
|
var LOCAL_IDB_BACKEND_ID = "local-idb";
|
|
490
489
|
function tombstoneFileName(filePath) {
|
|
491
490
|
return filePath.replace(/^\//, "").replace(/\//g, "__").replace(/\./g, "++") + ".json";
|
|
@@ -1080,7 +1079,13 @@ var ConfigRepo = class {
|
|
|
1080
1079
|
backendFilePath(id) {
|
|
1081
1080
|
return `${BACKENDS_DIR}/${id}.json`;
|
|
1082
1081
|
}
|
|
1083
|
-
/**
|
|
1082
|
+
/**
|
|
1083
|
+
* Read all backend descriptors from .meta/backends/*.json.
|
|
1084
|
+
*
|
|
1085
|
+
* If duplicate backends are detected (same type + options but different id),
|
|
1086
|
+
* only the first one (sorted by id) is kept and the rest are removed
|
|
1087
|
+
* (including their version sidecar files).
|
|
1088
|
+
*/
|
|
1084
1089
|
async readAllBackendDescriptors() {
|
|
1085
1090
|
try {
|
|
1086
1091
|
const entries = await this.cachedFS.readdir(BACKENDS_DIR);
|
|
@@ -1089,11 +1094,33 @@ var ConfigRepo = class {
|
|
|
1089
1094
|
if (!entry.endsWith(".json")) continue;
|
|
1090
1095
|
try {
|
|
1091
1096
|
const raw = await this.cachedFS.readFile(`${BACKENDS_DIR}/${entry}`);
|
|
1092
|
-
|
|
1097
|
+
const desc = JSON.parse(new TextDecoder().decode(toUint8Array(raw)));
|
|
1098
|
+
if (desc.id && desc.type) {
|
|
1099
|
+
descriptors.push(desc);
|
|
1100
|
+
}
|
|
1093
1101
|
} catch {
|
|
1094
1102
|
}
|
|
1095
1103
|
}
|
|
1096
|
-
|
|
1104
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1105
|
+
const duplicates = [];
|
|
1106
|
+
descriptors.sort((a, b) => a.id.localeCompare(b.id));
|
|
1107
|
+
for (const desc of descriptors) {
|
|
1108
|
+
const key = `${desc.type}:${JSON.stringify(desc.options ?? {})}`;
|
|
1109
|
+
if (seen.has(key)) {
|
|
1110
|
+
duplicates.push(desc.id);
|
|
1111
|
+
} else {
|
|
1112
|
+
seen.set(key, desc.id);
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
if (duplicates.length > 0) {
|
|
1116
|
+
console.log(
|
|
1117
|
+
`[ConfigRepo] readAllBackendDescriptors: removing ${duplicates.length} duplicate(s): ${duplicates.join(", ")}`
|
|
1118
|
+
);
|
|
1119
|
+
for (const dupId of duplicates) {
|
|
1120
|
+
await this.removeBackendDescriptor(dupId);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
return descriptors.filter((d) => !duplicates.includes(d.id));
|
|
1097
1124
|
} catch {
|
|
1098
1125
|
return [];
|
|
1099
1126
|
}
|
|
@@ -1291,22 +1318,9 @@ async function createConfigRepo(appId, options = {}) {
|
|
|
1291
1318
|
const allBackends = await tempRepo.readAllBackendDescriptors();
|
|
1292
1319
|
console.log(`[createConfigRepo] Replica backends: ${allBackends.map((b) => b.id).join(", ") || "(none)"}`);
|
|
1293
1320
|
let nodeId = options.nodeId;
|
|
1294
|
-
if (!nodeId && typeof process !== "undefined" && process.env?.NODE_ID) {
|
|
1295
|
-
nodeId = process.env.NODE_ID;
|
|
1296
|
-
}
|
|
1297
|
-
if (!nodeId) {
|
|
1298
|
-
try {
|
|
1299
|
-
const raw = await cachedFS.readFile(NODE_ID_FILE);
|
|
1300
|
-
nodeId = new TextDecoder().decode(toUint8Array(raw)).trim();
|
|
1301
|
-
} catch {
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
1321
|
if (!nodeId) {
|
|
1305
1322
|
nodeId = `node-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1306
|
-
|
|
1307
|
-
await cachedFS.writeFile(NODE_ID_FILE, new TextEncoder().encode(nodeId));
|
|
1308
|
-
} catch {
|
|
1309
|
-
}
|
|
1323
|
+
console.log(`[createConfigRepo] Generated nodeId: ${nodeId}`);
|
|
1310
1324
|
}
|
|
1311
1325
|
const serializer = createSerializerChain(options.serializer);
|
|
1312
1326
|
const repo = new ConfigRepo(
|
package/dist/index.mjs
CHANGED
|
@@ -433,7 +433,6 @@ var BACKENDS_DIR = `${META_DIR}/backends`;
|
|
|
433
433
|
var CONFLICTS_DIR = `${META_DIR}/.conflicts`;
|
|
434
434
|
var DELETIONS_DIR = `${META_DIR}/.deleted`;
|
|
435
435
|
var NODES_DIR = "/nodes";
|
|
436
|
-
var NODE_ID_FILE = `${NODES_DIR}/.node-id`;
|
|
437
436
|
var LOCAL_IDB_BACKEND_ID = "local-idb";
|
|
438
437
|
function tombstoneFileName(filePath) {
|
|
439
438
|
return filePath.replace(/^\//, "").replace(/\//g, "__").replace(/\./g, "++") + ".json";
|
|
@@ -1028,7 +1027,13 @@ var ConfigRepo = class {
|
|
|
1028
1027
|
backendFilePath(id) {
|
|
1029
1028
|
return `${BACKENDS_DIR}/${id}.json`;
|
|
1030
1029
|
}
|
|
1031
|
-
/**
|
|
1030
|
+
/**
|
|
1031
|
+
* Read all backend descriptors from .meta/backends/*.json.
|
|
1032
|
+
*
|
|
1033
|
+
* If duplicate backends are detected (same type + options but different id),
|
|
1034
|
+
* only the first one (sorted by id) is kept and the rest are removed
|
|
1035
|
+
* (including their version sidecar files).
|
|
1036
|
+
*/
|
|
1032
1037
|
async readAllBackendDescriptors() {
|
|
1033
1038
|
try {
|
|
1034
1039
|
const entries = await this.cachedFS.readdir(BACKENDS_DIR);
|
|
@@ -1037,11 +1042,33 @@ var ConfigRepo = class {
|
|
|
1037
1042
|
if (!entry.endsWith(".json")) continue;
|
|
1038
1043
|
try {
|
|
1039
1044
|
const raw = await this.cachedFS.readFile(`${BACKENDS_DIR}/${entry}`);
|
|
1040
|
-
|
|
1045
|
+
const desc = JSON.parse(new TextDecoder().decode(toUint8Array(raw)));
|
|
1046
|
+
if (desc.id && desc.type) {
|
|
1047
|
+
descriptors.push(desc);
|
|
1048
|
+
}
|
|
1041
1049
|
} catch {
|
|
1042
1050
|
}
|
|
1043
1051
|
}
|
|
1044
|
-
|
|
1052
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1053
|
+
const duplicates = [];
|
|
1054
|
+
descriptors.sort((a, b) => a.id.localeCompare(b.id));
|
|
1055
|
+
for (const desc of descriptors) {
|
|
1056
|
+
const key = `${desc.type}:${JSON.stringify(desc.options ?? {})}`;
|
|
1057
|
+
if (seen.has(key)) {
|
|
1058
|
+
duplicates.push(desc.id);
|
|
1059
|
+
} else {
|
|
1060
|
+
seen.set(key, desc.id);
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
if (duplicates.length > 0) {
|
|
1064
|
+
console.log(
|
|
1065
|
+
`[ConfigRepo] readAllBackendDescriptors: removing ${duplicates.length} duplicate(s): ${duplicates.join(", ")}`
|
|
1066
|
+
);
|
|
1067
|
+
for (const dupId of duplicates) {
|
|
1068
|
+
await this.removeBackendDescriptor(dupId);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
return descriptors.filter((d) => !duplicates.includes(d.id));
|
|
1045
1072
|
} catch {
|
|
1046
1073
|
return [];
|
|
1047
1074
|
}
|
|
@@ -1239,22 +1266,9 @@ async function createConfigRepo(appId, options = {}) {
|
|
|
1239
1266
|
const allBackends = await tempRepo.readAllBackendDescriptors();
|
|
1240
1267
|
console.log(`[createConfigRepo] Replica backends: ${allBackends.map((b) => b.id).join(", ") || "(none)"}`);
|
|
1241
1268
|
let nodeId = options.nodeId;
|
|
1242
|
-
if (!nodeId && typeof process !== "undefined" && process.env?.NODE_ID) {
|
|
1243
|
-
nodeId = process.env.NODE_ID;
|
|
1244
|
-
}
|
|
1245
|
-
if (!nodeId) {
|
|
1246
|
-
try {
|
|
1247
|
-
const raw = await cachedFS.readFile(NODE_ID_FILE);
|
|
1248
|
-
nodeId = new TextDecoder().decode(toUint8Array(raw)).trim();
|
|
1249
|
-
} catch {
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
1269
|
if (!nodeId) {
|
|
1253
1270
|
nodeId = `node-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1254
|
-
|
|
1255
|
-
await cachedFS.writeFile(NODE_ID_FILE, new TextEncoder().encode(nodeId));
|
|
1256
|
-
} catch {
|
|
1257
|
-
}
|
|
1271
|
+
console.log(`[createConfigRepo] Generated nodeId: ${nodeId}`);
|
|
1258
1272
|
}
|
|
1259
1273
|
const serializer = createSerializerChain(options.serializer);
|
|
1260
1274
|
const repo = new ConfigRepo(
|