@hyperscale0/hsx 1.0.125 → 1.0.130
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/README.md +2 -2
- package/dist/src/cli.js +1 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/compile.d.ts.map +1 -1
- package/dist/src/compile.js +155 -21
- package/dist/src/compile.js.map +1 -1
- package/dist/src/examples-bundle.js +9 -9
- package/dist/src/examples-bundle.js.map +1 -1
- package/dist/src/headers.d.ts +1 -1
- package/dist/src/headers.d.ts.map +1 -1
- package/dist/src/headers.js +1 -0
- package/dist/src/headers.js.map +1 -1
- package/dist/src/parse.js +4 -1
- package/dist/src/parse.js.map +1 -1
- package/dist/src/std-bundle.d.ts.map +1 -1
- package/dist/src/std-bundle.js +8 -7
- package/dist/src/std-bundle.js.map +1 -1
- package/docs/README.md +102 -50
- package/examples/cards.hsx +4 -0
- package/examples/collections.hsx +5 -1
- package/examples/cost-table.json +80 -56
- package/examples/financing.hsx +1 -1
- package/examples/insurance.hsx +5 -4
- package/examples/lending.hsx +1 -1
- package/examples/library.hsx +1 -1
- package/examples/rental-deposit.hsx +1 -1
- package/examples/reporting.hsx +1 -1
- package/examples/serviced.hsx +1 -1
- package/package.json +4 -4
- package/src/cli.ts +1 -1
- package/src/compile.ts +223 -27
- package/src/examples-bundle.ts +9 -9
- package/src/headers.ts +1 -0
- package/src/parse.ts +4 -1
- package/src/std-bundle.ts +8 -7
- package/std/booking.hsx +75 -0
- package/std/cards.hsx +5 -3
- package/std/escrow.hsx +35 -9
- package/std/financing.hsx +158 -36
- package/std/insurance.hsx +9 -5
- package/std/marketplace.hsx +3 -3
- package/std/money.hsx +3 -3
- package/std/wallet.hsx +20 -9
package/README.md
CHANGED
|
@@ -21,8 +21,8 @@ Start with the [first program and rental guide](docs/README.md). Save the
|
|
|
21
21
|
It holds 1,000 SAR, charges a one-time 50 SAR late fee, and returns the remainder.
|
|
22
22
|
The guide explains the fixed business binding and the host needed to execute it.
|
|
23
23
|
|
|
24
|
-
`npx hsx headers` prints every std instrument and its tunables from the
|
|
25
|
-
headers. The [samples](examples/) include both complete action paths and
|
|
24
|
+
`npx hsx headers --json` prints every std instrument and its tunables from the
|
|
25
|
+
bundled headers as JSON. The [samples](examples/) include both complete action paths and
|
|
26
26
|
compositions that still need child-record actions or adapter bindings. A compile
|
|
27
27
|
pass does not prove that a flow is publicly executable or funded.
|
|
28
28
|
|
package/dist/src/cli.js
CHANGED
|
@@ -75,7 +75,7 @@ export async function runCli(argv, io) {
|
|
|
75
75
|
else {
|
|
76
76
|
const result = compile(source, { standardLibrary });
|
|
77
77
|
for (const d of result.diagnostics)
|
|
78
|
-
io.err(`${d.source && d.source !== "program" ? d.source : file}:${d.line}:${d.column}: ${d.code} ${d.message
|
|
78
|
+
io.err(`${d.source && d.source !== "program" ? d.source : file}:${d.line}:${d.column}: ${d.code} ${d.message.replace(/[^.?!]$/, "$&.")} ${d.fix}`);
|
|
79
79
|
if (!result.artifacts || result.verdict !== "valid")
|
|
80
80
|
return 1;
|
|
81
81
|
if (command === "check")
|
package/dist/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/compile.ts"],"names":[],"mappings":"AAOA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAgBL,KAAK,WAAW,EAQjB,MAAM,kBAAkB,CAAC;AAU1B,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,
|
|
1
|
+
{"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/compile.ts"],"names":[],"mappings":"AAOA,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAgBL,KAAK,WAAW,EAQjB,MAAM,kBAAkB,CAAC;AAU1B,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,CA6zHf"}
|
package/dist/src/compile.js
CHANGED
|
@@ -349,10 +349,6 @@ export function compile(source, options = {}) {
|
|
|
349
349
|
for (const decl of program.decls)
|
|
350
350
|
if (decl.kind === "instrument")
|
|
351
351
|
templates.set(decl.name, decl);
|
|
352
|
-
for (const decl of program.decls) {
|
|
353
|
-
if (decl.kind === "instrument" && decl.parameters.length)
|
|
354
|
-
fail(decl, "This compiler cannot instantiate a parameterized instrument declared inside a program.", "For this version, specialize the instrument with fixed bindings and remove its parameters. Custom reusable headers require a host-supplied library.");
|
|
355
|
-
}
|
|
356
352
|
const document = {
|
|
357
353
|
udl: UDL_FORMAT_VERSION,
|
|
358
354
|
version: 1,
|
|
@@ -600,7 +596,11 @@ export function compile(source, options = {}) {
|
|
|
600
596
|
const fallback = param.value.kind === "default" ? param.value.value : undefined;
|
|
601
597
|
const typeName = type.kind === "type" || type.kind === "call" ? type.name : text(type);
|
|
602
598
|
const partyParameter = attachmentInfo && typeName === "party";
|
|
599
|
+
const optional = type.kind === "type" && type.optional;
|
|
600
|
+
// An optional party stays unset unless the attachment binds it, so a
|
|
601
|
+
// program party that shares its name does not switch it on.
|
|
603
602
|
const byName = partyParameter &&
|
|
603
|
+
!optional &&
|
|
604
604
|
(subjectPartyRoles.includes(param.key) ||
|
|
605
605
|
document.parties[param.key])
|
|
606
606
|
? { kind: "name", value: param.key, span: origin }
|
|
@@ -612,7 +612,7 @@ export function compile(source, options = {}) {
|
|
|
612
612
|
source: declarationSources.get(decl) ?? "program",
|
|
613
613
|
});
|
|
614
614
|
if (!actual) {
|
|
615
|
-
if (
|
|
615
|
+
if (optional)
|
|
616
616
|
continue;
|
|
617
617
|
parameterErrors.push({
|
|
618
618
|
span: origin,
|
|
@@ -678,7 +678,9 @@ export function compile(source, options = {}) {
|
|
|
678
678
|
const suppliedValue = supplied.get(key);
|
|
679
679
|
const requirements = decl.body.entries
|
|
680
680
|
.filter((entry) => entry.key.startsWith("action "))
|
|
681
|
-
.flatMap((entry) =>
|
|
681
|
+
.flatMap((entry) =>
|
|
682
|
+
// Read subject rows directly: entries() refuses repeated when branches.
|
|
683
|
+
asBlock(asBlock(entry.value).entries.find((row) => row.key === "subject")?.value).entries);
|
|
682
684
|
const moneyFields = [
|
|
683
685
|
...new Set(requirements
|
|
684
686
|
.filter((entry) => {
|
|
@@ -708,6 +710,21 @@ export function compile(source, options = {}) {
|
|
|
708
710
|
(!!attachmentInfo &&
|
|
709
711
|
subjectPartyRoles.includes(name));
|
|
710
712
|
const resolvedParties = new Set();
|
|
713
|
+
// A party of a sibling attachment this one references, such as the
|
|
714
|
+
// borrower of `self.plan`, binds here the way it binds there.
|
|
715
|
+
const reachedParty = (name) => {
|
|
716
|
+
if (!attachmentInfo)
|
|
717
|
+
return;
|
|
718
|
+
const targets = fields.flatMap((field) => field.type === "ref" && field.targetKind === "instrument"
|
|
719
|
+
? [field.target].flat()
|
|
720
|
+
: []);
|
|
721
|
+
const bindings = attachmentInfo.attachments.flatMap((attachment) => targets.some((target) => target === attachment.instrument ||
|
|
722
|
+
target.startsWith(`${attachment.instrument}_`)) && attachment.parties[name]
|
|
723
|
+
? [attachment.parties[name]]
|
|
724
|
+
: []);
|
|
725
|
+
const distinct = new Set(bindings.map((item) => JSON.stringify(item)));
|
|
726
|
+
return distinct.size === 1 ? bindings[0] : undefined;
|
|
727
|
+
};
|
|
711
728
|
const resolve = (expr, seen = new Set(), partyBinding = false) => {
|
|
712
729
|
if (expr.kind === "call" &&
|
|
713
730
|
["object", "all", "party"].includes(expr.name)) {
|
|
@@ -737,6 +754,15 @@ export function compile(source, options = {}) {
|
|
|
737
754
|
const local = (name) => attachmentSubjects.has(name)
|
|
738
755
|
? name.slice(attachmentInfo.subjectKindId.length + 1)
|
|
739
756
|
: `${name} (program)`;
|
|
757
|
+
const elsewhere = [...assignments.values()]
|
|
758
|
+
.filter((assignment) => assignment.target === type &&
|
|
759
|
+
attachmentSubjects.has(assignment.name) &&
|
|
760
|
+
attachmentSubjects.get(assignment.name) !==
|
|
761
|
+
attachmentInfo.subjectKindId)
|
|
762
|
+
.map((assignment) => {
|
|
763
|
+
const subject = attachmentSubjects.get(assignment.name);
|
|
764
|
+
return `\`${subject}.${assignment.name.slice(subject.length + 1)}\``;
|
|
765
|
+
});
|
|
740
766
|
const target = templates.get(type);
|
|
741
767
|
const required = target?.parameters
|
|
742
768
|
.filter((p) => p.value.kind !== "default" &&
|
|
@@ -746,7 +772,7 @@ export function compile(source, options = {}) {
|
|
|
746
772
|
? `No \`${type}\` attachment exists on \`${attachmentInfo.subjectKindId}\`.`
|
|
747
773
|
: `Several \`${type}\` attachments match on \`${attachmentInfo.subjectKindId}\`: ${matches.map(local).join(", ")}.`}`, matches.length
|
|
748
774
|
? `Bind \`${parameter}\` explicitly to one of: ${matches.map(local).join(", ")}.`
|
|
749
|
-
: `
|
|
775
|
+
: `Attach \`${type}\` to \`${attachmentInfo.subjectKindId}\` and bind \`${parameter}\` to that attachment's name. Choose ${required.map((name) => (name.startsWith("per_") ? `its ${name.slice(4).replaceAll("_", " ")} limit` : `\`${name}\``)).join(", ") || "its required bindings"} explicitly.${elsewhere.length ? ` ${elsewhere.join(", ")} ${elsewhere.length === 1 ? "is" : "are"} on another object, which this binding cannot reach.` : ""}`);
|
|
750
776
|
}
|
|
751
777
|
if (expr.name !== "all" && matches.length !== 1)
|
|
752
778
|
failWithCode(expr, partyBinding ? "subject_party_unbound" : "HSX1001", `${id} needs ${expr.name === "all" ? "at least one" : "exactly one"} ${type}`, "declare the required object or supply this tunable explicitly");
|
|
@@ -1057,6 +1083,19 @@ export function compile(source, options = {}) {
|
|
|
1057
1083
|
value: `${id}_${key}`,
|
|
1058
1084
|
span: origin,
|
|
1059
1085
|
});
|
|
1086
|
+
// A subject role only has money here when this attachment binds it.
|
|
1087
|
+
const moneyPath = (expr) => {
|
|
1088
|
+
const lowered = path(expr);
|
|
1089
|
+
const role = lowered.slice("party.".length);
|
|
1090
|
+
if (attachmentInfo &&
|
|
1091
|
+
lowered.startsWith("party.") &&
|
|
1092
|
+
subjectPartyRoles.includes(role) &&
|
|
1093
|
+
!Object.values(attachmentInfo.parties).some((binding) => "role" in binding && binding.role === role))
|
|
1094
|
+
failWithCode(expr, "subject_party_unbound", `\`${role}\` has no money account in \`${decl.name}\``, role === "operator"
|
|
1095
|
+
? "Use `programOperator` for the company's own account."
|
|
1096
|
+
: `Add a party parameter to \`${decl.name}\` and bind it to \`${role}\` where you attach it.`);
|
|
1097
|
+
return lowered;
|
|
1098
|
+
};
|
|
1060
1099
|
const fields = [];
|
|
1061
1100
|
const calculations = [];
|
|
1062
1101
|
let currentAction;
|
|
@@ -1653,10 +1692,10 @@ export function compile(source, options = {}) {
|
|
|
1653
1692
|
};
|
|
1654
1693
|
}
|
|
1655
1694
|
}
|
|
1656
|
-
const
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1695
|
+
const from = slots.get("from");
|
|
1696
|
+
// A policy member may sit in a state list such as `[funded, dispute.refund_after]`.
|
|
1697
|
+
const fromBinding = (from?.kind === "list" ? from.items : [from]).find((item) => item?.kind === "name" && item.value.includes("."));
|
|
1698
|
+
if (fromBinding?.kind === "name" && slots.has("moves")) {
|
|
1660
1699
|
const [parameter, member] = fromBinding.value.split(".");
|
|
1661
1700
|
const suppliedPolicy = supplied.get(parameter);
|
|
1662
1701
|
if (suppliedPolicy?.kind === "block") {
|
|
@@ -1693,6 +1732,7 @@ export function compile(source, options = {}) {
|
|
|
1693
1732
|
...(actionSubject ? { subject: actionSubject } : {}),
|
|
1694
1733
|
};
|
|
1695
1734
|
authored.set(a, row.value);
|
|
1735
|
+
const actionFeeCalculations = [];
|
|
1696
1736
|
for (const binding of boundaryBindings)
|
|
1697
1737
|
if (!a.subject?.adapters.find((entry) => entry.binding === binding)
|
|
1698
1738
|
?.snapshot)
|
|
@@ -1777,9 +1817,17 @@ export function compile(source, options = {}) {
|
|
|
1777
1817
|
"pass_through",
|
|
1778
1818
|
].includes(purposeName))
|
|
1779
1819
|
fail(purpose, `unknown economic purpose ${purposeName}`, "choose a declared economic purpose");
|
|
1780
|
-
|
|
1820
|
+
let sourcePartyName = sourceParty
|
|
1781
1821
|
? String(data(sourceParty))
|
|
1782
1822
|
: undefined;
|
|
1823
|
+
const reached = sourcePartyName && !isParty(sourcePartyName)
|
|
1824
|
+
? reachedParty(sourcePartyName)
|
|
1825
|
+
: undefined;
|
|
1826
|
+
if (reached) {
|
|
1827
|
+
attachmentInfo.parties[sourcePartyName] = reached;
|
|
1828
|
+
sourcePartyName =
|
|
1829
|
+
"role" in reached ? reached.role : reached.party;
|
|
1830
|
+
}
|
|
1783
1831
|
if (sourcePartyName && !isParty(sourcePartyName))
|
|
1784
1832
|
fail(sourceParty, `unknown source party ${sourcePartyName}`, "bind an authored party");
|
|
1785
1833
|
return economicsParts
|
|
@@ -1866,7 +1914,7 @@ export function compile(source, options = {}) {
|
|
|
1866
1914
|
operation: "internal_transfer.create",
|
|
1867
1915
|
...(economics ? { economics } : {}),
|
|
1868
1916
|
amount: piece,
|
|
1869
|
-
from:
|
|
1917
|
+
from: moneyPath(from),
|
|
1870
1918
|
to: `party.${recipient.value}`,
|
|
1871
1919
|
});
|
|
1872
1920
|
}
|
|
@@ -1886,8 +1934,8 @@ export function compile(source, options = {}) {
|
|
|
1886
1934
|
? { capture: String(data(parts.get("capture"))) }
|
|
1887
1935
|
: {}),
|
|
1888
1936
|
amount: val(amount),
|
|
1889
|
-
from:
|
|
1890
|
-
to:
|
|
1937
|
+
from: moneyPath(from),
|
|
1938
|
+
to: moneyPath(to),
|
|
1891
1939
|
};
|
|
1892
1940
|
const fee = parts.get("fee");
|
|
1893
1941
|
if (!fee)
|
|
@@ -1920,12 +1968,21 @@ export function compile(source, options = {}) {
|
|
|
1920
1968
|
if (rate.kind !== "percent")
|
|
1921
1969
|
fail(rate, "fee rate needs a percentage", "write a percentage such as 1%");
|
|
1922
1970
|
const prefix = `${name}_${key}`;
|
|
1971
|
+
// Instrument calculations run at create, before any action
|
|
1972
|
+
// input exists, so a fee on an input amount runs with its action.
|
|
1973
|
+
const perAction = "field" in transfer.amount &&
|
|
1974
|
+
transfer.amount.field.startsWith("input.");
|
|
1923
1975
|
const derived = (suffix, label, calculation) => {
|
|
1924
1976
|
const target = prefix + "_" + suffix;
|
|
1925
1977
|
if (fields.some((f) => f.name === target))
|
|
1926
1978
|
fail(move, `generated fee field ${target} conflicts with a field`, "rename the authored field or move key");
|
|
1927
|
-
fields.push({
|
|
1928
|
-
|
|
1979
|
+
fields.push({
|
|
1980
|
+
name: target,
|
|
1981
|
+
type: "money",
|
|
1982
|
+
label,
|
|
1983
|
+
...(perAction ? { optional: true } : {}),
|
|
1984
|
+
});
|
|
1985
|
+
(perAction ? actionFeeCalculations : calculations).push({
|
|
1929
1986
|
...calculation,
|
|
1930
1987
|
target,
|
|
1931
1988
|
});
|
|
@@ -2026,6 +2083,8 @@ export function compile(source, options = {}) {
|
|
|
2026
2083
|
else
|
|
2027
2084
|
a[key] = data(expr);
|
|
2028
2085
|
}
|
|
2086
|
+
if (actionFeeCalculations.length)
|
|
2087
|
+
a.calculate = [...(a.calculate ?? []), ...actionFeeCalculations];
|
|
2029
2088
|
if (attachmentInfo && !attachmentInfo.child) {
|
|
2030
2089
|
if (attachmentInfo.exposed.has(name)) {
|
|
2031
2090
|
if (automatic(a.actor))
|
|
@@ -2080,6 +2139,20 @@ export function compile(source, options = {}) {
|
|
|
2080
2139
|
message: `${id}.${name}.subject.${requirement.field.name}`,
|
|
2081
2140
|
});
|
|
2082
2141
|
}
|
|
2142
|
+
// A parent actor over an empty all() names no instrument that could
|
|
2143
|
+
// invoke the action. A std action then does not exist in this program;
|
|
2144
|
+
// in user code the all() is a mistake.
|
|
2145
|
+
if (typeof a.actor === "object" &&
|
|
2146
|
+
"parent" in a.actor &&
|
|
2147
|
+
Array.isArray(a.actor.parent) &&
|
|
2148
|
+
!a.actor.parent.length) {
|
|
2149
|
+
if ((declarationSources.get(decl) ?? "program") === "program") {
|
|
2150
|
+
const parent = entries(asBlock(slots.get("actor"))).get("parent");
|
|
2151
|
+
fail(parent ?? row, `${parent?.kind === "call" ? `${parent.name}(${text(parent.args[0])})` : `the parent actor of ${name}`} matches no instrument`, "name an instrument this program declares or attaches");
|
|
2152
|
+
}
|
|
2153
|
+
delete lifecycle.transitions[name];
|
|
2154
|
+
continue;
|
|
2155
|
+
}
|
|
2083
2156
|
inst.actions[name] = a;
|
|
2084
2157
|
inst.actionOrder.push(name);
|
|
2085
2158
|
}
|
|
@@ -2377,7 +2450,9 @@ export function compile(source, options = {}) {
|
|
|
2377
2450
|
});
|
|
2378
2451
|
};
|
|
2379
2452
|
for (const decl of program.decls) {
|
|
2380
|
-
|
|
2453
|
+
// A parameterized program instrument is a template, like a header
|
|
2454
|
+
// instrument: each attachment instantiates it with its own bindings.
|
|
2455
|
+
if (decl.kind === "instrument" && !decl.parameters.length) {
|
|
2381
2456
|
addInstrument(decl, decl.name, emptyBlock, decl.span);
|
|
2382
2457
|
}
|
|
2383
2458
|
if (decl.kind === "assignment") {
|
|
@@ -2632,7 +2707,9 @@ export function compile(source, options = {}) {
|
|
|
2632
2707
|
const checkParty = (name, at, inst) => {
|
|
2633
2708
|
const names = parties(inst);
|
|
2634
2709
|
if (!names.includes(name))
|
|
2635
|
-
fail(at, `\`${name}\` is not a declared party.${didYouMean(name, names)}`,
|
|
2710
|
+
fail(at, `\`${name}\` is not a declared party.${didYouMean(name, names)}`, subjectPartyRoles.includes(name)
|
|
2711
|
+
? `Declare a party parameter such as \`holder: party\` on the instrument, use it here, and bind \`holder: ${name}\` where you attach it.`
|
|
2712
|
+
: `Declare it with \`party ${name}: business\`, or name a declared party (${names.join(", ")}).`);
|
|
2636
2713
|
};
|
|
2637
2714
|
const checkInput = (name, at, label, input) => {
|
|
2638
2715
|
const names = input.map((field) => field.name);
|
|
@@ -2685,9 +2762,61 @@ export function compile(source, options = {}) {
|
|
|
2685
2762
|
inst,
|
|
2686
2763
|
label: declarations.get(inst).name,
|
|
2687
2764
|
});
|
|
2765
|
+
// A family member drops an optional reference field its binding left
|
|
2766
|
+
// unset (a borrower-funded plan has no `funds`), so it cannot match and
|
|
2767
|
+
// leaves the selection. The header must still declare the field.
|
|
2768
|
+
const declaredMembers = (selection) => {
|
|
2769
|
+
const members = [selection.instrument].flat();
|
|
2770
|
+
const header = selection.family
|
|
2771
|
+
? templates.get(`${selection.family.module}.${selection.family.exportPath}`)
|
|
2772
|
+
: undefined;
|
|
2773
|
+
if (!header ||
|
|
2774
|
+
!entries(asBlock(entries(header.body).get("fields"))).has(selection.reference))
|
|
2775
|
+
return members;
|
|
2776
|
+
return members.filter((id) => resolveField(document, byId.get(id), `self.${selection.reference}`));
|
|
2777
|
+
};
|
|
2778
|
+
// A member whose reference points at another attachment of the anchor's
|
|
2779
|
+
// own template (the plan funding another object's escrow) cannot match
|
|
2780
|
+
// either, so each object only selects what can reference it.
|
|
2781
|
+
const kin = (a, b) => {
|
|
2782
|
+
const left = byId.get(a);
|
|
2783
|
+
const right = byId.get(b);
|
|
2784
|
+
return (!!left && !!right && declarations.get(left) === declarations.get(right));
|
|
2785
|
+
};
|
|
2786
|
+
const matchable = (selection, inst, action) => declaredMembers(selection).filter((id) => {
|
|
2787
|
+
const member = byId.get(id);
|
|
2788
|
+
if (!member)
|
|
2789
|
+
return true;
|
|
2790
|
+
const anchor = resolveField(document, inst, selection.anchor, action?.input, action);
|
|
2791
|
+
const reference = resolveField(document, member, `self.${selection.reference}`);
|
|
2792
|
+
if (anchor?.type !== "ref" || reference?.type !== "ref")
|
|
2793
|
+
return true;
|
|
2794
|
+
const targets = [anchor.target].flat();
|
|
2795
|
+
const candidates = [reference.target].flat();
|
|
2796
|
+
return !candidates.every((candidate) => !targets.includes(candidate) &&
|
|
2797
|
+
targets.some((target) => kin(target, candidate)));
|
|
2798
|
+
});
|
|
2799
|
+
// A count over no matchable member is zero.
|
|
2800
|
+
for (const inst of document.instruments)
|
|
2801
|
+
for (const action of Object.values(inst.actions))
|
|
2802
|
+
action.requires = action.requires.map((requirement) => requirement.kind === "aggregate" &&
|
|
2803
|
+
requirement.measure === "count" &&
|
|
2804
|
+
!matchable(requirement.selection, inst, action).length
|
|
2805
|
+
? {
|
|
2806
|
+
kind: "compare",
|
|
2807
|
+
left: { literal: 0 },
|
|
2808
|
+
operator: requirement.operator,
|
|
2809
|
+
right: requirement.value,
|
|
2810
|
+
}
|
|
2811
|
+
: requirement);
|
|
2688
2812
|
const checkSelection = (selection, at, scope) => {
|
|
2813
|
+
walk(selection.overlaps, "overlaps", site(selection, "overlaps", at), scope);
|
|
2689
2814
|
walk(selection.anchor, "anchor", site(selection, "anchor", at), scope);
|
|
2690
2815
|
walk(selection.where, "where", site(selection, "where", at), scope);
|
|
2816
|
+
const members = matchable(selection, scope.inst, scope.action);
|
|
2817
|
+
if (members.length &&
|
|
2818
|
+
members.length < [selection.instrument].flat().length)
|
|
2819
|
+
selection.instrument = members;
|
|
2691
2820
|
for (const id of [selection.instrument].flat()) {
|
|
2692
2821
|
checkTarget(id, site(selection, "instrument", at));
|
|
2693
2822
|
const target = scopeOf(byId.get(id));
|
|
@@ -2696,6 +2825,9 @@ export function compile(source, options = {}) {
|
|
|
2696
2825
|
member(key, keySite(selection.where, key, at));
|
|
2697
2826
|
member(selection.reference, site(selection, "reference", at));
|
|
2698
2827
|
selection.order?.forEach((key, index) => member(key, site(selection.order, index, at)));
|
|
2828
|
+
if (selection.overlaps)
|
|
2829
|
+
for (const key of ["start", "end"])
|
|
2830
|
+
member(selection.overlaps[key], site(selection.overlaps, key, at));
|
|
2699
2831
|
if (selection.window)
|
|
2700
2832
|
member(selection.window.field, site(selection.window, "field", at));
|
|
2701
2833
|
}
|
|
@@ -2921,12 +3053,14 @@ export function compile(source, options = {}) {
|
|
|
2921
3053
|
?.find((binding) => binding.defaultState === stranded.state &&
|
|
2922
3054
|
instrument.actions[binding.action]?.moves.some((move) => "amount" in move &&
|
|
2923
3055
|
stranded.accounts.some((account) => move.from === `self.${account}`)));
|
|
3056
|
+
const reaching = stranded.actions.at(-1);
|
|
3057
|
+
const drain = `move ${stranded.accounts.map((account) => `\`self.${account}.balance\``).join(" and ")} out in ${reaching ? `\`${reaching}\`` : "the action that reaches it"}, or add an action from \`${stranded.state}\` that does`;
|
|
2924
3058
|
return diagnostic({
|
|
2925
3059
|
code: i.code,
|
|
2926
3060
|
message: `\`${attachment?.name ?? instrument.id}\` can reach \`${stranded.state}\` with money in ${stranded.accounts.map((account) => `\`${account}\``).join(", ")}, but no action leaves that state and disposes of the balance.`,
|
|
2927
3061
|
fix: binding
|
|
2928
|
-
? `Restore \`${binding.parameter}: ${stranded.state}\`, or
|
|
2929
|
-
:
|
|
3062
|
+
? `Restore \`${binding.parameter}: ${stranded.state}\`, or ${drain}.`
|
|
3063
|
+
: `${drain[0].toUpperCase()}${drain.slice(1)}.`,
|
|
2930
3064
|
span: binding?.span ?? origin?.span ?? program.span,
|
|
2931
3065
|
related: stranded.accounts.map((account) => ({
|
|
2932
3066
|
source: "program",
|