@hyperscale0/hsx 3.2.0 → 4.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.
- package/CHANGELOG.md +8 -0
- package/README.md +1 -1
- package/dist/src/ast.d.ts +17 -2
- package/dist/src/ast.d.ts.map +1 -1
- package/dist/src/ast.js.map +1 -1
- package/dist/src/cli.js +1 -1
- package/dist/src/compile.d.ts +6 -0
- package/dist/src/compile.d.ts.map +1 -1
- package/dist/src/compile.js +1194 -97
- package/dist/src/compile.js.map +1 -1
- package/dist/src/cost.d.ts +1 -1
- package/dist/src/cost.d.ts.map +1 -1
- package/dist/src/cost.js +52 -9
- package/dist/src/cost.js.map +1 -1
- package/dist/src/headers.d.ts +2 -2
- package/dist/src/headers.d.ts.map +1 -1
- package/dist/src/headers.js +3 -2
- package/dist/src/headers.js.map +1 -1
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lex.d.ts +1 -1
- package/dist/src/lex.d.ts.map +1 -1
- package/dist/src/lex.js +5 -0
- package/dist/src/lex.js.map +1 -1
- package/dist/src/parse.js +91 -5
- package/dist/src/parse.js.map +1 -1
- package/dist/src/std-bundle.d.ts.map +1 -1
- package/dist/src/std-bundle.js +10 -9
- package/dist/src/std-bundle.js.map +1 -1
- package/dist/src/version.d.ts +2 -2
- package/dist/src/version.js +2 -2
- package/docs/README.md +51 -27
- package/docs/headers.md +43 -40
- package/examples/cost-table.json +40 -324
- package/examples/library.hsx +12 -57
- package/package.json +7 -5
- package/src/ast.ts +11 -1
- package/src/cli.ts +1 -1
- package/src/compile.ts +1630 -114
- package/src/cost.ts +60 -16
- package/src/headers.ts +3 -2
- package/src/index.ts +12 -1
- package/src/lex.ts +5 -0
- package/src/parse.ts +87 -5
- package/src/std-bundle.ts +10 -9
- package/src/version.ts +2 -2
- package/std/approvals.hsx +3 -3
- package/std/collections.hsx +45 -4
- package/std/escrow.hsx +17 -8
- package/std/financing.hsx +292 -42
- package/std/insurance.hsx +4 -5
- package/std/lending.hsx +7 -8
- package/std/marketplace.hsx +90 -6
- package/std/money.hsx +15 -49
- package/std/reporting.hsx +1286 -0
- package/std/travel.hsx +5 -6
package/docs/README.md
CHANGED
|
@@ -1,24 +1,41 @@
|
|
|
1
|
-
# HSX
|
|
1
|
+
# HSX 4
|
|
2
2
|
|
|
3
|
-
A program declares
|
|
4
|
-
|
|
5
|
-
account ids, reference filters, credentials or bank beneficiary ids.
|
|
3
|
+
A program declares business objects and financial instruments. Objects contain
|
|
4
|
+
optional metadata. Attachments expose named actions against an object.
|
|
6
5
|
|
|
7
6
|
```hsx
|
|
8
|
-
program
|
|
9
|
-
use marketplace
|
|
7
|
+
program cars "Cars"
|
|
10
8
|
use escrow
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
sale = escrow.hold {
|
|
16
|
-
payer: buyer, payee: seller, for: order, accept_within: 48h
|
|
17
|
-
fee { seller: 1% cap 750 SAR, tax: 15% }
|
|
18
|
-
dispute { refund_after: return_verified }
|
|
9
|
+
object car "Cars" {
|
|
10
|
+
fields { make: text, model: text, year: integer }
|
|
11
|
+
columns: [make, model, year]
|
|
12
|
+
attach sale = escrow.hold { payer: actor, payee: owner, expose fund as sell }
|
|
19
13
|
}
|
|
20
14
|
```
|
|
21
15
|
|
|
16
|
+
Every attached party parameter binds to `owner`, `actor`, or `operator`.
|
|
17
|
+
`owner` is the object's resolved customer or business, `actor` is the authenticated
|
|
18
|
+
caller, and `operator` is the program operator. A parameter with one of these
|
|
19
|
+
names binds by name. Other party parameters require an explicit binding.
|
|
20
|
+
Unbound parameters report `subject_party_unbound`. These bindings are frozen in
|
|
21
|
+
UDL `objects[].attachments[].parties`; no caller supplies party IDs at creation.
|
|
22
|
+
|
|
23
|
+
Object `fields` are authored metadata. `columns` names up to eight normalized
|
|
24
|
+
fields. An action's `subject { price: money }` declares its metadata requirement;
|
|
25
|
+
`subject { adapter: verification }` inherits a selected ADL declaration. The
|
|
26
|
+
compiler freezes the adapter identity, digest and requirements. An unavailable
|
|
27
|
+
declaration leaves a null snapshot and an unavailable action.
|
|
28
|
+
|
|
29
|
+
An attachment can use `rename { price: salePrice }` to separate requirements with
|
|
30
|
+
different meanings. Matching names must match types and constraints. The compiler
|
|
31
|
+
reports `subject_field_conflict` with both origins, or `subject_field_unknown` for
|
|
32
|
+
unknown rename sources, columns or subject expressions. Action admission reports
|
|
33
|
+
`subject_requirement_missing` or `subject_adapter_unbound` before dispatch.
|
|
34
|
+
|
|
35
|
+
Creation accepts `{}`. Every normalized field, including adapter requirements,
|
|
36
|
+
is optional at creation. Only a named action requires its subject metadata.
|
|
37
|
+
Use `attach` inside the object block to configure its financial instruments.
|
|
38
|
+
|
|
22
39
|
The header defines the available policies. The company chooses percentages, amounts, durations,
|
|
23
40
|
parties and typed references. `funds: sale` links the stored records through the
|
|
24
41
|
library's declared reference type. References can name a child, such as
|
|
@@ -38,11 +55,11 @@ Tax binds `programTax`. Fees default to `programOperator`. Fine, recovery and
|
|
|
38
55
|
residual destinations are party tunables. Unused `programFines` and `programCosts`
|
|
39
56
|
bindings are omitted.
|
|
40
57
|
|
|
41
|
-
|
|
42
|
-
`
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
58
|
+
Attached actions are private unless the attachment exposes them with
|
|
59
|
+
`expose fund as sell`. Exposure grants no authority. Clock and parent actions
|
|
60
|
+
remain executor-owned. Instruments have no standalone create route: an
|
|
61
|
+
attachment exposes its create action by name (`expose create as finance`) or
|
|
62
|
+
keeps it internal. Callers create objects and run their attached actions.
|
|
46
63
|
|
|
47
64
|
Accounts use cash or claim books. A move stays in one book. `account of buyer`
|
|
48
65
|
aliases the default cash account; `account of self` provisions an owned account.
|
|
@@ -143,6 +160,12 @@ when disburse_to is borrower {
|
|
|
143
160
|
}
|
|
144
161
|
```
|
|
145
162
|
|
|
163
|
+
`when <reference tunable> has <field>` includes its clauses only when the bound
|
|
164
|
+
object declares that field. The compiler checks the object's declared shape,
|
|
165
|
+
regardless of declaration order, and emits no runtime branch. Financing uses
|
|
166
|
+
this to commit marketplace orders for order-backed holds while plain money
|
|
167
|
+
holds need no order relation.
|
|
168
|
+
|
|
146
169
|
`when <enum tunable> is <value>` accepts requirements, calculations, moves and
|
|
147
170
|
invocations, including nested branches. The compiler emits only the selected
|
|
148
171
|
clauses and preserves their order within each UDL phase. Lifecycle and actor
|
|
@@ -160,13 +183,6 @@ requires a valid hours interval. `at_most` and `greater_than` are also supported
|
|
|
160
183
|
A refusal names the tunable. Empty `all(type)` selections lower to zero aggregates
|
|
161
184
|
or no invocations, so a plan does not require a late-charge object.
|
|
162
185
|
|
|
163
|
-
The permutation spec builds a dependency-closed program per object. It takes each
|
|
164
|
-
enum value and the minimum, default or example value, and a large numeric value.
|
|
165
|
-
It uses the full product through 512 cases and pair coverage above that. Invalid
|
|
166
|
-
bound combinations must refuse with a named diagnostic. Valid cases must produce
|
|
167
|
-
valid UDL and retain public names on every caller action. This proves compilation,
|
|
168
|
-
not executed balances or bank settlement.
|
|
169
|
-
|
|
170
186
|
Build with `hsx build company.hsx --out company.udl.json`; check with
|
|
171
187
|
`hsx check company.hsx`; print instruction counts with `hsx cost company.hsx`.
|
|
172
188
|
Print the compiler-owned object manifest with `hsx headers --json`.
|
|
@@ -175,5 +191,13 @@ The compiler API is `compile(source)`. A valid result contains `artifacts.docume
|
|
|
175
191
|
promise of provider execution cost.
|
|
176
192
|
|
|
177
193
|
The [header inventory](headers.md) is generated from the declarations. The
|
|
178
|
-
[
|
|
194
|
+
[object example](../examples/library.hsx) shows authenticated role bindings.
|
|
179
195
|
The [playground](../playground/index.html) compiles locally in the browser.
|
|
196
|
+
|
|
197
|
+
## Financing attachments
|
|
198
|
+
|
|
199
|
+
Financing retains its authored borrower and portfolio limits. Bind every party
|
|
200
|
+
parameter to a subject role and link the existing escrow and limits attachments.
|
|
201
|
+
No limit is inferred from object metadata.
|
|
202
|
+
|
|
203
|
+
See the complete [financing object example](../examples/library.hsx).
|
package/docs/headers.md
CHANGED
|
@@ -1,44 +1,47 @@
|
|
|
1
1
|
# Header inventory
|
|
2
2
|
|
|
3
|
-
Each
|
|
3
|
+
Attach library instruments inside authored object kinds. Each program selects policies through typed tunables.
|
|
4
|
+
Bind party parameters to owner, actor, operator or declared parties. Configure declared businesses per Build; staff declarations name approval authority. The authoringTemplate source is an attach fragment for an object block. Expose the chosen business action; instrument creation stays internal.
|
|
4
5
|
`ref<T>[]` accepts one reference or up to 16 references as one policy. `approval` accepts a party and generates the required decision records.
|
|
5
6
|
|
|
6
|
-
|
|
|
7
|
-
|
|
|
8
|
-
| money.transfer
|
|
9
|
-
| money.hold
|
|
10
|
-
| money.split
|
|
11
|
-
| money.schedule
|
|
12
|
-
| money.pool
|
|
13
|
-
| money.swap
|
|
14
|
-
| money.deposit
|
|
15
|
-
| money.payout
|
|
16
|
-
| money.metered
|
|
17
|
-
|
|
|
18
|
-
| marketplace.
|
|
19
|
-
| marketplace.
|
|
20
|
-
| escrow.hold
|
|
21
|
-
| wallet.balance
|
|
22
|
-
| wallet.spend
|
|
23
|
-
| financing.installments | `months: integer(1, 366)`, `profit: percent`, `disburse_to: enum(funds, borrower) = funds`, `profit_earned: enum(on_payment, by_schedule, at_disbursement) = on_payment`, `apply: enum(fines_profit_principal, principal_profit, pro_rata) = fines_profit_principal`, `payoff_rebate: percent = 100%`, `down_payment: percent = 0%`, `funds: ref`, `approval: approval`, `borrower: party = party(person)`, `capital: party = programOperator`, `
|
|
24
|
-
| financing.late_charge
|
|
25
|
-
| financing.limits
|
|
26
|
-
| financing.credit_line
|
|
27
|
-
| financing.advance
|
|
28
|
-
| lending.round
|
|
29
|
-
| lending.commitment
|
|
30
|
-
| lending.distribution
|
|
31
|
-
| insurance.cover
|
|
32
|
-
| insurance.claim
|
|
33
|
-
| approvals.decision
|
|
34
|
-
| collections.case
|
|
35
|
-
| collections.contact
|
|
36
|
-
|
|
|
37
|
-
| travel.
|
|
38
|
-
|
|
|
39
|
-
| cards.
|
|
40
|
-
| cards.
|
|
41
|
-
| cards.
|
|
42
|
-
| cards.
|
|
43
|
-
|
|
|
44
|
-
| savings.
|
|
7
|
+
| Instrument | Tunables |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| money.transfer | `payer: party`, `payee: party`, `amount: money = runtime` |
|
|
10
|
+
| money.hold | `payer: party`, `payee: party`, `amount: money = runtime` |
|
|
11
|
+
| money.split | `payer: party`, `amount: money = runtime`, `shares: split = { programOperator: 100% }` |
|
|
12
|
+
| money.schedule | `payer: party`, `payee: party`, `amount: money = runtime`, `count: integer(1, 366) = 12` |
|
|
13
|
+
| money.pool | `payer: party`, `payee: party`, `target: money`, `closes: date` |
|
|
14
|
+
| money.swap | `first: party`, `second: party`, `first_amount: money`, `second_amount: money`, `expires: date` |
|
|
15
|
+
| money.deposit | `payer: party`, `payee: party`, `amount: money`, `expires: date`, `approval: approval` |
|
|
16
|
+
| money.payout | `payer: party`, `payee: party`, `adapter: text`, `max_age: duration`, `amount: money = runtime` |
|
|
17
|
+
| money.metered | `payer: party`, `payee: party`, `unit_price: money`, `units: integer = 1`, `fee: fee = { seller: 0% }` |
|
|
18
|
+
| marketplace.listing | `seller: party` |
|
|
19
|
+
| marketplace.order | `listing: ref<marketplace.listing>`, `buyer: party` |
|
|
20
|
+
| marketplace.reservation | `listing: ref<marketplace.listing>`, `funds: ref<escrow.hold>`, `plans: ref<financing.installments>[]`, `converters: ref[]`, `buyer: party`, `seller: party`, `expires_after: duration = 48h`, `deposit: money = 1000 SAR`, `cancellation_refund: percent = 100%`, `expiry_refund: percent = 100%`, `retained_to: party = programOperator`, `operator: party = programOperator`, `competing_quotes: enum(allowed, blocked) = allowed` |
|
|
21
|
+
| escrow.hold | `payer: party = party(person)`, `payee: party = programOperator`, `accept_within: duration = 48h`, `fee: fee = { seller: 0%, tax: 0% }`, `dispute: policy = { refund_after: return_verified }` |
|
|
22
|
+
| wallet.balance | `holder: party`, `spend_limit: money = 100000 SAR` |
|
|
23
|
+
| wallet.spend | `wallet: ref<wallet.balance>`, `payee: party` |
|
|
24
|
+
| financing.installments | `months: integer(1, 366)`, `charge_limit: integer(1, 3) = 3`, `profit: percent`, `disburse_to: enum(funds, borrower) = funds`, `profit_earned: enum(on_payment, by_schedule, at_disbursement) = on_payment`, `apply: enum(fines_profit_principal, principal_profit, pro_rata) = fines_profit_principal`, `payoff_rebate: percent = 100%`, `write_off_after: duration = 90d`, `max_extension: duration = 90d`, `max_amendments: integer(0, 366) = 2`, `waiver_limit: percent = 100%`, `amendment_expiry: duration = 7d`, `payoff_quote_expiry: duration = 1h`, `allow_overdue: enum(allowed, blocked) = allowed`, `assessed_fines: enum(carry, require_waiver) = carry`, `down_payment: percent = 0%`, `funds: ref = object(escrow.hold)`, `approval: approval = programOperator`, `borrower: party = party(person)`, `capital: party = programOperator`, `share: percent = 0%`, `limits: ref<financing.limits> = object(financing.limits)` |
|
|
25
|
+
| financing.late_charge | `on: ref<financing.installments>[]`, `grace: duration = 3d`, `fine: money = 50 SAR`, `cap: money = 25 SAR`, `fines_to: party = programOperator`, `costs_to: party = programOperator`, `approval: approval = programOperator`, `borrower: party = party(person)` |
|
|
26
|
+
| financing.limits | `per_borrower: money`, `portfolio: money`, `borrower: party = party(person)`, `active_plans: integer = 1` |
|
|
27
|
+
| financing.credit_line | `borrower: party`, `lender: party`, `limit: money`, `expires: date` |
|
|
28
|
+
| financing.advance | `line: ref<financing.credit_line>`, `amount: money = runtime` |
|
|
29
|
+
| lending.round | `borrower: party`, `plan: ref<financing.installments> = object(financing.installments)`, `minimum_ticket: money = 100 SAR`, `investor_cap: percent = 20%`, `commitments: ref<lending.commitment> = object(lending.commitment)` |
|
|
30
|
+
| lending.commitment | `round: ref<lending.round>`, `wallet: ref<wallet.balance>`, `investor: party = party(person)` |
|
|
31
|
+
| lending.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%` |
|
|
32
|
+
| insurance.cover | `holder: party`, `insurer: party`, `approval: approval = programOperator`, `commission: percent = 0%`, `covers: ref`, `premium: money = runtime` |
|
|
33
|
+
| insurance.claim | `cover: ref<insurance.cover>`, `approved_by: approval` |
|
|
34
|
+
| approvals.decision | `for: ref`, `approved_by: approval`, `action: text = "approve"`, `protected_request: text = "self.target"` |
|
|
35
|
+
| collections.case | `on: ref<financing.installments>[]`, `agency: approval`, `overdue: duration = 3d`, `fee: percent = 20%` |
|
|
36
|
+
| collections.contact | `case: ref<collections.case>[]`, `agency: party`, `max_contacts: integer = 10`, `window: duration = 30d`, `contact_from: integer(0, 23) = 8`, `contact_until: integer(1, 23) = 20`, `timezone: text = "Asia/Riyadh"`; contact_from less_than contact_until |
|
|
37
|
+
| collections.reminder | `on: ref<financing.installments>[]`, `operator: party = programOperator`, `before_days: integer(0, 366) = 3`, `overdue_days: integer(1, 366) = 1`, `max_per_day: integer(1, 10) = 1`, `send_from: integer(0, 23) = 8`, `send_until: integer(1, 24) = 20`, `timezone: text = "Asia/Riyadh"`; send_from less_than send_until |
|
|
38
|
+
| travel.package | `price: money`, `supplier_cost: money`, `departure: date`; supplier_cost at_most price |
|
|
39
|
+
| travel.booking | `package: ref<travel.package>`, `buyer: party`, `supplier: party`, `approval: approval = programOperator`, `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%`; early_before greater_than middle_before |
|
|
40
|
+
| cards.cardholder | `holder: party` |
|
|
41
|
+
| cards.card | `holder: ref<cards.cardholder>`, `spend_limit: money` |
|
|
42
|
+
| cards.authorization | `card: ref<cards.card>`, `merchant: party`, `approval: approval` |
|
|
43
|
+
| cards.transaction | `authorization: ref<cards.authorization>` |
|
|
44
|
+
| cards.dispute | `transaction: ref<cards.transaction>`, `approved_by: approval`, `within: duration = 90d` |
|
|
45
|
+
| savings.circle | `contribution: money`, `members: integer(1, 366)`, `starts: date`, `memberships: ref<savings.membership> = object(savings.membership)` |
|
|
46
|
+
| savings.membership | `circle: ref<savings.circle>`, `member: party` |
|
|
47
|
+
| reporting.portfolio | `on: ref<financing.installments>[]`, `default_days: integer(1, 3650) = 90`, `retention_years: integer(1, 100) = 10`, `aging_first_days: integer(1, 3650) = 30`, `aging_second_days: integer(1, 3650) = 60`, `aging_third_days: integer(1, 3650) = 90`, `ratio_scale: integer(1, 1000000) = 10000`, `ratio_rounding: enum(floor, halfUp) = floor`, `lock_wait_ms: integer(1, 2000) = 2000`, `capture_ms: integer(1, 10000) = 10000`, `max_rows: integer(1, 100000) = 10000`, `max_join_rows: integer(1, 1000000) = 100000`, `max_bytes: integer(1024, 16777216) = 8388608`; aging_first_days less_than aging_second_days, aging_second_days less_than aging_third_days |
|