@hyperscale0/hsx 5.4.2 → 5.6.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # HSX 5.6.0
2
+
3
+ The compiler records the standard block origin of every instrument compiled
4
+ from a bundled std header: block key, record path and header digest. Travel
5
+ booking cancellations declare `purpose: option`. Follows UDL 4.8.0.
6
+
7
+ # HSX 5.5.0
8
+
9
+ Std money moves declare posted economic purposes. Fee legs and recipient choices
10
+ retain separate purposes. Paid earnings and payout refunds retain their original
11
+ transfer identity. Supports UDL pass-through money.
12
+
1
13
  # HSX 5.4.2
2
14
 
3
15
  Follows UDL 4.6.0: an action's `availability` carries `blockers` with a code and a plain reason instead of one code; an adapter that is not set up reads as `setup_required`. Tests updated. No compiler behaviour changed.
@@ -15,6 +15,11 @@ export interface CompileOriginMapEntry {
15
15
  line: number;
16
16
  column: number;
17
17
  };
18
+ standardBlock?: {
19
+ key: string;
20
+ recordPath: string;
21
+ headerDigest: string;
22
+ };
18
23
  }
19
24
  export interface AdapterBindingTarget {
20
25
  adapter: ProviderAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/compile.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAeL,KAAK,WAAW,EAOjB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAIL,KAAK,UAAU,EAKf,KAAK,IAAI,EACV,MAAM,UAAU,CAAC;AAClB,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;CACpC;AACD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AACD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;CAClE;AACD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,SAAS,CAAC,EAAE;QACV,QAAQ,EAAE,WAAW,CAAC;QACtB,YAAY,EAAE,eAAe,CAAC;QAC9B,SAAS,EAAE,qBAAqB,EAAE,CAAC;KACpC,CAAC;CACH;AAqTD,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,cAAmB,GAC3B,aAAa,CAmjGf"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/compile.ts"],"names":[],"mappings":"AAEA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAeL,KAAK,WAAW,EAOjB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAIL,KAAK,UAAU,EAKf,KAAK,IAAI,EACV,MAAM,UAAU,CAAC;AAClB,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;CACpC;AACD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,aAAa,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AACD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;CAClE;AACD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC,SAAS,CAAC,EAAE;QACV,QAAQ,EAAE,WAAW,CAAC;QACtB,YAAY,EAAE,eAAe,CAAC;QAC9B,SAAS,EAAE,qBAAqB,EAAE,CAAC;KACpC,CAAC;CACH;AAqTD,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,cAAmB,GAC3B,aAAa,CAktGf"}
@@ -277,6 +277,7 @@ export function compile(source, options = {}) {
277
277
  fail(program, "this release supports SAR", "write currency SAR or omit currency");
278
278
  const templates = new Map();
279
279
  const declarationSources = new Map();
280
+ const standardOrigins = new Map();
280
281
  const requirementOrigins = new Map();
281
282
  const used = new Set();
282
283
  for (const use of program.decls.filter((d) => d.kind === "use")) {
@@ -287,6 +288,10 @@ export function compile(source, options = {}) {
287
288
  if (!content)
288
289
  fail(use, `unknown header ${use.name}`, "choose a published header");
289
290
  sources.set(use.name, content);
291
+ const bundled = bundledStandardLibrary.source(use.name);
292
+ const headerDigest = bundled === content
293
+ ? Array.from(sha256(new TextEncoder().encode(content)), (byte) => byte.toString(16).padStart(2, "0")).join("")
294
+ : undefined;
290
295
  let header;
291
296
  try {
292
297
  header = parseHeader(content, use.name);
@@ -310,6 +315,14 @@ export function compile(source, options = {}) {
310
315
  fail(parentDecl, `duplicate instrument ${prefix}`, "give each instrument a distinct name");
311
316
  templates.set(prefix, parentDecl);
312
317
  declarationSources.set(parentDecl, use.name);
318
+ if (headerDigest) {
319
+ const [, root, ...record] = prefix.split(".");
320
+ standardOrigins.set(parentDecl, {
321
+ key: `${use.name}.${root}`,
322
+ recordPath: record.join("."),
323
+ headerDigest,
324
+ });
325
+ }
313
326
  const recs = entries(asBlock(entries(parentDecl.body).get("records")));
314
327
  for (const [recName, recBlock] of recs) {
315
328
  const recDecl = {
@@ -441,7 +454,7 @@ export function compile(source, options = {}) {
441
454
  }
442
455
  return { module: moduleName, exportPath, revision };
443
456
  };
444
- const addInstrument = (decl, id, arguments_, origin, inherited = new Map(), inheritedEnums = new Map(), attachmentInfo, familyDeclaration) => {
457
+ const addInstrument = (decl, id, arguments_, origin, inherited = new Map(), inheritedEnums = new Map(), attachmentInfo, familyDeclaration, standardOrigin) => {
445
458
  const resolveFamilyInstruments = (family, currentInstId, expr) => {
446
459
  const found = new Set();
447
460
  if (currentInstId && familyDeclaration) {
@@ -1677,6 +1690,77 @@ export function compile(source, options = {}) {
1677
1690
  const key = parts.has("key")
1678
1691
  ? String(data(parts.get("key")))
1679
1692
  : `move${index + 1}`;
1693
+ const lowerEconomics = (economicsExpr) => {
1694
+ if (economicsExpr) {
1695
+ const resolved = resolve(economicsExpr);
1696
+ if (resolved.kind === "name" &&
1697
+ resolved.value === "unclassified")
1698
+ return undefined;
1699
+ const choices = entries(asBlock(resolve(economicsExpr)));
1700
+ if (choices.has("recipient")) {
1701
+ for (const term of choices.keys())
1702
+ if (!["recipient", "company", "participant"].includes(term))
1703
+ fail(economicsExpr, `unknown economics choice ${term}`, "use recipient, company and participant");
1704
+ const recipient = String(data(choices.get("recipient")));
1705
+ if (!isParty(recipient) ||
1706
+ !choices.has("company") ||
1707
+ !choices.has("participant"))
1708
+ fail(economicsExpr, "economics choice needs a bound recipient and both branches", "declare recipient, company and participant");
1709
+ const company = recipient === "operator" ||
1710
+ recipient === "programOperator" ||
1711
+ document.parties[recipient]?.role === "program_operator";
1712
+ return lowerEconomics(choices.get(company ? "company" : "participant"));
1713
+ }
1714
+ }
1715
+ const economicsParts = economicsExpr
1716
+ ? entries(asBlock(resolve(economicsExpr)))
1717
+ : undefined;
1718
+ if (economicsParts) {
1719
+ for (const term of economicsParts.keys())
1720
+ if (!["purpose", "sourceParty", "reversalOf"].includes(term))
1721
+ fail(economicsExpr, `unknown economics term ${term}`, "use purpose, sourceParty or reversalOf");
1722
+ }
1723
+ const purpose = economicsParts?.get("purpose");
1724
+ const sourceParty = economicsParts?.get("sourceParty");
1725
+ if (economicsParts && (!purpose || !sourceParty))
1726
+ fail(economicsExpr, "economics needs purpose and sourceParty", "declare both economics fields");
1727
+ const purposeName = purpose ? String(data(purpose)) : undefined;
1728
+ if (purposeName &&
1729
+ ![
1730
+ "earning",
1731
+ "principal",
1732
+ "participant_payout",
1733
+ "internal",
1734
+ "prepaid_credit",
1735
+ "pass_through",
1736
+ ].includes(purposeName))
1737
+ fail(purpose, `unknown economic purpose ${purposeName}`, "choose a declared economic purpose");
1738
+ const sourcePartyName = sourceParty
1739
+ ? String(data(sourceParty))
1740
+ : undefined;
1741
+ if (sourcePartyName && !isParty(sourcePartyName))
1742
+ fail(sourceParty, `unknown source party ${sourcePartyName}`, "bind an authored party");
1743
+ return economicsParts
1744
+ ? {
1745
+ purpose: purposeName,
1746
+ sourceParty: sourcePartyName,
1747
+ ...(economicsParts.has("reversalOf")
1748
+ ? {
1749
+ reversalOf: path(economicsParts.get("reversalOf")),
1750
+ }
1751
+ : {}),
1752
+ }
1753
+ : undefined;
1754
+ };
1755
+ const economicsExpr = parts.get("economics");
1756
+ const feeEconomics = parts.has("fee") && economicsExpr
1757
+ ? entries(asBlock(resolve(economicsExpr)))
1758
+ : undefined;
1759
+ if (feeEconomics)
1760
+ for (const term of feeEconomics.keys())
1761
+ if (!["payee", "fee", "tax"].includes(term))
1762
+ fail(economicsExpr, `unknown fee economics leg ${term}`, "declare payee, fee or tax economics separately");
1763
+ const economics = lowerEconomics(feeEconomics ? feeEconomics.get("payee") : economicsExpr);
1680
1764
  if (op === "internal_transfer.create" ||
1681
1765
  op === "internal_transfer.reserve") {
1682
1766
  const amount = parts.get("amount"), from = parts.get("from"), to = parts.get("to");
@@ -1738,6 +1822,7 @@ export function compile(source, options = {}) {
1738
1822
  a.moves.push({
1739
1823
  key: `${key}_${index + 1}`,
1740
1824
  operation: "internal_transfer.create",
1825
+ ...(economics ? { economics } : {}),
1741
1826
  amount: piece,
1742
1827
  from: path(from),
1743
1828
  to: `party.${recipient.value}`,
@@ -1752,6 +1837,7 @@ export function compile(source, options = {}) {
1752
1837
  const transfer = {
1753
1838
  key,
1754
1839
  operation: op,
1840
+ ...(economics ? { economics } : {}),
1755
1841
  ...(parts.has("capture")
1756
1842
  ? { capture: String(data(parts.get("capture"))) }
1757
1843
  : {}),
@@ -1851,6 +1937,9 @@ export function compile(source, options = {}) {
1851
1937
  });
1852
1938
  a.moves.push({
1853
1939
  key: key + "Fee",
1940
+ ...(feeEconomics?.has("fee")
1941
+ ? { economics: lowerEconomics(feeEconomics.get("fee")) }
1942
+ : {}),
1854
1943
  operation: "internal_transfer.create",
1855
1944
  amount: charge,
1856
1945
  from: transfer.from,
@@ -1859,6 +1948,9 @@ export function compile(source, options = {}) {
1859
1948
  if (vat)
1860
1949
  a.moves.push({
1861
1950
  key: key + "Tax",
1951
+ ...(feeEconomics?.has("tax")
1952
+ ? { economics: lowerEconomics(feeEconomics.get("tax")) }
1953
+ : {}),
1862
1954
  operation: "internal_transfer.create",
1863
1955
  amount: vat,
1864
1956
  from: transfer.from,
@@ -1871,6 +1963,7 @@ export function compile(source, options = {}) {
1871
1963
  a.moves.push({
1872
1964
  key,
1873
1965
  operation: op,
1966
+ ...(economics ? { economics } : {}),
1874
1967
  transfer: path(parts.get("transfer")),
1875
1968
  ...(parts.has("capture")
1876
1969
  ? { capture: String(data(parts.get("capture"))) }
@@ -1957,6 +2050,7 @@ export function compile(source, options = {}) {
1957
2050
  origins.push({
1958
2051
  path: `$.instruments[${document.instruments.length}]`,
1959
2052
  span: { ...origin, ...lineColAt(source, origin.start) },
2053
+ ...(standardOrigin ? { standardBlock: standardOrigin } : {}),
1960
2054
  });
1961
2055
  if (familyDeclaration && familyDeclaration.revision !== undefined) {
1962
2056
  inst.family = {
@@ -2002,7 +2096,14 @@ export function compile(source, options = {}) {
2002
2096
  addInstrument(child, `${id}_${key}`, emptyBlock, origin, new Map([
2003
2097
  ...environment,
2004
2098
  ["parent", { kind: "name", value: id, span: origin }],
2005
- ]), enums, childAttachment, childFamily);
2099
+ ]), enums, childAttachment, childFamily, standardOrigin
2100
+ ? {
2101
+ ...standardOrigin,
2102
+ recordPath: [standardOrigin.recordPath, key]
2103
+ .filter(Boolean)
2104
+ .join("."),
2105
+ }
2106
+ : undefined);
2006
2107
  }
2007
2108
  };
2008
2109
  const compileObject = (decl) => {
@@ -2090,7 +2191,7 @@ export function compile(source, options = {}) {
2090
2191
  exposed,
2091
2192
  parties,
2092
2193
  attachments,
2093
- }, templateFamily ? { ...templateFamily } : undefined);
2194
+ }, templateFamily ? { ...templateFamily } : undefined, standardOrigins.get(template));
2094
2195
  }
2095
2196
  catch (error) {
2096
2197
  if (!(error instanceof CompileFailure))
@@ -2188,7 +2289,7 @@ export function compile(source, options = {}) {
2188
2289
  if (!template)
2189
2290
  fail(decl, `unknown instrument ${decl.target}`, `add use ${decl.target.split(".")[0]} and choose a declared instrument`);
2190
2291
  const templateFamily = resolveFamily(decl.target, decl, false);
2191
- addInstrument(template, decl.name, decl.body, decl.span, new Map(), new Map(), undefined, templateFamily ? { ...templateFamily } : undefined);
2292
+ addInstrument(template, decl.name, decl.body, decl.span, new Map(), new Map(), undefined, templateFamily ? { ...templateFamily } : undefined, standardOrigins.get(template));
2192
2293
  }
2193
2294
  if (decl.kind === "object") {
2194
2295
  compileObject(decl);