@le-space/node 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 +41 -0
- package/index.js +190 -10
- package/package.json +4 -4
package/index.d.ts
CHANGED
|
@@ -160,6 +160,26 @@ interface JsonFetchLikeResponse {
|
|
|
160
160
|
}
|
|
161
161
|
type JsonFetchLike = (url: string, init?: RequestInit) => Promise<JsonFetchLikeResponse>;
|
|
162
162
|
|
|
163
|
+
declare function forgetAlephMessages(args: {
|
|
164
|
+
sender: string;
|
|
165
|
+
hashes?: string[];
|
|
166
|
+
aggregates?: string[];
|
|
167
|
+
reason?: string;
|
|
168
|
+
signer: MessageSigner;
|
|
169
|
+
hasher: MessageHasher;
|
|
170
|
+
fetch: JsonFetchLike;
|
|
171
|
+
channel?: string;
|
|
172
|
+
apiHost?: string;
|
|
173
|
+
sync?: boolean;
|
|
174
|
+
now?: number;
|
|
175
|
+
}): Promise<{
|
|
176
|
+
sender: string;
|
|
177
|
+
itemHash: string;
|
|
178
|
+
response: _shared_aleph_shared_types.AlephBroadcastResponse;
|
|
179
|
+
httpStatus: number;
|
|
180
|
+
status: _shared_aleph_shared_types.MessageStatus;
|
|
181
|
+
}>;
|
|
182
|
+
|
|
163
183
|
interface RetentionRecord {
|
|
164
184
|
instance_item_hash: string;
|
|
165
185
|
rootfs_item_hash: string;
|
|
@@ -197,6 +217,9 @@ declare function retainSuccessfulDeployments(args: {
|
|
|
197
217
|
retainedRecords: RetentionRecord[];
|
|
198
218
|
prunedRecords: RetentionRecord[];
|
|
199
219
|
forgetHashes: string[];
|
|
220
|
+
forgottenHashes: string[];
|
|
221
|
+
outstandingForgetHashes: string[];
|
|
222
|
+
forgetStatuses: Record<string, string>;
|
|
200
223
|
forgetResult: {
|
|
201
224
|
sender: string;
|
|
202
225
|
itemHash: string;
|
|
@@ -204,6 +227,24 @@ declare function retainSuccessfulDeployments(args: {
|
|
|
204
227
|
httpStatus: number;
|
|
205
228
|
status: _shared_aleph_shared_types.MessageStatus;
|
|
206
229
|
} | null;
|
|
230
|
+
followUpForgetResults: {
|
|
231
|
+
hash: string;
|
|
232
|
+
result: Awaited<ReturnType<typeof forgetAlephMessages>>;
|
|
233
|
+
}[];
|
|
234
|
+
forgetStageResults: {
|
|
235
|
+
stage: "instances" | "dependents";
|
|
236
|
+
hashes: string[];
|
|
237
|
+
skipped?: boolean;
|
|
238
|
+
skippedReason?: string;
|
|
239
|
+
forgottenHashes: string[];
|
|
240
|
+
outstandingForgetHashes: string[];
|
|
241
|
+
statuses: Record<string, string>;
|
|
242
|
+
forgetResult: Awaited<ReturnType<typeof forgetAlephMessages>> | null;
|
|
243
|
+
followUpForgetResults: Array<{
|
|
244
|
+
hash: string;
|
|
245
|
+
result: Awaited<ReturnType<typeof forgetAlephMessages>>;
|
|
246
|
+
}>;
|
|
247
|
+
}[];
|
|
207
248
|
}>;
|
|
208
249
|
|
|
209
250
|
declare function buildScaffoldDeployResult(env?: NodeJS.ProcessEnv): DeployOutputResult;
|
package/index.js
CHANGED
|
@@ -896,6 +896,26 @@ function retentionRecordId(record) {
|
|
|
896
896
|
function hashesFromRetentionRecord(record) {
|
|
897
897
|
return [record.instance_item_hash, record.rootfs_item_hash, record.site_item_hash].filter(Boolean);
|
|
898
898
|
}
|
|
899
|
+
function uniqueHashes(hashes) {
|
|
900
|
+
return [...new Set(hashes.filter(Boolean))];
|
|
901
|
+
}
|
|
902
|
+
function dependentHashesFromRetentionRecord(record) {
|
|
903
|
+
return [record.rootfs_item_hash, record.site_item_hash].filter(Boolean);
|
|
904
|
+
}
|
|
905
|
+
function splitForgetStages(args) {
|
|
906
|
+
const instanceForgetHashes = uniqueHashes(args.prunedRecords.map((record) => record.instance_item_hash)).filter(
|
|
907
|
+
(hash) => !args.retainedHashes.has(hash)
|
|
908
|
+
);
|
|
909
|
+
const dependentForgetHashes = uniqueHashes([
|
|
910
|
+
...args.prunedRecords.flatMap(dependentHashesFromRetentionRecord),
|
|
911
|
+
...args.extraForgetHashes
|
|
912
|
+
]).filter((hash) => !args.retainedHashes.has(hash) && !instanceForgetHashes.includes(hash));
|
|
913
|
+
return {
|
|
914
|
+
instanceForgetHashes,
|
|
915
|
+
dependentForgetHashes,
|
|
916
|
+
orderedForgetHashes: [...instanceForgetHashes, ...dependentForgetHashes]
|
|
917
|
+
};
|
|
918
|
+
}
|
|
899
919
|
async function fetchAggregateKey(args) {
|
|
900
920
|
const requestUrl = new URL(`/api/v0/aggregates/${args.address}.json`, args.apiHost ?? "https://api2.aleph.im");
|
|
901
921
|
requestUrl.searchParams.set("keys", args.key);
|
|
@@ -948,6 +968,98 @@ async function publishAggregateKey(args) {
|
|
|
948
968
|
httpStatus
|
|
949
969
|
};
|
|
950
970
|
}
|
|
971
|
+
async function fetchMessageStatus(args) {
|
|
972
|
+
const requestUrl = new URL(`/api/v0/messages/${args.hash}`, args.apiHost ?? "https://api2.aleph.im");
|
|
973
|
+
const response = await args.fetch(requestUrl.toString(), { cache: "no-cache" });
|
|
974
|
+
if (response.status === 404) return "missing";
|
|
975
|
+
if (!response.ok) return "unknown";
|
|
976
|
+
const payload = await response.json();
|
|
977
|
+
return asString3(payload?.status) ?? "unknown";
|
|
978
|
+
}
|
|
979
|
+
async function classifyForgetHashes(args) {
|
|
980
|
+
const statuses = {};
|
|
981
|
+
for (const hash of args.hashes) {
|
|
982
|
+
statuses[hash] = await fetchMessageStatus({
|
|
983
|
+
hash,
|
|
984
|
+
fetch: args.fetch,
|
|
985
|
+
apiHost: args.apiHost
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
const forgottenHashes = args.hashes.filter((hash) => statuses[hash] === "forgotten");
|
|
989
|
+
const outstandingForgetHashes = args.hashes.filter((hash) => statuses[hash] !== "forgotten");
|
|
990
|
+
return {
|
|
991
|
+
forgottenHashes,
|
|
992
|
+
outstandingForgetHashes,
|
|
993
|
+
statuses
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
async function executeForgetStage(args) {
|
|
997
|
+
const stageHashes = uniqueHashes(args.hashes);
|
|
998
|
+
let forgetResult = null;
|
|
999
|
+
const followUpForgetResults = [];
|
|
1000
|
+
if (stageHashes.length === 0) {
|
|
1001
|
+
return {
|
|
1002
|
+
hashes: stageHashes,
|
|
1003
|
+
forgottenHashes: [],
|
|
1004
|
+
outstandingForgetHashes: [],
|
|
1005
|
+
statuses: {},
|
|
1006
|
+
forgetResult,
|
|
1007
|
+
followUpForgetResults
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
let classified = await classifyForgetHashes({
|
|
1011
|
+
hashes: stageHashes,
|
|
1012
|
+
fetch: args.fetch,
|
|
1013
|
+
apiHost: args.apiHost
|
|
1014
|
+
});
|
|
1015
|
+
if (classified.outstandingForgetHashes.length > 0) {
|
|
1016
|
+
forgetResult = await forgetAlephMessages({
|
|
1017
|
+
sender: args.sender,
|
|
1018
|
+
hashes: classified.outstandingForgetHashes,
|
|
1019
|
+
reason: args.reason,
|
|
1020
|
+
signer: args.signer,
|
|
1021
|
+
hasher: args.hasher,
|
|
1022
|
+
fetch: args.fetch,
|
|
1023
|
+
channel: args.channel,
|
|
1024
|
+
apiHost: args.apiHost,
|
|
1025
|
+
now: args.now
|
|
1026
|
+
});
|
|
1027
|
+
classified = await classifyForgetHashes({
|
|
1028
|
+
hashes: stageHashes,
|
|
1029
|
+
fetch: args.fetch,
|
|
1030
|
+
apiHost: args.apiHost
|
|
1031
|
+
});
|
|
1032
|
+
if (classified.outstandingForgetHashes.length > 0) {
|
|
1033
|
+
for (const hash of classified.outstandingForgetHashes) {
|
|
1034
|
+
const result = await forgetAlephMessages({
|
|
1035
|
+
sender: args.sender,
|
|
1036
|
+
hashes: [hash],
|
|
1037
|
+
reason: args.reason,
|
|
1038
|
+
signer: args.signer,
|
|
1039
|
+
hasher: args.hasher,
|
|
1040
|
+
fetch: args.fetch,
|
|
1041
|
+
channel: args.channel,
|
|
1042
|
+
apiHost: args.apiHost,
|
|
1043
|
+
now: args.now
|
|
1044
|
+
});
|
|
1045
|
+
followUpForgetResults.push({ hash, result });
|
|
1046
|
+
}
|
|
1047
|
+
classified = await classifyForgetHashes({
|
|
1048
|
+
hashes: stageHashes,
|
|
1049
|
+
fetch: args.fetch,
|
|
1050
|
+
apiHost: args.apiHost
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
return {
|
|
1055
|
+
hashes: stageHashes,
|
|
1056
|
+
forgottenHashes: classified.forgottenHashes,
|
|
1057
|
+
outstandingForgetHashes: classified.outstandingForgetHashes,
|
|
1058
|
+
statuses: classified.statuses,
|
|
1059
|
+
forgetResult,
|
|
1060
|
+
followUpForgetResults
|
|
1061
|
+
};
|
|
1062
|
+
}
|
|
951
1063
|
async function retainSuccessfulDeployments(args) {
|
|
952
1064
|
const keepCount = Math.max(0, Number.parseInt(String(args.keepCount ?? 0), 10) || 0);
|
|
953
1065
|
const aggregateKey = asString3(args.aggregateKey) ?? SUCCESSFUL_DEPLOYMENTS_AGGREGATE_KEY;
|
|
@@ -974,10 +1086,13 @@ async function retainSuccessfulDeployments(args) {
|
|
|
974
1086
|
const retainedRecords = keepCount > 0 ? uniqueRecords.slice(0, keepCount) : [];
|
|
975
1087
|
const prunedRecords = keepCount > 0 ? uniqueRecords.slice(keepCount) : uniqueRecords;
|
|
976
1088
|
const retainedHashes = new Set(retainedRecords.flatMap(hashesFromRetentionRecord));
|
|
977
|
-
const extraForgetHashes =
|
|
978
|
-
const
|
|
979
|
-
|
|
980
|
-
|
|
1089
|
+
const extraForgetHashes = uniqueHashes(args.extraForgetHashes ?? []);
|
|
1090
|
+
const { instanceForgetHashes, dependentForgetHashes, orderedForgetHashes } = splitForgetStages({
|
|
1091
|
+
prunedRecords,
|
|
1092
|
+
extraForgetHashes,
|
|
1093
|
+
retainedHashes
|
|
1094
|
+
});
|
|
1095
|
+
const forgetHashes = orderedForgetHashes;
|
|
981
1096
|
const aggregateContent = {
|
|
982
1097
|
keep: keepCount,
|
|
983
1098
|
updated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -994,12 +1109,18 @@ async function retainSuccessfulDeployments(args) {
|
|
|
994
1109
|
apiHost: args.apiHost,
|
|
995
1110
|
now: args.now
|
|
996
1111
|
});
|
|
1112
|
+
const forgetReason = args.reason ?? `Prune successful deployments beyond retention limit ${keepCount}`;
|
|
1113
|
+
const forgetStageResults = [];
|
|
1114
|
+
let forgottenHashes = [];
|
|
1115
|
+
let outstandingForgetHashes = [];
|
|
1116
|
+
let forgetStatuses = {};
|
|
997
1117
|
let forgetResult = null;
|
|
998
|
-
|
|
999
|
-
|
|
1118
|
+
const followUpForgetResults = [];
|
|
1119
|
+
if (instanceForgetHashes.length > 0) {
|
|
1120
|
+
const instanceStage = await executeForgetStage({
|
|
1000
1121
|
sender: args.sender,
|
|
1001
|
-
hashes:
|
|
1002
|
-
reason:
|
|
1122
|
+
hashes: instanceForgetHashes,
|
|
1123
|
+
reason: forgetReason,
|
|
1003
1124
|
signer: args.signer,
|
|
1004
1125
|
hasher: args.hasher,
|
|
1005
1126
|
fetch: args.fetch,
|
|
@@ -1007,7 +1128,60 @@ async function retainSuccessfulDeployments(args) {
|
|
|
1007
1128
|
apiHost: args.apiHost,
|
|
1008
1129
|
now: args.now
|
|
1009
1130
|
});
|
|
1131
|
+
forgetStageResults.push({ stage: "instances", ...instanceStage });
|
|
1132
|
+
forgottenHashes.push(...instanceStage.forgottenHashes);
|
|
1133
|
+
outstandingForgetHashes.push(...instanceStage.outstandingForgetHashes);
|
|
1134
|
+
forgetStatuses = { ...forgetStatuses, ...instanceStage.statuses };
|
|
1135
|
+
if (!forgetResult && instanceStage.forgetResult) {
|
|
1136
|
+
forgetResult = instanceStage.forgetResult;
|
|
1137
|
+
}
|
|
1138
|
+
followUpForgetResults.push(...instanceStage.followUpForgetResults);
|
|
1139
|
+
}
|
|
1140
|
+
if (dependentForgetHashes.length > 0) {
|
|
1141
|
+
if (outstandingForgetHashes.length === 0) {
|
|
1142
|
+
const dependentStage = await executeForgetStage({
|
|
1143
|
+
sender: args.sender,
|
|
1144
|
+
hashes: dependentForgetHashes,
|
|
1145
|
+
reason: forgetReason,
|
|
1146
|
+
signer: args.signer,
|
|
1147
|
+
hasher: args.hasher,
|
|
1148
|
+
fetch: args.fetch,
|
|
1149
|
+
channel: args.channel,
|
|
1150
|
+
apiHost: args.apiHost,
|
|
1151
|
+
now: args.now
|
|
1152
|
+
});
|
|
1153
|
+
forgetStageResults.push({ stage: "dependents", ...dependentStage });
|
|
1154
|
+
forgottenHashes.push(...dependentStage.forgottenHashes);
|
|
1155
|
+
outstandingForgetHashes.push(...dependentStage.outstandingForgetHashes);
|
|
1156
|
+
forgetStatuses = { ...forgetStatuses, ...dependentStage.statuses };
|
|
1157
|
+
if (!forgetResult && dependentStage.forgetResult) {
|
|
1158
|
+
forgetResult = dependentStage.forgetResult;
|
|
1159
|
+
}
|
|
1160
|
+
followUpForgetResults.push(...dependentStage.followUpForgetResults);
|
|
1161
|
+
} else {
|
|
1162
|
+
const dependentStageStatus = await classifyForgetHashes({
|
|
1163
|
+
hashes: dependentForgetHashes,
|
|
1164
|
+
fetch: args.fetch,
|
|
1165
|
+
apiHost: args.apiHost
|
|
1166
|
+
});
|
|
1167
|
+
forgetStageResults.push({
|
|
1168
|
+
stage: "dependents",
|
|
1169
|
+
hashes: dependentForgetHashes,
|
|
1170
|
+
skipped: true,
|
|
1171
|
+
skippedReason: "Waiting for instance forget stage to complete before pruning dependent store items.",
|
|
1172
|
+
forgottenHashes: dependentStageStatus.forgottenHashes,
|
|
1173
|
+
outstandingForgetHashes: dependentStageStatus.outstandingForgetHashes,
|
|
1174
|
+
statuses: dependentStageStatus.statuses,
|
|
1175
|
+
forgetResult: null,
|
|
1176
|
+
followUpForgetResults: []
|
|
1177
|
+
});
|
|
1178
|
+
forgottenHashes.push(...dependentStageStatus.forgottenHashes);
|
|
1179
|
+
outstandingForgetHashes.push(...dependentStageStatus.outstandingForgetHashes);
|
|
1180
|
+
forgetStatuses = { ...forgetStatuses, ...dependentStageStatus.statuses };
|
|
1181
|
+
}
|
|
1010
1182
|
}
|
|
1183
|
+
forgottenHashes = uniqueHashes(forgottenHashes);
|
|
1184
|
+
outstandingForgetHashes = uniqueHashes(outstandingForgetHashes);
|
|
1011
1185
|
return {
|
|
1012
1186
|
sender: args.sender,
|
|
1013
1187
|
aggregateKey,
|
|
@@ -1016,7 +1190,12 @@ async function retainSuccessfulDeployments(args) {
|
|
|
1016
1190
|
retainedRecords,
|
|
1017
1191
|
prunedRecords,
|
|
1018
1192
|
forgetHashes,
|
|
1019
|
-
|
|
1193
|
+
forgottenHashes,
|
|
1194
|
+
outstandingForgetHashes,
|
|
1195
|
+
forgetStatuses,
|
|
1196
|
+
forgetResult,
|
|
1197
|
+
followUpForgetResults,
|
|
1198
|
+
forgetStageResults
|
|
1020
1199
|
};
|
|
1021
1200
|
}
|
|
1022
1201
|
|
|
@@ -2098,7 +2277,8 @@ async function runActionMode(env = process.env, hooks = {}) {
|
|
|
2098
2277
|
`- Keep count: \`${payload.keepCount}\``,
|
|
2099
2278
|
`- Retained deployments: \`${payload.retainedRecords?.length ?? 0}\``,
|
|
2100
2279
|
`- Pruned deployments: \`${payload.prunedRecords?.length ?? 0}\``,
|
|
2101
|
-
`- Forgotten hashes: \`${(payload.forgetHashes ?? []).length}
|
|
2280
|
+
`- Forgotten hashes: \`${(payload.forgottenHashes ?? payload.forgetHashes ?? []).length}\``,
|
|
2281
|
+
`- Outstanding forget hashes: \`${(payload.outstandingForgetHashes ?? []).length}\``
|
|
2102
2282
|
], env);
|
|
2103
2283
|
stdout(`${JSON.stringify(payload)}
|
|
2104
2284
|
`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@le-space/node",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Node and GitHub Actions adapters for shared Aleph tooling.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@le-space/core": "0.1.
|
|
20
|
-
"@le-space/shared-types": "0.1.
|
|
21
|
-
"@le-space/rootfs": "0.1.
|
|
19
|
+
"@le-space/core": "0.1.17",
|
|
20
|
+
"@le-space/shared-types": "0.1.17",
|
|
21
|
+
"@le-space/rootfs": "0.1.17",
|
|
22
22
|
"ethers": "^6.15.0"
|
|
23
23
|
}
|
|
24
24
|
}
|