@flemist/test-variants 3.0.1 → 3.0.3

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.
@@ -83,50 +83,50 @@ return l.sent(),[4,i.promises.writeFile(t,r,"utf-8")]
83
83
  ;case 2:return l.sent(),[2]}})})}function v(e,t){
84
84
  return e<t}class g{
85
85
  constructor({objectPool:e,lessThanFunc:t}={}){
86
- this._size=0,this._root=null,this.merge=_,
87
- this.collapse=y,this._objectPool=e,this._lessThanFunc=t||v
86
+ this._size=0,this._root=null,this.merge=p,
87
+ this.collapse=_,this._objectPool=e,this._lessThanFunc=t||v
88
88
  }clear(){this._root=null,this._size=0}get size(){
89
89
  return this._size}add(e){
90
90
  let t=null!=this._objectPool?this._objectPool.get():null
91
91
  ;return null==t?t={child:null,next:null,prev:null,
92
92
  item:e
93
- }:t.item=e,this._size++,this._root=_(this._root,t,this._lessThanFunc),t
93
+ }:t.item=e,this._size++,this._root=p(this._root,t,this._lessThanFunc),t
94
94
  }getMin(){const{_root:e}=this
95
95
  ;return null==e?void 0:e.item}getMinNode(){
96
96
  return this._root}deleteMin(){const{_root:e}=this
97
97
  ;if(null==e)return;const t=e.item
98
98
  ;return this.delete(e),t}delete(e){var t
99
- ;if(e===this._root)this._root=y(e.child,this._lessThanFunc);else{
99
+ ;if(e===this._root)this._root=_(e.child,this._lessThanFunc);else{
100
100
  if(null==e.prev){
101
101
  if(this._objectPool)throw new Error("The node is already deleted. Don't use the objectPool to prevent this error.")
102
102
  ;return}
103
103
  e.prev.child===e?e.prev.child=e.next:e.prev.next=e.next,null!=e.next&&(e.next.prev=e.prev),
104
- this._root=_(this._root,y(e.child,this._lessThanFunc),this._lessThanFunc)
104
+ this._root=p(this._root,_(e.child,this._lessThanFunc),this._lessThanFunc)
105
105
  }
106
106
  e.child=null,e.prev=null,e.next=null,e.item=void 0,null===(t=this._objectPool)||void 0===t||t.release(e),
107
107
  this._size--}decreaseKey(e){
108
108
  e!==this._root&&(e.prev.child===e?e.prev.child=e.next:e.prev.next=e.next,
109
109
  null!=e.next&&(e.next.prev=e.prev),
110
- this._root=_(this._root,e,this._lessThanFunc))}
110
+ this._root=p(this._root,e,this._lessThanFunc))}
111
111
  get isEmpty(){return null==this._root}
112
112
  [Symbol.iterator](){return this._iterate(!1)}
113
113
  nodes(){return{
114
114
  [Symbol.iterator]:()=>this._iterate(!0)}}
115
115
  _iterate(e){const t=this._lessThanFunc
116
116
  ;return function*n(r){
117
- r&&(e?yield r:yield r.item,r.child&&(null!=r.child.next&&(r.child=y(r.child,t),
117
+ r&&(e?yield r:yield r.item,r.child&&(null!=r.child.next&&(r.child=_(r.child,t),
118
118
  r.child.prev=r),yield*n(r.child)))}(this._root)}}
119
- function _(e,t,n){let r,i
119
+ function p(e,t,n){let r,i
120
120
  ;return null==e?t:null==t||e===t?e:(n(t.item,e.item)?(r=t,
121
121
  i=e):(r=e,i=t),i.next=r.child,
122
122
  null!=r.child&&(r.child.prev=i),i.prev=r,r.child=i,
123
- r.next=null,r.prev=null,r)}function y(e,t){
123
+ r.next=null,r.prev=null,r)}function _(e,t){
124
124
  let n,r,i,s,o;if(null==e)return null
125
125
  ;for(s=e,n=null;null!=s;){
126
126
  if(r=s,i=r.next,null==i){r.prev=n,n=r;break}
127
- s=i.next,o=_(r,i,t),o.prev=n,n=o}
128
- for(o=null;null!=n;)s=n.prev,o=_(o,n,t),n=s
129
- ;return o}function p(e,t){e(function(e){return{
127
+ s=i.next,o=p(r,i,t),o.prev=n,n=o}
128
+ for(o=null;null!=n;)s=n.prev,o=p(o,n,t),n=s
129
+ ;return o}function y(e,t){e(function(e){return{
130
130
  then(t,n){n(e)}}}(t))}function b(e){
131
131
  return null!=e&&"object"==typeof e&&"function"==typeof e.then
132
132
  }let m,x=[];function w(e){
@@ -200,7 +200,7 @@ const P=function(){};class k{constructor(e){
200
200
  if(this._status="pending",e&&e.aborted)this.promise=A.reject(e.reason),
201
201
  this.resolve=P,this.reject=P;else{let t,n
202
202
  ;if(this.promise=new Promise(function(e){
203
- t=e,n=function(t){p(e,t)}}),e){
203
+ t=e,n=function(t){y(e,t)}}),e){
204
204
  const r=e.subscribe(function(e){n(e)})
205
205
  ;this.resolve=function(e){r(),t(e)
206
206
  },this.reject=function(e){r(),n(e)}
@@ -247,21 +247,21 @@ return i(e,t,n)});return"number"==typeof s?{
247
247
  iterationsAsync:0,iterationsSync:s
248
248
  }:null!==s&&"object"==typeof s?s:{
249
249
  iterationsAsync:0,iterationsSync:1}}catch(e){
250
- return i(e,t,n)}}}class F{constructor(e,t){
250
+ return i(e,t,n)}}}class V{constructor(e,t){
251
251
  this._branch=null,this.order=e,this.parent=t}
252
252
  get branch(){if(!this._branch){
253
253
  const e=[this.order];let t=this.parent
254
254
  ;for(;null!=t;)e.push(t.order),t=t.parent
255
255
  ;this._branch=e}return this._branch}}
256
- function V(e){
256
+ function F(e){
257
257
  return null!=e&&"object"==typeof e&&"function"==typeof e.then
258
- }let D,M=[];function C(e){
259
- M.push(e),D||(D=function(){
258
+ }let M,D=[];function C(e){
259
+ D.push(e),M||(M=function(){
260
260
  return l(this,void 0,void 0,function*(){
261
- for(;M.length>0;){yield 0;const e=M
262
- ;M=[],e.forEach(e=>{try{e()}catch(e){
261
+ for(;D.length>0;){yield 0;const e=D
262
+ ;D=[],e.forEach(e=>{try{e()}catch(e){
263
263
  console.error("Unhandled promise rejection",e)}})}
264
- D=null})}())}function R(e,t,n){C(()=>{try{
264
+ M=null})}())}function R(e,t,n){C(()=>{try{
265
265
  const r=t?t(e):e;n._resolve(r)}catch(e){
266
266
  n._reject(e)}})}function q(e,t,n){C(()=>{if(t)try{
267
267
  const r=t(e);n._resolve(r)}catch(e){n._reject(e)
@@ -276,14 +276,14 @@ this.status="pending",this.value=void 0,this.reason=void 0,this._handlers=null
276
276
  },e(this._resolve,this._reject)}_resolve(e){
277
277
  "pending"===this.status&&(this.status="fulfilled",
278
278
  this._resolveAsync(e))}_resolveAsync(e){
279
- V(e)?e.then(this._resolveAsync,this._rejectAsync):this._resolveSync(e)
279
+ F(e)?e.then(this._resolveAsync,this._rejectAsync):this._resolveSync(e)
280
280
  }_resolveSync(e){const t=this._handlers
281
281
  ;if(this.value=e,null!=t){this._handlers=null
282
282
  ;for(let n=0,r=t.length;n<r;n++){const[r,,i]=t[n]
283
283
  ;R(e,r,i)}}}_reject(e){
284
284
  "pending"===this.status&&this._rejectAsync(e)}
285
285
  _rejectAsync(e){
286
- this.status="rejected",V(e)?e.then(this._rejectAsync,this._rejectAsync):this._rejectSync(e)
286
+ this.status="rejected",F(e)?e.then(this._rejectAsync,this._rejectAsync):this._rejectSync(e)
287
287
  }_rejectSync(e){const t=this._handlers
288
288
  ;if(this.reason=e,null!=t){this._handlers=null
289
289
  ;for(let n=0,r=t.length;n<r;n++){const[,r,i]=t[n]
@@ -292,9 +292,9 @@ this.status="rejected",V(e)?e.then(this._rejectAsync,this._rejectAsync):this._re
292
292
  this._handlers.push([e,t,n])):"fulfilled"===this.status?R(this.value,e,n):q(this.reason,t,n),
293
293
  n}catch(e){return this.then(void 0,e)}finally(e){
294
294
  const t=e&&function(t){const n=e()
295
- ;return V(n)?n.then(()=>t):J.resolve(t)
295
+ ;return F(n)?n.then(()=>t):J.resolve(t)
296
296
  },n=e&&function(t){const n=e()
297
- ;return V(n)?n.then(()=>J.reject(t)):J.reject(t)}
297
+ ;return F(n)?n.then(()=>J.reject(t)):J.reject(t)}
298
298
  ;return this.then(t,n)}static resolve(e){
299
299
  const t=new J(B);return t._resolve(e),t}
300
300
  static reject(e){const t=new J(B)
@@ -303,25 +303,25 @@ return"Promise"}static get[Symbol.species](){
303
303
  return J}static all(e){return function(e,t){
304
304
  let n,r;t||(t=Promise);const i=new t((e,t)=>{
305
305
  n=e,r=t});let s=e.length;const o=[]
306
- ;return e.forEach((e,t)=>{V(e)?e.then(e=>{
306
+ ;return e.forEach((e,t)=>{F(e)?e.then(e=>{
307
307
  o[t]=e,0===--s&&n(o)},r):(o[t]=e,0===--s&&n(o))
308
308
  }),i}(e,J)}static allSettled(e){
309
309
  return function(e,t){let n;t||(t=Promise)
310
310
  ;const r=new t((e,t)=>{n=e});let i=e.length
311
311
  ;const s=[];return e.forEach((e,t)=>{
312
- V(e)?e.then(e=>{s[t]={status:"fulfilled",value:e
312
+ F(e)?e.then(e=>{s[t]={status:"fulfilled",value:e
313
313
  },0===--i&&n(s)},e=>{s[t]={status:"rejected",
314
314
  reason:e},0===--i&&n(s)}):(s[t]={
315
315
  status:"fulfilled",value:e},0===--i&&n(s))}),r
316
316
  }(e,J)}static any(e){return function(e,t){let n,r
317
317
  ;t||(t=Promise);const i=new t((e,t)=>{n=e,r=t})
318
318
  ;let s=e.length;const o=[]
319
- ;return e.forEach((e,t)=>{V(e)?e.then(n,e=>{
319
+ ;return e.forEach((e,t)=>{F(e)?e.then(n,e=>{
320
320
  o[t]=e,0===--s&&r(new AggregateError(o))}):n(e)
321
321
  }),i}(e,J)}static race(e){return function(e,t){
322
322
  let n,r;t||(t=Promise);const i=new t((e,t)=>{
323
323
  n=e,r=t});return e.forEach(e=>{
324
- V(e)?e.then(n,r):n(e)}),i}(e,J)}}
324
+ F(e)?e.then(n,r):n(e)}),i}(e,J)}}
325
325
  const N=function(){};class ${constructor(e){
326
326
  if(this._status="pending",e&&e.aborted)this.promise=J.reject(e.reason),
327
327
  this.resolve=N,this.reject=N;else{let t,n
@@ -381,7 +381,7 @@ constructor(){this._queue=new g({lessThanFunc:W})}
381
381
  run(e,t,n){return this._run(!1,e,t,n)}
382
382
  runTask(e,t,n){return this._run(!0,e,t,n)}
383
383
  _run(e,t,n,r){const i=new $(r),s={
384
- priority:(o=Q++,l=n,null==o?null==l?null:l:new F(o,l)),
384
+ priority:(o=Q++,l=n,null==o?null==l?null:l:new V(o,l)),
385
385
  func:t,abortSignal:r,resolve:i.resolve,
386
386
  reject:i.reject,readyToRun:!e};var o,l
387
387
  ;if(this._queue.add(s),e){const e=this;return{
@@ -423,8 +423,8 @@ const e=this._tickPromise
423
423
  tick(e){
424
424
  if(!(this._size>=this._maxSize))return this._tickPromise||(this._tickPromise=new k),
425
425
  function(e,t){return e?new Promise(function(n){
426
- if(e&&e.aborted)return void p(n,e.reason);let r,i
427
- ;function s(e){i||(i=!0,r&&r(),p(n,e))}
426
+ if(e&&e.aborted)return void y(n,e.reason);let r,i
427
+ ;function s(e){i||(i=!0,r&&r(),y(n,e))}
428
428
  t.then(function(e){r&&r(),n(e)
429
429
  }).catch(s),e&&(r=e.subscribe(s))}):t
430
430
  }(e,this._tickPromise.promise)}holdWait(e,t,n,r){
@@ -441,10 +441,10 @@ setTimeout(function(){t(e)},1)})
441
441
  ;if(t<60)return"".concat(t.toFixed(1),"s")
442
442
  ;var n=t/60
443
443
  ;return n<60?"".concat(n.toFixed(1),"m"):"".concat((n/60).toFixed(1),"h")
444
- }function ee(e,t,n){var r,i,o,v,g,_,y,p,m
444
+ }function ee(e,t,n){var r,i,o,v,g,p,_,y,m
445
445
  ;return void 0===n&&(n={}),l(this,void 0,void 0,function(){
446
- var x,w,j,E,S,A,P,k,I,T,O,L,F,V,D,M,C,R,q,B,J,N,$,G,U,W,Q,K,H,ee,te,ne,re,ie,se,oe,le,ae,ce,ue,he,fe,de,ve,ge=this
447
- ;return a(this,function(_e){switch(_e.label){
446
+ var x,w,j,E,S,A,P,k,I,T,O,L,V,F,M,D,C,R,q,B,J,N,$,G,U,W,Q,K,H,ee,te,ne,re,ie,se,oe,le,ae,ce,ue,he,fe,de,ve,ge=this
447
+ ;return a(this,function(pe){switch(pe.label){
448
448
  case 0:
449
449
  return x=n.saveErrorVariants,w=null!==(r=null==x?void 0:x.retriesPerVariant)&&void 0!==r?r:1,
450
450
  j=null==x?void 0:x.useToFindBestError,
@@ -452,27 +452,27 @@ E=new Date,S=x?s.resolve(x.dir,null!==(o=null===(i=x.getFilePath)||void 0===i?vo
452
452
  sessionDate:E}))&&void 0!==o?o:f({sessionDate:E
453
453
  })):null,A=null!==(v=n.GC_Iterations)&&void 0!==v?v:1e6,
454
454
  P=null!==(g=n.GC_IterationsAsync)&&void 0!==g?g:1e4,
455
- k=null!==(_=n.GC_Interval)&&void 0!==_?_:1e3,
456
- I=null!==(y=n.logInterval)&&void 0!==y?y:5e3,
457
- T=null===(p=n.logCompleted)||void 0===p||p,
458
- O=n.abortSignal,L=n.findBestError,F=null!==(m=null==L?void 0:L.cycles)&&void 0!==m?m:1,
459
- V=null==L?void 0:L.dontThrowIfError,
460
- D=n.limitTime,M=!0===n.parallel?Math.pow(2,31):!n.parallel||n.parallel<=0?1:n.parallel,
455
+ k=null!==(p=n.GC_Interval)&&void 0!==p?p:1e3,
456
+ I=null!==(_=n.logInterval)&&void 0!==_?_:5e3,
457
+ T=null===(y=n.logCompleted)||void 0===y||y,
458
+ O=n.abortSignal,L=n.findBestError,V=null!==(m=null==L?void 0:L.cycles)&&void 0!==m?m:1,
459
+ F=null==L?void 0:L.dontThrowIfError,
460
+ M=n.limitTime,D=!0===n.parallel?Math.pow(2,31):!n.parallel||n.parallel<=0?1:n.parallel,
461
461
  null!=n.limitVariantsCount&&t.addLimit({
462
462
  index:n.limitVariantsCount}),x?[4,u(x.dir)]:[3,15]
463
- ;case 1:C=_e.sent(),_e.label=2;case 2:
464
- _e.trys.push([2,13,14,15]),R=c(C),q=R.next(),
465
- _e.label=3;case 3:
463
+ ;case 1:C=pe.sent(),pe.label=2;case 2:
464
+ pe.trys.push([2,13,14,15]),R=c(C),q=R.next(),
465
+ pe.label=3;case 3:
466
466
  return q.done?[3,12]:[4,h(q.value,x.jsonToArgs)]
467
- ;case 4:ue=_e.sent(),B=0,_e.label=5;case 5:
468
- if(!(B<w))return[3,11];_e.label=6;case 6:
469
- return _e.trys.push([6,9,,10]),b(J=e(ue,-1,null))?[4,J]:[3,8]
470
- ;case 7:_e.sent(),_e.label=8;case 8:return[3,10]
471
- ;case 9:if(N=_e.sent(),j&&L)return t.addLimit({
467
+ ;case 4:ue=pe.sent(),B=0,pe.label=5;case 5:
468
+ if(!(B<w))return[3,11];pe.label=6;case 6:
469
+ return pe.trys.push([6,9,,10]),b(J=e(ue,-1,null))?[4,J]:[3,8]
470
+ ;case 7:pe.sent(),pe.label=8;case 8:return[3,10]
471
+ ;case 9:if(N=pe.sent(),j&&L)return t.addLimit({
472
472
  args:ue,error:N}),[3,11];throw N;case 10:
473
473
  return B++,[3,5];case 11:return q=R.next(),[3,3]
474
474
  ;case 12:return[3,15];case 13:
475
- return $=_e.sent(),de={error:$},[3,15];case 14:
475
+ return $=pe.sent(),de={error:$},[3,15];case 14:
476
476
  try{q&&!q.done&&(ve=R.return)&&ve.call(R)}finally{
477
477
  if(de)throw de.error}return[7];case 15:
478
478
  G=null,U=null,W=Date.now(),Q=W,K=new z,H=function(...e){
@@ -482,29 +482,29 @@ if(s.aborted)return s
482
482
  ;n?(t||(t=new z,n.subscribe(r)),s.subscribe(r)):n=s
483
483
  }}return t?t.signal:n||(new z).signal
484
484
  }(O,K.signal),ee=H,te=!1,ne=0,re=0,ie=Date.now(),
485
- se=ie,oe=ne,le=re,ae=M<=1?null:new X(M),
486
- ce=!1,t.start(),_e.label=16;case 16:
487
- if(!(t.cycleIndex<F)||ce)return[3,20]
485
+ se=ie,oe=ne,le=re,ae=D<=1?null:new X(D),
486
+ ce=!1,t.start(),pe.label=16;case 16:
487
+ if(!(t.cycleIndex<V)||ce)return[3,20]
488
488
  ;ue=void 0,he=function(){
489
- var n,r,i,s,o,c,u,h,f,v,g,_,y,p,m,w
489
+ var n,r,i,s,o,c,u,h,f,v,g,p,_,y,m,w
490
490
  ;return a(this,function(j){switch(j.label){case 0:
491
- return n=t.index,r=ue,i=(I||k||D)&&Date.now(),
492
- D&&i-W>=D?(ce=!0,[2,"break"]):(I&&i-ie>=I&&(s="",
491
+ return n=t.index,r=ue,i=(I||k||M)&&Date.now(),
492
+ M&&i-W>=M?(ce=!0,[2,"break"]):(I&&i-ie>=I&&(s="",
493
493
  o=i-Q,c=i-W,L?(s+="cycle: ".concat(t.cycleIndex,", variant: ").concat(t.index),
494
494
  null!=(u=t.count)&&null!=G&&G<u&&(u=G),
495
495
  null!=u&&t.index>0?(h=void 0,null!=U&&null!=G&&t.index<G&&o<U?(f=U-o,
496
496
  v=G-t.index,
497
- g=f/v,_=(u-t.index)*g,h=o+_):h=o*u/t.index,s+="/".concat(u," (").concat(Z(o),"/").concat(Z(h),")")):s+=" (".concat(Z(o),")")):s+="variant: ".concat(t.index," (").concat(Z(o),")"),
497
+ g=f/v,p=(u-t.index)*g,h=o+p):h=o*u/t.index,s+="/".concat(u," (").concat(Z(o),"/").concat(Z(h),")")):s+=" (".concat(Z(o),")")):s+="variant: ".concat(t.index," (").concat(Z(o),")"),
498
498
  s+=", total: ".concat(ne," (").concat(Z(c),")"),
499
499
  console.log(s),ie=i),A&&ne-oe>=A||P&&re-le>=P||k&&i-se>=k?(oe=ne,
500
500
  le=re,se=i,[4,Y(1)]):[3,2]);case 1:
501
501
  j.sent(),j.label=2;case 2:
502
502
  if(null==O?void 0:O.aborted)return[2,"continue"]
503
503
  ;if(ae&&!H.aborted)return[3,10];j.label=3;case 3:
504
- return j.trys.push([3,6,,9]),b(y=e(r,n,H))?[4,y]:[3,5]
505
- ;case 4:y=j.sent(),j.label=5;case 5:
506
- return y?(p=y.iterationsAsync,m=y.iterationsSync,
507
- re+=p,ne+=m+p,[3,9]):(te=!0,K.abort(),
504
+ return j.trys.push([3,6,,9]),b(_=e(r,n,H))?[4,_]:[3,5]
505
+ ;case 4:_=j.sent(),j.label=5;case 5:
506
+ return _?(y=_.iterationsAsync,m=_.iterationsSync,
507
+ re+=y,ne+=m+y,[3,9]):(te=!0,K.abort(),
508
508
  [2,"continue"]);case 6:
509
509
  return w=j.sent(),S?[4,d(r,S,x.argsToJson)]:[3,8]
510
510
  ;case 7:j.sent(),j.label=8;case 8:if(!L)throw w
@@ -523,20 +523,20 @@ return l=a.sent(),S?[4,d(r,S,x.argsToJson)]:[3,5]
523
523
  ;case 4:a.sent(),a.label=5;case 5:if(!L)throw l
524
524
  ;return t.addLimit({error:l}),te=!1,[3,7];case 6:
525
525
  return ae.release(1),[7];case 7:return[2]}})
526
- }),j.label=13;case 13:return[2]}})},_e.label=17
526
+ }),j.label=13;case 13:return[2]}})},pe.label=17
527
527
  ;case 17:
528
528
  return(null==O?void 0:O.aborted)||!te&&null==(ue=t.next())?[3,19]:[5,he()]
529
- ;case 18:return"break"===_e.sent()?[3,19]:[3,17]
529
+ ;case 18:return"break"===pe.sent()?[3,19]:[3,17]
530
530
  ;case 19:
531
531
  return G=t.count,U=Date.now()-Q,Q=Date.now(),t.start(),[3,16]
532
- ;case 20:return ae?[4,ae.holdWait(M)]:[3,22]
533
- ;case 21:_e.sent(),ae.release(M),_e.label=22
532
+ ;case 20:return ae?[4,ae.holdWait(D)]:[3,22]
533
+ ;case 21:pe.sent(),ae.release(D),pe.label=22
534
534
  ;case 22:
535
535
  if(null==ee?void 0:ee.aborted)throw ee.reason
536
536
  ;return T&&console.log("[test-variants] variants: ".concat(t.index,", iterations: ").concat(ne,", async: ").concat(re)),
537
- [4,Y(1)];case 23:if(_e.sent(),(fe=t.limit?{
537
+ [4,Y(1)];case 23:if(pe.sent(),(fe=t.limit?{
538
538
  error:t.limit.error,args:t.limit.args,
539
- index:t.count}:null)&&!V)throw fe.error;return[2,{
539
+ index:t.count}:null)&&!F)throw fe.error;return[2,{
540
540
  iterations:ne,bestError:fe}]}})})}
541
541
  function te(e,t,n){if(n){
542
542
  for(var r=e.length-1;r>=0;r--)if(n(e[r],t))return r
@@ -545,7 +545,7 @@ for(r=e.length-1;r>=0;r--)if(e[r]===t)return r
545
545
  ;return-1}function ne(e,t,n){var r=e[n]
546
546
  ;return"function"==typeof r?r(t):r}
547
547
  function re(e,t){
548
- var n=e.variants[t].length,r=e.argLimits[t]
548
+ var n=e.argValues[t].length,r=e.argLimits[t]
549
549
  ;return null==r?n:r<n?r:n}function ie(e,t,n){
550
550
  var r,i,s=Object.keys(e).filter(function(e){
551
551
  return"seed"!==e});if(s.length!==n)return!1;try{
@@ -559,91 +559,111 @@ var o=t[s]
559
559
  ;if("function"!=typeof o)if(te(o,e[n[s]],i)<0)return!1
560
560
  }return!0}function oe(e,t,n,r,i){
561
561
  for(var s=!1,o=0;o<r;o++){
562
- var l=e.indexes[o],a=t[n[o]],c=te(e.variants[o],a,i)
562
+ var l=e.indexes[o],a=t[n[o]],c=te(e.argValues[o],a,i)
563
563
  ;if(!(c<0)){if(s=!0,l<c)return!1;if(l>c)return!0}}
564
- return s}function le(e,t,n,r,i,s,o){
565
- if(o)for(var l=0;l<i;l++){
566
- var a=r[l],c=t[a],u=e.variants[l].length>0?e.variants[l]:ne(n,e.args,l),h=te(u,c,s)
567
- ;if(!(h<=0)){if("function"==typeof o)if(!o({
568
- name:a,valueIndex:h,values:u,
569
- maxValueIndex:e.argLimits[l]}))continue
570
- ;var f=e.argLimits[l]
571
- ;(null==f||h<f)&&(e.argLimits[l]=h)}}}
572
- function ae(e){
564
+ return s}function le(e,t,n,r,i){
565
+ for(var s=[],o=0;o<r;o++){
566
+ var l=e[n[o]],a=te(ne(t,e,o),l,i)
567
+ ;if(a<0)return null;s.push(a)}return s}
568
+ function ae(e,t,n,r,i,s,o,l){if(!l)return!1
569
+ ;var a=le(t,r,i,s,o);if(!a)return!1;if(n){
570
+ var c=le(n,r,i,s,o);if(c){var u=function(e,t){
571
+ for(var n,r,i=Math.max(e.length,t.length),s=0;s<i;s++){
572
+ var o=null!==(n=e[s])&&void 0!==n?n:0,l=null!==(r=t[s])&&void 0!==r?r:0
573
+ ;if(o<l)return-1;if(o>l)return 1}return 0}(a,c)
574
+ ;if(u>=0)return!1}}for(var h=0;h<s;h++){var f=a[h]
575
+ ;if("function"==typeof l)if(!l({name:i[h],
576
+ valueIndex:f,values:ne(r,t,h),
577
+ maxValueIndex:e.argLimits[h]})){
578
+ e.argLimits[h]=null;continue}
579
+ e.argLimits[h]=f>0?f:null}
580
+ return e.pendingLimits=e.pendingLimits.filter(function(t){
581
+ for(var n=0;n<s;n++){
582
+ var l=t.args[i[n]],a=te(ne(r,t.args,n),l,o),c=e.argLimits[n]
583
+ ;if(null!=c&&a>=c)return!1}return!0}),!0}
584
+ function ce(e){
573
585
  for(var t=e.argsTemplates,n=e.getSeed,r=e.repeatsPerVariant,i=e.equals,s=e.limitArgOnError,l=null!=r?r:1,a=Object.keys(t),c=Object.values(t),u=a.length,h=new Set(a),f=[],d=[],v=[],g=0;g<u;g++)f[g]=-1,
574
- d[g]=[],v[g]=null;var _={args:{},indexes:f,
575
- variants:d,argLimits:v,index:-1,cycleIndex:-1,
586
+ d[g]=[],v[g]=null;var p={args:{},indexes:f,
587
+ argValues:d,argLimits:v,index:-1,cycleIndex:-1,
576
588
  repeatIndex:0,count:null,limit:null,started:!1,
577
- currentArgs:null,pendingLimits:[]},y={get index(){
578
- return _.index},get cycleIndex(){
579
- return _.cycleIndex},get count(){return _.count},
580
- get limit(){return _.limit},addLimit:function(e){
581
- var t=void 0!==(null==e?void 0:e.args)&&null!==e.args,n=null!=(null==e?void 0:e.index)
582
- ;if(t||n)if(!n||t)if(!t||n){if(t&&n){
583
- var r=null==_.count||e.index<_.count
584
- ;if(r&&(_.count=e.index),!ie(e.args,h,u))return
585
- ;if(!se(e.args,c,a,u,i))return
586
- ;r&&(_.limit=void 0!==e.error?{args:e.args,
589
+ currentArgs:null,pendingLimits:[]},_={get index(){
590
+ return p.index},get cycleIndex(){
591
+ return p.cycleIndex},get count(){return p.count},
592
+ get limit(){return p.limit},addLimit:function(e){
593
+ var t,n,r,o,l,f,d=void 0!==(null==e?void 0:e.args)&&null!==e.args,v=null!=(null==e?void 0:e.index)
594
+ ;if(d||v)if(!v||d)if(!d||v){if(d&&v){
595
+ var g=null==p.count||e.index<p.count
596
+ ;if(g&&(p.count=e.index),!ie(e.args,h,u))return
597
+ ;if(!se(e.args,c,a,u,i))return;if(g){
598
+ _=null!==(f=null===(l=p.limit)||void 0===l?void 0:l.args)&&void 0!==f?f:null
599
+ ;p.limit=void 0!==e.error?{args:e.args,
587
600
  error:e.error}:{args:e.args
588
- },le(_,e.args,c,a,u,i,s))}}else{
601
+ },ae(p,e.args,_,c,a,u,i,s)}}}else{
589
602
  if(!ie(e.args,h,u))return
590
603
  ;if(!se(e.args,c,a,u,i))return
591
- ;var o=void 0!==e.error?{args:e.args,error:e.error
592
- }:{args:e.args};_.pendingLimits.push(o)
593
- }else(null==_.count||e.index<_.count)&&(_.count=e.index);else{
594
- if(_.index<0)throw new Error("[testVariantsIterator] addLimit() requires at least one next() call")
595
- ;(null==_.count||_.index<_.count)&&(_.count=_.index,
596
- _.limit=void 0!==(null==e?void 0:e.error)?{
597
- args:_.currentArgs,error:e.error}:{
598
- args:_.currentArgs},le(_,_.args,c,a,u,i,s))}},
599
- start:function(){_.cycleIndex++,function(e,t,n){
604
+ ;var _=null!==(o=null===(r=p.limit)||void 0===r?void 0:r.args)&&void 0!==o?o:null
605
+ ;if(ae(p,e.args,_,c,a,u,i,s))p.limit=void 0!==e.error?{
606
+ args:e.args,error:e.error}:{args:e.args
607
+ };else if(!s){var y=void 0!==e.error?{args:e.args,
608
+ error:e.error}:{args:e.args}
609
+ ;p.pendingLimits.push(y)}
610
+ }else(null==p.count||e.index<p.count)&&(p.count=e.index);else{
611
+ if(p.index<0)throw new Error("[testVariantsIterator] addLimit() requires at least one next() call")
612
+ ;if(null==p.count||p.index<p.count){
613
+ var _=null!==(n=null===(t=p.limit)||void 0===t?void 0:t.args)&&void 0!==n?n:null
614
+ ;p.count=p.index,
615
+ p.limit=void 0!==(null==e?void 0:e.error)?{
616
+ args:p.currentArgs,error:e.error}:{
617
+ args:p.currentArgs},ae(p,p.args,_,c,a,u,i,s)}}},
618
+ start:function(){p.cycleIndex++,function(e,t,n){
600
619
  e.index=-1,e.repeatIndex=0
601
- ;for(var r=0;r<n;r++)e.indexes[r]=-1,e.variants[r]=[]
602
- ;n>0&&(e.variants[0]=ne(t,e.args,0))
603
- }(_,c,u),_.started=!0},next:function(){
604
- if(!_.started)throw new Error("[testVariantsIterator] start() must be called before next()")
605
- ;if(_.index>=0&&_.repeatIndex+1<l&&(null==_.count||_.index<_.count)){
606
- if(_.repeatIndex++,n){var e=n({
607
- variantIndex:_.index,cycleIndex:_.cycleIndex,
608
- repeatIndex:_.repeatIndex})
609
- ;_.currentArgs=o(o({},_.args),{seed:e})
610
- }else _.currentArgs=o({},_.args)
611
- ;return _.currentArgs}
612
- if(_.repeatIndex=0,!function(e,t,n,r){
620
+ ;for(var r=0;r<n;r++)e.indexes[r]=-1,e.argValues[r]=[]
621
+ ;n>0&&(e.argValues[0]=ne(t,e.args,0))
622
+ }(p,c,u),p.started=!0},next:function(){
623
+ if(!p.started)throw new Error("[testVariantsIterator] start() must be called before next()")
624
+ ;if(p.index>=0&&p.repeatIndex+1<l&&(null==p.count||p.index<p.count)){
625
+ if(p.repeatIndex++,n){var e=n({
626
+ variantIndex:p.index,cycleIndex:p.cycleIndex,
627
+ repeatIndex:p.repeatIndex})
628
+ ;p.currentArgs=o(o({},p.args),{seed:e})
629
+ }else p.currentArgs=o({},p.args)
630
+ ;return p.currentArgs}
631
+ if(p.repeatIndex=0,!function(e,t,n,r){
613
632
  for(var i,s=r-1;s>=0;s--){var o=e.indexes[s]+1
614
- ;if(o<re(e,s)){var l=n[s],a=e.variants[s][o]
633
+ ;if(o<re(e,s)){var l=n[s],a=e.argValues[s][o]
615
634
  ;for(e.indexes[s]=o,e.args[l]=a,s++;s<r;s++){
616
635
  var c=ne(t,e.args,s),u=null!==(i=e.argLimits[s])&&void 0!==i?i:c.length
617
636
  ;if(0===c.length||u<=0)break
618
- ;e.indexes[s]=0,e.variants[s]=c;var h=n[s],f=c[0]
637
+ ;e.indexes[s]=0,e.argValues[s]=c;var h=n[s],f=c[0]
619
638
  ;e.args[h]=f}if(s>=r)return!0}}return!1
620
- }(_,c,a,u))return null==_.count&&(_.count=_.index+1),
639
+ }(p,c,a,u))return null==p.count&&(p.count=p.index+1),
621
640
  null
622
- ;if(_.index++,_.pendingLimits.length>0&&function(e,t,n,r,i,s){
623
- for(var o=!1,l=e.pendingLimits.length-1;l>=0;l--){
624
- var a=e.pendingLimits[l]
625
- ;oe(e,a.args,n,r,i)&&((null==e.count||e.index<e.count)&&(e.count=e.index,
626
- e.limit=void 0!==a.error?{args:a.args,
627
- error:a.error}:{args:a.args
628
- },le(e,a.args,t,n,r,i,s),o=!0),e.pendingLimits.splice(l,1))
629
- }
630
- }(_,c,a,u,i,s),null!=_.count&&_.index>=_.count)return null
631
- ;if(n){e=n({variantIndex:_.index,
632
- cycleIndex:_.cycleIndex,repeatIndex:_.repeatIndex
633
- });_.currentArgs=o(o({},_.args),{seed:e})
634
- }else _.currentArgs=o({},_.args)
635
- ;return _.currentArgs}};return y}
641
+ ;if(p.index++,p.pendingLimits.length>0&&function(e,t,n,r,i,s){
642
+ for(var o,l,a=!1,c=e.pendingLimits.length-1;c>=0;c--){
643
+ var u=e.pendingLimits[c];if(oe(e,u.args,n,r,i)){
644
+ if(null==e.count||e.index<e.count){
645
+ var h=null!==(l=null===(o=e.limit)||void 0===o?void 0:o.args)&&void 0!==l?l:null
646
+ ;e.count=e.index,e.limit=void 0!==u.error?{
647
+ args:u.args,error:u.error}:{args:u.args
648
+ },ae(e,u.args,h,t,n,r,i,s),a=!0}
649
+ e.pendingLimits.splice(c,1)}}
650
+ }(p,c,a,u,i,s),null!=p.count&&p.index>=p.count)return null
651
+ ;if(n){e=n({variantIndex:p.index,
652
+ cycleIndex:p.cycleIndex,repeatIndex:p.repeatIndex
653
+ });p.currentArgs=o(o({},p.args),{seed:e})
654
+ }else p.currentArgs=o({},p.args)
655
+ ;return p.currentArgs}};return _}
636
656
  e.createTestVariants=function(e){
637
657
  return function(t){return function(n){var r,i,s,o
638
658
  ;return l(this,void 0,void 0,function(){var l,c
639
659
  ;return a(this,function(a){return l=L(e,{
640
- onError:null==n?void 0:n.onError}),c=ae({
660
+ onError:null==n?void 0:n.onError}),c=ce({
641
661
  argsTemplates:t,
642
662
  getSeed:null===(r=null==n?void 0:n.findBestError)||void 0===r?void 0:r.getSeed,
643
663
  repeatsPerVariant:null===(i=null==n?void 0:n.findBestError)||void 0===i?void 0:i.repeatsPerVariant,
644
664
  equals:null===(s=null==n?void 0:n.findBestError)||void 0===s?void 0:s.equals,
645
665
  limitArgOnError:null===(o=null==n?void 0:n.findBestError)||void 0===o?void 0:o.limitArgOnError
646
666
  }),[2,ee(l,c,n)]})})}}
647
- },e.generateErrorVariantFilePath=f,e.testVariantsIterator=ae,
667
+ },e.generateErrorVariantFilePath=f,e.testVariantsIterator=ce,
648
668
  Object.defineProperty(e,"__esModule",{value:!0})
649
669
  }({},fs,path);
@@ -33,20 +33,20 @@ function resetIteratorState(state, templates, keysCount) {
33
33
  state.repeatIndex = 0;
34
34
  for (let i = 0; i < keysCount; i++) {
35
35
  state.indexes[i] = -1;
36
- state.variants[i] = [];
36
+ state.argValues[i] = [];
37
37
  }
38
38
  if (keysCount > 0) {
39
- state.variants[0] = calcTemplateValues(templates, state.args, 0);
39
+ state.argValues[0] = calcTemplateValues(templates, state.args, 0);
40
40
  }
41
41
  }
42
42
  /** Get effective max index for an arg (considering argLimit) */
43
43
  function getMaxIndex(state, keyIndex) {
44
- const variantsLen = state.variants[keyIndex].length;
44
+ const valuesLen = state.argValues[keyIndex].length;
45
45
  const argLimit = state.argLimits[keyIndex];
46
46
  if (argLimit == null) {
47
- return variantsLen;
47
+ return valuesLen;
48
48
  }
49
- return argLimit < variantsLen ? argLimit : variantsLen;
49
+ return argLimit < valuesLen ? argLimit : valuesLen;
50
50
  }
51
51
  /** Advance to next variant in cartesian product; returns true if successful */
52
52
  function advanceVariant(state, templates, keys, keysCount) {
@@ -56,7 +56,7 @@ function advanceVariant(state, templates, keys, keysCount) {
56
56
  const maxIndex = getMaxIndex(state, keyIndex);
57
57
  if (valueIndex < maxIndex) {
58
58
  const key = keys[keyIndex];
59
- const value = state.variants[keyIndex][valueIndex];
59
+ const value = state.argValues[keyIndex][valueIndex];
60
60
  state.indexes[keyIndex] = valueIndex;
61
61
  state.args[key] = value;
62
62
  for (keyIndex++; keyIndex < keysCount; keyIndex++) {
@@ -66,7 +66,7 @@ function advanceVariant(state, templates, keys, keysCount) {
66
66
  break;
67
67
  }
68
68
  state.indexes[keyIndex] = 0;
69
- state.variants[keyIndex] = keyVariants;
69
+ state.argValues[keyIndex] = keyVariants;
70
70
  const key = keys[keyIndex];
71
71
  const value = keyVariants[0];
72
72
  state.args[key] = value;
@@ -110,7 +110,7 @@ function isPositionReached(state, pendingArgs, keys, keysCount, equals) {
110
110
  for (let i = 0; i < keysCount; i++) {
111
111
  const currentValueIndex = state.indexes[i];
112
112
  const pendingValue = pendingArgs[keys[i]];
113
- const pendingValueIndex = findLastIndex(state.variants[i], pendingValue, equals);
113
+ const pendingValueIndex = findLastIndex(state.argValues[i], pendingValue, equals);
114
114
  // Dynamic template value not found - skip this arg from comparison
115
115
  if (pendingValueIndex < 0) {
116
116
  continue;
@@ -126,24 +126,66 @@ function isPositionReached(state, pendingArgs, keys, keysCount, equals) {
126
126
  // All compared args are equal - position reached; or all args skipped - keep pending
127
127
  return anyCompared;
128
128
  }
129
- /** Update per-arg limits from args values */
130
- function updateArgLimits(state, limitArgs, templates, keys, keysCount, equals, limitArgOnError) {
131
- if (!limitArgOnError) {
132
- return;
133
- }
129
+ /** Calculate indexes for given args; returns null if any value not found */
130
+ function calcArgsIndexes(limitArgs, templates, keys, keysCount, equals) {
131
+ const indexes = [];
134
132
  for (let i = 0; i < keysCount; i++) {
135
133
  const key = keys[i];
136
134
  const value = limitArgs[key];
137
- const values = state.variants[i].length > 0
138
- ? state.variants[i]
139
- : calcTemplateValues(templates, state.args, i);
135
+ // Use limitArgs for dynamic template calculation
136
+ const values = calcTemplateValues(templates, limitArgs, i);
140
137
  const valueIndex = findLastIndex(values, value, equals);
141
- // Skip if value not found or already at index 0
142
- if (valueIndex <= 0) {
143
- continue;
138
+ if (valueIndex < 0) {
139
+ return null;
140
+ }
141
+ indexes.push(valueIndex);
142
+ }
143
+ return indexes;
144
+ }
145
+ /** Compare two index arrays lexicographically; returns -1 if a < b, 0 if equal, 1 if a > b */
146
+ function compareLexicographic(a, b) {
147
+ var _a, _b;
148
+ const len = Math.max(a.length, b.length);
149
+ for (let i = 0; i < len; i++) {
150
+ const ai = (_a = a[i]) !== null && _a !== void 0 ? _a : 0;
151
+ const bi = (_b = b[i]) !== null && _b !== void 0 ? _b : 0;
152
+ if (ai < bi) {
153
+ return -1;
154
+ }
155
+ if (ai > bi) {
156
+ return 1;
157
+ }
158
+ }
159
+ return 0;
160
+ }
161
+ /** Update per-arg limits from args values using lexicographic comparison; returns true if updated */
162
+ function updateArgLimits(state, limitArgs, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError) {
163
+ if (!limitArgOnError) {
164
+ return false;
165
+ }
166
+ // Calculate indexes for new limit args
167
+ const newIndexes = calcArgsIndexes(limitArgs, templates, keys, keysCount, equals);
168
+ if (!newIndexes) {
169
+ return false; // Value not found, can't apply limit
170
+ }
171
+ // If we have existing limit, compare lexicographically
172
+ if (oldLimitArgs) {
173
+ const currentIndexes = calcArgsIndexes(oldLimitArgs, templates, keys, keysCount, equals);
174
+ if (currentIndexes) {
175
+ const cmp = compareLexicographic(newIndexes, currentIndexes);
176
+ if (cmp >= 0) {
177
+ // New is larger or equal - reject entirely
178
+ return false;
179
+ }
144
180
  }
181
+ }
182
+ // New is smaller (or first limit) - replace all argLimits
183
+ for (let i = 0; i < keysCount; i++) {
184
+ const valueIndex = newIndexes[i];
145
185
  // Check callback if provided
146
186
  if (typeof limitArgOnError === 'function') {
187
+ const key = keys[i];
188
+ const values = calcTemplateValues(templates, limitArgs, i);
147
189
  const shouldLimit = limitArgOnError({
148
190
  name: key,
149
191
  valueIndex,
@@ -151,29 +193,43 @@ function updateArgLimits(state, limitArgs, templates, keys, keysCount, equals, l
151
193
  maxValueIndex: state.argLimits[i],
152
194
  });
153
195
  if (!shouldLimit) {
196
+ state.argLimits[i] = null;
154
197
  continue;
155
198
  }
156
199
  }
157
- // Update limit: argLimit = min(current argLimit, valueIndex)
158
- const currentLimit = state.argLimits[i];
159
- if (currentLimit == null || valueIndex < currentLimit) {
160
- state.argLimits[i] = valueIndex;
161
- }
200
+ // Set argLimit: index 0 can't be limited further, store null
201
+ state.argLimits[i] = valueIndex > 0 ? valueIndex : null;
162
202
  }
203
+ // Filter out pending limits that are now excluded by argLimits
204
+ state.pendingLimits = state.pendingLimits.filter(pending => {
205
+ for (let i = 0; i < keysCount; i++) {
206
+ const value = pending.args[keys[i]];
207
+ const values = calcTemplateValues(templates, pending.args, i);
208
+ const valueIndex = findLastIndex(values, value, equals);
209
+ const argLimit = state.argLimits[i];
210
+ if (argLimit != null && valueIndex >= argLimit) {
211
+ return false; // Pending position is excluded by argLimits
212
+ }
213
+ }
214
+ return true; // Keep
215
+ });
216
+ return true;
163
217
  }
164
218
  /** Process pending limits; returns true if any limit was applied */
165
219
  function processPendingLimits(state, templates, keys, keysCount, equals, limitArgOnError) {
220
+ var _a, _b;
166
221
  let applied = false;
167
222
  for (let i = state.pendingLimits.length - 1; i >= 0; i--) {
168
223
  const pending = state.pendingLimits[i];
169
224
  if (isPositionReached(state, pending.args, keys, keysCount, equals)) {
170
225
  // Current position >= pending position: apply limit
171
226
  if (state.count == null || state.index < state.count) {
227
+ const oldLimitArgs = (_b = (_a = state.limit) === null || _a === void 0 ? void 0 : _a.args) !== null && _b !== void 0 ? _b : null;
172
228
  state.count = state.index;
173
229
  state.limit = typeof pending.error !== 'undefined'
174
230
  ? { args: pending.args, error: pending.error }
175
231
  : { args: pending.args };
176
- updateArgLimits(state, pending.args, templates, keys, keysCount, equals, limitArgOnError);
232
+ updateArgLimits(state, pending.args, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError);
177
233
  applied = true;
178
234
  }
179
235
  // Remove from pending
@@ -192,17 +248,17 @@ function testVariantsIterator(options) {
192
248
  const keysSet = new Set(keys);
193
249
  // Initialize state
194
250
  const indexes = [];
195
- const variants = [];
251
+ const argValues = [];
196
252
  const argLimits = [];
197
253
  for (let i = 0; i < keysCount; i++) {
198
254
  indexes[i] = -1;
199
- variants[i] = [];
255
+ argValues[i] = [];
200
256
  argLimits[i] = null;
201
257
  }
202
258
  const state = {
203
259
  args: {},
204
260
  indexes,
205
- variants,
261
+ argValues,
206
262
  argLimits,
207
263
  index: -1,
208
264
  cycleIndex: -1,
@@ -227,6 +283,7 @@ function testVariantsIterator(options) {
227
283
  return state.limit;
228
284
  },
229
285
  addLimit(_options) {
286
+ var _a, _b, _c, _d, _e, _f;
230
287
  const hasArgs = typeof (_options === null || _options === void 0 ? void 0 : _options.args) !== 'undefined' && _options.args !== null;
231
288
  const hasIndex = (_options === null || _options === void 0 ? void 0 : _options.index) != null;
232
289
  // addLimit() or addLimit({error}) - uses current args and index
@@ -235,11 +292,12 @@ function testVariantsIterator(options) {
235
292
  throw new Error('[testVariantsIterator] addLimit() requires at least one next() call');
236
293
  }
237
294
  if (state.count == null || state.index < state.count) {
295
+ const oldLimitArgs = (_b = (_a = state.limit) === null || _a === void 0 ? void 0 : _a.args) !== null && _b !== void 0 ? _b : null;
238
296
  state.count = state.index;
239
297
  state.limit = typeof (_options === null || _options === void 0 ? void 0 : _options.error) !== 'undefined'
240
298
  ? { args: state.currentArgs, error: _options.error }
241
299
  : { args: state.currentArgs };
242
- updateArgLimits(state, state.args, templates, keys, keysCount, equals, limitArgOnError);
300
+ updateArgLimits(state, state.args, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError);
243
301
  }
244
302
  return;
245
303
  }
@@ -250,7 +308,7 @@ function testVariantsIterator(options) {
250
308
  }
251
309
  return;
252
310
  }
253
- // addLimit({args}) or addLimit({args, error}) - pending limit
311
+ // addLimit({args}) or addLimit({args, error}) - pending limit + immediate per-arg limits
254
312
  if (hasArgs && !hasIndex) {
255
313
  // Validate args keys match iterator's arg names
256
314
  if (!validateArgsKeys(_options.args, keysSet, keysCount)) {
@@ -260,11 +318,24 @@ function testVariantsIterator(options) {
260
318
  if (!validateStaticArgsValues(_options.args, templates, keys, keysCount, equals)) {
261
319
  return; // Discard - unreproducible (value not in template)
262
320
  }
263
- // Store as pending limit
264
- const pending = typeof _options.error !== 'undefined'
265
- ? { args: _options.args, error: _options.error }
266
- : { args: _options.args };
267
- state.pendingLimits.push(pending);
321
+ // Apply per-arg limits immediately (if limitArgOnError enabled)
322
+ const oldLimitArgs = (_d = (_c = state.limit) === null || _c === void 0 ? void 0 : _c.args) !== null && _d !== void 0 ? _d : null;
323
+ const updated = updateArgLimits(state, _options.args, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError);
324
+ if (updated) {
325
+ // argLimits updated - this is the new best, update state.limit for future comparisons
326
+ state.limit = typeof _options.error !== 'undefined'
327
+ ? { args: _options.args, error: _options.error }
328
+ : { args: _options.args };
329
+ // Pending limit at this position is now filtered by argLimits, don't add
330
+ }
331
+ else if (!limitArgOnError) {
332
+ // No argLimits filtering - add pending limit for position-based stopping
333
+ const pending = typeof _options.error !== 'undefined'
334
+ ? { args: _options.args, error: _options.error }
335
+ : { args: _options.args };
336
+ state.pendingLimits.push(pending);
337
+ }
338
+ // If limitArgOnError and not updated (lexicographically larger), discard entirely
268
339
  return;
269
340
  }
270
341
  // addLimit({args, index}) or addLimit({args, index, error}) - immediate index + pending args
@@ -284,10 +355,11 @@ function testVariantsIterator(options) {
284
355
  }
285
356
  // Update limit if this is earliest
286
357
  if (isEarliest) {
358
+ const oldLimitArgs = (_f = (_e = state.limit) === null || _e === void 0 ? void 0 : _e.args) !== null && _f !== void 0 ? _f : null;
287
359
  state.limit = typeof _options.error !== 'undefined'
288
360
  ? { args: _options.args, error: _options.error }
289
361
  : { args: _options.args };
290
- updateArgLimits(state, _options.args, templates, keys, keysCount, equals, limitArgOnError);
362
+ updateArgLimits(state, _options.args, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError);
291
363
  }
292
364
  }
293
365
  },
@@ -29,20 +29,20 @@ function resetIteratorState(state, templates, keysCount) {
29
29
  state.repeatIndex = 0;
30
30
  for (let i = 0; i < keysCount; i++) {
31
31
  state.indexes[i] = -1;
32
- state.variants[i] = [];
32
+ state.argValues[i] = [];
33
33
  }
34
34
  if (keysCount > 0) {
35
- state.variants[0] = calcTemplateValues(templates, state.args, 0);
35
+ state.argValues[0] = calcTemplateValues(templates, state.args, 0);
36
36
  }
37
37
  }
38
38
  /** Get effective max index for an arg (considering argLimit) */
39
39
  function getMaxIndex(state, keyIndex) {
40
- const variantsLen = state.variants[keyIndex].length;
40
+ const valuesLen = state.argValues[keyIndex].length;
41
41
  const argLimit = state.argLimits[keyIndex];
42
42
  if (argLimit == null) {
43
- return variantsLen;
43
+ return valuesLen;
44
44
  }
45
- return argLimit < variantsLen ? argLimit : variantsLen;
45
+ return argLimit < valuesLen ? argLimit : valuesLen;
46
46
  }
47
47
  /** Advance to next variant in cartesian product; returns true if successful */
48
48
  function advanceVariant(state, templates, keys, keysCount) {
@@ -52,7 +52,7 @@ function advanceVariant(state, templates, keys, keysCount) {
52
52
  const maxIndex = getMaxIndex(state, keyIndex);
53
53
  if (valueIndex < maxIndex) {
54
54
  const key = keys[keyIndex];
55
- const value = state.variants[keyIndex][valueIndex];
55
+ const value = state.argValues[keyIndex][valueIndex];
56
56
  state.indexes[keyIndex] = valueIndex;
57
57
  state.args[key] = value;
58
58
  for (keyIndex++; keyIndex < keysCount; keyIndex++) {
@@ -62,7 +62,7 @@ function advanceVariant(state, templates, keys, keysCount) {
62
62
  break;
63
63
  }
64
64
  state.indexes[keyIndex] = 0;
65
- state.variants[keyIndex] = keyVariants;
65
+ state.argValues[keyIndex] = keyVariants;
66
66
  const key = keys[keyIndex];
67
67
  const value = keyVariants[0];
68
68
  state.args[key] = value;
@@ -106,7 +106,7 @@ function isPositionReached(state, pendingArgs, keys, keysCount, equals) {
106
106
  for (let i = 0; i < keysCount; i++) {
107
107
  const currentValueIndex = state.indexes[i];
108
108
  const pendingValue = pendingArgs[keys[i]];
109
- const pendingValueIndex = findLastIndex(state.variants[i], pendingValue, equals);
109
+ const pendingValueIndex = findLastIndex(state.argValues[i], pendingValue, equals);
110
110
  // Dynamic template value not found - skip this arg from comparison
111
111
  if (pendingValueIndex < 0) {
112
112
  continue;
@@ -122,24 +122,66 @@ function isPositionReached(state, pendingArgs, keys, keysCount, equals) {
122
122
  // All compared args are equal - position reached; or all args skipped - keep pending
123
123
  return anyCompared;
124
124
  }
125
- /** Update per-arg limits from args values */
126
- function updateArgLimits(state, limitArgs, templates, keys, keysCount, equals, limitArgOnError) {
127
- if (!limitArgOnError) {
128
- return;
129
- }
125
+ /** Calculate indexes for given args; returns null if any value not found */
126
+ function calcArgsIndexes(limitArgs, templates, keys, keysCount, equals) {
127
+ const indexes = [];
130
128
  for (let i = 0; i < keysCount; i++) {
131
129
  const key = keys[i];
132
130
  const value = limitArgs[key];
133
- const values = state.variants[i].length > 0
134
- ? state.variants[i]
135
- : calcTemplateValues(templates, state.args, i);
131
+ // Use limitArgs for dynamic template calculation
132
+ const values = calcTemplateValues(templates, limitArgs, i);
136
133
  const valueIndex = findLastIndex(values, value, equals);
137
- // Skip if value not found or already at index 0
138
- if (valueIndex <= 0) {
139
- continue;
134
+ if (valueIndex < 0) {
135
+ return null;
136
+ }
137
+ indexes.push(valueIndex);
138
+ }
139
+ return indexes;
140
+ }
141
+ /** Compare two index arrays lexicographically; returns -1 if a < b, 0 if equal, 1 if a > b */
142
+ function compareLexicographic(a, b) {
143
+ var _a, _b;
144
+ const len = Math.max(a.length, b.length);
145
+ for (let i = 0; i < len; i++) {
146
+ const ai = (_a = a[i]) !== null && _a !== void 0 ? _a : 0;
147
+ const bi = (_b = b[i]) !== null && _b !== void 0 ? _b : 0;
148
+ if (ai < bi) {
149
+ return -1;
150
+ }
151
+ if (ai > bi) {
152
+ return 1;
153
+ }
154
+ }
155
+ return 0;
156
+ }
157
+ /** Update per-arg limits from args values using lexicographic comparison; returns true if updated */
158
+ function updateArgLimits(state, limitArgs, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError) {
159
+ if (!limitArgOnError) {
160
+ return false;
161
+ }
162
+ // Calculate indexes for new limit args
163
+ const newIndexes = calcArgsIndexes(limitArgs, templates, keys, keysCount, equals);
164
+ if (!newIndexes) {
165
+ return false; // Value not found, can't apply limit
166
+ }
167
+ // If we have existing limit, compare lexicographically
168
+ if (oldLimitArgs) {
169
+ const currentIndexes = calcArgsIndexes(oldLimitArgs, templates, keys, keysCount, equals);
170
+ if (currentIndexes) {
171
+ const cmp = compareLexicographic(newIndexes, currentIndexes);
172
+ if (cmp >= 0) {
173
+ // New is larger or equal - reject entirely
174
+ return false;
175
+ }
140
176
  }
177
+ }
178
+ // New is smaller (or first limit) - replace all argLimits
179
+ for (let i = 0; i < keysCount; i++) {
180
+ const valueIndex = newIndexes[i];
141
181
  // Check callback if provided
142
182
  if (typeof limitArgOnError === 'function') {
183
+ const key = keys[i];
184
+ const values = calcTemplateValues(templates, limitArgs, i);
143
185
  const shouldLimit = limitArgOnError({
144
186
  name: key,
145
187
  valueIndex,
@@ -147,29 +189,43 @@ function updateArgLimits(state, limitArgs, templates, keys, keysCount, equals, l
147
189
  maxValueIndex: state.argLimits[i],
148
190
  });
149
191
  if (!shouldLimit) {
192
+ state.argLimits[i] = null;
150
193
  continue;
151
194
  }
152
195
  }
153
- // Update limit: argLimit = min(current argLimit, valueIndex)
154
- const currentLimit = state.argLimits[i];
155
- if (currentLimit == null || valueIndex < currentLimit) {
156
- state.argLimits[i] = valueIndex;
157
- }
196
+ // Set argLimit: index 0 can't be limited further, store null
197
+ state.argLimits[i] = valueIndex > 0 ? valueIndex : null;
158
198
  }
199
+ // Filter out pending limits that are now excluded by argLimits
200
+ state.pendingLimits = state.pendingLimits.filter(pending => {
201
+ for (let i = 0; i < keysCount; i++) {
202
+ const value = pending.args[keys[i]];
203
+ const values = calcTemplateValues(templates, pending.args, i);
204
+ const valueIndex = findLastIndex(values, value, equals);
205
+ const argLimit = state.argLimits[i];
206
+ if (argLimit != null && valueIndex >= argLimit) {
207
+ return false; // Pending position is excluded by argLimits
208
+ }
209
+ }
210
+ return true; // Keep
211
+ });
212
+ return true;
159
213
  }
160
214
  /** Process pending limits; returns true if any limit was applied */
161
215
  function processPendingLimits(state, templates, keys, keysCount, equals, limitArgOnError) {
216
+ var _a, _b;
162
217
  let applied = false;
163
218
  for (let i = state.pendingLimits.length - 1; i >= 0; i--) {
164
219
  const pending = state.pendingLimits[i];
165
220
  if (isPositionReached(state, pending.args, keys, keysCount, equals)) {
166
221
  // Current position >= pending position: apply limit
167
222
  if (state.count == null || state.index < state.count) {
223
+ const oldLimitArgs = (_b = (_a = state.limit) === null || _a === void 0 ? void 0 : _a.args) !== null && _b !== void 0 ? _b : null;
168
224
  state.count = state.index;
169
225
  state.limit = typeof pending.error !== 'undefined'
170
226
  ? { args: pending.args, error: pending.error }
171
227
  : { args: pending.args };
172
- updateArgLimits(state, pending.args, templates, keys, keysCount, equals, limitArgOnError);
228
+ updateArgLimits(state, pending.args, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError);
173
229
  applied = true;
174
230
  }
175
231
  // Remove from pending
@@ -188,17 +244,17 @@ function testVariantsIterator(options) {
188
244
  const keysSet = new Set(keys);
189
245
  // Initialize state
190
246
  const indexes = [];
191
- const variants = [];
247
+ const argValues = [];
192
248
  const argLimits = [];
193
249
  for (let i = 0; i < keysCount; i++) {
194
250
  indexes[i] = -1;
195
- variants[i] = [];
251
+ argValues[i] = [];
196
252
  argLimits[i] = null;
197
253
  }
198
254
  const state = {
199
255
  args: {},
200
256
  indexes,
201
- variants,
257
+ argValues,
202
258
  argLimits,
203
259
  index: -1,
204
260
  cycleIndex: -1,
@@ -223,6 +279,7 @@ function testVariantsIterator(options) {
223
279
  return state.limit;
224
280
  },
225
281
  addLimit(_options) {
282
+ var _a, _b, _c, _d, _e, _f;
226
283
  const hasArgs = typeof (_options === null || _options === void 0 ? void 0 : _options.args) !== 'undefined' && _options.args !== null;
227
284
  const hasIndex = (_options === null || _options === void 0 ? void 0 : _options.index) != null;
228
285
  // addLimit() or addLimit({error}) - uses current args and index
@@ -231,11 +288,12 @@ function testVariantsIterator(options) {
231
288
  throw new Error('[testVariantsIterator] addLimit() requires at least one next() call');
232
289
  }
233
290
  if (state.count == null || state.index < state.count) {
291
+ const oldLimitArgs = (_b = (_a = state.limit) === null || _a === void 0 ? void 0 : _a.args) !== null && _b !== void 0 ? _b : null;
234
292
  state.count = state.index;
235
293
  state.limit = typeof (_options === null || _options === void 0 ? void 0 : _options.error) !== 'undefined'
236
294
  ? { args: state.currentArgs, error: _options.error }
237
295
  : { args: state.currentArgs };
238
- updateArgLimits(state, state.args, templates, keys, keysCount, equals, limitArgOnError);
296
+ updateArgLimits(state, state.args, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError);
239
297
  }
240
298
  return;
241
299
  }
@@ -246,7 +304,7 @@ function testVariantsIterator(options) {
246
304
  }
247
305
  return;
248
306
  }
249
- // addLimit({args}) or addLimit({args, error}) - pending limit
307
+ // addLimit({args}) or addLimit({args, error}) - pending limit + immediate per-arg limits
250
308
  if (hasArgs && !hasIndex) {
251
309
  // Validate args keys match iterator's arg names
252
310
  if (!validateArgsKeys(_options.args, keysSet, keysCount)) {
@@ -256,11 +314,24 @@ function testVariantsIterator(options) {
256
314
  if (!validateStaticArgsValues(_options.args, templates, keys, keysCount, equals)) {
257
315
  return; // Discard - unreproducible (value not in template)
258
316
  }
259
- // Store as pending limit
260
- const pending = typeof _options.error !== 'undefined'
261
- ? { args: _options.args, error: _options.error }
262
- : { args: _options.args };
263
- state.pendingLimits.push(pending);
317
+ // Apply per-arg limits immediately (if limitArgOnError enabled)
318
+ const oldLimitArgs = (_d = (_c = state.limit) === null || _c === void 0 ? void 0 : _c.args) !== null && _d !== void 0 ? _d : null;
319
+ const updated = updateArgLimits(state, _options.args, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError);
320
+ if (updated) {
321
+ // argLimits updated - this is the new best, update state.limit for future comparisons
322
+ state.limit = typeof _options.error !== 'undefined'
323
+ ? { args: _options.args, error: _options.error }
324
+ : { args: _options.args };
325
+ // Pending limit at this position is now filtered by argLimits, don't add
326
+ }
327
+ else if (!limitArgOnError) {
328
+ // No argLimits filtering - add pending limit for position-based stopping
329
+ const pending = typeof _options.error !== 'undefined'
330
+ ? { args: _options.args, error: _options.error }
331
+ : { args: _options.args };
332
+ state.pendingLimits.push(pending);
333
+ }
334
+ // If limitArgOnError and not updated (lexicographically larger), discard entirely
264
335
  return;
265
336
  }
266
337
  // addLimit({args, index}) or addLimit({args, index, error}) - immediate index + pending args
@@ -280,10 +351,11 @@ function testVariantsIterator(options) {
280
351
  }
281
352
  // Update limit if this is earliest
282
353
  if (isEarliest) {
354
+ const oldLimitArgs = (_f = (_e = state.limit) === null || _e === void 0 ? void 0 : _e.args) !== null && _f !== void 0 ? _f : null;
283
355
  state.limit = typeof _options.error !== 'undefined'
284
356
  ? { args: _options.args, error: _options.error }
285
357
  : { args: _options.args };
286
- updateArgLimits(state, _options.args, templates, keys, keysCount, equals, limitArgOnError);
358
+ updateArgLimits(state, _options.args, oldLimitArgs, templates, keys, keysCount, equals, limitArgOnError);
287
359
  }
288
360
  }
289
361
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flemist/test-variants",
3
- "version": "3.0.1",
3
+ "version": "3.0.3",
4
4
  "description": "Runs a test function with all possible combinations of its parameters.",
5
5
  "main": "dist/lib/index.cjs",
6
6
  "module": "dist/lib/index.mjs",
@@ -32,24 +32,6 @@
32
32
  "publishConfig": {
33
33
  "access": "public"
34
34
  },
35
- "scripts": {
36
- "_prepublishOnly": "pnpm run audit && pnpm run lint && pnpm run build && pnpm run test:mocha:ci && npm login",
37
- "audit": "pnpm audit --prod",
38
- "lint": "eslint ./**/*.{js,cjs,mjs,ts,tsx}",
39
- "lint:fix": "eslint --fix ./**/*.{js,cjs,mjs,ts,tsx}",
40
- "lint:wizard": "eslint-nibble --cache --multi ./**/*.{js,cjs,mjs,ts,tsx}",
41
- "build:js": "rimraf dist/lib && cpy \"**/assets/**\" \"**/*.{js,cjs,mjs}\" \"../dist/lib/\" --parents --cwd=src && rollup -c",
42
- "build": "rimraf dist && pnpm run build:js",
43
- "coverage:merge": "rimraf tmp/coverage/{all,merge} && cp-flat \"tmp/coverage/*/json/**/*.json\" \"tmp/coverage/merge\" && nyc report -r lcov --report-dir tmp/coverage/all/lcov --temp-dir \"tmp/coverage/merge/\"",
44
- "coverage:check": "pnpm run coverage:merge && nyc check-coverage --report-dir tmp/coverage/all/lcov --lines 50 --functions 50 --branches 50 --statements 50",
45
- "test:mocha": "mocha ./src/**/*.test.*",
46
- "test:mocha:coverage": "rimraf tmp/coverage/mocha && nyc --all mocha ./src/**/*.test.*",
47
- "test:mocha:watch": "mocha --watch ./src/**/*.test.*",
48
- "test:karma": "rimraf tmp/coverage/karma && karma start --single-run --log-level debug",
49
- "test:mocha:ci": "rimraf tmp/coverage/mocha && nyc --all mocha ./{src,dist/lib}/**/*.test.*",
50
- "coveralls": "pnpm run coverage:check && nyc report --reporter=text-lcov --temp-dir \"tmp/coverage/merge/\" | coveralls",
51
- "mcp:tools": "mcp-project-tools"
52
- },
53
35
  "devDependencies": {
54
36
  "@anthropic-ai/claude-code": "^2.0.76",
55
37
  "@babel/core": "7.18.5",
@@ -105,5 +87,22 @@
105
87
  "@flemist/async-utils": "^1.0.0",
106
88
  "@flemist/time-limits": "^1.0.1",
107
89
  "tslib": "2.5.3"
90
+ },
91
+ "scripts": {
92
+ "audit": "pnpm audit --prod",
93
+ "lint": "eslint ./**/*.{js,cjs,mjs,ts,tsx}",
94
+ "lint:fix": "eslint --fix ./**/*.{js,cjs,mjs,ts,tsx}",
95
+ "lint:wizard": "eslint-nibble --cache --multi ./**/*.{js,cjs,mjs,ts,tsx}",
96
+ "build:js": "rimraf dist/lib && cpy \"**/assets/**\" \"**/*.{js,cjs,mjs}\" \"../dist/lib/\" --parents --cwd=src && rollup -c",
97
+ "build": "rimraf dist && pnpm run build:js",
98
+ "coverage:merge": "rimraf tmp/coverage/{all,merge} && cp-flat \"tmp/coverage/*/json/**/*.json\" \"tmp/coverage/merge\" && nyc report -r lcov --report-dir tmp/coverage/all/lcov --temp-dir \"tmp/coverage/merge/\"",
99
+ "coverage:check": "pnpm run coverage:merge && nyc check-coverage --report-dir tmp/coverage/all/lcov --lines 50 --functions 50 --branches 50 --statements 50",
100
+ "test:mocha": "mocha ./src/**/*.test.*",
101
+ "test:mocha:coverage": "rimraf tmp/coverage/mocha && nyc --all mocha ./src/**/*.test.*",
102
+ "test:mocha:watch": "mocha --watch ./src/**/*.test.*",
103
+ "test:karma": "rimraf tmp/coverage/karma && karma start --single-run --log-level debug",
104
+ "test:mocha:ci": "rimraf tmp/coverage/mocha && nyc --all mocha ./{src,dist/lib}/**/*.test.*",
105
+ "coveralls": "pnpm run coverage:check && nyc report --reporter=text-lcov --temp-dir \"tmp/coverage/merge/\" | coveralls",
106
+ "mcp:tools": "mcp-project-tools"
108
107
  }
109
- }
108
+ }