eyeling 1.16.4 → 1.16.5

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.
@@ -0,0 +1,15 @@
1
+ @prefix : <https://example.org/parcellocker#> .
2
+ @prefix log: <http://www.w3.org/2000/10/swap/log#> .
3
+
4
+ :case :checkC8 :Passed .
5
+ :case :checkC6 :Passed .
6
+ :case :checkC7 :Passed .
7
+ :case :checkC9 :Passed .
8
+ :case :checkC10 :Passed .
9
+ :case :checkC1 :Passed .
10
+ :case :checkC2 :Passed .
11
+ :case :checkC3 :Passed .
12
+ :case :checkC4 :Passed .
13
+ :case :checkC5 :Passed .
14
+ :case :decision :Permit .
15
+ :out log:outputString "ParcelLocker — One-time parcel pickup by a friend\n\nAnswer\nPERMIT\nNoah may collect Maya's parcel from locker B17.\n\nReason Why\nMaya created a one-time authorization for Noah only, for this parcel only, at this locker only, and for pickup only. The token is active, the parcel is ready, and the same authorization does not reveal billing details or allow redirection.\n\nCheck\nC1 OK - requester matches the named delegate\nC2 OK - requested parcel matches the authorized parcel\nC3 OK - requested locker matches the authorized locker\nC4 OK - requested action is parcel collection\nC5 OK - requested purpose is pickup only\nC6 OK - authorization is active\nC7 OK - authorization is single-use\nC8 OK - parcel is ready for pickup\nC9 OK - billing details stay hidden\nC10 OK - parcel redirection is not allowed\n" .
@@ -0,0 +1,164 @@
1
+ # ===========================================================================
2
+ # ParcelLocker — One-time parcel pickup by a friend.
3
+ #
4
+ # This example shows how a person can let someone else collect a parcel without
5
+ # handing over their full shopping account. A one-time authorization is limited
6
+ # to one named person, one parcel, one locker, and one purpose: pickup. The
7
+ # locker may release the parcel, but the same authorization cannot be used to
8
+ # view billing details or redirect the parcel somewhere else.
9
+ # ===========================================================================
10
+
11
+ @prefix : <https://example.org/parcellocker#> .
12
+ @prefix log: <http://www.w3.org/2000/10/swap/log#> .
13
+
14
+ # -----
15
+ # Facts
16
+ # -----
17
+
18
+ :maya a :Person; :name "Maya" .
19
+ :noah a :Person; :name "Noah" .
20
+
21
+ :parcel123 a :Parcel;
22
+ :owner :maya;
23
+ :status :ReadyForPickup .
24
+
25
+ :lockerB17 a :Locker;
26
+ :site "Station West" .
27
+
28
+ :pickupToken a :PickupAuthorization;
29
+ :issuedBy :maya;
30
+ :delegate :noah;
31
+ :parcel :parcel123;
32
+ :locker :lockerB17;
33
+ :action :CollectParcel;
34
+ :purpose :PickupOnly;
35
+ :state :Active;
36
+ :reuse :SingleUse;
37
+ :billingAccess :None;
38
+ :redirectAllowed :No .
39
+
40
+ :pickupRequest a :Request;
41
+ :requester :noah;
42
+ :parcel :parcel123;
43
+ :locker :lockerB17;
44
+ :action :CollectParcel;
45
+ :purpose :PickupOnly .
46
+
47
+ # -----
48
+ # Logic
49
+ # -----
50
+
51
+ { :pickupToken :delegate ?who .
52
+ :pickupRequest :requester ?who . }
53
+ => { :case :checkC1 :Passed . } .
54
+
55
+ { :pickupToken :parcel ?parcel .
56
+ :pickupRequest :parcel ?parcel . }
57
+ => { :case :checkC2 :Passed . } .
58
+
59
+ { :pickupToken :locker ?locker .
60
+ :pickupRequest :locker ?locker . }
61
+ => { :case :checkC3 :Passed . } .
62
+
63
+ { :pickupToken :action ?action .
64
+ :pickupRequest :action ?action . }
65
+ => { :case :checkC4 :Passed . } .
66
+
67
+ { :pickupToken :purpose ?purpose .
68
+ :pickupRequest :purpose ?purpose . }
69
+ => { :case :checkC5 :Passed . } .
70
+
71
+ { :pickupToken :state :Active . }
72
+ => { :case :checkC6 :Passed . } .
73
+
74
+ { :pickupToken :reuse :SingleUse . }
75
+ => { :case :checkC7 :Passed . } .
76
+
77
+ { :parcel123 :status :ReadyForPickup . }
78
+ => { :case :checkC8 :Passed . } .
79
+
80
+ { :pickupToken :billingAccess :None . }
81
+ => { :case :checkC9 :Passed . } .
82
+
83
+ { :pickupToken :redirectAllowed :No . }
84
+ => { :case :checkC10 :Passed . } .
85
+
86
+ { :case :checkC1 :Passed .
87
+ :case :checkC2 :Passed .
88
+ :case :checkC3 :Passed .
89
+ :case :checkC4 :Passed .
90
+ :case :checkC5 :Passed .
91
+ :case :checkC6 :Passed .
92
+ :case :checkC7 :Passed .
93
+ :case :checkC8 :Passed .
94
+ :case :checkC9 :Passed .
95
+ :case :checkC10 :Passed . }
96
+ => { :case :decision :Permit . } .
97
+
98
+ # ------------------
99
+ # Presentation (ARC)
100
+ # ------------------
101
+
102
+ { :case :decision :Permit . }
103
+ => {
104
+ :out log:outputString "ParcelLocker — One-time parcel pickup by a friend\n\nAnswer\nPERMIT\nNoah may collect Maya's parcel from locker B17.\n\nReason Why\nMaya created a one-time authorization for Noah only, for this parcel only, at this locker only, and for pickup only. The token is active, the parcel is ready, and the same authorization does not reveal billing details or allow redirection.\n\nCheck\nC1 OK - requester matches the named delegate\nC2 OK - requested parcel matches the authorized parcel\nC3 OK - requested locker matches the authorized locker\nC4 OK - requested action is parcel collection\nC5 OK - requested purpose is pickup only\nC6 OK - authorization is active\nC7 OK - authorization is single-use\nC8 OK - parcel is ready for pickup\nC9 OK - billing details stay hidden\nC10 OK - parcel redirection is not allowed\n" .
105
+ } .
106
+
107
+ # ----------------
108
+ # Fail-loud checks
109
+ # ----------------
110
+
111
+ { :case :decision :Permit .
112
+ :pickupRequest :requester ?r .
113
+ :pickupToken :delegate ?d .
114
+ ?r log:notEqualTo ?d . }
115
+ => false .
116
+
117
+ { :case :decision :Permit .
118
+ :pickupRequest :parcel ?requested .
119
+ :pickupToken :parcel ?authorized .
120
+ ?requested log:notEqualTo ?authorized . }
121
+ => false .
122
+
123
+ { :case :decision :Permit .
124
+ :pickupRequest :locker ?requested .
125
+ :pickupToken :locker ?authorized .
126
+ ?requested log:notEqualTo ?authorized . }
127
+ => false .
128
+
129
+ { :case :decision :Permit .
130
+ :pickupRequest :action ?requested .
131
+ :pickupToken :action ?authorized .
132
+ ?requested log:notEqualTo ?authorized . }
133
+ => false .
134
+
135
+ { :case :decision :Permit .
136
+ :pickupRequest :purpose ?requested .
137
+ :pickupToken :purpose ?authorized .
138
+ ?requested log:notEqualTo ?authorized . }
139
+ => false .
140
+
141
+ { :case :decision :Permit .
142
+ :pickupToken :state ?state .
143
+ ?state log:notEqualTo :Active . }
144
+ => false .
145
+
146
+ { :case :decision :Permit .
147
+ :pickupToken :reuse ?reuse .
148
+ ?reuse log:notEqualTo :SingleUse . }
149
+ => false .
150
+
151
+ { :case :decision :Permit .
152
+ :parcel123 :status ?status .
153
+ ?status log:notEqualTo :ReadyForPickup . }
154
+ => false .
155
+
156
+ { :case :decision :Permit .
157
+ :pickupToken :billingAccess ?access .
158
+ ?access log:notEqualTo :None . }
159
+ => false .
160
+
161
+ { :case :decision :Permit .
162
+ :pickupToken :redirectAllowed ?redirect .
163
+ ?redirect log:notEqualTo :No . }
164
+ => false .
package/eyeling.js CHANGED
@@ -4719,6 +4719,8 @@ const {
4719
4719
  MATH_NS,
4720
4720
  LOG_NS,
4721
4721
  SKOLEM_NS,
4722
+ MAX_LITERAL_TID_LEN,
4723
+ normalizeLiteralForTid,
4722
4724
  Literal,
4723
4725
  Iri,
4724
4726
  Var,
@@ -5627,7 +5629,18 @@ function __internCompoundTid(key) {
5627
5629
 
5628
5630
  function termFastKey(t) {
5629
5631
  // Atomic terms that already have a stable id.
5630
- if (t instanceof Iri || t instanceof Blank || t instanceof Literal) return t.__tid;
5632
+ if (t instanceof Iri || t instanceof Blank) return t.__tid;
5633
+
5634
+ if (t instanceof Literal) {
5635
+ // Very large literals intentionally skip global interning in prelude.js to
5636
+ // avoid retaining huge strings forever. Their per-object __tid is therefore
5637
+ // not value-stable, so using it here breaks duplicate detection for facts
5638
+ // such as long log:outputString blocks that are re-derived during forward
5639
+ // chaining. Fall back to a value-based key in that case.
5640
+ const norm = normalizeLiteralForTid(t.value);
5641
+ if (typeof norm === 'string' && norm.length > MAX_LITERAL_TID_LEN) return 'L:' + norm;
5642
+ return t.__tid;
5643
+ }
5631
5644
 
5632
5645
  // Structural fast key for strict-ground list terms.
5633
5646
  // We only index when every element has a fast key; otherwise return null.
@@ -10389,6 +10402,8 @@ module.exports = {
10389
10402
  RDF_JSON_DT,
10390
10403
  resolveIriRef,
10391
10404
  literalParts,
10405
+ normalizeLiteralForTid,
10406
+ MAX_LITERAL_TID_LEN,
10392
10407
  Term,
10393
10408
  Iri,
10394
10409
  Literal,
package/lib/engine.js CHANGED
@@ -13,6 +13,8 @@ const {
13
13
  MATH_NS,
14
14
  LOG_NS,
15
15
  SKOLEM_NS,
16
+ MAX_LITERAL_TID_LEN,
17
+ normalizeLiteralForTid,
16
18
  Literal,
17
19
  Iri,
18
20
  Var,
@@ -921,7 +923,18 @@ function __internCompoundTid(key) {
921
923
 
922
924
  function termFastKey(t) {
923
925
  // Atomic terms that already have a stable id.
924
- if (t instanceof Iri || t instanceof Blank || t instanceof Literal) return t.__tid;
926
+ if (t instanceof Iri || t instanceof Blank) return t.__tid;
927
+
928
+ if (t instanceof Literal) {
929
+ // Very large literals intentionally skip global interning in prelude.js to
930
+ // avoid retaining huge strings forever. Their per-object __tid is therefore
931
+ // not value-stable, so using it here breaks duplicate detection for facts
932
+ // such as long log:outputString blocks that are re-derived during forward
933
+ // chaining. Fall back to a value-based key in that case.
934
+ const norm = normalizeLiteralForTid(t.value);
935
+ if (typeof norm === 'string' && norm.length > MAX_LITERAL_TID_LEN) return 'L:' + norm;
936
+ return t.__tid;
937
+ }
925
938
 
926
939
  // Structural fast key for strict-ground list terms.
927
940
  // We only index when every element has a fast key; otherwise return null.
package/lib/prelude.js CHANGED
@@ -515,6 +515,8 @@ module.exports = {
515
515
  RDF_JSON_DT,
516
516
  resolveIriRef,
517
517
  literalParts,
518
+ normalizeLiteralForTid,
519
+ MAX_LITERAL_TID_LEN,
518
520
  Term,
519
521
  Iri,
520
522
  Literal,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.16.4",
3
+ "version": "1.16.5",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [