@le-space/node 0.1.16 → 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.
Files changed (3) hide show
  1. package/index.d.ts +14 -0
  2. package/index.js +151 -47
  3. package/package.json +4 -4
package/index.d.ts CHANGED
@@ -231,6 +231,20 @@ declare function retainSuccessfulDeployments(args: {
231
231
  hash: string;
232
232
  result: Awaited<ReturnType<typeof forgetAlephMessages>>;
233
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
+ }[];
234
248
  }>;
235
249
 
236
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);
@@ -973,6 +993,73 @@ async function classifyForgetHashes(args) {
973
993
  statuses
974
994
  };
975
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
+ }
976
1063
  async function retainSuccessfulDeployments(args) {
977
1064
  const keepCount = Math.max(0, Number.parseInt(String(args.keepCount ?? 0), 10) || 0);
978
1065
  const aggregateKey = asString3(args.aggregateKey) ?? SUCCESSFUL_DEPLOYMENTS_AGGREGATE_KEY;
@@ -999,10 +1086,13 @@ async function retainSuccessfulDeployments(args) {
999
1086
  const retainedRecords = keepCount > 0 ? uniqueRecords.slice(0, keepCount) : [];
1000
1087
  const prunedRecords = keepCount > 0 ? uniqueRecords.slice(keepCount) : uniqueRecords;
1001
1088
  const retainedHashes = new Set(retainedRecords.flatMap(hashesFromRetentionRecord));
1002
- const extraForgetHashes = [...new Set((args.extraForgetHashes ?? []).filter(Boolean))];
1003
- const forgetHashes = [.../* @__PURE__ */ new Set([...prunedRecords.flatMap(hashesFromRetentionRecord), ...extraForgetHashes])].filter(
1004
- (hash) => !retainedHashes.has(hash)
1005
- );
1089
+ const extraForgetHashes = uniqueHashes(args.extraForgetHashes ?? []);
1090
+ const { instanceForgetHashes, dependentForgetHashes, orderedForgetHashes } = splitForgetStages({
1091
+ prunedRecords,
1092
+ extraForgetHashes,
1093
+ retainedHashes
1094
+ });
1095
+ const forgetHashes = orderedForgetHashes;
1006
1096
  const aggregateContent = {
1007
1097
  keep: keepCount,
1008
1098
  updated_at: (/* @__PURE__ */ new Date()).toISOString(),
@@ -1019,25 +1109,40 @@ async function retainSuccessfulDeployments(args) {
1019
1109
  apiHost: args.apiHost,
1020
1110
  now: args.now
1021
1111
  });
1022
- let forgetResult = null;
1023
- let followUpForgetResults = [];
1112
+ const forgetReason = args.reason ?? `Prune successful deployments beyond retention limit ${keepCount}`;
1113
+ const forgetStageResults = [];
1024
1114
  let forgottenHashes = [];
1025
1115
  let outstandingForgetHashes = [];
1026
1116
  let forgetStatuses = {};
1027
- if (forgetHashes.length > 0) {
1028
- const initiallyOutstanding = await classifyForgetHashes({
1029
- hashes: forgetHashes,
1117
+ let forgetResult = null;
1118
+ const followUpForgetResults = [];
1119
+ if (instanceForgetHashes.length > 0) {
1120
+ const instanceStage = await executeForgetStage({
1121
+ sender: args.sender,
1122
+ hashes: instanceForgetHashes,
1123
+ reason: forgetReason,
1124
+ signer: args.signer,
1125
+ hasher: args.hasher,
1030
1126
  fetch: args.fetch,
1031
- apiHost: args.apiHost
1127
+ channel: args.channel,
1128
+ apiHost: args.apiHost,
1129
+ now: args.now
1032
1130
  });
1033
- forgottenHashes = initiallyOutstanding.forgottenHashes;
1034
- outstandingForgetHashes = initiallyOutstanding.outstandingForgetHashes;
1035
- forgetStatuses = initiallyOutstanding.statuses;
1036
- if (outstandingForgetHashes.length > 0) {
1037
- forgetResult = await forgetAlephMessages({
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({
1038
1143
  sender: args.sender,
1039
- hashes: outstandingForgetHashes,
1040
- reason: args.reason ?? `Prune successful deployments beyond retention limit ${keepCount}`,
1144
+ hashes: dependentForgetHashes,
1145
+ reason: forgetReason,
1041
1146
  signer: args.signer,
1042
1147
  hasher: args.hasher,
1043
1148
  fetch: args.fetch,
@@ -1045,40 +1150,38 @@ async function retainSuccessfulDeployments(args) {
1045
1150
  apiHost: args.apiHost,
1046
1151
  now: args.now
1047
1152
  });
1048
- let postBatch = await classifyForgetHashes({
1049
- hashes: forgetHashes,
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,
1050
1164
  fetch: args.fetch,
1051
1165
  apiHost: args.apiHost
1052
1166
  });
1053
- forgottenHashes = postBatch.forgottenHashes;
1054
- outstandingForgetHashes = postBatch.outstandingForgetHashes;
1055
- forgetStatuses = postBatch.statuses;
1056
- if (outstandingForgetHashes.length > 0) {
1057
- for (const hash of outstandingForgetHashes) {
1058
- const result = await forgetAlephMessages({
1059
- sender: args.sender,
1060
- hashes: [hash],
1061
- reason: args.reason ?? `Prune successful deployments beyond retention limit ${keepCount}`,
1062
- signer: args.signer,
1063
- hasher: args.hasher,
1064
- fetch: args.fetch,
1065
- channel: args.channel,
1066
- apiHost: args.apiHost,
1067
- now: args.now
1068
- });
1069
- followUpForgetResults.push({ hash, result });
1070
- }
1071
- postBatch = await classifyForgetHashes({
1072
- hashes: forgetHashes,
1073
- fetch: args.fetch,
1074
- apiHost: args.apiHost
1075
- });
1076
- forgottenHashes = postBatch.forgottenHashes;
1077
- outstandingForgetHashes = postBatch.outstandingForgetHashes;
1078
- forgetStatuses = postBatch.statuses;
1079
- }
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 };
1080
1181
  }
1081
1182
  }
1183
+ forgottenHashes = uniqueHashes(forgottenHashes);
1184
+ outstandingForgetHashes = uniqueHashes(outstandingForgetHashes);
1082
1185
  return {
1083
1186
  sender: args.sender,
1084
1187
  aggregateKey,
@@ -1091,7 +1194,8 @@ async function retainSuccessfulDeployments(args) {
1091
1194
  outstandingForgetHashes,
1092
1195
  forgetStatuses,
1093
1196
  forgetResult,
1094
- followUpForgetResults
1197
+ followUpForgetResults,
1198
+ forgetStageResults
1095
1199
  };
1096
1200
  }
1097
1201
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@le-space/node",
3
- "version": "0.1.16",
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.16",
20
- "@le-space/shared-types": "0.1.16",
21
- "@le-space/rootfs": "0.1.16",
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
  }