@hyperscale0/hsx 2.4.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/CHANGELOG.md +2 -408
  2. package/README.md +3 -92
  3. package/dist/src/ast.d.ts +99 -310
  4. package/dist/src/ast.d.ts.map +1 -1
  5. package/dist/src/ast.js +16 -69
  6. package/dist/src/ast.js.map +1 -1
  7. package/dist/src/cli.d.ts +6 -19
  8. package/dist/src/cli.d.ts.map +1 -1
  9. package/dist/src/cli.js +76 -315
  10. package/dist/src/cli.js.map +1 -1
  11. package/dist/src/compile.d.ts +23 -73
  12. package/dist/src/compile.d.ts.map +1 -1
  13. package/dist/src/compile.js +1113 -148
  14. package/dist/src/compile.js.map +1 -1
  15. package/dist/src/cost.d.ts +8 -77
  16. package/dist/src/cost.d.ts.map +1 -1
  17. package/dist/src/cost.js +13 -422
  18. package/dist/src/cost.js.map +1 -1
  19. package/dist/src/format.d.ts +8 -7
  20. package/dist/src/format.d.ts.map +1 -1
  21. package/dist/src/format.js +9 -175
  22. package/dist/src/format.js.map +1 -1
  23. package/dist/src/headers.d.ts +35 -0
  24. package/dist/src/headers.d.ts.map +1 -0
  25. package/dist/src/headers.js +108 -0
  26. package/dist/src/headers.js.map +1 -0
  27. package/dist/src/index.d.ts +6 -12
  28. package/dist/src/index.d.ts.map +1 -1
  29. package/dist/src/index.js +4 -9
  30. package/dist/src/index.js.map +1 -1
  31. package/dist/src/lex.d.ts +8 -28
  32. package/dist/src/lex.d.ts.map +1 -1
  33. package/dist/src/lex.js +88 -146
  34. package/dist/src/lex.js.map +1 -1
  35. package/dist/src/parse.d.ts +4 -17
  36. package/dist/src/parse.d.ts.map +1 -1
  37. package/dist/src/parse.js +402 -1040
  38. package/dist/src/parse.js.map +1 -1
  39. package/dist/src/std-bundle.d.ts.map +1 -1
  40. package/dist/src/std-bundle.js +12 -20
  41. package/dist/src/std-bundle.js.map +1 -1
  42. package/dist/src/std-library.d.ts +1 -1
  43. package/dist/src/std-library.d.ts.map +1 -1
  44. package/dist/src/std-library.js +1 -5
  45. package/dist/src/std-library.js.map +1 -1
  46. package/dist/src/tunables.d.ts +7 -0
  47. package/dist/src/tunables.d.ts.map +1 -0
  48. package/dist/src/tunables.js +26 -0
  49. package/dist/src/tunables.js.map +1 -0
  50. package/dist/src/version.d.ts +2 -4
  51. package/dist/src/version.d.ts.map +1 -1
  52. package/dist/src/version.js +2 -4
  53. package/dist/src/version.js.map +1 -1
  54. package/docs/README.md +179 -41
  55. package/docs/headers.md +44 -0
  56. package/examples/cost-table.json +99 -751
  57. package/examples/library.hsx +59 -0
  58. package/package.json +9 -17
  59. package/src/ast.ts +82 -441
  60. package/src/cli.ts +77 -362
  61. package/src/compile.ts +1535 -247
  62. package/src/cost.ts +28 -671
  63. package/src/format.ts +12 -256
  64. package/src/headers.ts +126 -0
  65. package/src/index.ts +7 -39
  66. package/src/lex.ts +99 -195
  67. package/src/parse.ts +403 -1209
  68. package/src/std-bundle.ts +12 -20
  69. package/src/std-library.ts +2 -7
  70. package/src/tunables.ts +31 -0
  71. package/src/version.ts +2 -5
  72. package/std/approvals.hsx +17 -0
  73. package/std/cards.hsx +63 -0
  74. package/std/collections.hsx +31 -0
  75. package/std/escrow.hsx +43 -0
  76. package/std/financing.hsx +372 -0
  77. package/std/insurance.hsx +59 -0
  78. package/std/lending.hsx +115 -0
  79. package/std/marketplace.hsx +24 -0
  80. package/std/money.hsx +195 -0
  81. package/std/savings.hsx +44 -0
  82. package/std/travel.hsx +98 -0
  83. package/std/wallet.hsx +41 -0
  84. package/dist/src/diagnostics.d.ts +0 -13
  85. package/dist/src/diagnostics.d.ts.map +0 -1
  86. package/dist/src/diagnostics.js +0 -587
  87. package/dist/src/diagnostics.js.map +0 -1
  88. package/dist/src/emit.d.ts +0 -51
  89. package/dist/src/emit.d.ts.map +0 -1
  90. package/dist/src/emit.js +0 -192
  91. package/dist/src/emit.js.map +0 -1
  92. package/dist/src/entry-overrides.d.ts +0 -58
  93. package/dist/src/entry-overrides.d.ts.map +0 -1
  94. package/dist/src/entry-overrides.js +0 -284
  95. package/dist/src/entry-overrides.js.map +0 -1
  96. package/dist/src/ir.d.ts +0 -73
  97. package/dist/src/ir.d.ts.map +0 -1
  98. package/dist/src/ir.js +0 -15
  99. package/dist/src/ir.js.map +0 -1
  100. package/dist/src/limits.d.ts +0 -23
  101. package/dist/src/limits.d.ts.map +0 -1
  102. package/dist/src/limits.js +0 -23
  103. package/dist/src/limits.js.map +0 -1
  104. package/dist/src/lsp/server.d.ts +0 -32
  105. package/dist/src/lsp/server.d.ts.map +0 -1
  106. package/dist/src/lsp/server.js +0 -391
  107. package/dist/src/lsp/server.js.map +0 -1
  108. package/dist/src/modules.d.ts +0 -38
  109. package/dist/src/modules.d.ts.map +0 -1
  110. package/dist/src/modules.js +0 -372
  111. package/dist/src/modules.js.map +0 -1
  112. package/dist/src/typecheck.d.ts +0 -8
  113. package/dist/src/typecheck.d.ts.map +0 -1
  114. package/dist/src/typecheck.js +0 -4160
  115. package/dist/src/typecheck.js.map +0 -1
  116. package/docs/guide/01-first-program.md +0 -24
  117. package/docs/guide/02-money.md +0 -25
  118. package/docs/guide/03-instruments.md +0 -93
  119. package/docs/guide/04-lifecycles.md +0 -40
  120. package/docs/guide/05-fees-and-splits.md +0 -45
  121. package/docs/guide/06-schedules.md +0 -26
  122. package/docs/guide/07-composition.md +0 -52
  123. package/docs/guide/08-writing-a-module.md +0 -85
  124. package/docs/guide/09-cost.md +0 -24
  125. package/docs/guide/10-diagnostics.md +0 -27
  126. package/docs/llms-full.txt +0 -3684
  127. package/docs/llms.txt +0 -44
  128. package/docs/piece-plans.md +0 -120
  129. package/docs/playground.md +0 -55
  130. package/docs/reference/cli.md +0 -36
  131. package/docs/reference/diagnostics.md +0 -901
  132. package/docs/reference/grammar.md +0 -38
  133. package/docs/reference/std/advance.md +0 -112
  134. package/docs/reference/std/cancellable_booking.md +0 -159
  135. package/docs/reference/std/captured_payment.md +0 -115
  136. package/docs/reference/std/conditional_disbursement.md +0 -101
  137. package/docs/reference/std/credit_facility.md +0 -108
  138. package/docs/reference/std/held_payment.md +0 -173
  139. package/docs/reference/std/instant_transfer.md +0 -97
  140. package/docs/reference/std/metered.md +0 -89
  141. package/docs/reference/std/pooled_split.md +0 -95
  142. package/docs/reference/std/premium_forward.md +0 -119
  143. package/docs/reference/std/reconciled_payout.md +0 -103
  144. package/docs/reference/std/rotating_pool.md +0 -130
  145. package/docs/reference/std/scheduled.md +0 -136
  146. package/docs/reference/std/security_deposit.md +0 -138
  147. package/docs/reference/std/settlement_batch.md +0 -123
  148. package/docs/reference/std/swap.md +0 -133
  149. package/docs/reference/std/threshold_pool.md +0 -138
  150. package/docs/reference/std/weighted_distribution.md +0 -135
  151. package/docs/reference/types.md +0 -61
  152. package/docs/reference/udl-output.md +0 -13
  153. package/examples/01-first-program/README.md +0 -45
  154. package/examples/01-first-program/tip-jar.hsx +0 -17
  155. package/examples/02-imports-and-modules/README.md +0 -96
  156. package/examples/02-imports-and-modules/photo-booth.hsx +0 -37
  157. package/examples/03-diagnostics/README.md +0 -68
  158. package/examples/03-diagnostics/corner-shop-fixed.hsx +0 -22
  159. package/examples/03-diagnostics/corner-shop.hsx +0 -19
  160. package/examples/04-complete-product/README.md +0 -84
  161. package/examples/04-complete-product/study-hall.hsx +0 -67
  162. package/examples/05-authored-instrument/README.md +0 -5
  163. package/examples/05-authored-instrument/payment.hsx +0 -37
  164. package/examples/05-watch-club/README.md +0 -6
  165. package/examples/05-watch-club/watch-club.hsx +0 -123
  166. package/examples/README.md +0 -48
  167. package/examples/advance/README.md +0 -3
  168. package/examples/advance/advance.hsx +0 -13
  169. package/examples/advance/advance.udl +0 -367
  170. package/examples/cancellable_booking/README.md +0 -3
  171. package/examples/cancellable_booking/cancellable_booking.hsx +0 -14
  172. package/examples/cancellable_booking/cancellable_booking.udl +0 -413
  173. package/examples/captured_payment/README.md +0 -3
  174. package/examples/captured_payment/captured_payment.hsx +0 -17
  175. package/examples/captured_payment/captured_payment.udl +0 -686
  176. package/examples/conditional_disbursement/README.md +0 -3
  177. package/examples/conditional_disbursement/conditional_disbursement.hsx +0 -15
  178. package/examples/conditional_disbursement/conditional_disbursement.udl +0 -418
  179. package/examples/credit_facility/README.md +0 -3
  180. package/examples/credit_facility/credit_facility.hsx +0 -24
  181. package/examples/credit_facility/credit_facility.udl +0 -1396
  182. package/examples/held_payment/README.md +0 -3
  183. package/examples/held_payment/held_payment.hsx +0 -13
  184. package/examples/held_payment/held_payment.udl +0 -569
  185. package/examples/instant_transfer/README.md +0 -3
  186. package/examples/instant_transfer/instant_transfer.hsx +0 -16
  187. package/examples/instant_transfer/instant_transfer.udl +0 -376
  188. package/examples/metered/README.md +0 -3
  189. package/examples/metered/metered.hsx +0 -13
  190. package/examples/metered/metered.udl +0 -253
  191. package/examples/pooled_split/README.md +0 -3
  192. package/examples/pooled_split/pooled_split.hsx +0 -15
  193. package/examples/pooled_split/pooled_split.udl +0 -432
  194. package/examples/premium_forward/README.md +0 -3
  195. package/examples/premium_forward/premium_forward.hsx +0 -19
  196. package/examples/premium_forward/premium_forward.udl +0 -604
  197. package/examples/reconciled_payout/README.md +0 -3
  198. package/examples/reconciled_payout/reconciled_payout.hsx +0 -13
  199. package/examples/reconciled_payout/reconciled_payout.udl +0 -312
  200. package/examples/rotating_pool/README.md +0 -3
  201. package/examples/rotating_pool/rotating_pool.hsx +0 -18
  202. package/examples/rotating_pool/rotating_pool.udl +0 -4370
  203. package/examples/scheduled/README.md +0 -3
  204. package/examples/scheduled/scheduled.hsx +0 -12
  205. package/examples/scheduled/scheduled.udl +0 -355
  206. package/examples/security_deposit/README.md +0 -3
  207. package/examples/security_deposit/security_deposit.hsx +0 -21
  208. package/examples/security_deposit/security_deposit.udl +0 -320
  209. package/examples/settlement_batch/README.md +0 -3
  210. package/examples/settlement_batch/settlement_batch.hsx +0 -19
  211. package/examples/settlement_batch/settlement_batch.udl +0 -757
  212. package/examples/swap/README.md +0 -3
  213. package/examples/swap/swap.hsx +0 -19
  214. package/examples/swap/swap.udl +0 -892
  215. package/examples/threshold_pool/README.md +0 -3
  216. package/examples/threshold_pool/threshold_pool.hsx +0 -16
  217. package/examples/threshold_pool/threshold_pool.udl +0 -680
  218. package/examples/weighted_distribution/README.md +0 -3
  219. package/examples/weighted_distribution/weighted_distribution.hsx +0 -20
  220. package/examples/weighted_distribution/weighted_distribution.udl +0 -348
  221. package/skills/hsx/SKILL.md +0 -449
  222. package/src/diagnostics.ts +0 -620
  223. package/src/emit.ts +0 -282
  224. package/src/entry-overrides.ts +0 -428
  225. package/src/ir.ts +0 -113
  226. package/src/limits.ts +0 -22
  227. package/src/lsp/server.ts +0 -460
  228. package/src/modules.ts +0 -452
  229. package/src/typecheck.ts +0 -5515
  230. package/std/SEMANTICS.md +0 -44
  231. package/std/money_flows/advance.hsx +0 -235
  232. package/std/money_flows/cancellable_booking.hsx +0 -402
  233. package/std/money_flows/captured_payment.hsx +0 -220
  234. package/std/money_flows/conditional_disbursement.hsx +0 -226
  235. package/std/money_flows/credit_facility.hsx +0 -214
  236. package/std/money_flows/held_payment.hsx +0 -812
  237. package/std/money_flows/index.hsx +0 -4
  238. package/std/money_flows/instant_transfer.hsx +0 -231
  239. package/std/money_flows/metered.hsx +0 -104
  240. package/std/money_flows/pooled_split.hsx +0 -109
  241. package/std/money_flows/premium_forward.hsx +0 -307
  242. package/std/money_flows/reconciled_payout.hsx +0 -119
  243. package/std/money_flows/rotating_pool.hsx +0 -305
  244. package/std/money_flows/scheduled.hsx +0 -599
  245. package/std/money_flows/security_deposit.hsx +0 -248
  246. package/std/money_flows/settlement_batch.hsx +0 -173
  247. package/std/money_flows/swap.hsx +0 -1192
  248. package/std/money_flows/threshold_pool.hsx +0 -307
  249. package/std/money_flows/weighted_distribution.hsx +0 -237
@@ -0,0 +1,59 @@
1
+ header insurance
2
+
3
+ instrument cover(holder: party, insurer: party, commission: percent = 0%, covers: ref, premium: money = runtime) {
4
+ summary: "Recurring cover with separate premium slices and commission clawback."
5
+ fields { covers: ref<covers>, holder: account of holder, insurer: account of insurer, expiresAt: date }
6
+ lifecycle { states: [pending, active, cancelled, expired], initial: pending }
7
+ action create {}
8
+ action activate { from: pending, to: active, actor: { party: insurer } }
9
+ action cancel {
10
+ from: active, to: cancelled
11
+ invoke: [{ selection: { instrument: slice, reference: "cover", anchor: self.id, states: [paid], limit: 366 }, action: refund, input: {} }]
12
+ }
13
+ action expire { from: active, to: expired, actor: clock, due: { at: self.expiresAt } }
14
+ records {
15
+ slice: {
16
+ summary: "A whole premium period, collected once and refundable only before it starts."
17
+ fields {
18
+ cover: ref<parent>, covers: ref<covers>, premium: money = premium, startsAt: date, endsAt: date
19
+ commission: money = rate(self.premium, commission)
20
+ carrierNet: money = subtract(self.premium, self.commission)
21
+ }
22
+ lifecycle { states: [pending, paid, active, expired, refunded], initial: pending }
23
+ action create {
24
+ requires self.covers == self.cover.covers
25
+ requires self.startsAt < self.endsAt
26
+ requires unique "premium_period" on [self.cover, self.startsAt, self.endsAt]
27
+ }
28
+ action collect {
29
+ from: pending, to: paid
30
+ requires self.cover in [active]
31
+ moves self.premium from holder to insurer
32
+ moves self.commission from insurer to programOperator
33
+ }
34
+ action start { from: paid, to: active, actor: clock, due: { at: self.startsAt } }
35
+ action expire { from: active, to: expired, actor: clock, due: { at: self.endsAt } }
36
+ action refund {
37
+ from: paid, to: refunded, deadline: { at: self.startsAt }
38
+ moves self.commission from programOperator to insurer
39
+ moves self.premium from insurer to holder
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ instrument claim(cover: ref<insurance.cover>, approved_by: approval) {
46
+ summary: "A carrier decision reserves one claim payment before settlement."
47
+ fields { cover: ref<cover>, amount: money, expiresAt: date, evidence: text, reservation: text? }
48
+ lifecycle { states: [submitted, approved, paid, denied, expired], initial: submitted }
49
+ action create { requires self.cover in [active] }
50
+ action approve {
51
+ from: submitted, to: approved, actor: { party: approved_by }
52
+ requires approval by approved_by
53
+ deadline: { at: self.expiresAt }
54
+ moves reserve self.amount from self.cover.insurer to self.cover.holder capture "reservation"
55
+ }
56
+ action pay { from: approved, to: paid, deadline: { at: self.expiresAt }, moves post self.reservation }
57
+ action deny { from: submitted, to: denied, requires approval by approved_by for approve is "declined" }
58
+ action expire { from: approved, to: expired, actor: clock, due: { at: self.expiresAt }, moves void self.reservation }
59
+ }
@@ -0,0 +1,115 @@
1
+ header lending
2
+
3
+ instrument round(borrower: party, capital: party, plan: ref<financing.installments> = object(financing.installments), months: integer(1, 366) = 3, profit: percent = 3%, minimum_ticket: money = 100 SAR, investor_cap: percent = 20%, commitments: ref<lending.commitment> = object(lending.commitment)) {
4
+ summary: "A threshold funding round; failed rounds return each original wallet contribution."
5
+ fields {
6
+ borrower: account of borrower, capital: account(capital, cash, "capital"), plan: ref<plan>, price: money, closesAt: date
7
+ months: integer = months, profit: money = rate(self.price, profit)
8
+ minimumTicket: money = minimum_ticket, maximumTicket: money = rate(self.price, investor_cap)
9
+ held: account of self
10
+ }
11
+ lifecycle { states: [open, funded, failed], initial: open }
12
+ action create { requires unique "funding_plan" on [self.plan]; requires self.months == self.plan.months; requires self.profit == self.plan.profit; requires self.price == self.plan.principal; requires self.borrower == self.plan.funds.payer }
13
+ action close {
14
+ from: open, to: funded
15
+ requires sum "amount" of { instrument: commitments, reference: "round", anchor: self.id, states: [committed], limit: 366 } == self.price
16
+ requires self.held.balance == self.price
17
+ moves self.price from self.held to self.plan.capital
18
+ invoke: [{ selection: { instrument: commitments, reference: "round", anchor: self.id, states: [committed], limit: 366 }, action: fund, input: {} }]
19
+ }
20
+ action fail {
21
+ from: open, to: failed, actor: clock, due: { at: self.closesAt }
22
+ requires self.held.balance < self.price
23
+ invoke: [{ selection: { instrument: commitments, reference: "round", anchor: self.id, states: [committed], limit: 366 }, action: refund, input: {} }]
24
+ }
25
+ }
26
+
27
+ instrument commitment(round: ref<lending.round>, wallet: ref<wallet.balance>, investor: party = party(person)) {
28
+ summary: "One investor's original-wallet contribution, capped cumulatively within the round."
29
+ fields { round: ref<round>, wallet: ref<wallet>, amount: money, loss: account(investor, claim, "loss") }
30
+ lifecycle { states: [committed, funded, withdrawn, refunded], initial: committed }
31
+ invariants sum "amount" of { instrument: all(lending.commitment), reference: "round", anchor: self.round, states: [committed, funded], limit: 366, where: { wallet: { field: self.wallet } } } <= self.round.maximumTicket
32
+ invariants sum "amount" of { instrument: all(lending.commitment), reference: "round", anchor: self.round, states: [committed, funded], limit: 366 } <= self.round.price
33
+ action create {
34
+ requires self.round in [open]
35
+ requires self.wallet in [active]
36
+ requires self.amount >= self.round.minimumTicket
37
+ deadline: { at: self.round.closesAt }
38
+ moves self.amount from self.wallet.held to self.round.held
39
+ }
40
+ action fund { from: committed, to: funded, actor: { parent: round } }
41
+ action withdraw {
42
+ from: committed, to: withdrawn
43
+ requires self.round in [open]
44
+ deadline: { at: self.round.closesAt }
45
+ moves self.amount from self.round.held to self.wallet.held
46
+ }
47
+ action refund {
48
+ from: committed, to: refunded, actor: { parent: round }
49
+ moves self.amount from self.round.held to self.wallet.held
50
+ }
51
+ }
52
+
53
+ instrument distribution(round: ref<lending.round>, receipt: ref, commitments: ref<lending.commitment> = object(lending.commitment), mode: enum(cash, loss) = cash, residual_to: party = programOperator, fee: percent = 1%, tax: percent = 15%) {
54
+ summary: "Frozen weighted shares, floored once, with residual assigned to the chosen party."
55
+ fields {
56
+ round: ref<round>, source: ref<receipt>, mode: enum(cash, loss) = mode
57
+ principal: money?, profit: money?, grossTotal: money?, charge: money?, vat: money?, net: money?
58
+ held: account of self, losses: account(self, claim), residualLoss: account(residual_to, claim, "loss")
59
+ }
60
+ lifecycle { states: [pending, cash_ready, loss_ready, distributed], initial: pending }
61
+ action create { requires self.round in [funded]; requires self.source.plan == self.round.plan; requires unique "settlement_consumption" on [self.source.plan, self.source.identity] }
62
+ action prepare_cash {
63
+ from: pending, to: cash_ready
64
+ requires self.mode == "cash"; requires self.source.kind == "cash"
65
+ calculate: [
66
+ { target: "principal", op: "sum", values: [{ field: self.source.principal }] }
67
+ { target: "profit", op: "sum", values: [{ field: self.source.profit }] }
68
+ { target: "charge", op: "rate", base: { field: self.profit }, bps: { literal: fee }, rounding: "floor" }
69
+ { target: "vat", op: "rate", base: { field: self.charge }, bps: { literal: tax }, rounding: "floor" }
70
+ { target: "grossTotal", op: "sum", values: [{ field: self.principal }, { field: self.profit }] }
71
+ { target: "net", op: "subtract", base: { field: self.grossTotal }, subtract: [{ field: self.charge }, { field: self.vat }] }
72
+ ]
73
+ }
74
+ action prepare_loss {
75
+ from: pending, to: loss_ready
76
+ requires self.mode == "loss"; requires self.source.kind == "loss"
77
+ calculate: [{ target: "net", op: "sum", values: [{ field: self.source.loss }] }]
78
+ }
79
+ action distribute_cash {
80
+ from: cash_ready, to: distributed
81
+ requires sum "weight" of { instrument: share, reference: "distribution", anchor: self.id, states: [pending], limit: 366 } == self.round.price
82
+ moves self.principal from self.source.capital to self.held; moves self.profit from self.source.profitIncome to self.held; moves self.charge from self.held to programOperator; moves self.vat from self.held to programTax
83
+ invoke: [{ selection: { instrument: share, reference: "distribution", anchor: self.id, states: [pending], limit: 366 }, action: cash, input: {} }, { reference: self.id, action: residual_cash, input: {} }]
84
+ }
85
+ action residual_cash {
86
+ from: distributed, to: distributed, actor: { parent: current() }
87
+ moves self.held.balance from self.held to residual_to
88
+ }
89
+ action distribute_loss {
90
+ from: loss_ready, to: distributed
91
+ requires sum "weight" of { instrument: share, reference: "distribution", anchor: self.id, states: [pending], limit: 366 } == self.round.price
92
+ moves self.net from self.source.lossAccount to self.losses
93
+ invoke: [{ selection: { instrument: share, reference: "distribution", anchor: self.id, states: [pending], limit: 366 }, action: loss, input: {} }, { reference: self.id, action: residual_loss, input: {} }]
94
+ }
95
+ action residual_loss {
96
+ from: distributed, to: distributed, actor: { parent: current() }
97
+ moves self.losses.balance from self.losses to self.residualLoss
98
+ }
99
+ records {
100
+ share: {
101
+ fields {
102
+ distribution: ref<parent>, commitment: ref<commitments>
103
+ weight: money = self.commitment.amount
104
+ gross: money = ratio(self.distribution.net, self.weight, self.distribution.round.price)
105
+ }
106
+ lifecycle { states: [pending, paid], initial: pending }
107
+ action create { requires self.distribution in [cash_ready, loss_ready]; requires self.commitment in [funded]; requires unique "distribution_weight" on [self.distribution, self.commitment]; requires self.commitment.round == self.distribution.round }
108
+ action cash {
109
+ from: pending, to: paid, actor: { parent: parent }
110
+ moves self.gross from self.distribution.held to self.commitment.wallet.held
111
+ }
112
+ action loss { from: pending, to: paid, actor: { parent: parent }, moves self.gross from self.distribution.losses to self.commitment.loss }
113
+ }
114
+ }
115
+ }
@@ -0,0 +1,24 @@
1
+ header marketplace
2
+
3
+ instrument listing(seller: party) {
4
+ summary: "A seller's offer and its asking price."
5
+ fields { seller: account of seller, title: text, price: money }
6
+ lifecycle { states: [draft, active, withdrawn, sold], initial: draft }
7
+ action create { actor: { party: seller } }
8
+ action publish { from: draft, to: active, actor: { party: seller } }
9
+ action withdraw { from: active, to: withdrawn, actor: { party: seller } }
10
+ action sell { from: active, to: sold, actor: { party: seller } }
11
+ }
12
+
13
+ instrument order(listing: ref<marketplace.listing>, buyer: party) {
14
+ summary: "A buyer's order for one listing at its declared price."
15
+ fields { listing: ref<listing>, buyer: account of buyer, price: money }
16
+ lifecycle { states: [placed, fulfilled, cancelled], initial: placed }
17
+ action create {
18
+ actor: { party: buyer }
19
+ requires self.listing in [active]
20
+ requires self.price == self.listing.price
21
+ }
22
+ action fulfill { from: placed, to: fulfilled }
23
+ action cancel { from: placed, to: cancelled, actor: { party: buyer } }
24
+ }
package/std/money.hsx ADDED
@@ -0,0 +1,195 @@
1
+ header money
2
+
3
+ instrument transfer(payer: party, payee: party, amount: money = runtime) {
4
+ summary: "One transfer between the bound parties."
5
+ fields { amount: money = amount }
6
+ lifecycle { states: [pending, paid, cancelled], initial: pending }
7
+ action create { actor: { party: payer } }
8
+ action pay {
9
+ from: pending, to: paid, actor: { party: payer }
10
+ moves self.amount from payer to payee
11
+ }
12
+ action cancel { from: pending, to: cancelled, actor: { party: payer } }
13
+ }
14
+
15
+ instrument hold(payer: party, payee: party, amount: money = runtime) {
16
+ summary: "Hold the declared amount until release or refund."
17
+ fields { payer: account of payer, payee: account of payee, amount: money = amount, price: money = self.amount, held: account of self }
18
+ lifecycle { states: [pending, funded, released, refunded, cancelled], initial: pending }
19
+ action create { }
20
+ action fund {
21
+ from: pending, to: funded, actor: { party: payer }
22
+ moves self.amount from payer to self.held
23
+ }
24
+ action confirm {
25
+ from: pending, to: funded
26
+ requires self.held.balance == self.amount
27
+ }
28
+ action release {
29
+ from: funded, to: released
30
+ moves self.amount from self.held to payee
31
+ }
32
+ action refund {
33
+ from: funded, to: refunded
34
+ moves self.amount from self.held to payer
35
+ }
36
+ action cancel { from: pending, to: cancelled }
37
+ }
38
+
39
+ instrument split(payer: party, amount: money = runtime, shares: split = { programOperator: 100% }) {
40
+ summary: "Split one amount; the last declared recipient receives the rounding remainder."
41
+ fields { amount: money = amount }
42
+ lifecycle { states: [pending, paid, cancelled], initial: pending }
43
+ action create {}
44
+ action pay { from: pending, to: paid, moves self.amount from payer shares shares }
45
+ action cancel { from: pending, to: cancelled }
46
+ }
47
+
48
+ instrument schedule(payer: party, payee: party, amount: money = runtime, count: integer(1, 366) = 12) {
49
+ summary: "A finite schedule whose dated pieces sum exactly to the declared total."
50
+ fields { amount: money = amount, count: integer = count, dates: list(date, count) }
51
+ lifecycle { states: [draft, active, complete, cancelled], initial: draft }
52
+ action create {}
53
+ action activate {
54
+ from: draft, to: active
55
+ requires count of { instrument: occurrence, reference: "schedule", anchor: self.id, states: [pending], limit: 366 } == self.count
56
+ }
57
+ action complete {
58
+ from: active, to: complete
59
+ requires count of { instrument: occurrence, reference: "schedule", anchor: self.id, states: [pending], limit: 366 } == 0
60
+ }
61
+ action cancel { from: [draft, active], to: cancelled }
62
+ records {
63
+ occurrence: {
64
+ fields {
65
+ schedule: ref<parent>, position: integer(1, count), dueAt: date = at(self.schedule.dates, self.position)
66
+ base: money = divide(self.schedule.amount, count)
67
+ allocated: money = multiply(self.base, count)
68
+ remainder: money = subtract(self.schedule.amount, self.allocated)
69
+ first: integer = divide(1, self.position)
70
+ adjustment: money = multiply(self.remainder, self.first)
71
+ amount: money = sum(self.base, self.adjustment)
72
+ }
73
+ lifecycle { states: [pending, paid, cancelled], initial: pending }
74
+ action create { requires self.schedule in [draft]; requires unique "scheduled_position" on [self.schedule, self.position] }
75
+ action pay { from: pending, to: paid, actor: clock, due: { at: self.dueAt }, requires self.schedule in [active], moves self.amount from payer to payee }
76
+ action cancel { from: pending, to: cancelled, requires self.schedule in [cancelled] }
77
+ }
78
+ }
79
+ }
80
+
81
+ instrument pool(payer: party, payee: party, target: money, closes: date) {
82
+ summary: "Contributions fund one threshold or return to their original contributor."
83
+ fields { target: money = target, closesAt: date = closes, held: account of self }
84
+ lifecycle { states: [open, paid, failed], initial: open }
85
+ action create { }
86
+ action pay {
87
+ from: open, to: paid
88
+ requires self.held.balance == self.target
89
+ moves self.target from self.held to payee
90
+ }
91
+ action fail {
92
+ from: open, to: failed, actor: clock, due: { at: self.closesAt }
93
+ requires self.held.balance < self.target
94
+ invoke: [{ selection: { instrument: contribution, reference: "pool", anchor: self.id, states: [paid], limit: 366 }, action: refund, input: {} }]
95
+ }
96
+ records {
97
+ contribution: {
98
+ fields { pool: ref<parent>, payer: account of payer, amount: money }
99
+ lifecycle { states: [pending, paid, refunded], initial: pending }
100
+ action create { requires self.pool in [open] }
101
+ action pay { from: pending, to: paid, deadline: { at: self.pool.closesAt }, requires self.pool in [open], moves self.amount from self.payer to self.pool.held }
102
+ action refund { from: paid, to: refunded, actor: { parent: parent }, moves self.amount from self.pool.held to self.payer }
103
+ }
104
+ }
105
+ }
106
+
107
+ instrument swap(first: party, second: party, first_amount: money, second_amount: money, expires: date) {
108
+ summary: "Two reservations settle together or both return."
109
+ fields { firstAmount: money = first_amount, secondAmount: money = second_amount, expiresAt: date = expires, firstReceipt: text?, secondReceipt: text? }
110
+ lifecycle { states: [pending, first_ready, second_ready, both_ready, exchanged, cancelled], initial: pending }
111
+ action create {}
112
+ action fund_first { from: pending, to: first_ready, actor: { party: first }, deadline: { at: self.expiresAt }, moves reserve self.firstAmount from first to second capture "firstReceipt" }
113
+ action fund_second { from: first_ready, to: both_ready, actor: { party: second }, deadline: { at: self.expiresAt }, moves reserve self.secondAmount from second to first capture "secondReceipt" }
114
+ action start_second { from: pending, to: second_ready, actor: { party: second }, deadline: { at: self.expiresAt }, moves reserve self.secondAmount from second to first capture "secondReceipt" }
115
+ action finish_first { from: second_ready, to: both_ready, actor: { party: first }, deadline: { at: self.expiresAt }, moves reserve self.firstAmount from first to second capture "firstReceipt" }
116
+ action expire_second { from: second_ready, to: cancelled, actor: clock, due: { at: self.expiresAt }, moves void self.secondReceipt }
117
+ action exchange { from: both_ready, to: exchanged, moves post self.firstReceipt; moves post self.secondReceipt }
118
+ action cancel { from: pending, to: cancelled }
119
+ action expire_first { from: first_ready, to: cancelled, actor: clock, due: { at: self.expiresAt }, moves void self.firstReceipt }
120
+ action expire_both { from: both_ready, to: cancelled, actor: clock, due: { at: self.expiresAt }, moves void self.firstReceipt; moves void self.secondReceipt }
121
+ }
122
+
123
+ instrument deposit(payer: party, payee: party, amount: money, expires: date, approval: approval) {
124
+ fields { amount: money = amount, expiresAt: date = expires, reservation: text? }
125
+ lifecycle { states: [pending, held, claimed, returned, cancelled], initial: pending }
126
+ action create {}
127
+ action fund { from: pending, to: held, actor: { party: payer }, moves reserve self.amount from payer to payee capture "reservation" }
128
+ action claim { from: held, to: claimed, deadline: { at: self.expiresAt }, requires approval by approval, moves post self.reservation }
129
+ action return { from: held, to: returned, actor: clock, due: { at: self.expiresAt }, moves void self.reservation }
130
+ action cancel { from: pending, to: cancelled }
131
+ }
132
+
133
+ instrument payout(payer: party, payee: party, amount: money = runtime, reconcile_within: duration = 3d) {
134
+ summary: "A bank-linked transfer with confirmation bound to its captured identity."
135
+ fields { amount: money = amount, bank: account(payee, cash, external, "bank"), receipt: text?, expectedAt: date = after(self.createdAt, reconcile_within) }
136
+ lifecycle { states: [pending, instructed, settled, exception, reversed], initial: pending }
137
+ action create {}
138
+ action instruct { from: pending, to: instructed, actor: { party: payer }, moves self.amount from payer to self.bank capture "receipt" }
139
+ action confirm {
140
+ from: [instructed, exception], to: settled
141
+ requires self.receipt.status == "settled"
142
+ }
143
+ action expire {
144
+ from: instructed, to: exception, actor: clock, due: { at: self.expectedAt }
145
+ requires self.receipt.status != "settled"
146
+ }
147
+ action reverse {
148
+ from: [instructed, exception], to: reversed
149
+ requires self.receipt.status == "reversed"
150
+ }
151
+ }
152
+
153
+ instrument metered(payer: party, payee: party, unit_price: money, units: integer = 1, fee: fee = { seller: 0% }) {
154
+ summary: "A unique usage event priced once at the fixed unit price."
155
+ fields { usageIdentity: text, unitPrice: money = unit_price, units: integer = units, amount: money = multiply(self.unitPrice, self.units) }
156
+ lifecycle { states: [recorded, billed, cancelled], initial: recorded }
157
+ action create { requires unique "usage_event" on [self.usageIdentity] }
158
+ action bill { from: recorded, to: billed, moves self.amount from payer to payee fee fee }
159
+ action cancel { from: recorded, to: cancelled }
160
+ }
161
+
162
+ instrument batch(payer: party, payee: party, closes: date, approval: approval, reconcile_within: duration = 3d) {
163
+ summary: "A frozen positive net of credit and debit entries, paid once."
164
+ fields { closesAt: date = closes, credits: money, debits: money, amount: money = subtract(self.credits, self.debits), bank: account(payee, cash, external, "bank"), receipt: text?, instructedAt: date?, expectedAt: date? }
165
+ lifecycle { states: [open, closed, approved, instructed, exception, paid, reversed], initial: open }
166
+ action create {}
167
+ action close {
168
+ from: open, to: closed, actor: clock, due: { at: self.closesAt }
169
+ requires sum "amount" of { instrument: credit, reference: "batch", anchor: self.id, states: [recorded], limit: 366 } == self.credits
170
+ requires sum "amount" of { instrument: debit, reference: "batch", anchor: self.id, states: [recorded], limit: 366 } == self.debits
171
+ requires self.amount > "0"
172
+ }
173
+ action approve { from: closed, to: approved, requires approval by approval }
174
+ action pay {
175
+ from: approved, to: instructed
176
+ set: { instructedAt: { field: self.now } }
177
+ calculate: [{ target: "expectedAt", op: "shift", date: { field: self.now }, milliseconds: { literal: reconcile_within }, direction: "after" }]
178
+ moves self.amount from payer to self.bank capture "receipt"
179
+ }
180
+ action confirm { from: [instructed, exception], to: paid, requires self.receipt.status == "settled" }
181
+ action expire { from: instructed, to: exception, actor: clock, due: { at: self.expectedAt }, requires self.receipt.status != "settled" }
182
+ action reverse { from: [instructed, exception], to: reversed, requires self.receipt.status == "reversed" }
183
+ records {
184
+ credit: {
185
+ fields { batch: ref<parent>, identity: text, amount: money }
186
+ lifecycle { states: [recorded], initial: recorded }
187
+ action create { requires self.batch in [open]; requires unique "batch_credit" on [self.identity] }
188
+ }
189
+ debit: {
190
+ fields { batch: ref<parent>, identity: text, amount: money }
191
+ lifecycle { states: [recorded], initial: recorded }
192
+ action create { requires self.batch in [open]; requires unique "batch_debit" on [self.identity] }
193
+ }
194
+ }
195
+ }
@@ -0,0 +1,44 @@
1
+ header savings
2
+
3
+ instrument circle(contribution: money, members: integer(1, 366), starts: date, memberships: ref<savings.membership> = object(savings.membership)) {
4
+ summary: "A fixed group contributes on its explicit calendar and takes the pot in order."
5
+ fields { contribution: money = contribution, members: integer = members, startsAt: date = starts, dates: list(date, members), pot: money = multiply(self.contribution, self.members), held: account of self }
6
+ lifecycle { states: [forming, active, closed, disbanded], initial: forming }
7
+ action create { }
8
+ action activate {
9
+ from: forming, to: active, actor: clock, due: { at: self.startsAt }
10
+ requires count of { instrument: memberships, reference: "circle", anchor: self.id, states: [joined], limit: 60 } == self.members
11
+ }
12
+ action close {
13
+ from: active, to: closed
14
+ requires count of { instrument: memberships, reference: "circle", anchor: self.id, states: [paid], limit: 60 } == self.members
15
+ requires self.held.balance == "0"
16
+ }
17
+ action disband { from: forming, to: disbanded }
18
+ }
19
+
20
+ instrument membership(circle: ref<savings.circle>, member: party) {
21
+ fields { circle: ref<circle>, member: account of member, position: integer(1, 60), preceding: integer = subtract(self.position, 1), receivesAt: date = at(self.circle.dates, self.position), contribution: money = self.circle.contribution, total: money = self.circle.pot, dates: list(date, 60) }
22
+ lifecycle { states: [joined, active, paid, withdrawn], initial: joined }
23
+ action create { requires self.position <= self.circle.members; requires self.circle in [forming]; requires unique "circle_seat" on [self.circle, self.position]; requires unique "circle_member" on [self.circle, self.member] }
24
+ action activate {
25
+ from: joined, to: active
26
+ requires self.circle in [active]
27
+ requires count of { instrument: contribution, reference: "membership", anchor: self.id, states: [pending], limit: 60 } == self.circle.members
28
+ }
29
+ action receive {
30
+ from: active, to: paid, actor: clock, due: { at: self.receivesAt }
31
+ requires self.circle in [active]
32
+ requires count of { instrument: all(savings.membership), reference: "circle", anchor: self.circle, states: [paid], limit: 60 } == self.preceding
33
+ moves self.total from self.circle.held to self.member
34
+ }
35
+ action withdraw { from: joined, to: withdrawn, requires self.circle in [disbanded] }
36
+ records {
37
+ contribution: {
38
+ fields { membership: ref<parent>, position: integer(1, 60), dueAt: date = at(self.membership.circle.dates, self.position), amount: money = self.membership.contribution }
39
+ lifecycle { states: [pending, paid], initial: pending }
40
+ action create { requires self.position <= self.membership.circle.members; requires self.membership in [joined]; requires unique "seat_period" on [self.membership, self.position] }
41
+ action pay { from: pending, to: paid, actor: clock, due: { at: self.dueAt }, requires self.membership in [active, paid]; requires self.membership.circle in [active], moves self.amount from self.membership.member to self.membership.circle.held }
42
+ }
43
+ }
44
+ }
package/std/travel.hsx ADDED
@@ -0,0 +1,98 @@
1
+ header travel
2
+
3
+ instrument package(price: money, supplier_cost: money, departure: date) {
4
+ constraints { supplier_cost: at_most(price) }
5
+ summary: "Immutable package price, supplier cost and departure."
6
+ fields { price: money = price, supplierCost: money = supplier_cost, departure: date = departure }
7
+ lifecycle { states: [draft, published, closed], initial: draft }
8
+ action create { requires self.supplierCost <= self.price }
9
+ action publish { from: draft, to: published }
10
+ action close { from: published, to: closed, actor: clock, due: { at: self.departure } }
11
+ }
12
+
13
+ instrument booking(package: ref<travel.package>, buyer: party, supplier: approval, cover: ref<insurance.cover>, deposit: percent = 30%, balance_before: duration = 14d, confirm_within: duration = 24h, tax: percent = 15%, early_before: duration = 30d, middle_before: duration = 15d, middle_penalty: percent = 10%, late_penalty: percent = 30%) {
14
+ constraints { early_before: greater_than(middle_before) }
15
+ summary: "A deposited booking with three cancellation bands and supplier confirmation."
16
+ fields {
17
+ package: ref<package>, bookingReference: text, buyer: account of buyer, supplier: account of supplier
18
+ price: money = self.package.price, supplierCost: money = self.package.supplierCost
19
+ deposit: money = rate(self.price, deposit), balance: money = subtract(self.price, self.deposit)
20
+ margin: money = subtract(self.price, self.supplierCost)
21
+ tax: money = rate(self.margin, tax), operatorNet: money = subtract(self.margin, self.tax)
22
+ middlePenalty: money = rate(self.supplierCost, middle_penalty)
23
+ latePenalty: money = rate(self.supplierCost, late_penalty)
24
+ balanceAt: date = before(self.package.departure, balance_before)
25
+ earlyAt: date = before(self.package.departure, early_before)
26
+ middleAt: date = before(self.package.departure, middle_before)
27
+ lateAt: date = after(self.middleAt, 1ms)
28
+ confirmBy: date = after(self.package.departure, confirm_within)
29
+ held: account of self
30
+ refund: money?, retainedMargin: money?, retainedTax: money?, retainedNet: money?
31
+ }
32
+ lifecycle { states: [created, deposit_paid, paid, completed, cancelled, refunded], initial: created }
33
+ action create {
34
+ requires self.package in [published]
35
+ requires unique "booking_reference" on [self.bookingReference]
36
+ }
37
+ action deposit {
38
+ from: created, to: deposit_paid, actor: { party: buyer }, deadline: { at: self.balanceAt }
39
+ requires count of { instrument: child(cover, slice), reference: "covers", anchor: self.id, states: [pending], limit: 366 } >= 1
40
+ moves self.deposit from buyer to self.held
41
+ invoke: [{ selection: { instrument: child(cover, slice), reference: "covers", anchor: self.id, states: [pending], limit: 366 }, action: collect, input: {} }]
42
+ }
43
+ action balance {
44
+ from: deposit_paid, to: paid, actor: { party: buyer }, deadline: { at: self.balanceAt }
45
+ moves self.balance from buyer to self.held
46
+ }
47
+ action confirm {
48
+ from: paid, to: completed, actor: { party: supplier }
49
+ due: { at: self.package.departure }, deadline: { at: self.confirmBy }
50
+ requires approval by supplier
51
+ moves self.supplierCost from self.held to supplier
52
+ moves self.tax from self.held to programTax
53
+ moves self.operatorNet from self.held to programOperator
54
+ }
55
+ action timeout {
56
+ from: paid, to: refunded, actor: clock, due: { at: self.confirmBy }
57
+ moves self.price from self.held to buyer
58
+ }
59
+ action cancel_early {
60
+ from: [deposit_paid, paid], to: cancelled, deadline: { at: self.earlyAt }
61
+ moves self.held.balance from self.held to buyer
62
+ }
63
+ action cancel_middle {
64
+ from: [deposit_paid, paid], to: cancelled, due: { at: self.earlyAt }, deadline: { at: self.lateAt }
65
+ calculate: [
66
+ { target: refund, op: "subtract", base: { field: self.held.balance }, subtract: [{ field: self.deposit }] }
67
+ { target: retainedMargin, op: "subtract", base: { field: self.deposit }, subtract: [{ field: self.middlePenalty }] }
68
+ { target: retainedTax, op: "rate", base: { field: self.retainedMargin }, bps: { literal: tax }, rounding: "floor" }
69
+ { target: retainedNet, op: "subtract", base: { field: self.retainedMargin }, subtract: [{ field: self.retainedTax }] }
70
+ ]
71
+ moves self.refund from self.held to buyer
72
+ moves self.middlePenalty from self.held to supplier
73
+ moves self.retainedTax from self.held to programTax
74
+ moves self.retainedNet from self.held to programOperator
75
+ }
76
+ action cancel_late {
77
+ from: [deposit_paid, paid], to: cancelled, actor: caller, due: { at: self.lateAt }
78
+ calculate: [
79
+ { target: retainedMargin, op: "subtract", base: { field: self.held.balance }, subtract: [{ field: self.latePenalty }] }
80
+ { target: retainedTax, op: "rate", base: { field: self.retainedMargin }, bps: { literal: tax }, rounding: "floor" }
81
+ { target: retainedNet, op: "subtract", base: { field: self.retainedMargin }, subtract: [{ field: self.retainedTax }] }
82
+ ]
83
+ moves self.latePenalty from self.held to supplier
84
+ moves self.retainedTax from self.held to programTax
85
+ moves self.retainedNet from self.held to programOperator
86
+ }
87
+ action default_balance {
88
+ from: deposit_paid, to: cancelled, actor: clock, due: { at: self.balanceAt }
89
+ calculate: [
90
+ { target: retainedMargin, op: "subtract", base: { field: self.held.balance }, subtract: [{ field: self.latePenalty }] }
91
+ { target: retainedTax, op: "rate", base: { field: self.retainedMargin }, bps: { literal: tax }, rounding: "floor" }
92
+ { target: retainedNet, op: "subtract", base: { field: self.retainedMargin }, subtract: [{ field: self.retainedTax }] }
93
+ ]
94
+ moves self.latePenalty from self.held to supplier
95
+ moves self.retainedTax from self.held to programTax
96
+ moves self.retainedNet from self.held to programOperator
97
+ }
98
+ }
package/std/wallet.hsx ADDED
@@ -0,0 +1,41 @@
1
+ header wallet
2
+
3
+ instrument balance(holder: party, spend_limit: money = 100000 SAR) {
4
+ summary: "A holder's reusable balance with an immutable per-spend ceiling."
5
+ fields { holder: account of holder, held: account of self, spendLimit: money = spend_limit }
6
+ lifecycle { states: [pending, active, frozen, closed], initial: pending }
7
+ action create { }
8
+ action activate { from: pending, to: active, actor: { party: holder } }
9
+ action topup {
10
+ from: active, to: active, actor: { party: holder }
11
+ input { amount: money }
12
+ moves input.amount from holder to self.held
13
+ }
14
+ action withdraw {
15
+ from: active, to: active, actor: { party: holder }
16
+ input { amount: money }
17
+ moves input.amount from self.held to holder
18
+ }
19
+ action freeze { from: active, to: frozen, }
20
+ action unfreeze { from: frozen, to: active, }
21
+ action close { from: [pending, active], to: closed, requires self.held.balance == "0" }
22
+ }
23
+
24
+ instrument spend(wallet: ref<wallet.balance>, payee: party) {
25
+ summary: "Reserve one wallet spend, then post or void the same reservation."
26
+ fields { wallet: ref<wallet>, amount: money, expiresAt: date, reservation: text? }
27
+ lifecycle { states: [pending, reserved, paid, cancelled, expired], initial: pending }
28
+ action create {
29
+ requires self.wallet in [active]
30
+ requires self.amount <= self.wallet.spendLimit
31
+ }
32
+ action reserve {
33
+ from: pending, to: reserved
34
+ requires self.wallet in [active]
35
+ deadline: { at: self.expiresAt }
36
+ moves reserve self.amount from self.wallet.held to payee capture "reservation"
37
+ }
38
+ action pay { from: reserved, to: paid, moves post self.reservation }
39
+ action cancel { from: reserved, to: cancelled, moves void self.reservation }
40
+ action expire { from: reserved, to: expired, actor: clock, due: { at: self.expiresAt }, moves void self.reservation }
41
+ }
@@ -1,13 +0,0 @@
1
- export interface HsxDiagnosticCatalogEntry {
2
- readonly code: `HSX${number}`;
3
- readonly stage: "bind" | "lower" | "parse" | "typecheck";
4
- readonly title: string;
5
- readonly fix: string;
6
- readonly example: string | null;
7
- readonly reason?: string;
8
- }
9
- /** Stable public descriptions for every diagnostic code emitted by HSX. */
10
- export declare const hsxDiagnostics: readonly HsxDiagnosticCatalogEntry[];
11
- /** Preserve the UDL diagnostic family when reporting a typed clause. */
12
- export declare function hsxClauseDiagnosticCode(code: string): string;
13
- //# sourceMappingURL=diagnostics.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/diagnostics.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,MAAM,EAAE,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,CAAC;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAiBD,2EAA2E;AAC3E,eAAO,MAAM,cAAc,EAAE,SAAS,yBAAyB,EAqkBrD,CAAC;AAEX,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU5D"}