@hardkas/artifacts 0.6.0-alpha → 0.7.0-alpha

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/dist/index.d.ts +651 -19
  2. package/dist/index.js +203 -24
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@hardkas/artifacts",
4
- version: "0.6.0-alpha",
4
+ version: "0.7.0-alpha",
5
5
  type: "module",
6
6
  license: "MIT",
7
7
  author: "Javier Rodriguez",
@@ -205,7 +205,18 @@ var SEMANTIC_EXCLUSIONS = /* @__PURE__ */ new Set([
205
205
  "dagContext"
206
206
  ]);
207
207
  var CURRENT_HASH_VERSION = 3;
208
- function canonicalStringify(obj, version = CURRENT_HASH_VERSION) {
208
+ var STRICT_PATH_KEYS = /* @__PURE__ */ new Set([
209
+ "file_path",
210
+ "sandboxSnapshotPath",
211
+ "receiptPath",
212
+ "tracePath",
213
+ "outputPath",
214
+ "artifactPath",
215
+ "workspacePath",
216
+ "relativePath",
217
+ "absolutePath"
218
+ ]);
219
+ function canonicalStringify(obj, version = CURRENT_HASH_VERSION, keyName) {
209
220
  if (obj === null || typeof obj !== "object") {
210
221
  if (typeof obj === "bigint") {
211
222
  if (version >= 2) {
@@ -214,13 +225,16 @@ function canonicalStringify(obj, version = CURRENT_HASH_VERSION) {
214
225
  return JSON.stringify(obj.toString());
215
226
  }
216
227
  if (typeof obj === "string" && version >= 3) {
217
- const normalized = obj.normalize("NFC").replace(/\r\n/g, "\n");
228
+ let normalized = obj.normalize("NFC").replace(/\r\n/g, "\n");
229
+ if (keyName && STRICT_PATH_KEYS.has(keyName)) {
230
+ normalized = normalized.replace(/\\/g, "/");
231
+ }
218
232
  return JSON.stringify(normalized);
219
233
  }
220
234
  return JSON.stringify(obj);
221
235
  }
222
236
  if (Array.isArray(obj)) {
223
- return "[" + obj.map((item) => canonicalStringify(item, version)).join(",") + "]";
237
+ return "[" + obj.map((item) => canonicalStringify(item, version, keyName)).join(",") + "]";
224
238
  }
225
239
  if (obj instanceof Map) {
226
240
  throw new Error("Map is not canonicalizable. Use a plain object.");
@@ -240,7 +254,7 @@ function canonicalStringify(obj, version = CURRENT_HASH_VERSION) {
240
254
  ).sort(deterministicCompare);
241
255
  const result = sortedKeys.map((key) => {
242
256
  const value = obj[key];
243
- return JSON.stringify(key) + ":" + canonicalStringify(value, version);
257
+ return JSON.stringify(key) + ":" + canonicalStringify(value, version, key);
244
258
  }).join(",");
245
259
  return "{" + result + "}";
246
260
  }
@@ -260,8 +274,24 @@ var ArtifactLineageSchema = z.object({
260
274
  rootArtifactId: z.string(),
261
275
  sequence: z.number().optional()
262
276
  });
277
+ var ScriptCapabilitySchema = z.enum([
278
+ "p2pk",
279
+ "multisig",
280
+ "timelock",
281
+ "covenant-experimental",
282
+ "silverscript-experimental",
283
+ "tockata-experimental"
284
+ ]);
285
+ var ScriptMetadataSchema = z.object({
286
+ language: z.enum(["native", "silverscript", "tockata"]).optional(),
287
+ version: z.string().optional(),
288
+ experimental: z.boolean(),
289
+ notes: z.array(z.string()).optional(),
290
+ consensusImpact: z.enum(["none", "experimental"]).optional()
291
+ });
263
292
  var BaseArtifactSchema = z.object({
264
293
  schema: z.string(),
294
+ schemaVersion: z.string().optional(),
265
295
  hardkasVersion: z.string(),
266
296
  version: z.literal(ARTIFACT_VERSION),
267
297
  hashVersion: z.union([z.number(), z.string()]).optional(),
@@ -269,7 +299,13 @@ var BaseArtifactSchema = z.object({
269
299
  mode: executionModeSchema,
270
300
  contentHash: z.string().optional(),
271
301
  createdAt: z.string().datetime(),
272
- lineage: ArtifactLineageSchema.optional()
302
+ lineage: ArtifactLineageSchema.optional(),
303
+ parents: z.array(z.string()).optional(),
304
+ lineageDepth: z.number().optional(),
305
+ workflowId: z.string().optional(),
306
+ scriptProfile: z.enum(["standard", "experimental"]).optional(),
307
+ scriptCapabilities: z.array(ScriptCapabilitySchema).optional(),
308
+ scriptMetadata: ScriptMetadataSchema.optional()
273
309
  });
274
310
  var AccountRefSchema = z.object({
275
311
  address: z.string(),
@@ -429,6 +465,17 @@ var WorkflowSchema = BaseArtifactSchema.extend({
429
465
  redacted: z.boolean()
430
466
  }).optional()
431
467
  });
468
+ var RuntimeSessionSchema = BaseArtifactSchema.extend({
469
+ sessionId: z.string(),
470
+ workflowIds: z.array(z.string()),
471
+ artifactIds: z.array(z.string()),
472
+ startedAt: z.string().datetime(),
473
+ network: z.string(),
474
+ deterministic: z.boolean(),
475
+ snapshotOf: z.string().optional(),
476
+ parentSessionId: z.string().optional(),
477
+ notes: z.string().optional()
478
+ });
432
479
 
433
480
  // src/verify.ts
434
481
  import fs from "fs";
@@ -595,6 +642,7 @@ function verifyLineage(artifact, parent, options = {}) {
595
642
  // src/verify.ts
596
643
  var defaultClock = {
597
644
  now: () => Date.now()
645
+ // hardkas-determinism-allow: default clock ambient source
598
646
  };
599
647
  function deterministicCompare2(a, b) {
600
648
  return a < b ? -1 : a > b ? 1 : 0;
@@ -995,30 +1043,148 @@ var InvariantWatcher = class {
995
1043
  };
996
1044
 
997
1045
  // src/migration.ts
998
- function migrateToCanonical(v1Artifact) {
999
- if (v1Artifact.version === ARTIFACT_VERSION) {
1000
- return v1Artifact;
1046
+ var migrationRegistry = [];
1047
+ function registerMigrationStep(step) {
1048
+ const existing = migrationRegistry.find(
1049
+ (s) => s.fromVersion === step.fromVersion && s.toVersion === step.toVersion
1050
+ );
1051
+ if (existing) {
1052
+ throw new Error(
1053
+ `Duplicate migration step: ${step.fromVersion} \u2192 ${step.toVersion} already registered`
1054
+ );
1055
+ }
1056
+ migrationRegistry.push(step);
1057
+ }
1058
+ function getRegisteredMigrationSteps() {
1059
+ return [...migrationRegistry];
1060
+ }
1061
+ registerMigrationStep({
1062
+ fromVersion: "0.1.0",
1063
+ toVersion: ARTIFACT_VERSION,
1064
+ description: "Legacy v1 schemas to canonical 1.0.0-alpha format",
1065
+ transform(artifact) {
1066
+ const migrated = { ...artifact };
1067
+ if (typeof migrated.schema === "string" && migrated.schema.endsWith(".v1")) {
1068
+ if (migrated.schema !== "hardkas.workflow.v1") {
1069
+ migrated.schema = migrated.schema.replace(/\.v1$/, "");
1070
+ }
1071
+ }
1072
+ migrated.version = ARTIFACT_VERSION;
1073
+ if (migrated.schema === "hardkas.txPlan" && migrated.selectedUtxos !== void 0) {
1074
+ migrated.inputs = migrated.selectedUtxos;
1075
+ delete migrated.selectedUtxos;
1076
+ }
1077
+ if (migrated.schema === "hardkas.snapshot" && Array.isArray(migrated.utxos)) {
1078
+ migrated.utxos = sortUtxosByOutpoint(migrated.utxos);
1079
+ }
1080
+ if (!migrated.hardkasVersion) {
1081
+ migrated.hardkasVersion = HARDKAS_VERSION;
1082
+ }
1083
+ if (!migrated.createdAt) {
1084
+ migrated.createdAt = (/* @__PURE__ */ new Date()).toISOString();
1085
+ }
1086
+ if (migrated.hashVersion === void 0 || migrated.hashVersion === null) {
1087
+ migrated.hashVersion = CURRENT_HASH_VERSION;
1088
+ }
1089
+ return migrated;
1001
1090
  }
1002
- const v2Artifact = { ...v1Artifact };
1003
- if (v1Artifact.schema) {
1004
- v2Artifact.schema = v1Artifact.schema.replace(".v1", "");
1091
+ });
1092
+ function detectArtifactVersion(artifact) {
1093
+ if (typeof artifact.version === "string" && artifact.version.length > 0) {
1094
+ return artifact.version;
1005
1095
  }
1006
- v2Artifact.version = ARTIFACT_VERSION;
1007
- if (v2Artifact.schema === "hardkas.txPlan" && v1Artifact.selectedUtxos) {
1008
- v2Artifact.inputs = v1Artifact.selectedUtxos;
1009
- delete v2Artifact.selectedUtxos;
1096
+ if (typeof artifact.schema === "string" && artifact.schema.endsWith(".v1")) {
1097
+ return "0.1.0";
1010
1098
  }
1011
- if (v2Artifact.schema === "hardkas.snapshot" && v1Artifact.utxos) {
1012
- v2Artifact.utxos = sortUtxosByOutpoint(v1Artifact.utxos);
1099
+ return "0.1.0";
1100
+ }
1101
+ function getMigrationPath(fromVersion, toVersion) {
1102
+ if (fromVersion === toVersion) {
1103
+ return [];
1013
1104
  }
1014
- if (!v2Artifact.hardkasVersion) {
1015
- v2Artifact.hardkasVersion = HARDKAS_VERSION;
1105
+ const visited = /* @__PURE__ */ new Set();
1106
+ const queue = [
1107
+ { version: fromVersion, path: [] }
1108
+ ];
1109
+ visited.add(fromVersion);
1110
+ while (queue.length > 0) {
1111
+ const current = queue.shift();
1112
+ const outgoing = migrationRegistry.filter(
1113
+ (s) => s.fromVersion === current.version
1114
+ );
1115
+ for (const step of outgoing) {
1116
+ const newPath = [...current.path, step];
1117
+ if (step.toVersion === toVersion) {
1118
+ return newPath;
1119
+ }
1120
+ if (!visited.has(step.toVersion)) {
1121
+ visited.add(step.toVersion);
1122
+ queue.push({ version: step.toVersion, path: newPath });
1123
+ }
1124
+ }
1125
+ }
1126
+ return [];
1127
+ }
1128
+ function canMigrate(artifact, targetVersion = ARTIFACT_VERSION) {
1129
+ const currentVersion = detectArtifactVersion(artifact);
1130
+ if (currentVersion === targetVersion) {
1131
+ return true;
1132
+ }
1133
+ const path4 = getMigrationPath(currentVersion, targetVersion);
1134
+ return path4.length > 0;
1135
+ }
1136
+ function migrateArtifactPayload(artifact, targetVersion = ARTIFACT_VERSION) {
1137
+ const currentVersion = detectArtifactVersion(artifact);
1138
+ if (currentVersion === targetVersion) {
1139
+ return {
1140
+ artifact,
1141
+ migrated: false,
1142
+ originalContentHash: artifact.contentHash,
1143
+ appliedSteps: []
1144
+ };
1145
+ }
1146
+ const path4 = getMigrationPath(currentVersion, targetVersion);
1147
+ if (path4.length === 0) {
1148
+ throw new Error(
1149
+ `No migration path from version "${currentVersion}" to "${targetVersion}". Registered steps: [${migrationRegistry.map((s) => `${s.fromVersion}\u2192${s.toVersion}`).join(", ")}]`
1150
+ );
1151
+ }
1152
+ const originalContentHash = artifact.contentHash;
1153
+ const originalLineage = artifact.lineage;
1154
+ let current = { ...artifact };
1155
+ const appliedSteps = [];
1156
+ for (const step of path4) {
1157
+ current = step.transform(current);
1158
+ appliedSteps.push({
1159
+ fromVersion: step.fromVersion,
1160
+ toVersion: step.toVersion,
1161
+ description: step.description
1162
+ });
1163
+ }
1164
+ if (originalContentHash) {
1165
+ current.originalContentHash = originalContentHash;
1016
1166
  }
1017
- if (!v2Artifact.createdAt) {
1018
- v2Artifact.createdAt = (/* @__PURE__ */ new Date()).toISOString();
1167
+ if (originalLineage && typeof originalLineage === "object") {
1168
+ const migratedLineage = current.lineage;
1169
+ if (migratedLineage && typeof migratedLineage === "object") {
1170
+ migratedLineage.rootArtifactId = originalLineage.rootArtifactId;
1171
+ }
1172
+ }
1173
+ current.hashVersion = CURRENT_HASH_VERSION;
1174
+ current.contentHash = calculateContentHash(current, CURRENT_HASH_VERSION);
1175
+ return {
1176
+ artifact: current,
1177
+ migrated: true,
1178
+ originalContentHash,
1179
+ appliedSteps
1180
+ };
1181
+ }
1182
+ function migrateToCanonical(v1Artifact) {
1183
+ if (v1Artifact.version === ARTIFACT_VERSION) {
1184
+ return v1Artifact;
1019
1185
  }
1020
- v2Artifact.contentHash = calculateContentHash(v2Artifact);
1021
- return v2Artifact;
1186
+ const result = migrateArtifactPayload(v1Artifact, ARTIFACT_VERSION);
1187
+ return result.artifact;
1022
1188
  }
1023
1189
 
1024
1190
  // src/io.ts
@@ -1193,6 +1359,7 @@ function createTxPlanArtifact(options) {
1193
1359
  const artifact = {
1194
1360
  schema: "hardkas.txPlan",
1195
1361
  hardkasVersion: HARDKAS_VERSION,
1362
+ schemaVersion: "hardkas.artifact.v1",
1196
1363
  version: ARTIFACT_VERSION,
1197
1364
  hashVersion: CURRENT_HASH_VERSION,
1198
1365
  createdAt: new Date(options.ctx.clock.now()).toISOString(),
@@ -1239,6 +1406,7 @@ function createTxPlanArtifact(options) {
1239
1406
  function createSimulatedSignedTxArtifact(plan, payload, ctx) {
1240
1407
  const artifact = {
1241
1408
  schema: "hardkas.signedTx",
1409
+ schemaVersion: "hardkas.artifact.v1",
1242
1410
  hardkasVersion: HARDKAS_VERSION,
1243
1411
  version: ARTIFACT_VERSION,
1244
1412
  hashVersion: CURRENT_HASH_VERSION,
@@ -1264,6 +1432,7 @@ function createSimulatedSignedTxArtifact(plan, payload, ctx) {
1264
1432
  function createSimulatedTxReceipt(plan, txId, ctx, extra) {
1265
1433
  const artifact = {
1266
1434
  schema: "hardkas.txReceipt",
1435
+ schemaVersion: "hardkas.receipt.v1",
1267
1436
  hardkasVersion: HARDKAS_VERSION,
1268
1437
  version: ARTIFACT_VERSION,
1269
1438
  hashVersion: CURRENT_HASH_VERSION,
@@ -1690,8 +1859,12 @@ export {
1690
1859
  LocalnetUtxoSchemaV2,
1691
1860
  NetworkInvariant,
1692
1861
  ReplayInvariant,
1862
+ RuntimeSessionSchema,
1693
1863
  SEMANTIC_EXCLUSIONS,
1864
+ STRICT_PATH_KEYS,
1694
1865
  SchemaInvariant,
1866
+ ScriptCapabilitySchema,
1867
+ ScriptMetadataSchema,
1695
1868
  SignedTxSchema,
1696
1869
  SnapshotSchema,
1697
1870
  TxPlanSchema,
@@ -1710,6 +1883,7 @@ export {
1710
1883
  assertValidTxReceiptArtifact,
1711
1884
  bigIntReplacer,
1712
1885
  calculateContentHash,
1886
+ canMigrate,
1713
1887
  canonicalStringify,
1714
1888
  createDeploymentRecord,
1715
1889
  createIgraDeployPlanId,
@@ -1720,6 +1894,7 @@ export {
1720
1894
  createTxPlanArtifact,
1721
1895
  defaultClock,
1722
1896
  deleteDeployment,
1897
+ detectArtifactVersion,
1723
1898
  diffArtifacts,
1724
1899
  explainArtifact,
1725
1900
  formatSignedTxArtifact,
@@ -1729,17 +1904,21 @@ export {
1729
1904
  getDefaultL2ReceiptsDir,
1730
1905
  getDefaultReceiptPath,
1731
1906
  getL2ReceiptPath,
1907
+ getMigrationPath,
1908
+ getRegisteredMigrationSteps,
1732
1909
  isIgraTxPlanArtifact,
1733
1910
  listDeployments,
1734
1911
  listIgraTxReceiptArtifacts,
1735
1912
  loadDeployment,
1736
1913
  loadIgraTxReceiptArtifact,
1914
+ migrateArtifactPayload,
1737
1915
  migrateToCanonical,
1738
1916
  readArtifact,
1739
1917
  readSignedTxArtifact,
1740
1918
  readTxPlanArtifact,
1741
1919
  readTxReceiptArtifact,
1742
1920
  recomputeMass,
1921
+ registerMigrationStep,
1743
1922
  saveDeployment,
1744
1923
  saveIgraTxReceiptArtifact,
1745
1924
  sortUtxosByOutpoint,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hardkas/artifacts",
3
- "version": "0.6.0-alpha",
3
+ "version": "0.7.0-alpha",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Javier Rodriguez",
@@ -24,8 +24,8 @@
24
24
  "types": "./dist/index.d.ts",
25
25
  "dependencies": {
26
26
  "zod": "^3.24.1",
27
- "@hardkas/core": "0.6.0-alpha",
28
- "@hardkas/tx-builder": "0.6.0-alpha"
27
+ "@hardkas/core": "0.7.0-alpha",
28
+ "@hardkas/tx-builder": "0.7.0-alpha"
29
29
  },
30
30
  "devDependencies": {
31
31
  "tsup": "^8.3.5",