@hyperscale0/hsx 1.0.330 → 1.0.334
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/dist/src/catalog-program.d.ts +7 -0
- package/dist/src/catalog-program.d.ts.map +1 -0
- package/dist/src/catalog-program.js +66 -0
- package/dist/src/catalog-program.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/template-guide.d.ts +57 -0
- package/dist/src/template-guide.d.ts.map +1 -0
- package/dist/src/template-guide.js +421 -0
- package/dist/src/template-guide.js.map +1 -0
- package/package.json +4 -4
- package/src/catalog-program.ts +65 -0
- package/src/index.ts +6 -0
- package/src/template-guide.ts +567 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One program that attaches every standard template with bindings the
|
|
3
|
+
* compiler admits. Each template guide takes its example from here, and
|
|
4
|
+
* std-headers.spec proves the whole program compiles.
|
|
5
|
+
*/
|
|
6
|
+
export declare const catalogProgramSource = "program catalog \"Template catalog\"\nuse money\nuse escrow\nuse purchase\nuse booking\nuse marketplace\nuse financing\nuse insurance\nuse lending\nuse wallet\nuse cards\nuse collections\nuse savings\nuse reporting\nparty supplier: business\nparty inspector: staff role claim_inspector\nparty investor: business\nobject item \"Item\" {\n attach transfer = money.transfer { payer: actor, payee: owner, amount: 750 SAR }\n attach hold = money.hold { payer: actor, payee: owner, amount: 750 SAR }\n attach split = money.split { payer: actor, amount: 750 SAR }\n attach schedule = money.schedule { payer: actor, payee: owner, amount: 750 SAR, count: 3 }\n attach pool = money.pool { payer: actor, payee: owner, target: 1000 SAR, closes: 2027-01-01 }\n attach swap = money.swap { first: actor, second: owner, first_amount: 100 SAR, second_amount: 200 SAR, expires: 2027-01-01 }\n attach payout = money.payout { payer: actor, payee: owner, adapter: \"conformance_boundary\" }\n attach mandate = money.mandate { payer: actor, payee: owner }\n attach metered = money.metered { payer: actor, payee: owner, unit_price: 10 SAR }\n attach policy = insurance.cover { holder: actor, adapter: \"conformance_boundary\" }\n attach claim = insurance.claim { cover: policy, inspector: inspector }\n attach cov = insurance.cover { holder: actor, broker: supplier, adapter: \"conformance_boundary\", covers: sale }\n attach deposit = escrow.hold { payer: actor, payee: owner }\n attach sale = escrow.hold { funding: { controllers: [checkout], reference: \"funds\", blocking_states: [active] }, payer: actor, payee: owner }\n attach trip = booking.reservation { customer: actor, operator: owner }\n attach limits = financing.limits { borrower: actor, per_borrower: 60000 SAR }\n attach ceiling = financing.portfolio_limit { limit: 1500000 SAR }\n attach checkout = purchase.checkout { plans: plan, funds: sale, borrower: actor, capital: operator }\n attach plan = financing.installments { borrower: actor, capital: operator, months: 3, pricing: flat_total, profit_rate: 2.5%, down_payment: 20%, funds: checkout, limits: limits, portfolio: ceiling }\n attach late = financing.late_charge { on: plan, borrower: actor }\n attach line = financing.credit_line { borrower: operator, adapter: \"conformance_boundary\", limit: 100000 SAR, expires: 2027-01-01 }\n attach advance = financing.advance { line: line }\n attach case = collections.case { on: plan, agency: supplier }\n attach contact = collections.contact { case: case, agency: supplier }\n attach reminder = collections.reminder { on: plan }\n attach wallet = wallet.balance { holder: investor }\n attach spend = wallet.spend { wallet: wallet, payee: supplier, holder: investor }\n attach round = lending.round { borrower: actor, plan: plan, minimum_ticket: 100 SAR, investor_cap: 100% }\n attach commitment = lending.commitment { round: round, wallet: wallet, investor: investor }\n attach distribution = lending.distribution { round: round, receipt: plan.settlement }\n attach cardholder = cards.cardholder { holder: actor }\n attach card = cards.card { holder: cardholder, person: actor, spend_limit: 5000 SAR }\n attach authorization = cards.authorization { card: card, merchant: supplier }\n attach transaction = cards.transaction { authorization: authorization }\n attach dispute = cards.dispute { transaction: transaction }\n attach listing = marketplace.listing { seller: owner }\n attach order = marketplace.order { listing: listing, buyer: actor }\n attach reservation = marketplace.reservation { listing: listing, funds: sale, converters: checkout, buyer: actor, seller: owner }\n attach circle = savings.circle { contribution: 300 SAR, members: 8, starts: 2027-01-01 }\n attach membership = savings.membership { circle: circle, member: actor }\n attach reports = reporting.portfolio { on: plan }\n}";
|
|
7
|
+
//# sourceMappingURL=catalog-program.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-program.d.ts","sourceRoot":"","sources":["../../src/catalog-program.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,swHA2D/B,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One program that attaches every standard template with bindings the
|
|
3
|
+
* compiler admits. Each template guide takes its example from here, and
|
|
4
|
+
* std-headers.spec proves the whole program compiles.
|
|
5
|
+
*/
|
|
6
|
+
export const catalogProgramSource = `program catalog "Template catalog"
|
|
7
|
+
use money
|
|
8
|
+
use escrow
|
|
9
|
+
use purchase
|
|
10
|
+
use booking
|
|
11
|
+
use marketplace
|
|
12
|
+
use financing
|
|
13
|
+
use insurance
|
|
14
|
+
use lending
|
|
15
|
+
use wallet
|
|
16
|
+
use cards
|
|
17
|
+
use collections
|
|
18
|
+
use savings
|
|
19
|
+
use reporting
|
|
20
|
+
party supplier: business
|
|
21
|
+
party inspector: staff role claim_inspector
|
|
22
|
+
party investor: business
|
|
23
|
+
object item "Item" {
|
|
24
|
+
attach transfer = money.transfer { payer: actor, payee: owner, amount: 750 SAR }
|
|
25
|
+
attach hold = money.hold { payer: actor, payee: owner, amount: 750 SAR }
|
|
26
|
+
attach split = money.split { payer: actor, amount: 750 SAR }
|
|
27
|
+
attach schedule = money.schedule { payer: actor, payee: owner, amount: 750 SAR, count: 3 }
|
|
28
|
+
attach pool = money.pool { payer: actor, payee: owner, target: 1000 SAR, closes: 2027-01-01 }
|
|
29
|
+
attach swap = money.swap { first: actor, second: owner, first_amount: 100 SAR, second_amount: 200 SAR, expires: 2027-01-01 }
|
|
30
|
+
attach payout = money.payout { payer: actor, payee: owner, adapter: "conformance_boundary" }
|
|
31
|
+
attach mandate = money.mandate { payer: actor, payee: owner }
|
|
32
|
+
attach metered = money.metered { payer: actor, payee: owner, unit_price: 10 SAR }
|
|
33
|
+
attach policy = insurance.cover { holder: actor, adapter: "conformance_boundary" }
|
|
34
|
+
attach claim = insurance.claim { cover: policy, inspector: inspector }
|
|
35
|
+
attach cov = insurance.cover { holder: actor, broker: supplier, adapter: "conformance_boundary", covers: sale }
|
|
36
|
+
attach deposit = escrow.hold { payer: actor, payee: owner }
|
|
37
|
+
attach sale = escrow.hold { funding: { controllers: [checkout], reference: "funds", blocking_states: [active] }, payer: actor, payee: owner }
|
|
38
|
+
attach trip = booking.reservation { customer: actor, operator: owner }
|
|
39
|
+
attach limits = financing.limits { borrower: actor, per_borrower: 60000 SAR }
|
|
40
|
+
attach ceiling = financing.portfolio_limit { limit: 1500000 SAR }
|
|
41
|
+
attach checkout = purchase.checkout { plans: plan, funds: sale, borrower: actor, capital: operator }
|
|
42
|
+
attach plan = financing.installments { borrower: actor, capital: operator, months: 3, pricing: flat_total, profit_rate: 2.5%, down_payment: 20%, funds: checkout, limits: limits, portfolio: ceiling }
|
|
43
|
+
attach late = financing.late_charge { on: plan, borrower: actor }
|
|
44
|
+
attach line = financing.credit_line { borrower: operator, adapter: "conformance_boundary", limit: 100000 SAR, expires: 2027-01-01 }
|
|
45
|
+
attach advance = financing.advance { line: line }
|
|
46
|
+
attach case = collections.case { on: plan, agency: supplier }
|
|
47
|
+
attach contact = collections.contact { case: case, agency: supplier }
|
|
48
|
+
attach reminder = collections.reminder { on: plan }
|
|
49
|
+
attach wallet = wallet.balance { holder: investor }
|
|
50
|
+
attach spend = wallet.spend { wallet: wallet, payee: supplier, holder: investor }
|
|
51
|
+
attach round = lending.round { borrower: actor, plan: plan, minimum_ticket: 100 SAR, investor_cap: 100% }
|
|
52
|
+
attach commitment = lending.commitment { round: round, wallet: wallet, investor: investor }
|
|
53
|
+
attach distribution = lending.distribution { round: round, receipt: plan.settlement }
|
|
54
|
+
attach cardholder = cards.cardholder { holder: actor }
|
|
55
|
+
attach card = cards.card { holder: cardholder, person: actor, spend_limit: 5000 SAR }
|
|
56
|
+
attach authorization = cards.authorization { card: card, merchant: supplier }
|
|
57
|
+
attach transaction = cards.transaction { authorization: authorization }
|
|
58
|
+
attach dispute = cards.dispute { transaction: transaction }
|
|
59
|
+
attach listing = marketplace.listing { seller: owner }
|
|
60
|
+
attach order = marketplace.order { listing: listing, buyer: actor }
|
|
61
|
+
attach reservation = marketplace.reservation { listing: listing, funds: sale, converters: checkout, buyer: actor, seller: owner }
|
|
62
|
+
attach circle = savings.circle { contribution: 300 SAR, members: 8, starts: 2027-01-01 }
|
|
63
|
+
attach membership = savings.membership { circle: circle, member: actor }
|
|
64
|
+
attach reports = reporting.portfolio { on: plan }
|
|
65
|
+
}`;
|
|
66
|
+
//# sourceMappingURL=catalog-program.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-program.js","sourceRoot":"","sources":["../../src/catalog-program.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2DlC,CAAC"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -7,4 +7,5 @@ export { bundledStandardLibrary, type StandardLibrary } from "./std-library.ts";
|
|
|
7
7
|
export { buildUdlCostManifest, type UdlCostManifest } from "./cost.ts";
|
|
8
8
|
export type { Program, Decl, AssignmentDecl, ObjectDecl, InstrumentDecl, Expr, Span, Diagnostic, } from "./ast.ts";
|
|
9
9
|
export { headerManifest, HEADER_NAMES } from "./headers.ts";
|
|
10
|
+
export { templateGuide, templateIndex, type TemplateGuide, type TemplateIndexEntry, } from "./template-guide.ts";
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,YAAY,EACV,OAAO,EACP,IAAI,EACJ,cAAc,EACd,UAAU,EACV,cAAc,EACd,IAAI,EACJ,IAAI,EACJ,UAAU,GACX,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AACvE,YAAY,EACV,OAAO,EACP,IAAI,EACJ,cAAc,EACd,UAAU,EACV,cAAc,EACd,IAAI,EACJ,IAAI,EACJ,UAAU,GACX,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EACL,aAAa,EACb,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -5,4 +5,5 @@ export { format } from "./format.js";
|
|
|
5
5
|
export { bundledStandardLibrary } from "./std-library.js";
|
|
6
6
|
export { buildUdlCostManifest } from "./cost.js";
|
|
7
7
|
export { headerManifest, HEADER_NAMES } from "./headers.js";
|
|
8
|
+
export { templateGuide, templateIndex, } from "./template-guide.js";
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,GAMR,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAwB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAwB,MAAM,WAAW,CAAC;AAYvE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,GAMR,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAwB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAwB,MAAM,WAAW,CAAC;AAYvE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EACL,aAAa,EACb,aAAa,GAGd,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type CompileOptions } from "./compile.ts";
|
|
2
|
+
import { type StandardLibrary } from "./std-library.ts";
|
|
3
|
+
export interface TemplateIndexEntry {
|
|
4
|
+
qualifiedName: string;
|
|
5
|
+
summary: string;
|
|
6
|
+
parties: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface TemplateGuideAction {
|
|
9
|
+
name: string;
|
|
10
|
+
runBy: string;
|
|
11
|
+
from?: string;
|
|
12
|
+
to?: string;
|
|
13
|
+
due?: string;
|
|
14
|
+
deadline?: string;
|
|
15
|
+
requires?: string[];
|
|
16
|
+
moves?: string[];
|
|
17
|
+
invokes?: string[];
|
|
18
|
+
when?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface TemplateGuide {
|
|
21
|
+
qualifiedName: string;
|
|
22
|
+
summary: string;
|
|
23
|
+
signature: string;
|
|
24
|
+
use: string;
|
|
25
|
+
states: string[];
|
|
26
|
+
tunables: Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
type: string;
|
|
29
|
+
required: boolean;
|
|
30
|
+
default?: string;
|
|
31
|
+
meaning: string;
|
|
32
|
+
}>;
|
|
33
|
+
createInput: Array<{
|
|
34
|
+
name: string;
|
|
35
|
+
type: string;
|
|
36
|
+
}>;
|
|
37
|
+
subject: Array<{
|
|
38
|
+
name: string;
|
|
39
|
+
type: string;
|
|
40
|
+
}>;
|
|
41
|
+
actions: TemplateGuideAction[];
|
|
42
|
+
example: string;
|
|
43
|
+
notes: string[];
|
|
44
|
+
}
|
|
45
|
+
/** One line per template, small enough to read whole. */
|
|
46
|
+
export declare function templateIndex(library?: StandardLibrary): TemplateIndexEntry[];
|
|
47
|
+
/**
|
|
48
|
+
* Everything an author needs for one template, spelled from its std
|
|
49
|
+
* declaration and proved by compiling its example. Undefined when the
|
|
50
|
+
* catalog has no such template.
|
|
51
|
+
*/
|
|
52
|
+
export declare function templateGuide(qualifiedName: string, options?: GuideOptions): TemplateGuide | undefined;
|
|
53
|
+
type GuideOptions = Pick<CompileOptions, "adapterRegistry"> & {
|
|
54
|
+
library?: StandardLibrary;
|
|
55
|
+
};
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=template-guide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-guide.d.ts","sourceRoot":"","sources":["../../src/template-guide.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAI5D,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AASD,yDAAyD;AACzD,wBAAgB,aAAa,CAC3B,OAAO,GAAE,eAAwC,GAChD,kBAAkB,EAAE,CAQtB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,YAAiB,GACzB,aAAa,GAAG,SAAS,CAgE3B;AAoYD,KAAK,YAAY,GAAG,IAAI,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG;IAC5D,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B,CAAC"}
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import { catalogProgramSource } from "./catalog-program.js";
|
|
2
|
+
import { compile } from "./compile.js";
|
|
3
|
+
import { parseHeader } from "./header-source.js";
|
|
4
|
+
import { headerManifest, HEADER_NAMES } from "./headers.js";
|
|
5
|
+
import { parseProgram } from "./parse.js";
|
|
6
|
+
import { bundledStandardLibrary } from "./std-library.js";
|
|
7
|
+
// How to read runBy, the same for every template.
|
|
8
|
+
const RUN_BY_NOTE = "runBy names who runs each action: a party is whoever the attach binds to it (owner, actor, operator or a declared business), clock is the platform when the action falls due, parent runs only inside its parent record's action, and caller is anyone the exposed action admits.";
|
|
9
|
+
const SUBJECT_NOTE = "subject names fields the attached object must carry, or rename to with rename { field: yourField }, before the actions that read them can run.";
|
|
10
|
+
/** One line per template, small enough to read whole. */
|
|
11
|
+
export function templateIndex(library = bundledStandardLibrary) {
|
|
12
|
+
return headerManifest(library).headers.flatMap((header) => header.objects.map((object) => ({
|
|
13
|
+
qualifiedName: object.qualifiedName,
|
|
14
|
+
summary: object.summary,
|
|
15
|
+
parties: object.parties,
|
|
16
|
+
})));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Everything an author needs for one template, spelled from its std
|
|
20
|
+
* declaration and proved by compiling its example. Undefined when the
|
|
21
|
+
* catalog has no such template.
|
|
22
|
+
*/
|
|
23
|
+
export function templateGuide(qualifiedName, options = {}) {
|
|
24
|
+
const library = options.library ?? bundledStandardLibrary;
|
|
25
|
+
const [header, name, extra] = qualifiedName.split(".");
|
|
26
|
+
if (!header || !name || extra !== undefined)
|
|
27
|
+
return undefined;
|
|
28
|
+
if (!HEADER_NAMES.includes(header))
|
|
29
|
+
return undefined;
|
|
30
|
+
const source = library.source(header);
|
|
31
|
+
if (!source)
|
|
32
|
+
return undefined;
|
|
33
|
+
const manifest = headerManifest(library, [header]).headers[0].objects.find((object) => object.name === name);
|
|
34
|
+
const decl = parseHeader(source, header).decls.find((d) => d.kind === "instrument" && d.name === name);
|
|
35
|
+
if (!manifest || !decl)
|
|
36
|
+
return undefined;
|
|
37
|
+
const spell = (expression) => source
|
|
38
|
+
.slice(expression.span.start, expression.span.end)
|
|
39
|
+
.trim()
|
|
40
|
+
.replace(/\s+/g, " ");
|
|
41
|
+
const actions = guideActions(decl.body, spell);
|
|
42
|
+
// Compile once bare, then expose each root action a party or caller runs
|
|
43
|
+
// that these bindings keep, and compile again to prove the example.
|
|
44
|
+
const example = exampleProgram(qualifiedName, library);
|
|
45
|
+
const bare = compiledAttachment(example.render([]), example.attachment, options);
|
|
46
|
+
const exposes = actions
|
|
47
|
+
.filter((action) => !action.name.includes(".") &&
|
|
48
|
+
!["clock", "parent"].includes(action.runBy) &&
|
|
49
|
+
bare.actions[action.name])
|
|
50
|
+
.map((action) => `expose ${action.name}`);
|
|
51
|
+
const program = example.render(exposes);
|
|
52
|
+
const create = compiledAttachment(program, example.attachment, options)
|
|
53
|
+
.actions.create;
|
|
54
|
+
return {
|
|
55
|
+
qualifiedName,
|
|
56
|
+
summary: manifest.summary,
|
|
57
|
+
signature: manifest.signature,
|
|
58
|
+
use: `use ${header}`,
|
|
59
|
+
states: manifest.states,
|
|
60
|
+
tunables: manifest.tunables.map((tunable) => ({
|
|
61
|
+
name: tunable.name,
|
|
62
|
+
type: tunable.type,
|
|
63
|
+
required: tunable.required,
|
|
64
|
+
...(tunable.default ? { default: tunable.default } : {}),
|
|
65
|
+
meaning: tunable.type === "party" || tunable.type === "party?"
|
|
66
|
+
? partyMeaning(tunable.name, actions)
|
|
67
|
+
: valueMeaning(tunable.name, tunable.default, decl, spell),
|
|
68
|
+
})),
|
|
69
|
+
createInput: (create?.input ?? []).map((field) => ({
|
|
70
|
+
name: field.name,
|
|
71
|
+
type: inputType(field),
|
|
72
|
+
})),
|
|
73
|
+
subject: manifest.subject,
|
|
74
|
+
actions,
|
|
75
|
+
example: program,
|
|
76
|
+
notes: [RUN_BY_NOTE, ...(manifest.subject.length ? [SUBJECT_NOTE] : [])],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function slot(block, key) {
|
|
80
|
+
return block.entries.find((entry) => entry.key === key)?.value;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The parser desugars `requires` and `moves` into blocks without source
|
|
84
|
+
* spans, so each clause is spelled from the slot's own source text.
|
|
85
|
+
*/
|
|
86
|
+
function clauses(action, key, spell) {
|
|
87
|
+
return action.entries
|
|
88
|
+
.filter((entry) => entry.key === key)
|
|
89
|
+
.flatMap((entry) => spell(entry.value)
|
|
90
|
+
.split(new RegExp(`(?:^|[;,]?\\s+)${key}\\s+`))
|
|
91
|
+
.map((clause) => clause.trim().replace(/[;,]$/, ""))
|
|
92
|
+
.filter(Boolean));
|
|
93
|
+
}
|
|
94
|
+
function items(expression) {
|
|
95
|
+
if (!expression)
|
|
96
|
+
return [];
|
|
97
|
+
return expression.kind === "list" ? expression.items : [expression];
|
|
98
|
+
}
|
|
99
|
+
/** Root actions first, then each record's, prefixed with the record name. */
|
|
100
|
+
function guideActions(body, spell, prefix = "", parentActions = []) {
|
|
101
|
+
const result = [];
|
|
102
|
+
for (const entry of body.entries) {
|
|
103
|
+
if (!entry.key.startsWith("action ") || entry.value.kind !== "block")
|
|
104
|
+
continue;
|
|
105
|
+
const action = entry.value;
|
|
106
|
+
const actor = slot(action, "actor");
|
|
107
|
+
const party = actor?.kind === "block" ? slot(actor, "party") : undefined;
|
|
108
|
+
const parent = actor?.kind === "block" ? slot(actor, "parent") : undefined;
|
|
109
|
+
const runBy = !actor
|
|
110
|
+
? "caller"
|
|
111
|
+
: party
|
|
112
|
+
? spell(party)
|
|
113
|
+
: parent
|
|
114
|
+
? "parent"
|
|
115
|
+
: spell(actor);
|
|
116
|
+
const at = (key) => {
|
|
117
|
+
const value = slot(action, key);
|
|
118
|
+
if (value?.kind !== "block")
|
|
119
|
+
return value ? spell(value) : undefined;
|
|
120
|
+
const instant = slot(value, "at");
|
|
121
|
+
const offset = slot(value, "offset");
|
|
122
|
+
if (!instant)
|
|
123
|
+
return spell(value);
|
|
124
|
+
return offset ? `${spell(instant)} + ${spell(offset)}` : spell(instant);
|
|
125
|
+
};
|
|
126
|
+
const due = at("due");
|
|
127
|
+
const deadline = at("deadline");
|
|
128
|
+
const requires = clauses(action, "requires", spell);
|
|
129
|
+
const moves = clauses(action, "moves", spell);
|
|
130
|
+
const invokes = items(slot(action, "invoke")).flatMap((item) => item.kind === "block" ? [invocation(item, spell, prefix)] : []);
|
|
131
|
+
const from = slot(action, "from");
|
|
132
|
+
const to = slot(action, "to");
|
|
133
|
+
const guide = {
|
|
134
|
+
name: prefix + entry.key.slice(7),
|
|
135
|
+
runBy,
|
|
136
|
+
...(from ? { from: spell(from) } : {}),
|
|
137
|
+
...(to ? { to: spell(to) } : {}),
|
|
138
|
+
...(due ? { due } : {}),
|
|
139
|
+
...(deadline ? { deadline } : {}),
|
|
140
|
+
...(requires.length ? { requires } : {}),
|
|
141
|
+
...(moves.length ? { moves } : {}),
|
|
142
|
+
...(invokes.length ? { invokes } : {}),
|
|
143
|
+
};
|
|
144
|
+
const when = timing(guide, parentActions);
|
|
145
|
+
result.push(when ? { ...guide, when } : guide);
|
|
146
|
+
}
|
|
147
|
+
const records = slot(body, "records");
|
|
148
|
+
if (records?.kind === "block")
|
|
149
|
+
for (const record of records.entries)
|
|
150
|
+
if (record.value.kind === "block")
|
|
151
|
+
result.push(...guideActions(record.value, spell, `${prefix}${record.key}.`, prefix ? parentActions : result));
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
function invocation(block, spell, prefix) {
|
|
155
|
+
const instrument = slot(block, "instrument");
|
|
156
|
+
const action = slot(block, "action");
|
|
157
|
+
const target = `${instrument ? `${prefix}${spell(instrument)}.` : ""}${action ? spell(action) : "?"}`;
|
|
158
|
+
const range = slot(block, "range");
|
|
159
|
+
const count = range?.kind === "block" ? slot(range, "count") : undefined;
|
|
160
|
+
const literal = count?.kind === "block" ? (slot(count, "literal") ?? count) : count;
|
|
161
|
+
const selection = slot(block, "selection");
|
|
162
|
+
const selected = selection?.kind === "block" ? slot(selection, "instrument") : undefined;
|
|
163
|
+
return literal
|
|
164
|
+
? `${target}, ${spell(literal)} times`
|
|
165
|
+
: selected
|
|
166
|
+
? `${target} on each matching ${spell(selected)}`
|
|
167
|
+
: target;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* The runtime's timing rules, applied to one action: a clock action that
|
|
171
|
+
* needs a record in another state waits, and the action that moves the
|
|
172
|
+
* record there collects it in the same request (docs/public/runtime.md).
|
|
173
|
+
*/
|
|
174
|
+
function timing(action, parentActions) {
|
|
175
|
+
if (action.runBy === "clock" && action.due) {
|
|
176
|
+
const waits = (action.requires ?? []).flatMap((requirement) => {
|
|
177
|
+
const match = requirement.match(/^self\.\w+ in \[([^\]]+)\]$/);
|
|
178
|
+
return match ? [{ requirement, states: match[1].split(/,\s*/) }] : [];
|
|
179
|
+
});
|
|
180
|
+
const openers = parentActions
|
|
181
|
+
.filter((parent) => waits.some((wait) => wait.states.includes(parent.to ?? "")))
|
|
182
|
+
.map((parent) => parent.name);
|
|
183
|
+
return [
|
|
184
|
+
`The clock runs it at ${action.due}.`,
|
|
185
|
+
...waits.map((wait) => `While ${wait.requirement} does not hold, it waits.`),
|
|
186
|
+
...(openers.length
|
|
187
|
+
? [
|
|
188
|
+
`${openers.join(" or ")} collects every one already due in the same request.`,
|
|
189
|
+
]
|
|
190
|
+
: []),
|
|
191
|
+
].join(" ");
|
|
192
|
+
}
|
|
193
|
+
const parts = [
|
|
194
|
+
...(action.due
|
|
195
|
+
? [`Runnable from ${action.due}; ${action.runBy} still runs it.`]
|
|
196
|
+
: []),
|
|
197
|
+
...(action.deadline ? [`Refused after ${action.deadline}.`] : []),
|
|
198
|
+
];
|
|
199
|
+
return parts.length ? parts.join(" ") : undefined;
|
|
200
|
+
}
|
|
201
|
+
function partyMeaning(name, actions) {
|
|
202
|
+
const runs = actions.filter((action) => action.runBy === name);
|
|
203
|
+
const pays = actions.filter((action) => action.moves?.some((move) => new RegExp(`\\bfrom ${name}\\b`).test(move)));
|
|
204
|
+
const receives = actions.filter((action) => action.moves?.some((move) => new RegExp(`\\bto ${name}\\b`).test(move)));
|
|
205
|
+
const names = (list) => list.map((action) => action.name).join(", ");
|
|
206
|
+
const parts = [
|
|
207
|
+
...(runs.length ? [`Runs ${names(runs)}.`] : []),
|
|
208
|
+
...(pays.length ? [`Pays in ${names(pays)}.`] : []),
|
|
209
|
+
...(receives.length ? [`Receives in ${names(receives)}.`] : []),
|
|
210
|
+
];
|
|
211
|
+
return parts.length
|
|
212
|
+
? parts.join(" ")
|
|
213
|
+
: "Named by the template; runs no action and moves no money itself.";
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* A value tunable's meaning is where it lands: the fields it sets and every
|
|
217
|
+
* field or action that reads those fields, spelled as the std writes them.
|
|
218
|
+
*/
|
|
219
|
+
function valueMeaning(name, fallback, decl, spell) {
|
|
220
|
+
const bare = new RegExp(`(?<![\\w.])${name}(?!\\w)`);
|
|
221
|
+
const fields = slot(decl.body, "fields");
|
|
222
|
+
const set = fields?.kind === "block"
|
|
223
|
+
? fields.entries.filter((entry) => bare.test(fieldValue(entry, spell)))
|
|
224
|
+
: [];
|
|
225
|
+
const read = new Set(set.map((entry) => entry.key));
|
|
226
|
+
const uses = [];
|
|
227
|
+
const visit = (body, prefix, parentRefs) => {
|
|
228
|
+
const own = slot(body, "fields");
|
|
229
|
+
const reads = (text) => bare.test(text) ||
|
|
230
|
+
[...read].some((field) => prefix
|
|
231
|
+
? parentRefs.some((ref) => new RegExp(`\\bself\\.${ref}\\.${field}\\b`).test(text))
|
|
232
|
+
: new RegExp(`\\bself\\.${field}\\b`).test(text));
|
|
233
|
+
if (own?.kind === "block" && prefix)
|
|
234
|
+
for (const entry of own.entries) {
|
|
235
|
+
const value = fieldValue(entry, spell);
|
|
236
|
+
if (reads(value))
|
|
237
|
+
uses.push(`${prefix}${entry.key}: ${value}`);
|
|
238
|
+
}
|
|
239
|
+
for (const entry of body.entries) {
|
|
240
|
+
if (!entry.key.startsWith("action ") || entry.value.kind !== "block")
|
|
241
|
+
continue;
|
|
242
|
+
for (const part of entry.value.entries) {
|
|
243
|
+
if (["actor", "from", "to", "summary"].includes(part.key))
|
|
244
|
+
continue;
|
|
245
|
+
const text = spell(part.value);
|
|
246
|
+
// A long slot, such as an invoke list, is named rather than spelled.
|
|
247
|
+
if (reads(text))
|
|
248
|
+
uses.push(`${prefix}${entry.key.slice(7)} ${part.key}${text.length > 100 ? "" : `: ${text}`}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const records = slot(body, "records");
|
|
252
|
+
if (records?.kind === "block")
|
|
253
|
+
for (const record of records.entries) {
|
|
254
|
+
if (record.value.kind !== "block")
|
|
255
|
+
continue;
|
|
256
|
+
const recordFields = slot(record.value, "fields");
|
|
257
|
+
const refs = recordFields?.kind === "block"
|
|
258
|
+
? recordFields.entries
|
|
259
|
+
.filter((entry) => /^ref<parent>/.test(fieldValue(entry, spell)))
|
|
260
|
+
.map((entry) => entry.key)
|
|
261
|
+
: [];
|
|
262
|
+
visit(record.value, `${prefix}${record.key}.`, refs);
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
visit(decl.body, "", []);
|
|
266
|
+
const parts = [
|
|
267
|
+
...(fallback === "runtime"
|
|
268
|
+
? [
|
|
269
|
+
`Leave it out of the attach and create takes ${name} for each record, or bind one fixed value.`,
|
|
270
|
+
]
|
|
271
|
+
: []),
|
|
272
|
+
...(set.length
|
|
273
|
+
? [
|
|
274
|
+
`Sets ${set.map((entry) => `${entry.key}: ${fieldValue(entry, spell)}`).join(", ")}.`,
|
|
275
|
+
]
|
|
276
|
+
: []),
|
|
277
|
+
...(uses.length ? [`Read by ${uses.slice(0, 6).join("; ")}.`] : []),
|
|
278
|
+
];
|
|
279
|
+
return parts.length ? parts.join(" ") : "Configures the template.";
|
|
280
|
+
}
|
|
281
|
+
function fieldValue(entry, spell) {
|
|
282
|
+
return entry.value.kind === "default"
|
|
283
|
+
? `${spell(entry.value.type)} = ${spell(entry.value.value)}`
|
|
284
|
+
: spell(entry.value);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* The template's attach from the catalog program, with every attach it names
|
|
288
|
+
* and the parties and headers those need.
|
|
289
|
+
*/
|
|
290
|
+
function exampleProgram(qualifiedName, library) {
|
|
291
|
+
const program = parseProgram(catalogProgramSource).program;
|
|
292
|
+
const object = program.decls.find((decl) => decl.kind === "object");
|
|
293
|
+
if (object?.kind !== "object")
|
|
294
|
+
throw new Error("catalog program has no object");
|
|
295
|
+
const attaches = object.body.entries.flatMap((entry) => {
|
|
296
|
+
const match = entry.key.match(/^attach (\w+) = (\w+)\.(\w+)$/);
|
|
297
|
+
return match
|
|
298
|
+
? [
|
|
299
|
+
{
|
|
300
|
+
entry,
|
|
301
|
+
name: match[1],
|
|
302
|
+
header: match[2],
|
|
303
|
+
template: `${match[2]}.${match[3]}`,
|
|
304
|
+
},
|
|
305
|
+
]
|
|
306
|
+
: [];
|
|
307
|
+
});
|
|
308
|
+
const target = attaches.find((attach) => attach.template === qualifiedName);
|
|
309
|
+
if (!target)
|
|
310
|
+
throw new Error(`catalog program does not attach ${qualifiedName}`);
|
|
311
|
+
const referenced = (expression) => {
|
|
312
|
+
if (expression.kind === "name")
|
|
313
|
+
return [expression.value.split(".")[0]];
|
|
314
|
+
if (expression.kind === "list")
|
|
315
|
+
return expression.items.flatMap(referenced);
|
|
316
|
+
if (expression.kind === "block")
|
|
317
|
+
return expression.entries.flatMap((entry) => referenced(entry.value));
|
|
318
|
+
return [];
|
|
319
|
+
};
|
|
320
|
+
// A parameter that defaults to object(header.template) binds the sibling
|
|
321
|
+
// attach of that template, so the example carries that attach too.
|
|
322
|
+
const templates = new Map(headerManifest(library).headers.flatMap((header) => header.objects.map((object) => [object.qualifiedName, object])));
|
|
323
|
+
const siblings = (template) => (templates.get(template)?.tunables ?? []).flatMap((tunable) => {
|
|
324
|
+
const match = tunable.default?.match(/^object\((\w+\.\w+)\)$/);
|
|
325
|
+
const sibling = match
|
|
326
|
+
? attaches.find((attach) => attach.template === match[1])
|
|
327
|
+
: undefined;
|
|
328
|
+
return sibling ? [sibling.name] : [];
|
|
329
|
+
});
|
|
330
|
+
const names = new Set();
|
|
331
|
+
const include = (name) => {
|
|
332
|
+
if (names.has(name))
|
|
333
|
+
return;
|
|
334
|
+
const attach = attaches.find((candidate) => candidate.name === name);
|
|
335
|
+
if (!attach)
|
|
336
|
+
return;
|
|
337
|
+
names.add(name);
|
|
338
|
+
[...referenced(attach.entry.value), ...siblings(attach.template)].forEach(include);
|
|
339
|
+
};
|
|
340
|
+
include(target.name);
|
|
341
|
+
const included = attaches.filter((attach) => names.has(attach.name));
|
|
342
|
+
const used = new Set(included.flatMap((attach) => referenced(attach.entry.value)));
|
|
343
|
+
const text = (span) => catalogProgramSource.slice(span.start, span.end).trim();
|
|
344
|
+
return {
|
|
345
|
+
attachment: target.name,
|
|
346
|
+
render: (exposes) => [
|
|
347
|
+
`program example "${qualifiedName} example"`,
|
|
348
|
+
...new Set(included.map((attach) => `use ${attach.header}`)),
|
|
349
|
+
...program.decls.flatMap((decl) => decl.kind === "party" && used.has(decl.name) ? [text(decl.span)] : []),
|
|
350
|
+
`object item "Item" {`,
|
|
351
|
+
...included.map((attach) => {
|
|
352
|
+
const line = text(attach.entry.span);
|
|
353
|
+
return wrapAttach(attach === target && exposes.length
|
|
354
|
+
? line.replace(/\s*\}$/, `, ${exposes.join(", ")} }`)
|
|
355
|
+
: line);
|
|
356
|
+
}),
|
|
357
|
+
"}",
|
|
358
|
+
].join("\n"),
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
/** An attach line within 76 columns, else one binding per line. */
|
|
362
|
+
function wrapAttach(line) {
|
|
363
|
+
if (line.length <= 74)
|
|
364
|
+
return ` ${line}`;
|
|
365
|
+
const open = line.indexOf("{");
|
|
366
|
+
const items = [];
|
|
367
|
+
let depth = 0;
|
|
368
|
+
let quoted = false;
|
|
369
|
+
let start = open + 1;
|
|
370
|
+
for (let index = start; index < line.length - 1; index++) {
|
|
371
|
+
const char = line[index];
|
|
372
|
+
if (char === '"')
|
|
373
|
+
quoted = !quoted;
|
|
374
|
+
if (quoted)
|
|
375
|
+
continue;
|
|
376
|
+
if ("{[(".includes(char))
|
|
377
|
+
depth++;
|
|
378
|
+
if ("}])".includes(char))
|
|
379
|
+
depth--;
|
|
380
|
+
if (char === "," && depth === 0) {
|
|
381
|
+
items.push(line.slice(start, index).trim());
|
|
382
|
+
start = index + 1;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
items.push(line.slice(start, line.lastIndexOf("}")).trim());
|
|
386
|
+
return [
|
|
387
|
+
` ${line.slice(0, open + 1)}`,
|
|
388
|
+
...items.map((item) => ` ${item},`),
|
|
389
|
+
" }",
|
|
390
|
+
].join("\n");
|
|
391
|
+
}
|
|
392
|
+
/** The example's compiled root instrument, or the compiler's refusal. */
|
|
393
|
+
function compiledAttachment(source, attachment, options) {
|
|
394
|
+
const result = compile(source, {
|
|
395
|
+
...(options.library ? { standardLibrary: options.library } : {}),
|
|
396
|
+
...(options.adapterRegistry
|
|
397
|
+
? { adapterRegistry: options.adapterRegistry }
|
|
398
|
+
: {}),
|
|
399
|
+
});
|
|
400
|
+
const document = result.artifacts?.document;
|
|
401
|
+
if (!document)
|
|
402
|
+
throw new Error(`${attachment} example does not compile: ${result.diagnostics.map((d) => d.message).join("; ")}`);
|
|
403
|
+
const instrumentId = document.objects
|
|
404
|
+
.flatMap((object) => object.attachments)
|
|
405
|
+
.find((candidate) => candidate.name === attachment)?.instrument;
|
|
406
|
+
const instrument = document.instruments.find((candidate) => candidate.id === instrumentId);
|
|
407
|
+
if (!instrument)
|
|
408
|
+
throw new Error(`${attachment} example has no instrument`);
|
|
409
|
+
return instrument;
|
|
410
|
+
}
|
|
411
|
+
function inputType(field) {
|
|
412
|
+
const type = String(field.type);
|
|
413
|
+
if (type === "list")
|
|
414
|
+
return `list of ${String(field.item)}${field.maxItems === undefined ? "" : `, at most ${String(field.maxItems)}`}`;
|
|
415
|
+
if (type === "ref" && field.target)
|
|
416
|
+
return `ref to ${String(field.target)}`;
|
|
417
|
+
if (type === "enum" && Array.isArray(field.values))
|
|
418
|
+
return `one of ${field.values.join(", ")}`;
|
|
419
|
+
return type;
|
|
420
|
+
}
|
|
421
|
+
//# sourceMappingURL=template-guide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-guide.js","sourceRoot":"","sources":["../../src/template-guide.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperscale0/hsx",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.334",
|
|
4
4
|
"description": "The strictly typed HSX language: compile total financial programs into canonical UDL.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hsx",
|
|
@@ -90,8 +90,8 @@
|
|
|
90
90
|
"bases:bundle": "bun scripts/bundle-bases.ts"
|
|
91
91
|
},
|
|
92
92
|
"dependencies": {
|
|
93
|
-
"@hyperscale0/adl": "1.0.
|
|
94
|
-
"@hyperscale0/udl": "1.0.
|
|
93
|
+
"@hyperscale0/adl": "1.0.334",
|
|
94
|
+
"@hyperscale0/udl": "1.0.334",
|
|
95
95
|
"fast-sha256": "1.3.0"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"Amir Ayub",
|
|
104
104
|
"Sara AlBakaawi"
|
|
105
105
|
],
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "63ce2f153ec13ff17f2ea8a910cc134bfecdab16"
|
|
107
107
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One program that attaches every standard template with bindings the
|
|
3
|
+
* compiler admits. Each template guide takes its example from here, and
|
|
4
|
+
* std-headers.spec proves the whole program compiles.
|
|
5
|
+
*/
|
|
6
|
+
export const catalogProgramSource = `program catalog "Template catalog"
|
|
7
|
+
use money
|
|
8
|
+
use escrow
|
|
9
|
+
use purchase
|
|
10
|
+
use booking
|
|
11
|
+
use marketplace
|
|
12
|
+
use financing
|
|
13
|
+
use insurance
|
|
14
|
+
use lending
|
|
15
|
+
use wallet
|
|
16
|
+
use cards
|
|
17
|
+
use collections
|
|
18
|
+
use savings
|
|
19
|
+
use reporting
|
|
20
|
+
party supplier: business
|
|
21
|
+
party inspector: staff role claim_inspector
|
|
22
|
+
party investor: business
|
|
23
|
+
object item "Item" {
|
|
24
|
+
attach transfer = money.transfer { payer: actor, payee: owner, amount: 750 SAR }
|
|
25
|
+
attach hold = money.hold { payer: actor, payee: owner, amount: 750 SAR }
|
|
26
|
+
attach split = money.split { payer: actor, amount: 750 SAR }
|
|
27
|
+
attach schedule = money.schedule { payer: actor, payee: owner, amount: 750 SAR, count: 3 }
|
|
28
|
+
attach pool = money.pool { payer: actor, payee: owner, target: 1000 SAR, closes: 2027-01-01 }
|
|
29
|
+
attach swap = money.swap { first: actor, second: owner, first_amount: 100 SAR, second_amount: 200 SAR, expires: 2027-01-01 }
|
|
30
|
+
attach payout = money.payout { payer: actor, payee: owner, adapter: "conformance_boundary" }
|
|
31
|
+
attach mandate = money.mandate { payer: actor, payee: owner }
|
|
32
|
+
attach metered = money.metered { payer: actor, payee: owner, unit_price: 10 SAR }
|
|
33
|
+
attach policy = insurance.cover { holder: actor, adapter: "conformance_boundary" }
|
|
34
|
+
attach claim = insurance.claim { cover: policy, inspector: inspector }
|
|
35
|
+
attach cov = insurance.cover { holder: actor, broker: supplier, adapter: "conformance_boundary", covers: sale }
|
|
36
|
+
attach deposit = escrow.hold { payer: actor, payee: owner }
|
|
37
|
+
attach sale = escrow.hold { funding: { controllers: [checkout], reference: "funds", blocking_states: [active] }, payer: actor, payee: owner }
|
|
38
|
+
attach trip = booking.reservation { customer: actor, operator: owner }
|
|
39
|
+
attach limits = financing.limits { borrower: actor, per_borrower: 60000 SAR }
|
|
40
|
+
attach ceiling = financing.portfolio_limit { limit: 1500000 SAR }
|
|
41
|
+
attach checkout = purchase.checkout { plans: plan, funds: sale, borrower: actor, capital: operator }
|
|
42
|
+
attach plan = financing.installments { borrower: actor, capital: operator, months: 3, pricing: flat_total, profit_rate: 2.5%, down_payment: 20%, funds: checkout, limits: limits, portfolio: ceiling }
|
|
43
|
+
attach late = financing.late_charge { on: plan, borrower: actor }
|
|
44
|
+
attach line = financing.credit_line { borrower: operator, adapter: "conformance_boundary", limit: 100000 SAR, expires: 2027-01-01 }
|
|
45
|
+
attach advance = financing.advance { line: line }
|
|
46
|
+
attach case = collections.case { on: plan, agency: supplier }
|
|
47
|
+
attach contact = collections.contact { case: case, agency: supplier }
|
|
48
|
+
attach reminder = collections.reminder { on: plan }
|
|
49
|
+
attach wallet = wallet.balance { holder: investor }
|
|
50
|
+
attach spend = wallet.spend { wallet: wallet, payee: supplier, holder: investor }
|
|
51
|
+
attach round = lending.round { borrower: actor, plan: plan, minimum_ticket: 100 SAR, investor_cap: 100% }
|
|
52
|
+
attach commitment = lending.commitment { round: round, wallet: wallet, investor: investor }
|
|
53
|
+
attach distribution = lending.distribution { round: round, receipt: plan.settlement }
|
|
54
|
+
attach cardholder = cards.cardholder { holder: actor }
|
|
55
|
+
attach card = cards.card { holder: cardholder, person: actor, spend_limit: 5000 SAR }
|
|
56
|
+
attach authorization = cards.authorization { card: card, merchant: supplier }
|
|
57
|
+
attach transaction = cards.transaction { authorization: authorization }
|
|
58
|
+
attach dispute = cards.dispute { transaction: transaction }
|
|
59
|
+
attach listing = marketplace.listing { seller: owner }
|
|
60
|
+
attach order = marketplace.order { listing: listing, buyer: actor }
|
|
61
|
+
attach reservation = marketplace.reservation { listing: listing, funds: sale, converters: checkout, buyer: actor, seller: owner }
|
|
62
|
+
attach circle = savings.circle { contribution: 300 SAR, members: 8, starts: 2027-01-01 }
|
|
63
|
+
attach membership = savings.membership { circle: circle, member: actor }
|
|
64
|
+
attach reports = reporting.portfolio { on: plan }
|
|
65
|
+
}`;
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
import type { BlockExpr, Entry, Expr, InstrumentDecl } from "./ast.ts";
|
|
2
|
+
import { catalogProgramSource } from "./catalog-program.ts";
|
|
3
|
+
import { compile, type CompileOptions } from "./compile.ts";
|
|
4
|
+
import { parseHeader } from "./header-source.ts";
|
|
5
|
+
import { headerManifest, HEADER_NAMES } from "./headers.ts";
|
|
6
|
+
import { parseProgram } from "./parse.ts";
|
|
7
|
+
import { bundledStandardLibrary, type StandardLibrary } from "./std-library.ts";
|
|
8
|
+
|
|
9
|
+
export interface TemplateIndexEntry {
|
|
10
|
+
qualifiedName: string;
|
|
11
|
+
summary: string;
|
|
12
|
+
parties: string[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface TemplateGuideAction {
|
|
16
|
+
name: string;
|
|
17
|
+
runBy: string;
|
|
18
|
+
from?: string;
|
|
19
|
+
to?: string;
|
|
20
|
+
due?: string;
|
|
21
|
+
deadline?: string;
|
|
22
|
+
requires?: string[];
|
|
23
|
+
moves?: string[];
|
|
24
|
+
invokes?: string[];
|
|
25
|
+
when?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface TemplateGuide {
|
|
29
|
+
qualifiedName: string;
|
|
30
|
+
summary: string;
|
|
31
|
+
signature: string;
|
|
32
|
+
use: string;
|
|
33
|
+
states: string[];
|
|
34
|
+
tunables: Array<{
|
|
35
|
+
name: string;
|
|
36
|
+
type: string;
|
|
37
|
+
required: boolean;
|
|
38
|
+
default?: string;
|
|
39
|
+
meaning: string;
|
|
40
|
+
}>;
|
|
41
|
+
createInput: Array<{ name: string; type: string }>;
|
|
42
|
+
subject: Array<{ name: string; type: string }>;
|
|
43
|
+
actions: TemplateGuideAction[];
|
|
44
|
+
example: string;
|
|
45
|
+
notes: string[];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// How to read runBy, the same for every template.
|
|
49
|
+
const RUN_BY_NOTE =
|
|
50
|
+
"runBy names who runs each action: a party is whoever the attach binds to it (owner, actor, operator or a declared business), clock is the platform when the action falls due, parent runs only inside its parent record's action, and caller is anyone the exposed action admits.";
|
|
51
|
+
|
|
52
|
+
const SUBJECT_NOTE =
|
|
53
|
+
"subject names fields the attached object must carry, or rename to with rename { field: yourField }, before the actions that read them can run.";
|
|
54
|
+
|
|
55
|
+
/** One line per template, small enough to read whole. */
|
|
56
|
+
export function templateIndex(
|
|
57
|
+
library: StandardLibrary = bundledStandardLibrary,
|
|
58
|
+
): TemplateIndexEntry[] {
|
|
59
|
+
return headerManifest(library).headers.flatMap((header) =>
|
|
60
|
+
header.objects.map((object) => ({
|
|
61
|
+
qualifiedName: object.qualifiedName,
|
|
62
|
+
summary: object.summary,
|
|
63
|
+
parties: object.parties,
|
|
64
|
+
})),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Everything an author needs for one template, spelled from its std
|
|
70
|
+
* declaration and proved by compiling its example. Undefined when the
|
|
71
|
+
* catalog has no such template.
|
|
72
|
+
*/
|
|
73
|
+
export function templateGuide(
|
|
74
|
+
qualifiedName: string,
|
|
75
|
+
options: GuideOptions = {},
|
|
76
|
+
): TemplateGuide | undefined {
|
|
77
|
+
const library = options.library ?? bundledStandardLibrary;
|
|
78
|
+
const [header, name, extra] = qualifiedName.split(".");
|
|
79
|
+
if (!header || !name || extra !== undefined) return undefined;
|
|
80
|
+
if (!(HEADER_NAMES as readonly string[]).includes(header)) return undefined;
|
|
81
|
+
const source = library.source(header);
|
|
82
|
+
if (!source) return undefined;
|
|
83
|
+
const manifest = headerManifest(library, [header]).headers[0]!.objects.find(
|
|
84
|
+
(object) => object.name === name,
|
|
85
|
+
);
|
|
86
|
+
const decl = parseHeader(source, header).decls.find(
|
|
87
|
+
(d): d is InstrumentDecl => d.kind === "instrument" && d.name === name,
|
|
88
|
+
);
|
|
89
|
+
if (!manifest || !decl) return undefined;
|
|
90
|
+
const spell = (expression: Expr) =>
|
|
91
|
+
source
|
|
92
|
+
.slice(expression.span.start, expression.span.end)
|
|
93
|
+
.trim()
|
|
94
|
+
.replace(/\s+/g, " ");
|
|
95
|
+
const actions = guideActions(decl.body, spell);
|
|
96
|
+
// Compile once bare, then expose each root action a party or caller runs
|
|
97
|
+
// that these bindings keep, and compile again to prove the example.
|
|
98
|
+
const example = exampleProgram(qualifiedName, library);
|
|
99
|
+
const bare = compiledAttachment(
|
|
100
|
+
example.render([]),
|
|
101
|
+
example.attachment,
|
|
102
|
+
options,
|
|
103
|
+
);
|
|
104
|
+
const exposes = actions
|
|
105
|
+
.filter(
|
|
106
|
+
(action) =>
|
|
107
|
+
!action.name.includes(".") &&
|
|
108
|
+
!["clock", "parent"].includes(action.runBy) &&
|
|
109
|
+
bare.actions[action.name],
|
|
110
|
+
)
|
|
111
|
+
.map((action) => `expose ${action.name}`);
|
|
112
|
+
const program = example.render(exposes);
|
|
113
|
+
const create = compiledAttachment(program, example.attachment, options)
|
|
114
|
+
.actions.create;
|
|
115
|
+
return {
|
|
116
|
+
qualifiedName,
|
|
117
|
+
summary: manifest.summary,
|
|
118
|
+
signature: manifest.signature,
|
|
119
|
+
use: `use ${header}`,
|
|
120
|
+
states: manifest.states,
|
|
121
|
+
tunables: manifest.tunables.map((tunable) => ({
|
|
122
|
+
name: tunable.name,
|
|
123
|
+
type: tunable.type,
|
|
124
|
+
required: tunable.required,
|
|
125
|
+
...(tunable.default ? { default: tunable.default } : {}),
|
|
126
|
+
meaning:
|
|
127
|
+
tunable.type === "party" || tunable.type === "party?"
|
|
128
|
+
? partyMeaning(tunable.name, actions)
|
|
129
|
+
: valueMeaning(tunable.name, tunable.default, decl, spell),
|
|
130
|
+
})),
|
|
131
|
+
createInput: (create?.input ?? []).map((field) => ({
|
|
132
|
+
name: field.name,
|
|
133
|
+
type: inputType(field as unknown as Record<string, unknown>),
|
|
134
|
+
})),
|
|
135
|
+
subject: manifest.subject,
|
|
136
|
+
actions,
|
|
137
|
+
example: program,
|
|
138
|
+
notes: [RUN_BY_NOTE, ...(manifest.subject.length ? [SUBJECT_NOTE] : [])],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function slot(block: BlockExpr, key: string) {
|
|
143
|
+
return block.entries.find((entry) => entry.key === key)?.value;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The parser desugars `requires` and `moves` into blocks without source
|
|
148
|
+
* spans, so each clause is spelled from the slot's own source text.
|
|
149
|
+
*/
|
|
150
|
+
function clauses(
|
|
151
|
+
action: BlockExpr,
|
|
152
|
+
key: "requires" | "moves",
|
|
153
|
+
spell: (expression: Expr) => string,
|
|
154
|
+
) {
|
|
155
|
+
return action.entries
|
|
156
|
+
.filter((entry) => entry.key === key)
|
|
157
|
+
.flatMap((entry) =>
|
|
158
|
+
spell(entry.value)
|
|
159
|
+
.split(new RegExp(`(?:^|[;,]?\\s+)${key}\\s+`))
|
|
160
|
+
.map((clause) => clause.trim().replace(/[;,]$/, ""))
|
|
161
|
+
.filter(Boolean),
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function items(expression: Expr | undefined): Expr[] {
|
|
166
|
+
if (!expression) return [];
|
|
167
|
+
return expression.kind === "list" ? expression.items : [expression];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Root actions first, then each record's, prefixed with the record name. */
|
|
171
|
+
function guideActions(
|
|
172
|
+
body: BlockExpr,
|
|
173
|
+
spell: (expression: Expr) => string,
|
|
174
|
+
prefix = "",
|
|
175
|
+
parentActions: TemplateGuideAction[] = [],
|
|
176
|
+
): TemplateGuideAction[] {
|
|
177
|
+
const result: TemplateGuideAction[] = [];
|
|
178
|
+
for (const entry of body.entries) {
|
|
179
|
+
if (!entry.key.startsWith("action ") || entry.value.kind !== "block")
|
|
180
|
+
continue;
|
|
181
|
+
const action = entry.value;
|
|
182
|
+
const actor = slot(action, "actor");
|
|
183
|
+
const party = actor?.kind === "block" ? slot(actor, "party") : undefined;
|
|
184
|
+
const parent = actor?.kind === "block" ? slot(actor, "parent") : undefined;
|
|
185
|
+
const runBy = !actor
|
|
186
|
+
? "caller"
|
|
187
|
+
: party
|
|
188
|
+
? spell(party)
|
|
189
|
+
: parent
|
|
190
|
+
? "parent"
|
|
191
|
+
: spell(actor);
|
|
192
|
+
const at = (key: string) => {
|
|
193
|
+
const value = slot(action, key);
|
|
194
|
+
if (value?.kind !== "block") return value ? spell(value) : undefined;
|
|
195
|
+
const instant = slot(value, "at");
|
|
196
|
+
const offset = slot(value, "offset");
|
|
197
|
+
if (!instant) return spell(value);
|
|
198
|
+
return offset ? `${spell(instant)} + ${spell(offset)}` : spell(instant);
|
|
199
|
+
};
|
|
200
|
+
const due = at("due");
|
|
201
|
+
const deadline = at("deadline");
|
|
202
|
+
const requires = clauses(action, "requires", spell);
|
|
203
|
+
const moves = clauses(action, "moves", spell);
|
|
204
|
+
const invokes = items(slot(action, "invoke")).flatMap((item) =>
|
|
205
|
+
item.kind === "block" ? [invocation(item, spell, prefix)] : [],
|
|
206
|
+
);
|
|
207
|
+
const from = slot(action, "from");
|
|
208
|
+
const to = slot(action, "to");
|
|
209
|
+
const guide: TemplateGuideAction = {
|
|
210
|
+
name: prefix + entry.key.slice(7),
|
|
211
|
+
runBy,
|
|
212
|
+
...(from ? { from: spell(from) } : {}),
|
|
213
|
+
...(to ? { to: spell(to) } : {}),
|
|
214
|
+
...(due ? { due } : {}),
|
|
215
|
+
...(deadline ? { deadline } : {}),
|
|
216
|
+
...(requires.length ? { requires } : {}),
|
|
217
|
+
...(moves.length ? { moves } : {}),
|
|
218
|
+
...(invokes.length ? { invokes } : {}),
|
|
219
|
+
};
|
|
220
|
+
const when = timing(guide, parentActions);
|
|
221
|
+
result.push(when ? { ...guide, when } : guide);
|
|
222
|
+
}
|
|
223
|
+
const records = slot(body, "records");
|
|
224
|
+
if (records?.kind === "block")
|
|
225
|
+
for (const record of records.entries)
|
|
226
|
+
if (record.value.kind === "block")
|
|
227
|
+
result.push(
|
|
228
|
+
...guideActions(
|
|
229
|
+
record.value,
|
|
230
|
+
spell,
|
|
231
|
+
`${prefix}${record.key}.`,
|
|
232
|
+
prefix ? parentActions : result,
|
|
233
|
+
),
|
|
234
|
+
);
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function invocation(
|
|
239
|
+
block: BlockExpr,
|
|
240
|
+
spell: (expression: Expr) => string,
|
|
241
|
+
prefix: string,
|
|
242
|
+
) {
|
|
243
|
+
const instrument = slot(block, "instrument");
|
|
244
|
+
const action = slot(block, "action");
|
|
245
|
+
const target = `${instrument ? `${prefix}${spell(instrument)}.` : ""}${action ? spell(action) : "?"}`;
|
|
246
|
+
const range = slot(block, "range");
|
|
247
|
+
const count = range?.kind === "block" ? slot(range, "count") : undefined;
|
|
248
|
+
const literal =
|
|
249
|
+
count?.kind === "block" ? (slot(count, "literal") ?? count) : count;
|
|
250
|
+
const selection = slot(block, "selection");
|
|
251
|
+
const selected =
|
|
252
|
+
selection?.kind === "block" ? slot(selection, "instrument") : undefined;
|
|
253
|
+
return literal
|
|
254
|
+
? `${target}, ${spell(literal)} times`
|
|
255
|
+
: selected
|
|
256
|
+
? `${target} on each matching ${spell(selected)}`
|
|
257
|
+
: target;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* The runtime's timing rules, applied to one action: a clock action that
|
|
262
|
+
* needs a record in another state waits, and the action that moves the
|
|
263
|
+
* record there collects it in the same request (docs/public/runtime.md).
|
|
264
|
+
*/
|
|
265
|
+
function timing(
|
|
266
|
+
action: TemplateGuideAction,
|
|
267
|
+
parentActions: TemplateGuideAction[],
|
|
268
|
+
): string | undefined {
|
|
269
|
+
if (action.runBy === "clock" && action.due) {
|
|
270
|
+
const waits = (action.requires ?? []).flatMap((requirement) => {
|
|
271
|
+
const match = requirement.match(/^self\.\w+ in \[([^\]]+)\]$/);
|
|
272
|
+
return match ? [{ requirement, states: match[1]!.split(/,\s*/) }] : [];
|
|
273
|
+
});
|
|
274
|
+
const openers = parentActions
|
|
275
|
+
.filter((parent) =>
|
|
276
|
+
waits.some((wait) => wait.states.includes(parent.to ?? "")),
|
|
277
|
+
)
|
|
278
|
+
.map((parent) => parent.name);
|
|
279
|
+
return [
|
|
280
|
+
`The clock runs it at ${action.due}.`,
|
|
281
|
+
...waits.map(
|
|
282
|
+
(wait) => `While ${wait.requirement} does not hold, it waits.`,
|
|
283
|
+
),
|
|
284
|
+
...(openers.length
|
|
285
|
+
? [
|
|
286
|
+
`${openers.join(" or ")} collects every one already due in the same request.`,
|
|
287
|
+
]
|
|
288
|
+
: []),
|
|
289
|
+
].join(" ");
|
|
290
|
+
}
|
|
291
|
+
const parts = [
|
|
292
|
+
...(action.due
|
|
293
|
+
? [`Runnable from ${action.due}; ${action.runBy} still runs it.`]
|
|
294
|
+
: []),
|
|
295
|
+
...(action.deadline ? [`Refused after ${action.deadline}.`] : []),
|
|
296
|
+
];
|
|
297
|
+
return parts.length ? parts.join(" ") : undefined;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function partyMeaning(name: string, actions: TemplateGuideAction[]) {
|
|
301
|
+
const runs = actions.filter((action) => action.runBy === name);
|
|
302
|
+
const pays = actions.filter((action) =>
|
|
303
|
+
action.moves?.some((move) => new RegExp(`\\bfrom ${name}\\b`).test(move)),
|
|
304
|
+
);
|
|
305
|
+
const receives = actions.filter((action) =>
|
|
306
|
+
action.moves?.some((move) => new RegExp(`\\bto ${name}\\b`).test(move)),
|
|
307
|
+
);
|
|
308
|
+
const names = (list: TemplateGuideAction[]) =>
|
|
309
|
+
list.map((action) => action.name).join(", ");
|
|
310
|
+
const parts = [
|
|
311
|
+
...(runs.length ? [`Runs ${names(runs)}.`] : []),
|
|
312
|
+
...(pays.length ? [`Pays in ${names(pays)}.`] : []),
|
|
313
|
+
...(receives.length ? [`Receives in ${names(receives)}.`] : []),
|
|
314
|
+
];
|
|
315
|
+
return parts.length
|
|
316
|
+
? parts.join(" ")
|
|
317
|
+
: "Named by the template; runs no action and moves no money itself.";
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* A value tunable's meaning is where it lands: the fields it sets and every
|
|
322
|
+
* field or action that reads those fields, spelled as the std writes them.
|
|
323
|
+
*/
|
|
324
|
+
function valueMeaning(
|
|
325
|
+
name: string,
|
|
326
|
+
fallback: string | undefined,
|
|
327
|
+
decl: InstrumentDecl,
|
|
328
|
+
spell: (expression: Expr) => string,
|
|
329
|
+
) {
|
|
330
|
+
const bare = new RegExp(`(?<![\\w.])${name}(?!\\w)`);
|
|
331
|
+
const fields = slot(decl.body, "fields");
|
|
332
|
+
const set =
|
|
333
|
+
fields?.kind === "block"
|
|
334
|
+
? fields.entries.filter((entry) => bare.test(fieldValue(entry, spell)))
|
|
335
|
+
: [];
|
|
336
|
+
const read = new Set(set.map((entry) => entry.key));
|
|
337
|
+
const uses: string[] = [];
|
|
338
|
+
const visit = (body: BlockExpr, prefix: string, parentRefs: string[]) => {
|
|
339
|
+
const own = slot(body, "fields");
|
|
340
|
+
const reads = (text: string) =>
|
|
341
|
+
bare.test(text) ||
|
|
342
|
+
[...read].some((field) =>
|
|
343
|
+
prefix
|
|
344
|
+
? parentRefs.some((ref) =>
|
|
345
|
+
new RegExp(`\\bself\\.${ref}\\.${field}\\b`).test(text),
|
|
346
|
+
)
|
|
347
|
+
: new RegExp(`\\bself\\.${field}\\b`).test(text),
|
|
348
|
+
);
|
|
349
|
+
if (own?.kind === "block" && prefix)
|
|
350
|
+
for (const entry of own.entries) {
|
|
351
|
+
const value = fieldValue(entry, spell);
|
|
352
|
+
if (reads(value)) uses.push(`${prefix}${entry.key}: ${value}`);
|
|
353
|
+
}
|
|
354
|
+
for (const entry of body.entries) {
|
|
355
|
+
if (!entry.key.startsWith("action ") || entry.value.kind !== "block")
|
|
356
|
+
continue;
|
|
357
|
+
for (const part of entry.value.entries) {
|
|
358
|
+
if (["actor", "from", "to", "summary"].includes(part.key)) continue;
|
|
359
|
+
const text = spell(part.value);
|
|
360
|
+
// A long slot, such as an invoke list, is named rather than spelled.
|
|
361
|
+
if (reads(text))
|
|
362
|
+
uses.push(
|
|
363
|
+
`${prefix}${entry.key.slice(7)} ${part.key}${text.length > 100 ? "" : `: ${text}`}`,
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const records = slot(body, "records");
|
|
368
|
+
if (records?.kind === "block")
|
|
369
|
+
for (const record of records.entries) {
|
|
370
|
+
if (record.value.kind !== "block") continue;
|
|
371
|
+
const recordFields = slot(record.value, "fields");
|
|
372
|
+
const refs =
|
|
373
|
+
recordFields?.kind === "block"
|
|
374
|
+
? recordFields.entries
|
|
375
|
+
.filter((entry) =>
|
|
376
|
+
/^ref<parent>/.test(fieldValue(entry, spell)),
|
|
377
|
+
)
|
|
378
|
+
.map((entry) => entry.key)
|
|
379
|
+
: [];
|
|
380
|
+
visit(record.value, `${prefix}${record.key}.`, refs);
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
visit(decl.body, "", []);
|
|
384
|
+
const parts = [
|
|
385
|
+
...(fallback === "runtime"
|
|
386
|
+
? [
|
|
387
|
+
`Leave it out of the attach and create takes ${name} for each record, or bind one fixed value.`,
|
|
388
|
+
]
|
|
389
|
+
: []),
|
|
390
|
+
...(set.length
|
|
391
|
+
? [
|
|
392
|
+
`Sets ${set.map((entry) => `${entry.key}: ${fieldValue(entry, spell)}`).join(", ")}.`,
|
|
393
|
+
]
|
|
394
|
+
: []),
|
|
395
|
+
...(uses.length ? [`Read by ${uses.slice(0, 6).join("; ")}.`] : []),
|
|
396
|
+
];
|
|
397
|
+
return parts.length ? parts.join(" ") : "Configures the template.";
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function fieldValue(entry: Entry, spell: (expression: Expr) => string) {
|
|
401
|
+
return entry.value.kind === "default"
|
|
402
|
+
? `${spell(entry.value.type)} = ${spell(entry.value.value)}`
|
|
403
|
+
: spell(entry.value);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
interface Example {
|
|
407
|
+
attachment: string;
|
|
408
|
+
render(exposes: string[]): string;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* The template's attach from the catalog program, with every attach it names
|
|
413
|
+
* and the parties and headers those need.
|
|
414
|
+
*/
|
|
415
|
+
function exampleProgram(
|
|
416
|
+
qualifiedName: string,
|
|
417
|
+
library: StandardLibrary,
|
|
418
|
+
): Example {
|
|
419
|
+
const program = parseProgram(catalogProgramSource).program;
|
|
420
|
+
const object = program.decls.find((decl) => decl.kind === "object");
|
|
421
|
+
if (object?.kind !== "object")
|
|
422
|
+
throw new Error("catalog program has no object");
|
|
423
|
+
const attaches = object.body.entries.flatMap((entry) => {
|
|
424
|
+
const match = entry.key.match(/^attach (\w+) = (\w+)\.(\w+)$/);
|
|
425
|
+
return match
|
|
426
|
+
? [
|
|
427
|
+
{
|
|
428
|
+
entry,
|
|
429
|
+
name: match[1]!,
|
|
430
|
+
header: match[2]!,
|
|
431
|
+
template: `${match[2]}.${match[3]}`,
|
|
432
|
+
},
|
|
433
|
+
]
|
|
434
|
+
: [];
|
|
435
|
+
});
|
|
436
|
+
const target = attaches.find((attach) => attach.template === qualifiedName);
|
|
437
|
+
if (!target)
|
|
438
|
+
throw new Error(`catalog program does not attach ${qualifiedName}`);
|
|
439
|
+
const referenced = (expression: Expr): string[] => {
|
|
440
|
+
if (expression.kind === "name") return [expression.value.split(".")[0]!];
|
|
441
|
+
if (expression.kind === "list") return expression.items.flatMap(referenced);
|
|
442
|
+
if (expression.kind === "block")
|
|
443
|
+
return expression.entries.flatMap((entry) => referenced(entry.value));
|
|
444
|
+
return [];
|
|
445
|
+
};
|
|
446
|
+
// A parameter that defaults to object(header.template) binds the sibling
|
|
447
|
+
// attach of that template, so the example carries that attach too.
|
|
448
|
+
const templates = new Map(
|
|
449
|
+
headerManifest(library).headers.flatMap((header) =>
|
|
450
|
+
header.objects.map((object) => [object.qualifiedName, object] as const),
|
|
451
|
+
),
|
|
452
|
+
);
|
|
453
|
+
const siblings = (template: string) =>
|
|
454
|
+
(templates.get(template)?.tunables ?? []).flatMap((tunable) => {
|
|
455
|
+
const match = tunable.default?.match(/^object\((\w+\.\w+)\)$/);
|
|
456
|
+
const sibling = match
|
|
457
|
+
? attaches.find((attach) => attach.template === match[1])
|
|
458
|
+
: undefined;
|
|
459
|
+
return sibling ? [sibling.name] : [];
|
|
460
|
+
});
|
|
461
|
+
const names = new Set<string>();
|
|
462
|
+
const include = (name: string) => {
|
|
463
|
+
if (names.has(name)) return;
|
|
464
|
+
const attach = attaches.find((candidate) => candidate.name === name);
|
|
465
|
+
if (!attach) return;
|
|
466
|
+
names.add(name);
|
|
467
|
+
[...referenced(attach.entry.value), ...siblings(attach.template)].forEach(
|
|
468
|
+
include,
|
|
469
|
+
);
|
|
470
|
+
};
|
|
471
|
+
include(target.name);
|
|
472
|
+
const included = attaches.filter((attach) => names.has(attach.name));
|
|
473
|
+
const used = new Set(
|
|
474
|
+
included.flatMap((attach) => referenced(attach.entry.value)),
|
|
475
|
+
);
|
|
476
|
+
const text = (span: { start: number; end: number }) =>
|
|
477
|
+
catalogProgramSource.slice(span.start, span.end).trim();
|
|
478
|
+
return {
|
|
479
|
+
attachment: target.name,
|
|
480
|
+
render: (exposes) =>
|
|
481
|
+
[
|
|
482
|
+
`program example "${qualifiedName} example"`,
|
|
483
|
+
...new Set(included.map((attach) => `use ${attach.header}`)),
|
|
484
|
+
...program.decls.flatMap((decl) =>
|
|
485
|
+
decl.kind === "party" && used.has(decl.name) ? [text(decl.span)] : [],
|
|
486
|
+
),
|
|
487
|
+
`object item "Item" {`,
|
|
488
|
+
...included.map((attach) => {
|
|
489
|
+
const line = text(attach.entry.span);
|
|
490
|
+
return wrapAttach(
|
|
491
|
+
attach === target && exposes.length
|
|
492
|
+
? line.replace(/\s*\}$/, `, ${exposes.join(", ")} }`)
|
|
493
|
+
: line,
|
|
494
|
+
);
|
|
495
|
+
}),
|
|
496
|
+
"}",
|
|
497
|
+
].join("\n"),
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/** An attach line within 76 columns, else one binding per line. */
|
|
502
|
+
function wrapAttach(line: string): string {
|
|
503
|
+
if (line.length <= 74) return ` ${line}`;
|
|
504
|
+
const open = line.indexOf("{");
|
|
505
|
+
const items: string[] = [];
|
|
506
|
+
let depth = 0;
|
|
507
|
+
let quoted = false;
|
|
508
|
+
let start = open + 1;
|
|
509
|
+
for (let index = start; index < line.length - 1; index++) {
|
|
510
|
+
const char = line[index]!;
|
|
511
|
+
if (char === '"') quoted = !quoted;
|
|
512
|
+
if (quoted) continue;
|
|
513
|
+
if ("{[(".includes(char)) depth++;
|
|
514
|
+
if ("}])".includes(char)) depth--;
|
|
515
|
+
if (char === "," && depth === 0) {
|
|
516
|
+
items.push(line.slice(start, index).trim());
|
|
517
|
+
start = index + 1;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
items.push(line.slice(start, line.lastIndexOf("}")).trim());
|
|
521
|
+
return [
|
|
522
|
+
` ${line.slice(0, open + 1)}`,
|
|
523
|
+
...items.map((item) => ` ${item},`),
|
|
524
|
+
" }",
|
|
525
|
+
].join("\n");
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
type GuideOptions = Pick<CompileOptions, "adapterRegistry"> & {
|
|
529
|
+
library?: StandardLibrary;
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
/** The example's compiled root instrument, or the compiler's refusal. */
|
|
533
|
+
function compiledAttachment(
|
|
534
|
+
source: string,
|
|
535
|
+
attachment: string,
|
|
536
|
+
options: GuideOptions,
|
|
537
|
+
) {
|
|
538
|
+
const result = compile(source, {
|
|
539
|
+
...(options.library ? { standardLibrary: options.library } : {}),
|
|
540
|
+
...(options.adapterRegistry
|
|
541
|
+
? { adapterRegistry: options.adapterRegistry }
|
|
542
|
+
: {}),
|
|
543
|
+
});
|
|
544
|
+
const document = result.artifacts?.document;
|
|
545
|
+
if (!document)
|
|
546
|
+
throw new Error(
|
|
547
|
+
`${attachment} example does not compile: ${result.diagnostics.map((d) => d.message).join("; ")}`,
|
|
548
|
+
);
|
|
549
|
+
const instrumentId = document.objects
|
|
550
|
+
.flatMap((object) => object.attachments)
|
|
551
|
+
.find((candidate) => candidate.name === attachment)?.instrument;
|
|
552
|
+
const instrument = document.instruments.find(
|
|
553
|
+
(candidate) => candidate.id === instrumentId,
|
|
554
|
+
);
|
|
555
|
+
if (!instrument) throw new Error(`${attachment} example has no instrument`);
|
|
556
|
+
return instrument;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
function inputType(field: Record<string, unknown>) {
|
|
560
|
+
const type = String(field.type);
|
|
561
|
+
if (type === "list")
|
|
562
|
+
return `list of ${String(field.item)}${field.maxItems === undefined ? "" : `, at most ${String(field.maxItems)}`}`;
|
|
563
|
+
if (type === "ref" && field.target) return `ref to ${String(field.target)}`;
|
|
564
|
+
if (type === "enum" && Array.isArray(field.values))
|
|
565
|
+
return `one of ${field.values.join(", ")}`;
|
|
566
|
+
return type;
|
|
567
|
+
}
|