@reventlessdev/reventless-spec 3.0.0-alpha.134 → 3.0.0-alpha.136

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 (36) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/package.json +4 -3
  3. package/run-check-lifecycle.mjs +2 -1
  4. package/run-prepare-accounts.mjs +3 -0
  5. package/src/components/CapabilityManifest.res +4 -0
  6. package/src/components/CapabilityManifest.res.mjs +13 -2
  7. package/src/components/DcbScopeInference.res +224 -73
  8. package/src/components/DcbScopeInference.res.mjs +187 -49
  9. package/src/components/DcbTag.res +142 -186
  10. package/src/components/DcbTag.res.mjs +137 -128
  11. package/src/components/DcbValidation.res +50 -0
  12. package/src/components/DcbValidation.res.mjs +51 -0
  13. package/src/generator/Codegen.res +2 -1
  14. package/src/generator/Codegen.res.mjs +1 -1
  15. package/src/generator/PlatformCodegen.res +1 -0
  16. package/src/generator/PlatformCodegen.res.mjs +5 -0
  17. package/src/lifecycle/CheckLifecycleModel.res +148 -8
  18. package/src/lifecycle/CheckLifecycleModel.res.mjs +154 -7
  19. package/src/semantic/Capabilities.res +17 -0
  20. package/src/semantic/Capabilities.res.mjs +9 -1
  21. package/src/semantic/CapabilityNeed.res +12 -0
  22. package/src/semantic/CapabilityNeed.res.mjs +9 -4
  23. package/src/semantic/IdentityProvider.res +127 -0
  24. package/src/semantic/IdentityProvider.res.mjs +65 -0
  25. package/src/semantic/Secrets.res +76 -0
  26. package/src/semantic/Secrets.res.mjs +49 -0
  27. package/src/types/AccountsManifest.res +287 -0
  28. package/src/types/AccountsManifest.res.mjs +312 -0
  29. package/src/types/AdminGroup.res +27 -0
  30. package/src/types/AdminGroup.res.mjs +9 -0
  31. package/src/types/OwnerScope.res +27 -0
  32. package/src/types/OwnerScope.res.mjs +12 -0
  33. package/src/types/PrepareAccounts.res +119 -0
  34. package/src/types/PrepareAccounts.res.mjs +148 -0
  35. package/src/util/Util_Password.res +60 -0
  36. package/src/util/Util_Password.res.mjs +53 -0
@@ -1,5 +1,6 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
+ import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
3
4
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
4
5
  import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
5
6
  import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
@@ -50,79 +51,214 @@ function foreignConsumedKeys(s) {
50
51
  }));
51
52
  }
52
53
 
53
- function partitionBlockers(s) {
54
- let foreign = foreignConsumedKeys(s);
55
- let ownProduced = new Set();
56
- s.produced.forEach(e => {
57
- ownProduced.add(e.eventType);
58
- });
59
- return producedKeys(s).filter(k => foreign.includes(k)).map(k => [
60
- k,
61
- s.consumed.filter(e => {
62
- if (ownProduced.has(e.eventType)) {
63
- return false;
64
- } else {
65
- return e.idFields.map(tagKeyOf).includes(k);
66
- }
67
- }).map(e => e.eventType)
68
- ]);
54
+ function sameAssignment(a, b) {
55
+ let entries = d => Object.entries(d).toSorted((param, param$1) => Primitive_string.compare(param[0], param$1[0]));
56
+ return Primitive_object.equal(entries(a), entries(b));
69
57
  }
70
58
 
71
- function crossPartitionForSlice(s) {
72
- let foreign = foreignConsumedKeys(s);
73
- let scalar = commandScalarKeys(s);
74
- let h = s.partitionHint;
75
- let partition;
76
- let exit = 0;
77
- if (h !== undefined && producedKeys(s).includes(h)) {
78
- partition = h;
79
- } else {
80
- exit = 1;
81
- }
82
- if (exit === 1) {
83
- let match = producedKeys(s).filter(k => !foreign.includes(k));
84
- partition = match.length !== 1 ? undefined : match[0];
85
- }
86
- return foreign.filter(k => {
87
- if (Primitive_object.notequal(k, partition)) {
88
- return scalar.includes(k);
59
+ function resolvePartitions(slices) {
60
+ let producersByEventType = {};
61
+ slices.forEach(s => {
62
+ s.produced.forEach(e => {
63
+ let prev = Stdlib_Option.getOr(producersByEventType[e.eventType], []);
64
+ if (!prev.some(p => p.sliceName === s.sliceName)) {
65
+ producersByEventType[e.eventType] = prev.concat([s]);
66
+ return;
67
+ }
68
+ });
69
+ });
70
+ let chapterKeys = {};
71
+ slices.forEach(s => Stdlib_Option.forEach(s.chapter, chapter => {
72
+ let events = s.produced.filter(e => e.idFields.length !== 0);
73
+ events.forEach(e => {
74
+ let keys = e.idFields.map(tagKeyOf);
75
+ let prev = chapterKeys[chapter];
76
+ let shared = prev !== undefined ? prev.filter(k => keys.includes(k)) : dedupSorted(keys);
77
+ chapterKeys[chapter] = shared;
78
+ });
79
+ }));
80
+ let chapterKeysOf = s => Stdlib_Option.flatMap(s.chapter, c => chapterKeys[c]);
81
+ let byChapter = (s, candidates) => {
82
+ let keys = chapterKeysOf(s);
83
+ if (keys === undefined) {
84
+ return candidates;
85
+ }
86
+ let match = candidates.filter(k => keys.includes(k));
87
+ if (match.length !== 1) {
88
+ return candidates;
89
+ } else {
90
+ return [match[0]];
91
+ }
92
+ };
93
+ let foreignArms = s => {
94
+ let own = new Set();
95
+ s.produced.forEach(e => {
96
+ own.add(e.eventType);
97
+ });
98
+ return s.consumed.filter(e => !own.has(e.eventType));
99
+ };
100
+ let armIsIdentity = (e, k, known) => {
101
+ let producers = producersByEventType[e.eventType];
102
+ if (producers !== undefined && producers.length !== 0) {
103
+ return producers.every(p => {
104
+ let pk = known[p.sliceName];
105
+ if (pk !== undefined) {
106
+ return pk === k;
107
+ } else {
108
+ return producedKeys(p).includes(k);
109
+ }
110
+ });
89
111
  } else {
90
112
  return false;
91
113
  }
114
+ };
115
+ let blockersOf = (s, known) => Stdlib_Array.filterMap(producedKeys(s), k => {
116
+ let arms = foreignArms(s).filter(e => {
117
+ if (e.idFields.map(tagKeyOf).includes(k)) {
118
+ return !armIsIdentity(e, k, known);
119
+ } else {
120
+ return false;
121
+ }
122
+ }).map(e => e.eventType);
123
+ if (arms.length !== 0) {
124
+ return [
125
+ k,
126
+ arms
127
+ ];
128
+ }
92
129
  });
93
- }
94
-
95
- function infer(slices) {
130
+ let seedOf = s => {
131
+ let produced = producedKeys(s);
132
+ let match = s.partitionHint;
133
+ if (match !== undefined && produced.includes(match)) {
134
+ return match;
135
+ }
136
+ if (produced.length !== 1) {
137
+ return;
138
+ } else {
139
+ return produced[0];
140
+ }
141
+ };
142
+ let subtracted = s => {
143
+ let foreign = foreignConsumedKeys(s);
144
+ return producedKeys(s).filter(k => !foreign.includes(k));
145
+ };
146
+ let candidatesOf = (s, known) => {
147
+ let k = seedOf(s);
148
+ if (k !== undefined) {
149
+ return [k];
150
+ }
151
+ let remaining = subtracted(s);
152
+ if (remaining.length !== 0) {
153
+ return byChapter(s, remaining);
154
+ }
155
+ let blocked = blockersOf(s, known).map(param => param[0]);
156
+ return byChapter(s, producedKeys(s).filter(k => !blocked.includes(k)));
157
+ };
158
+ let pass = known => {
159
+ let next = {};
160
+ slices.forEach(s => {
161
+ let match = candidatesOf(s, known);
162
+ if (match.length !== 1) {
163
+ return;
164
+ }
165
+ let k = match[0];
166
+ next[s.sliceName] = k;
167
+ });
168
+ return next;
169
+ };
170
+ let settle = (_known, _remaining) => {
171
+ while (true) {
172
+ let remaining = _remaining;
173
+ let known = _known;
174
+ let next = pass(known);
175
+ if (sameAssignment(next, known)) {
176
+ return [
177
+ next,
178
+ true
179
+ ];
180
+ }
181
+ if (remaining === 0) {
182
+ return [
183
+ next,
184
+ false
185
+ ];
186
+ }
187
+ _remaining = remaining - 1 | 0;
188
+ _known = next;
189
+ continue;
190
+ };
191
+ };
192
+ let match = settle({}, slices.length + 1 | 0);
193
+ let converged = match[1];
194
+ let settled = match[0];
195
+ let previous = pass(settled);
96
196
  let partitionBySlice = {};
197
+ let candidatesBySlice = {};
198
+ let blockersBySlice = {};
97
199
  let ambiguities = [];
98
200
  slices.forEach(s => {
99
- let produced = producedKeys(s);
100
- let h = s.partitionHint;
101
- if (h !== undefined && produced.includes(h)) {
102
- partitionBySlice[s.sliceName] = h;
201
+ let candidates = candidatesOf(s, settled);
202
+ candidatesBySlice[s.sliceName] = candidates;
203
+ if (!converged && Primitive_object.notequal(settled[s.sliceName], previous[s.sliceName])) {
204
+ ambiguities.push([
205
+ s.sliceName,
206
+ `partition inference did not settle — the slices it reads from keep changing each other's partition. Add an explicit @partitionTag`
207
+ ]);
103
208
  return;
104
209
  }
105
- let foreign = foreignConsumedKeys(s);
106
- let many = produced.filter(k => !foreign.includes(k));
107
- let len = many.length;
210
+ let len = candidates.length;
108
211
  if (len !== 1) {
109
212
  if (len !== 0) {
213
+ let match = s.chapter;
214
+ let match$1 = chapterKeysOf(s);
215
+ let chapterNote = match !== undefined && match$1 !== undefined ? ` The ` + match + ` chapter does not decide: the ids every event in it carries are [` + match$1.join(", ") + `].` : "";
110
216
  ambiguities.push([
111
217
  s.sliceName,
112
- `multiple candidate partition keys (` + many.join(", ") + `) — add an explicit @partitionTag`
218
+ `multiple candidate partition keys (` + candidates.join(", ") + `) — add an explicit @partitionTag.` + chapterNote
113
219
  ]);
114
220
  return;
115
221
  }
116
- let blame = partitionBlockers(s).map(param => param[1].join("/") + ` declares ` + param[0]).join("; ");
222
+ let blockers = blockersOf(s, settled);
223
+ blockersBySlice[s.sliceName] = blockers;
224
+ let blame = blockers.map(param => param[1].join("/") + ` declares ` + param[0]).join("; ");
117
225
  ambiguities.push([
118
226
  s.sliceName,
119
227
  `no own partition key — every produced *Id is read from a foreign producer (` + blame + `). If that field is this slice's own partition, remove it from the consumed arm; if the slice really is a pure join, add an explicit @partitionTag`
120
228
  ]);
121
229
  return;
122
230
  }
123
- let single = many[0];
124
- partitionBySlice[s.sliceName] = single;
231
+ let k = candidates[0];
232
+ partitionBySlice[s.sliceName] = k;
125
233
  });
234
+ return {
235
+ partitionBySlice: partitionBySlice,
236
+ candidatesBySlice: candidatesBySlice,
237
+ blockersBySlice: blockersBySlice,
238
+ ambiguities: ambiguities
239
+ };
240
+ }
241
+
242
+ function partitionBlockers(s) {
243
+ return Stdlib_Option.getOr(resolvePartitions([s]).blockersBySlice[s.sliceName], []);
244
+ }
245
+
246
+ function crossPartitionForSlice(s) {
247
+ let foreign = foreignConsumedKeys(s);
248
+ let scalar = commandScalarKeys(s);
249
+ let partition = resolvePartitions([s]).partitionBySlice[s.sliceName];
250
+ return foreign.filter(k => {
251
+ if (Primitive_object.notequal(k, partition)) {
252
+ return scalar.includes(k);
253
+ } else {
254
+ return false;
255
+ }
256
+ });
257
+ }
258
+
259
+ function infer(slices) {
260
+ let match = resolvePartitions(slices);
261
+ let partitionBySlice = match.partitionBySlice;
126
262
  let ownerByKey = {};
127
263
  let ownedPartitionKeys = new Set();
128
264
  slices.forEach(s => {
@@ -178,7 +314,7 @@ function infer(slices) {
178
314
  ownerByKey: ownerByKey,
179
315
  crossPartitionTagKeys: crossPartitionTagKeys,
180
316
  tagKeysByEventType: tagKeysByEventType,
181
- ambiguities: ambiguities
317
+ ambiguities: match.ambiguities
182
318
  };
183
319
  }
184
320
 
@@ -190,6 +326,8 @@ export {
190
326
  consumedKeys,
191
327
  commandScalarKeys,
192
328
  foreignConsumedKeys,
329
+ sameAssignment,
330
+ resolvePartitions,
193
331
  partitionBlockers,
194
332
  crossPartitionForSlice,
195
333
  infer,