@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/std/approvals.hsx
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
header approvals
|
|
2
2
|
|
|
3
|
-
instrument decision(for: ref, approved_by:
|
|
3
|
+
instrument decision(for: ref, approved_by: approval, action: text = "approve", protected_request: text = "self.target") {
|
|
4
4
|
summary: "One authenticated decision bound to an immutable target and expiry."
|
|
5
5
|
fields { target: ref<for>, expiresAt: date }
|
|
6
6
|
lifecycle { states: [pending, approved, declined, expired], initial: pending }
|
|
7
7
|
action create {}
|
|
8
8
|
action approve {
|
|
9
9
|
from: pending, to: approved, actor: { party: approved_by }, deadline: { at: self.expiresAt }
|
|
10
|
-
approval: { target: self.target, action: action, party: approved_by, expires: self.expiresAt, input: "material", decision: "approved" }
|
|
10
|
+
approval: { protectedRequest: protected_request, target: self.target, action: action, party: approved_by, expires: self.expiresAt, input: "material", decision: "approved" }
|
|
11
11
|
}
|
|
12
12
|
action decline {
|
|
13
13
|
from: pending, to: declined, actor: { party: approved_by }, deadline: { at: self.expiresAt }
|
|
14
|
-
approval: { target: self.target, action: action, party: approved_by, expires: self.expiresAt, input: "material", decision: "declined" }
|
|
14
|
+
approval: { protectedRequest: protected_request, target: self.target, action: action, party: approved_by, expires: self.expiresAt, input: "material", decision: "declined" }
|
|
15
15
|
}
|
|
16
16
|
action expire { from: pending, to: expired, actor: clock, due: { at: self.expiresAt } }
|
|
17
17
|
}
|
package/std/collections.hsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
header collections
|
|
2
2
|
|
|
3
3
|
instrument case(on: ref<financing.installments>[], agency: approval, overdue: duration = 3d, fee: percent = 20%) {
|
|
4
|
+
revisioned: true
|
|
4
5
|
summary: "Refer an overdue installment without creating another debt."
|
|
5
|
-
fields { plan: ref<on>, slice: ref<on.slice>, payment: ref<on.payment>, eligibleAt: date = after(self.slice.dueAt, overdue), agencyFee: money = rate(self.payment.amount, fee) }
|
|
6
|
+
fields { assignedAgency: account of agency, plan: ref<on>, slice: ref<on.slice>, payment: ref<on.payment>, eligibleAt: date = after(self.slice.dueAt, overdue), agencyFee: money = rate(self.payment.amount, fee) }
|
|
6
7
|
lifecycle { states: [opened, assigned, recovered, recalled, returned_uncollected], initial: opened }
|
|
7
8
|
action create {
|
|
8
9
|
due: { at: self.eligibleAt }
|
|
@@ -11,7 +12,7 @@ instrument case(on: ref<financing.installments>[], agency: approval, overdue: du
|
|
|
11
12
|
requires unique "overdue_referral" on [self.slice]
|
|
12
13
|
}
|
|
13
14
|
action assign { from: opened, to: assigned, requires approval by agency }
|
|
14
|
-
action recover { from: assigned, to: recovered, actor: { party: agency }, requires self.payment.plan == self.plan, invoke: [{ reference: self.payment, action: pay, input: {} }, { reference: self.id, action: pay_fee, input: {} }] }
|
|
15
|
+
action recover { expansionLimit: 8192, from: assigned, to: recovered, actor: { party: agency }, requires self.payment.plan == self.plan, invoke: [{ reference: self.payment, action: pay, input: {} }, { reference: self.id, action: pay_fee, input: {} }] }
|
|
15
16
|
action pay_fee { from: recovered, to: recovered, actor: { parent: current() }, moves self.agencyFee from self.plan.capital to agency }
|
|
16
17
|
action recall { from: [opened, assigned], to: recalled }
|
|
17
18
|
action return_uncollected { from: assigned, to: returned_uncollected, actor: { party: agency } }
|
|
@@ -20,12 +21,52 @@ instrument case(on: ref<financing.installments>[], agency: approval, overdue: du
|
|
|
20
21
|
instrument 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") {
|
|
21
22
|
constraints { contact_from: less_than(contact_until) }
|
|
22
23
|
summary: "An agency contact admitted against the locked rolling count and local hours."
|
|
23
|
-
fields { case: ref<case>, attemptedAt: date?, evidence: text, maximum: integer = max_contacts }
|
|
24
|
+
fields { agency: account of agency, case: ref<case>, attemptedAt: date?, evidence: text, maximum: integer = max_contacts }
|
|
24
25
|
lifecycle { states: [recorded], initial: recorded }
|
|
25
26
|
invariants count of { instrument: current(), reference: "case", anchor: self.case, states: [recorded], limit: 366, window: { field: attemptedAt, milliseconds: window } } <= self.maximum
|
|
26
27
|
action create {
|
|
27
28
|
actor: { party: agency }
|
|
28
29
|
set: { attemptedAt: { field: self.now } }
|
|
29
|
-
requires self.case in [assigned]; requires hours self.now between contact_from and contact_until timezone timezone
|
|
30
|
+
requires self.agency == self.case.assignedAgency; requires self.case in [assigned]; requires hours self.now between contact_from and contact_until timezone timezone
|
|
31
|
+
}
|
|
32
|
+
records {
|
|
33
|
+
outcome: {
|
|
34
|
+
fields { contact: ref<parent>, agency: account of agency, outcome: enum(reached, no_answer, promise_to_pay, disputed, wrong_contact, refused), evidence: text, recordedAt: date? }
|
|
35
|
+
lifecycle { states: [recorded], initial: recorded }
|
|
36
|
+
action create {
|
|
37
|
+
actor: { party: agency }
|
|
38
|
+
requires self.agency == self.contact.case.assignedAgency
|
|
39
|
+
set: { recordedAt: { field: self.now } }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
instrument 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") {
|
|
47
|
+
constraints { send_from: less_than(send_until) }
|
|
48
|
+
summary: "Send an email to the installment borrower's stored contact address."
|
|
49
|
+
fields { slice: ref<on.slice> }
|
|
50
|
+
lifecycle { states: [ready], initial: ready }
|
|
51
|
+
action create { requires unique "installment_reminder" on [self.slice] }
|
|
52
|
+
action dispatch {
|
|
53
|
+
from: ready, to: ready, actor: { party: operator }
|
|
54
|
+
invoke: [{ reference: self.id, action: send, input: {} }]
|
|
55
|
+
}
|
|
56
|
+
action before_due {
|
|
57
|
+
from: ready, to: ready, actor: clock
|
|
58
|
+
due: { at: self.slice.dueAt, localDay: { days: before_days, direction: "before", hour: send_from, timezone: timezone } }
|
|
59
|
+
invoke: [{ selection: { instrument: current(), reference: "slice", anchor: self.slice, states: [ready], limit: 1, where: { slice.plan.status: { literal: "active" } } }, action: send, guard: { kind: compare, left: { field: self.slice.principalReceivable.balance }, operator: ">", right: { literal: "0" } }, input: {} }]
|
|
60
|
+
}
|
|
61
|
+
action overdue {
|
|
62
|
+
from: ready, to: ready, actor: clock
|
|
63
|
+
due: { at: self.slice.dueAt, localDay: { days: overdue_days, direction: "after", hour: send_from, timezone: timezone } }
|
|
64
|
+
invoke: [{ selection: { instrument: current(), reference: "slice", anchor: self.slice, states: [ready], limit: 1, where: { slice.plan.status: { literal: "active" } } }, action: send, guard: { kind: compare, left: { field: self.slice.principalReceivable.balance }, operator: ">", right: { literal: "0" } }, input: {} }]
|
|
65
|
+
}
|
|
66
|
+
action send {
|
|
67
|
+
from: ready, to: ready, actor: { parent: current() }
|
|
68
|
+
requires self.slice.plan in [active]
|
|
69
|
+
requires self.slice.principalReceivable.balance > "0"
|
|
70
|
+
reminder: { installment: self.slice, recipient: self.slice.plan.borrower, dueAt: self.slice.dueAt, channel: "email", template: "payment_reminder", beforeDays: before_days, overdueDays: overdue_days, maxPerDay: max_per_day, startHour: send_from, endHour: send_until, timezone: timezone }
|
|
30
71
|
}
|
|
31
72
|
}
|
package/std/escrow.hsx
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
header escrow
|
|
2
2
|
|
|
3
|
-
instrument hold(payer: party, payee: party
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
instrument hold(payer: party = party(person), payee: party = programOperator, accept_within: duration = 48h, fee: fee = { seller: 0%, tax: 0% }, dispute: policy = { refund_after: return_verified }) {
|
|
4
|
+
revisioned: true
|
|
5
|
+
summary: "Hold the subject price through delivery, acceptance and verified return."
|
|
6
|
+
fields {
|
|
7
|
+
payer: account of payer, payee: account of payee
|
|
8
|
+
held: account of self, deliveredAt: date?
|
|
9
|
+
price: money = subject.price
|
|
10
|
+
}
|
|
6
11
|
lifecycle { states: [pending, funded, delivered, disputed, return_verified, released, refunded, cancelled], initial: pending }
|
|
7
12
|
action create {
|
|
8
|
-
|
|
13
|
+
subject { price: money }
|
|
14
|
+
actor: { party: payer }
|
|
9
15
|
}
|
|
10
16
|
action fund {
|
|
11
17
|
from: pending, to: funded, actor: { party: payer }
|
|
12
|
-
|
|
13
|
-
moves
|
|
18
|
+
subject { price: money }
|
|
19
|
+
moves subject.price from payer to self.held
|
|
14
20
|
}
|
|
15
21
|
action confirm {
|
|
16
22
|
from: pending, to: funded
|
|
@@ -22,7 +28,7 @@ instrument hold(payer: party, payee: party, for: ref<marketplace.order>, accept_
|
|
|
22
28
|
}
|
|
23
29
|
action accept {
|
|
24
30
|
from: delivered, to: released, actor: { party: payer }
|
|
25
|
-
input { acceptanceReference: text
|
|
31
|
+
input { acceptanceReference: text }
|
|
26
32
|
deadline: { at: self.deliveredAt, offset: accept_within }
|
|
27
33
|
moves self.price from self.held to payee fee fee
|
|
28
34
|
}
|
|
@@ -34,7 +40,10 @@ instrument hold(payer: party, payee: party, for: ref<marketplace.order>, accept_
|
|
|
34
40
|
from: delivered, to: disputed, actor: { party: payer }
|
|
35
41
|
deadline: { at: self.deliveredAt, offset: accept_within }
|
|
36
42
|
}
|
|
37
|
-
action verify_return {
|
|
43
|
+
action verify_return {
|
|
44
|
+
from: disputed, to: return_verified
|
|
45
|
+
input { returnEvidence: text }
|
|
46
|
+
}
|
|
38
47
|
action refund {
|
|
39
48
|
from: dispute.refund_after, to: refunded
|
|
40
49
|
moves self.price from self.held to payer
|