@featurevisor/sdk 1.29.3 → 1.31.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.
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">100% </span>
26
+ <span class="strong">95.45% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>8/8</span>
28
+ <span class='fraction'>42/44</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">100% </span>
33
+ <span class="strong">88.23% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>0/0</span>
35
+ <span class='fraction'>15/17</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
40
  <span class="strong">100% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>1/1</span>
42
+ <span class='fraction'>4/4</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">100% </span>
47
+ <span class="strong">95.45% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>8/8</span>
49
+ <span class='fraction'>42/44</span>
50
50
  </div>
51
51
 
52
52
 
@@ -76,7 +76,139 @@
76
76
  <a name='L11'></a><a href='#L11'>11</a>
77
77
  <a name='L12'></a><a href='#L12'>12</a>
78
78
  <a name='L13'></a><a href='#L13'>13</a>
79
- <a name='L14'></a><a href='#L14'>14</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">2x</span>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">2x</span>
206
+ <span class="cline-any cline-neutral">&nbsp;</span>
207
+ <span class="cline-any cline-neutral">&nbsp;</span>
208
+ <span class="cline-any cline-neutral">&nbsp;</span>
209
+ <span class="cline-any cline-neutral">&nbsp;</span>
210
+ <span class="cline-any cline-neutral">&nbsp;</span>
211
+ <span class="cline-any cline-neutral">&nbsp;</span>
80
212
  <span class="cline-any cline-neutral">&nbsp;</span>
81
213
  <span class="cline-any cline-yes">2x</span>
82
214
  <span class="cline-any cline-yes">2x</span>
@@ -89,8 +221,134 @@
89
221
  <span class="cline-any cline-neutral">&nbsp;</span>
90
222
  <span class="cline-any cline-yes">105x</span>
91
223
  <span class="cline-any cline-neutral">&nbsp;</span>
224
+ <span class="cline-any cline-neutral">&nbsp;</span>
225
+ <span class="cline-any cline-neutral">&nbsp;</span>
226
+ <span class="cline-any cline-neutral">&nbsp;</span>
227
+ <span class="cline-any cline-neutral">&nbsp;</span>
228
+ <span class="cline-any cline-neutral">&nbsp;</span>
229
+ <span class="cline-any cline-neutral">&nbsp;</span>
230
+ <span class="cline-any cline-neutral">&nbsp;</span>
231
+ <span class="cline-any cline-neutral">&nbsp;</span>
232
+ <span class="cline-any cline-neutral">&nbsp;</span>
233
+ <span class="cline-any cline-neutral">&nbsp;</span>
234
+ <span class="cline-any cline-neutral">&nbsp;</span>
235
+ <span class="cline-any cline-neutral">&nbsp;</span>
236
+ <span class="cline-any cline-neutral">&nbsp;</span>
237
+ <span class="cline-any cline-neutral">&nbsp;</span>
238
+ <span class="cline-any cline-neutral">&nbsp;</span>
239
+ <span class="cline-any cline-neutral">&nbsp;</span>
240
+ <span class="cline-any cline-neutral">&nbsp;</span>
241
+ <span class="cline-any cline-neutral">&nbsp;</span>
242
+ <span class="cline-any cline-yes">2x</span>
243
+ <span class="cline-any cline-yes">95x</span>
244
+ <span class="cline-any cline-neutral">&nbsp;</span>
245
+ <span class="cline-any cline-yes">95x</span>
246
+ <span class="cline-any cline-neutral">&nbsp;</span>
247
+ <span class="cline-any cline-neutral">&nbsp;</span>
248
+ <span class="cline-any cline-neutral">&nbsp;</span>
249
+ <span class="cline-any cline-neutral">&nbsp;</span>
250
+ <span class="cline-any cline-yes">95x</span>
251
+ <span class="cline-any cline-yes">88x</span>
252
+ <span class="cline-any cline-yes">88x</span>
253
+ <span class="cline-any cline-yes">7x</span>
254
+ <span class="cline-any cline-yes">2x</span>
255
+ <span class="cline-any cline-yes">2x</span>
256
+ <span class="cline-any cline-yes">5x</span>
257
+ <span class="cline-any cline-yes">5x</span>
258
+ <span class="cline-any cline-yes">5x</span>
259
+ <span class="cline-any cline-neutral">&nbsp;</span>
260
+ <span class="cline-any cline-no">&nbsp;</span>
261
+ <span class="cline-any cline-neutral">&nbsp;</span>
262
+ <span class="cline-any cline-no">&nbsp;</span>
263
+ <span class="cline-any cline-neutral">&nbsp;</span>
264
+ <span class="cline-any cline-neutral">&nbsp;</span>
265
+ <span class="cline-any cline-yes">95x</span>
266
+ <span class="cline-any cline-neutral">&nbsp;</span>
267
+ <span class="cline-any cline-yes">95x</span>
268
+ <span class="cline-any cline-yes">102x</span>
269
+ <span class="cline-any cline-neutral">&nbsp;</span>
270
+ <span class="cline-any cline-yes">102x</span>
271
+ <span class="cline-any cline-yes">13x</span>
272
+ <span class="cline-any cline-neutral">&nbsp;</span>
273
+ <span class="cline-any cline-neutral">&nbsp;</span>
274
+ <span class="cline-any cline-yes">89x</span>
275
+ <span class="cline-any cline-yes">81x</span>
276
+ <span class="cline-any cline-neutral">&nbsp;</span>
277
+ <span class="cline-any cline-neutral">&nbsp;</span>
278
+ <span class="cline-any cline-yes">8x</span>
279
+ <span class="cline-any cline-yes">5x</span>
280
+ <span class="cline-any cline-neutral">&nbsp;</span>
281
+ <span class="cline-any cline-neutral">&nbsp;</span>
282
+ <span class="cline-any cline-neutral">&nbsp;</span>
283
+ <span class="cline-any cline-neutral">&nbsp;</span>
284
+ <span class="cline-any cline-yes">95x</span>
285
+ <span class="cline-any cline-neutral">&nbsp;</span>
286
+ <span class="cline-any cline-yes">95x</span>
287
+ <span class="cline-any cline-neutral">&nbsp;</span>
288
+ <span class="cline-any cline-yes">95x</span>
289
+ <span class="cline-any cline-yes">10x</span>
290
+ <span class="cline-any cline-neutral">&nbsp;</span>
291
+ <span class="cline-any cline-neutral">&nbsp;</span>
292
+ <span class="cline-any cline-yes">85x</span>
293
+ <span class="cline-any cline-neutral">&nbsp;</span>
294
+ <span class="cline-any cline-neutral">&nbsp;</span>
295
+ <span class="cline-any cline-neutral">&nbsp;</span>
296
+ <span class="cline-any cline-neutral">&nbsp;</span>
297
+ <span class="cline-any cline-neutral">&nbsp;</span>
298
+ <span class="cline-any cline-neutral">&nbsp;</span>
299
+ <span class="cline-any cline-neutral">&nbsp;</span>
300
+ <span class="cline-any cline-neutral">&nbsp;</span>
301
+ <span class="cline-any cline-neutral">&nbsp;</span>
302
+ <span class="cline-any cline-neutral">&nbsp;</span>
303
+ <span class="cline-any cline-neutral">&nbsp;</span>
304
+ <span class="cline-any cline-neutral">&nbsp;</span>
305
+ <span class="cline-any cline-neutral">&nbsp;</span>
306
+ <span class="cline-any cline-neutral">&nbsp;</span>
307
+ <span class="cline-any cline-neutral">&nbsp;</span>
308
+ <span class="cline-any cline-neutral">&nbsp;</span>
309
+ <span class="cline-any cline-neutral">&nbsp;</span>
310
+ <span class="cline-any cline-neutral">&nbsp;</span>
311
+ <span class="cline-any cline-neutral">&nbsp;</span>
312
+ <span class="cline-any cline-neutral">&nbsp;</span>
313
+ <span class="cline-any cline-neutral">&nbsp;</span>
314
+ <span class="cline-any cline-neutral">&nbsp;</span>
315
+ <span class="cline-any cline-neutral">&nbsp;</span>
316
+ <span class="cline-any cline-neutral">&nbsp;</span>
317
+ <span class="cline-any cline-neutral">&nbsp;</span>
318
+ <span class="cline-any cline-yes">2x</span>
319
+ <span class="cline-any cline-neutral">&nbsp;</span>
320
+ <span class="cline-any cline-yes">95x</span>
321
+ <span class="cline-any cline-yes">95x</span>
322
+ <span class="cline-any cline-neutral">&nbsp;</span>
323
+ <span class="cline-any cline-neutral">&nbsp;</span>
324
+ <span class="cline-any cline-neutral">&nbsp;</span>
325
+ <span class="cline-any cline-neutral">&nbsp;</span>
326
+ <span class="cline-any cline-neutral">&nbsp;</span>
327
+ <span class="cline-any cline-neutral">&nbsp;</span>
328
+ <span class="cline-any cline-yes">95x</span>
329
+ <span class="cline-any cline-neutral">&nbsp;</span>
330
+ <span class="cline-any cline-yes">95x</span>
331
+ <span class="cline-any cline-yes">2x</span>
332
+ <span class="cline-any cline-neutral">&nbsp;</span>
333
+ <span class="cline-any cline-yes">2x</span>
334
+ <span class="cline-any cline-neutral">&nbsp;</span>
335
+ <span class="cline-any cline-neutral">&nbsp;</span>
336
+ <span class="cline-any cline-neutral">&nbsp;</span>
337
+ <span class="cline-any cline-neutral">&nbsp;</span>
338
+ <span class="cline-any cline-neutral">&nbsp;</span>
339
+ <span class="cline-any cline-yes">93x</span>
340
+ <span class="cline-any cline-neutral">&nbsp;</span>
341
+ <span class="cline-any cline-neutral">&nbsp;</span>
342
+ <span class="cline-any cline-neutral">&nbsp;</span>
343
+ <span class="cline-any cline-neutral">&nbsp;</span>
92
344
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import * as murmurhash from "murmurhash";
345
+ import { Feature, BucketKey, BucketValue, Context, AttributeValue } from "@featurevisor/types";
346
+ &nbsp;
347
+ import { Logger } from "./logger";
93
348
  &nbsp;
349
+ /**
350
+ * Generic hashing
351
+ */
94
352
  const HASH_SEED = 1;
95
353
  const MAX_HASH_VALUE = Math.pow(2, 32);
96
354
  &nbsp;
@@ -102,6 +360,126 @@ export function getBucketedNumber(bucketKey: string): number {
102
360
  &nbsp;
103
361
  return Math.floor(ratio * MAX_BUCKETED_NUMBER);
104
362
  }
363
+ &nbsp;
364
+ /**
365
+ * Feature specific bucketing
366
+ */
367
+ export type ConfigureBucketKey = (
368
+ feature: Feature,
369
+ context: Context,
370
+ bucketKey: BucketKey,
371
+ ) =&gt; BucketKey;
372
+ &nbsp;
373
+ export interface BucketKeyOptions {
374
+ feature: Feature;
375
+ context: Context;
376
+ logger: Logger;
377
+ bucketKeySeparator?: string;
378
+ configureBucketKey?: ConfigureBucketKey;
379
+ }
380
+ &nbsp;
381
+ export function getBucketKey(options: BucketKeyOptions): BucketKey {
382
+ const { feature, context, logger, bucketKeySeparator = <span class="branch-0 cbranch-no" title="branch not covered" >".",</span> configureBucketKey } = options;
383
+ &nbsp;
384
+ const featureKey = feature.key;
385
+ &nbsp;
386
+ let type;
387
+ let attributeKeys;
388
+ &nbsp;
389
+ if (typeof feature.bucketBy === "string") {
390
+ type = "plain";
391
+ attributeKeys = [feature.bucketBy];
392
+ } else if (Array.isArray(feature.bucketBy)) {
393
+ type = "and";
394
+ attributeKeys = feature.bucketBy;
395
+ } else if (typeof feature.bucketBy === "object" &amp;&amp; Array.isArray(feature.bucketBy.or)) {
396
+ type = "or";
397
+ attributeKeys = feature.bucketBy.or;
398
+ } else <span class="missing-if-branch" title="else path not taken" >E</span>{
399
+ <span class="cstat-no" title="statement not covered" > logger.error("invalid bucketBy", { featureKey, bucketBy: feature.bucketBy });</span>
400
+ &nbsp;
401
+ <span class="cstat-no" title="statement not covered" > throw new Error("invalid bucketBy");</span>
402
+ }
403
+ &nbsp;
404
+ const bucketKey: AttributeValue[] = [];
405
+ &nbsp;
406
+ attributeKeys.forEach((attributeKey) =&gt; {
407
+ const attributeValue = context[attributeKey];
408
+ &nbsp;
409
+ if (typeof attributeValue === "undefined") {
410
+ return;
411
+ }
412
+ &nbsp;
413
+ if (type === "plain" || type === "and") {
414
+ bucketKey.push(attributeValue);
415
+ } else {
416
+ // or
417
+ if (bucketKey.length === 0) {
418
+ bucketKey.push(attributeValue);
419
+ }
420
+ }
421
+ });
422
+ &nbsp;
423
+ bucketKey.push(featureKey);
424
+ &nbsp;
425
+ const result = bucketKey.join(bucketKeySeparator);
426
+ &nbsp;
427
+ if (configureBucketKey) {
428
+ return configureBucketKey(feature, context, result);
429
+ }
430
+ &nbsp;
431
+ return result;
432
+ }
433
+ &nbsp;
434
+ export interface Bucket {
435
+ bucketKey: BucketKey;
436
+ bucketValue: BucketValue;
437
+ }
438
+ &nbsp;
439
+ export type ConfigureBucketValue = (
440
+ feature: Feature,
441
+ context: Context,
442
+ bucketValue: BucketValue,
443
+ ) =&gt; BucketValue;
444
+ &nbsp;
445
+ export interface BucketValueOptions {
446
+ // common with BucketKeyOptions
447
+ feature: Feature;
448
+ context: Context;
449
+ logger: Logger;
450
+ bucketKeySeparator?: string;
451
+ configureBucketKey?: ConfigureBucketKey;
452
+ &nbsp;
453
+ // specific to BucketValueOptions
454
+ configureBucketValue?: ConfigureBucketValue;
455
+ }
456
+ &nbsp;
457
+ export function getBucket(options: BucketValueOptions): Bucket {
458
+ const { feature, context, logger, bucketKeySeparator, configureBucketKey, configureBucketValue } =
459
+ options;
460
+ const bucketKey = getBucketKey({
461
+ feature,
462
+ context,
463
+ logger,
464
+ bucketKeySeparator,
465
+ configureBucketKey,
466
+ });
467
+ const value = getBucketedNumber(bucketKey);
468
+ &nbsp;
469
+ if (configureBucketValue) {
470
+ const configuredValue = configureBucketValue(feature, context, value);
471
+ &nbsp;
472
+ return {
473
+ bucketKey,
474
+ bucketValue: configuredValue,
475
+ };
476
+ }
477
+ &nbsp;
478
+ return {
479
+ bucketKey,
480
+ bucketValue: value,
481
+ };
482
+ }
105
483
  &nbsp;</pre></td></tr></table></pre>
106
484
 
107
485
  <div class='push'></div><!-- for sticky footer -->
@@ -109,7 +487,7 @@ export function getBucketedNumber(bucketKey: string): number {
109
487
  <div class='footer quiet pad2 space-top1 center small'>
110
488
  Code coverage generated by
111
489
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
112
- at 2025-01-30T17:02:08.477Z
490
+ at 2025-02-13T21:59:15.722Z
113
491
  </div>
114
492
  <script src="prettify.js"></script>
115
493
  <script>
@@ -451,7 +451,7 @@ export function allConditionsAreMatched(
451
451
  <div class='footer quiet pad2 space-top1 center small'>
452
452
  Code coverage generated by
453
453
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
454
- at 2025-01-30T17:02:08.477Z
454
+ at 2025-02-13T21:59:15.722Z
455
455
  </div>
456
456
  <script src="prettify.js"></script>
457
457
  <script>
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">97.22% </span>
26
+ <span class="strong">97.5% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>35/36</span>
28
+ <span class='fraction'>39/40</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
33
  <span class="strong">100% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>6/6</span>
35
+ <span class='fraction'>7/7</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
40
  <span class="strong">100% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>12/12</span>
42
+ <span class='fraction'>13/13</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">97.22% </span>
47
+ <span class="strong">97.5% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>35/36</span>
49
+ <span class='fraction'>39/40</span>
50
50
  </div>
51
51
 
52
52
 
@@ -162,7 +162,14 @@
162
162
  <a name='L97'></a><a href='#L97'>97</a>
163
163
  <a name='L98'></a><a href='#L98'>98</a>
164
164
  <a name='L99'></a><a href='#L99'>99</a>
165
- <a name='L100'></a><a href='#L100'>100</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
166
173
  <span class="cline-any cline-neutral">&nbsp;</span>
167
174
  <span class="cline-any cline-neutral">&nbsp;</span>
168
175
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -221,6 +228,13 @@
221
228
  <span class="cline-any cline-yes">30x</span>
222
229
  <span class="cline-any cline-yes">30x</span>
223
230
  <span class="cline-any cline-yes">27x</span>
231
+ <span class="cline-any cline-yes">2x</span>
232
+ <span class="cline-any cline-yes">9x</span>
233
+ <span class="cline-any cline-yes">9x</span>
234
+ <span class="cline-any cline-neutral">&nbsp;</span>
235
+ <span class="cline-any cline-neutral">&nbsp;</span>
236
+ <span class="cline-any cline-neutral">&nbsp;</span>
237
+ <span class="cline-any cline-yes">27x</span>
224
238
  <span class="cline-any cline-neutral">&nbsp;</span>
225
239
  <span class="cline-any cline-neutral">&nbsp;</span>
226
240
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -319,6 +333,13 @@ export class DatafileReader {
319
333
  &nbsp;
320
334
  this.features = {};
321
335
  datafileJsonV1.features.forEach((f) =&gt; {
336
+ if (Array.isArray(f.variablesSchema)) {
337
+ f.variablesSchema = f.variablesSchema.reduce((acc, variable) =&gt; {
338
+ acc[variable.key] = variable;
339
+ return acc;
340
+ }, {});
341
+ }
342
+ &nbsp;
322
343
  this.features[f.key] = f;
323
344
  });
324
345
  }
@@ -367,7 +388,7 @@ export class DatafileReader {
367
388
  <div class='footer quiet pad2 space-top1 center small'>
368
389
  Code coverage generated by
369
390
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
370
- at 2025-01-30T17:02:08.477Z
391
+ at 2025-02-13T21:59:15.722Z
371
392
  </div>
372
393
  <script src="prettify.js"></script>
373
394
  <script>
@@ -229,7 +229,7 @@ export class Emitter {
229
229
  <div class='footer quiet pad2 space-top1 center small'>
230
230
  Code coverage generated by
231
231
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
232
- at 2025-01-30T17:02:08.477Z
232
+ at 2025-02-13T21:59:15.722Z
233
233
  </div>
234
234
  <script src="prettify.js"></script>
235
235
  <script>