@le-space/core 0.1.15 → 0.1.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/index.d.ts +21 -0
- package/index.js +188 -9
- package/package.json +2 -2
package/index.d.ts
CHANGED
|
@@ -320,6 +320,9 @@ declare function retainSuccessfulDeployments(args: {
|
|
|
320
320
|
retainedRecords: RetentionRecord[];
|
|
321
321
|
prunedRecords: RetentionRecord[];
|
|
322
322
|
forgetHashes: string[];
|
|
323
|
+
forgottenHashes: string[];
|
|
324
|
+
outstandingForgetHashes: string[];
|
|
325
|
+
forgetStatuses: Record<string, string>;
|
|
323
326
|
forgetResult: {
|
|
324
327
|
sender: string;
|
|
325
328
|
itemHash: string;
|
|
@@ -327,6 +330,24 @@ declare function retainSuccessfulDeployments(args: {
|
|
|
327
330
|
httpStatus: number;
|
|
328
331
|
status: _shared_aleph_shared_types.MessageStatus;
|
|
329
332
|
} | null;
|
|
333
|
+
followUpForgetResults: {
|
|
334
|
+
hash: string;
|
|
335
|
+
result: Awaited<ReturnType<typeof forgetAlephMessages>>;
|
|
336
|
+
}[];
|
|
337
|
+
forgetStageResults: {
|
|
338
|
+
stage: "instances" | "dependents";
|
|
339
|
+
hashes: string[];
|
|
340
|
+
skipped?: boolean;
|
|
341
|
+
skippedReason?: string;
|
|
342
|
+
forgottenHashes: string[];
|
|
343
|
+
outstandingForgetHashes: string[];
|
|
344
|
+
statuses: Record<string, string>;
|
|
345
|
+
forgetResult: Awaited<ReturnType<typeof forgetAlephMessages>> | null;
|
|
346
|
+
followUpForgetResults: Array<{
|
|
347
|
+
hash: string;
|
|
348
|
+
result: Awaited<ReturnType<typeof forgetAlephMessages>>;
|
|
349
|
+
}>;
|
|
350
|
+
}[];
|
|
330
351
|
}>;
|
|
331
352
|
|
|
332
353
|
declare function createPortForwardAggregateContent(args: {
|
package/index.js
CHANGED
|
@@ -841,6 +841,26 @@ function retentionRecordId(record) {
|
|
|
841
841
|
function hashesFromRetentionRecord(record) {
|
|
842
842
|
return [record.instance_item_hash, record.rootfs_item_hash, record.site_item_hash].filter(Boolean);
|
|
843
843
|
}
|
|
844
|
+
function uniqueHashes(hashes) {
|
|
845
|
+
return [...new Set(hashes.filter(Boolean))];
|
|
846
|
+
}
|
|
847
|
+
function dependentHashesFromRetentionRecord(record) {
|
|
848
|
+
return [record.rootfs_item_hash, record.site_item_hash].filter(Boolean);
|
|
849
|
+
}
|
|
850
|
+
function splitForgetStages(args) {
|
|
851
|
+
const instanceForgetHashes = uniqueHashes(args.prunedRecords.map((record) => record.instance_item_hash)).filter(
|
|
852
|
+
(hash) => !args.retainedHashes.has(hash)
|
|
853
|
+
);
|
|
854
|
+
const dependentForgetHashes = uniqueHashes([
|
|
855
|
+
...args.prunedRecords.flatMap(dependentHashesFromRetentionRecord),
|
|
856
|
+
...args.extraForgetHashes
|
|
857
|
+
]).filter((hash) => !args.retainedHashes.has(hash) && !instanceForgetHashes.includes(hash));
|
|
858
|
+
return {
|
|
859
|
+
instanceForgetHashes,
|
|
860
|
+
dependentForgetHashes,
|
|
861
|
+
orderedForgetHashes: [...instanceForgetHashes, ...dependentForgetHashes]
|
|
862
|
+
};
|
|
863
|
+
}
|
|
844
864
|
async function fetchAggregateKey(args) {
|
|
845
865
|
const requestUrl = new URL(`/api/v0/aggregates/${args.address}.json`, args.apiHost ?? "https://api2.aleph.im");
|
|
846
866
|
requestUrl.searchParams.set("keys", args.key);
|
|
@@ -893,6 +913,98 @@ async function publishAggregateKey(args) {
|
|
|
893
913
|
httpStatus
|
|
894
914
|
};
|
|
895
915
|
}
|
|
916
|
+
async function fetchMessageStatus(args) {
|
|
917
|
+
const requestUrl = new URL(`/api/v0/messages/${args.hash}`, args.apiHost ?? "https://api2.aleph.im");
|
|
918
|
+
const response = await args.fetch(requestUrl.toString(), { cache: "no-cache" });
|
|
919
|
+
if (response.status === 404) return "missing";
|
|
920
|
+
if (!response.ok) return "unknown";
|
|
921
|
+
const payload = await response.json();
|
|
922
|
+
return asString3(payload?.status) ?? "unknown";
|
|
923
|
+
}
|
|
924
|
+
async function classifyForgetHashes(args) {
|
|
925
|
+
const statuses = {};
|
|
926
|
+
for (const hash of args.hashes) {
|
|
927
|
+
statuses[hash] = await fetchMessageStatus({
|
|
928
|
+
hash,
|
|
929
|
+
fetch: args.fetch,
|
|
930
|
+
apiHost: args.apiHost
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
const forgottenHashes = args.hashes.filter((hash) => statuses[hash] === "forgotten");
|
|
934
|
+
const outstandingForgetHashes = args.hashes.filter((hash) => statuses[hash] !== "forgotten");
|
|
935
|
+
return {
|
|
936
|
+
forgottenHashes,
|
|
937
|
+
outstandingForgetHashes,
|
|
938
|
+
statuses
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
async function executeForgetStage(args) {
|
|
942
|
+
const stageHashes = uniqueHashes(args.hashes);
|
|
943
|
+
let forgetResult = null;
|
|
944
|
+
const followUpForgetResults = [];
|
|
945
|
+
if (stageHashes.length === 0) {
|
|
946
|
+
return {
|
|
947
|
+
hashes: stageHashes,
|
|
948
|
+
forgottenHashes: [],
|
|
949
|
+
outstandingForgetHashes: [],
|
|
950
|
+
statuses: {},
|
|
951
|
+
forgetResult,
|
|
952
|
+
followUpForgetResults
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
let classified = await classifyForgetHashes({
|
|
956
|
+
hashes: stageHashes,
|
|
957
|
+
fetch: args.fetch,
|
|
958
|
+
apiHost: args.apiHost
|
|
959
|
+
});
|
|
960
|
+
if (classified.outstandingForgetHashes.length > 0) {
|
|
961
|
+
forgetResult = await forgetAlephMessages({
|
|
962
|
+
sender: args.sender,
|
|
963
|
+
hashes: classified.outstandingForgetHashes,
|
|
964
|
+
reason: args.reason,
|
|
965
|
+
signer: args.signer,
|
|
966
|
+
hasher: args.hasher,
|
|
967
|
+
fetch: args.fetch,
|
|
968
|
+
channel: args.channel,
|
|
969
|
+
apiHost: args.apiHost,
|
|
970
|
+
now: args.now
|
|
971
|
+
});
|
|
972
|
+
classified = await classifyForgetHashes({
|
|
973
|
+
hashes: stageHashes,
|
|
974
|
+
fetch: args.fetch,
|
|
975
|
+
apiHost: args.apiHost
|
|
976
|
+
});
|
|
977
|
+
if (classified.outstandingForgetHashes.length > 0) {
|
|
978
|
+
for (const hash of classified.outstandingForgetHashes) {
|
|
979
|
+
const result = await forgetAlephMessages({
|
|
980
|
+
sender: args.sender,
|
|
981
|
+
hashes: [hash],
|
|
982
|
+
reason: args.reason,
|
|
983
|
+
signer: args.signer,
|
|
984
|
+
hasher: args.hasher,
|
|
985
|
+
fetch: args.fetch,
|
|
986
|
+
channel: args.channel,
|
|
987
|
+
apiHost: args.apiHost,
|
|
988
|
+
now: args.now
|
|
989
|
+
});
|
|
990
|
+
followUpForgetResults.push({ hash, result });
|
|
991
|
+
}
|
|
992
|
+
classified = await classifyForgetHashes({
|
|
993
|
+
hashes: stageHashes,
|
|
994
|
+
fetch: args.fetch,
|
|
995
|
+
apiHost: args.apiHost
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
return {
|
|
1000
|
+
hashes: stageHashes,
|
|
1001
|
+
forgottenHashes: classified.forgottenHashes,
|
|
1002
|
+
outstandingForgetHashes: classified.outstandingForgetHashes,
|
|
1003
|
+
statuses: classified.statuses,
|
|
1004
|
+
forgetResult,
|
|
1005
|
+
followUpForgetResults
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
896
1008
|
async function retainSuccessfulDeployments(args) {
|
|
897
1009
|
const keepCount = Math.max(0, Number.parseInt(String(args.keepCount ?? 0), 10) || 0);
|
|
898
1010
|
const aggregateKey = asString3(args.aggregateKey) ?? SUCCESSFUL_DEPLOYMENTS_AGGREGATE_KEY;
|
|
@@ -919,10 +1031,13 @@ async function retainSuccessfulDeployments(args) {
|
|
|
919
1031
|
const retainedRecords = keepCount > 0 ? uniqueRecords.slice(0, keepCount) : [];
|
|
920
1032
|
const prunedRecords = keepCount > 0 ? uniqueRecords.slice(keepCount) : uniqueRecords;
|
|
921
1033
|
const retainedHashes = new Set(retainedRecords.flatMap(hashesFromRetentionRecord));
|
|
922
|
-
const extraForgetHashes =
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
1034
|
+
const extraForgetHashes = uniqueHashes(args.extraForgetHashes ?? []);
|
|
1035
|
+
const { instanceForgetHashes, dependentForgetHashes, orderedForgetHashes } = splitForgetStages({
|
|
1036
|
+
prunedRecords,
|
|
1037
|
+
extraForgetHashes,
|
|
1038
|
+
retainedHashes
|
|
1039
|
+
});
|
|
1040
|
+
const forgetHashes = orderedForgetHashes;
|
|
926
1041
|
const aggregateContent = {
|
|
927
1042
|
keep: keepCount,
|
|
928
1043
|
updated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -939,12 +1054,18 @@ async function retainSuccessfulDeployments(args) {
|
|
|
939
1054
|
apiHost: args.apiHost,
|
|
940
1055
|
now: args.now
|
|
941
1056
|
});
|
|
1057
|
+
const forgetReason = args.reason ?? `Prune successful deployments beyond retention limit ${keepCount}`;
|
|
1058
|
+
const forgetStageResults = [];
|
|
1059
|
+
let forgottenHashes = [];
|
|
1060
|
+
let outstandingForgetHashes = [];
|
|
1061
|
+
let forgetStatuses = {};
|
|
942
1062
|
let forgetResult = null;
|
|
943
|
-
|
|
944
|
-
|
|
1063
|
+
const followUpForgetResults = [];
|
|
1064
|
+
if (instanceForgetHashes.length > 0) {
|
|
1065
|
+
const instanceStage = await executeForgetStage({
|
|
945
1066
|
sender: args.sender,
|
|
946
|
-
hashes:
|
|
947
|
-
reason:
|
|
1067
|
+
hashes: instanceForgetHashes,
|
|
1068
|
+
reason: forgetReason,
|
|
948
1069
|
signer: args.signer,
|
|
949
1070
|
hasher: args.hasher,
|
|
950
1071
|
fetch: args.fetch,
|
|
@@ -952,7 +1073,60 @@ async function retainSuccessfulDeployments(args) {
|
|
|
952
1073
|
apiHost: args.apiHost,
|
|
953
1074
|
now: args.now
|
|
954
1075
|
});
|
|
1076
|
+
forgetStageResults.push({ stage: "instances", ...instanceStage });
|
|
1077
|
+
forgottenHashes.push(...instanceStage.forgottenHashes);
|
|
1078
|
+
outstandingForgetHashes.push(...instanceStage.outstandingForgetHashes);
|
|
1079
|
+
forgetStatuses = { ...forgetStatuses, ...instanceStage.statuses };
|
|
1080
|
+
if (!forgetResult && instanceStage.forgetResult) {
|
|
1081
|
+
forgetResult = instanceStage.forgetResult;
|
|
1082
|
+
}
|
|
1083
|
+
followUpForgetResults.push(...instanceStage.followUpForgetResults);
|
|
1084
|
+
}
|
|
1085
|
+
if (dependentForgetHashes.length > 0) {
|
|
1086
|
+
if (outstandingForgetHashes.length === 0) {
|
|
1087
|
+
const dependentStage = await executeForgetStage({
|
|
1088
|
+
sender: args.sender,
|
|
1089
|
+
hashes: dependentForgetHashes,
|
|
1090
|
+
reason: forgetReason,
|
|
1091
|
+
signer: args.signer,
|
|
1092
|
+
hasher: args.hasher,
|
|
1093
|
+
fetch: args.fetch,
|
|
1094
|
+
channel: args.channel,
|
|
1095
|
+
apiHost: args.apiHost,
|
|
1096
|
+
now: args.now
|
|
1097
|
+
});
|
|
1098
|
+
forgetStageResults.push({ stage: "dependents", ...dependentStage });
|
|
1099
|
+
forgottenHashes.push(...dependentStage.forgottenHashes);
|
|
1100
|
+
outstandingForgetHashes.push(...dependentStage.outstandingForgetHashes);
|
|
1101
|
+
forgetStatuses = { ...forgetStatuses, ...dependentStage.statuses };
|
|
1102
|
+
if (!forgetResult && dependentStage.forgetResult) {
|
|
1103
|
+
forgetResult = dependentStage.forgetResult;
|
|
1104
|
+
}
|
|
1105
|
+
followUpForgetResults.push(...dependentStage.followUpForgetResults);
|
|
1106
|
+
} else {
|
|
1107
|
+
const dependentStageStatus = await classifyForgetHashes({
|
|
1108
|
+
hashes: dependentForgetHashes,
|
|
1109
|
+
fetch: args.fetch,
|
|
1110
|
+
apiHost: args.apiHost
|
|
1111
|
+
});
|
|
1112
|
+
forgetStageResults.push({
|
|
1113
|
+
stage: "dependents",
|
|
1114
|
+
hashes: dependentForgetHashes,
|
|
1115
|
+
skipped: true,
|
|
1116
|
+
skippedReason: "Waiting for instance forget stage to complete before pruning dependent store items.",
|
|
1117
|
+
forgottenHashes: dependentStageStatus.forgottenHashes,
|
|
1118
|
+
outstandingForgetHashes: dependentStageStatus.outstandingForgetHashes,
|
|
1119
|
+
statuses: dependentStageStatus.statuses,
|
|
1120
|
+
forgetResult: null,
|
|
1121
|
+
followUpForgetResults: []
|
|
1122
|
+
});
|
|
1123
|
+
forgottenHashes.push(...dependentStageStatus.forgottenHashes);
|
|
1124
|
+
outstandingForgetHashes.push(...dependentStageStatus.outstandingForgetHashes);
|
|
1125
|
+
forgetStatuses = { ...forgetStatuses, ...dependentStageStatus.statuses };
|
|
1126
|
+
}
|
|
955
1127
|
}
|
|
1128
|
+
forgottenHashes = uniqueHashes(forgottenHashes);
|
|
1129
|
+
outstandingForgetHashes = uniqueHashes(outstandingForgetHashes);
|
|
956
1130
|
return {
|
|
957
1131
|
sender: args.sender,
|
|
958
1132
|
aggregateKey,
|
|
@@ -961,7 +1135,12 @@ async function retainSuccessfulDeployments(args) {
|
|
|
961
1135
|
retainedRecords,
|
|
962
1136
|
prunedRecords,
|
|
963
1137
|
forgetHashes,
|
|
964
|
-
|
|
1138
|
+
forgottenHashes,
|
|
1139
|
+
outstandingForgetHashes,
|
|
1140
|
+
forgetStatuses,
|
|
1141
|
+
forgetResult,
|
|
1142
|
+
followUpForgetResults,
|
|
1143
|
+
forgetStageResults
|
|
965
1144
|
};
|
|
966
1145
|
}
|
|
967
1146
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@le-space/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Reusable Aleph deployment, runtime, and guest lifecycle logic.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -16,6 +16,6 @@
|
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@le-space/shared-types": "0.1.
|
|
19
|
+
"@le-space/shared-types": "0.1.17"
|
|
20
20
|
}
|
|
21
21
|
}
|