@demlik/tea 0.20.0 → 0.22.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.
Files changed (130) hide show
  1. package/README.md +11 -2
  2. package/dist/agent/index.d.ts +36 -23
  3. package/dist/agent/index.js +12 -10
  4. package/dist/{chunk-UHAQ4PI6.js → chunk-2A5XTKQQ.js} +205 -59
  5. package/dist/chunk-2A5XTKQQ.js.map +1 -0
  6. package/dist/{chunk-JAKM53JF.js → chunk-7K7SEYCH.js} +16 -15
  7. package/dist/chunk-7K7SEYCH.js.map +1 -0
  8. package/dist/{chunk-RKVUVALV.js → chunk-A3QPMX5M.js} +31 -9
  9. package/dist/chunk-A3QPMX5M.js.map +1 -0
  10. package/dist/{chunk-DVNXEB7V.js → chunk-BVFS3ICC.js} +3 -3
  11. package/dist/chunk-BVFS3ICC.js.map +1 -0
  12. package/dist/{chunk-FTCYY2DO.js → chunk-CPE5ZQXQ.js} +3 -3
  13. package/dist/{chunk-FTCYY2DO.js.map → chunk-CPE5ZQXQ.js.map} +1 -1
  14. package/dist/chunk-DEAPNMKO.js +11 -0
  15. package/dist/chunk-DEAPNMKO.js.map +1 -0
  16. package/dist/{chunk-XWIE5V7R.js → chunk-ETRNSJCR.js} +4 -4
  17. package/dist/{chunk-XWIE5V7R.js.map → chunk-ETRNSJCR.js.map} +1 -1
  18. package/dist/chunk-FXWDDNGD.js +98 -0
  19. package/dist/chunk-FXWDDNGD.js.map +1 -0
  20. package/dist/chunk-GFGOQIEC.js +10 -0
  21. package/dist/chunk-GFGOQIEC.js.map +1 -0
  22. package/dist/{chunk-2R62Q5UK.js → chunk-IAHEYPYJ.js} +3 -3
  23. package/dist/{chunk-2R62Q5UK.js.map → chunk-IAHEYPYJ.js.map} +1 -1
  24. package/dist/{chunk-NGYFBD5G.js → chunk-J5JNLXO7.js} +3 -3
  25. package/dist/{chunk-NGYFBD5G.js.map → chunk-J5JNLXO7.js.map} +1 -1
  26. package/dist/{chunk-72CN3VPY.js → chunk-NFOGYDRS.js} +5 -5
  27. package/dist/{chunk-72CN3VPY.js.map → chunk-NFOGYDRS.js.map} +1 -1
  28. package/dist/{chunk-A73IJ27X.js → chunk-R2YNDRGL.js} +3 -3
  29. package/dist/{chunk-A73IJ27X.js.map → chunk-R2YNDRGL.js.map} +1 -1
  30. package/dist/{chunk-5HVKDHY6.js → chunk-R5NXOPL2.js} +3 -3
  31. package/dist/{chunk-5HVKDHY6.js.map → chunk-R5NXOPL2.js.map} +1 -1
  32. package/dist/chunk-RMBZ7YH7.js +52 -0
  33. package/dist/chunk-RMBZ7YH7.js.map +1 -0
  34. package/dist/{chunk-AIXC33SE.js → chunk-SHXUSTHM.js} +62 -15
  35. package/dist/chunk-SHXUSTHM.js.map +1 -0
  36. package/dist/{chunk-TAKPC6SD.js → chunk-UGTC33VH.js} +4 -4
  37. package/dist/{chunk-TAKPC6SD.js.map → chunk-UGTC33VH.js.map} +1 -1
  38. package/dist/{chunk-EA47MI5Q.js → chunk-VH5MYJ2K.js} +4 -4
  39. package/dist/{chunk-EA47MI5Q.js.map → chunk-VH5MYJ2K.js.map} +1 -1
  40. package/dist/{chunk-2774I242.js → chunk-WZEDIUWR.js} +21 -20
  41. package/dist/chunk-WZEDIUWR.js.map +1 -0
  42. package/dist/{chunk-TGJLXZAU.js → chunk-ZRRET3RP.js} +11 -11
  43. package/dist/chunk-ZRRET3RP.js.map +1 -0
  44. package/dist/{core-CtvAyPpH.d.ts → core-DNDAEhO2.d.ts} +9 -12
  45. package/dist/devtools/index.d.ts +4 -4
  46. package/dist/do/index.d.ts +103 -38
  47. package/dist/do/index.js +40 -21
  48. package/dist/do/index.js.map +1 -1
  49. package/dist/{drive-loop-Dw1sGSsW.d.ts → drive-loop-DlOEv49c.d.ts} +2 -2
  50. package/dist/{durable-effects-Ump5lSdO.d.ts → durable-effects-wLWEdy9H.d.ts} +1 -1
  51. package/dist/effect/index.d.ts +121 -28
  52. package/dist/effect/index.js +45 -31
  53. package/dist/effect/index.js.map +1 -1
  54. package/dist/extension/index.d.ts +3 -3
  55. package/dist/extension/index.js +2 -2
  56. package/dist/extension/index.js.map +1 -1
  57. package/dist/flow/index.d.ts +17 -13
  58. package/dist/flow/index.js +15 -12
  59. package/dist/flow/index.js.map +1 -1
  60. package/dist/idempotency/index.d.ts +3 -3
  61. package/dist/idempotency/index.js +3 -3
  62. package/dist/{index-CrcoVfd_.d.ts → index-9P1PaXIV.d.ts} +2 -2
  63. package/dist/{index-D3NY3VCN.d.ts → index-BBLI2WWN.d.ts} +1 -1
  64. package/dist/{index-Dl71V7kt.d.ts → index-C1WhBZ6a.d.ts} +4 -5
  65. package/dist/{index-CKtEKGyp.d.ts → index-C92SgNWz.d.ts} +3 -3
  66. package/dist/{index-CZZ3HI-Z.d.ts → index-CAsUE_d1.d.ts} +4 -4
  67. package/dist/{index-EIgfl83J.d.ts → index-CO34esWT.d.ts} +2 -2
  68. package/dist/{index-Bk2hBUdK.d.ts → index-COeX9Bmz.d.ts} +11 -9
  69. package/dist/{index-CVU7SK3a.d.ts → index-Cg0QXnzf.d.ts} +2 -2
  70. package/dist/index.d.ts +9 -9
  71. package/dist/index.js +2 -2
  72. package/dist/jev/index.d.ts +15 -15
  73. package/dist/jev/index.js +5 -5
  74. package/dist/jev/index.js.map +1 -1
  75. package/dist/laws-DTtCDDlU.d.ts +135 -0
  76. package/dist/loop-DReKGV1X.d.ts +70 -0
  77. package/dist/{machine-Dtre2TmN.d.ts → machine-C0WhOAyB.d.ts} +7 -7
  78. package/dist/machine-viz/index.d.ts +1 -1
  79. package/dist/machine-viz/index.js +2 -2
  80. package/dist/mem/index.d.ts +4 -3
  81. package/dist/mem/index.js +2 -2
  82. package/dist/mem/index.js.map +1 -1
  83. package/dist/node/index.d.ts +57 -9
  84. package/dist/node/index.js +175 -68
  85. package/dist/node/index.js.map +1 -1
  86. package/dist/otel/index.d.ts +28 -12
  87. package/dist/otel/index.js +25 -21
  88. package/dist/otel/index.js.map +1 -1
  89. package/dist/paginate/index.d.ts +4 -4
  90. package/dist/paginate/index.js +5 -5
  91. package/dist/parity/index.d.ts +11 -15
  92. package/dist/parity/index.js +4 -9
  93. package/dist/parity/index.js.map +1 -1
  94. package/dist/pbt/index.d.ts +279 -67
  95. package/dist/pbt/index.js +299 -58
  96. package/dist/pbt/index.js.map +1 -1
  97. package/dist/persistence/index.d.ts +10 -12
  98. package/dist/persistence/index.js +4 -4
  99. package/dist/promise/index.d.ts +118 -21
  100. package/dist/promise/index.js +6 -4
  101. package/dist/react/index.d.ts +34 -21
  102. package/dist/react/index.js +271 -42
  103. package/dist/react/index.js.map +1 -1
  104. package/dist/resilience/index.d.ts +6 -6
  105. package/dist/resilience/index.js +5 -5
  106. package/dist/{run-fiBe7pOG.d.ts → run-Cnw4qXj2.d.ts} +105 -23
  107. package/dist/{runtime-types-DEluQgGO.d.ts → runtime-types-CP-ykwgf.d.ts} +157 -29
  108. package/dist/testing/effect/index.d.ts +162 -9
  109. package/dist/testing/effect/index.js +110 -10
  110. package/dist/testing/effect/index.js.map +1 -1
  111. package/dist/testing/index.d.ts +6 -8
  112. package/dist/testing/index.js +4 -24
  113. package/dist/testing/index.js.map +1 -1
  114. package/dist/testing/promise/index.d.ts +4 -4
  115. package/dist/testing/promise/index.js +5 -5
  116. package/dist/timing/index.d.ts +4 -4
  117. package/dist/timing/index.js +4 -4
  118. package/dist/{types-CXNzlbAg.d.ts → types-S53WDy_h.d.ts} +1 -1
  119. package/dist/work-queue/index.d.ts +4 -4
  120. package/dist/work-queue/index.js +2 -2
  121. package/package.json +19 -17
  122. package/dist/chunk-2774I242.js.map +0 -1
  123. package/dist/chunk-AIXC33SE.js.map +0 -1
  124. package/dist/chunk-DVNXEB7V.js.map +0 -1
  125. package/dist/chunk-HX3C6LDK.js +0 -34
  126. package/dist/chunk-HX3C6LDK.js.map +0 -1
  127. package/dist/chunk-JAKM53JF.js.map +0 -1
  128. package/dist/chunk-RKVUVALV.js.map +0 -1
  129. package/dist/chunk-TGJLXZAU.js.map +0 -1
  130. package/dist/chunk-UHAQ4PI6.js.map +0 -1
package/dist/pbt/index.js CHANGED
@@ -1,6 +1,8 @@
1
- import '../chunk-DVNXEB7V.js';
2
- import { replay, applyCell, msgKeysOf } from '../chunk-RKVUVALV.js';
3
- import * as fc from 'fast-check';
1
+ import { MAX_PICK, resolveGuided, foldEvents, lawTerminates, lawInvariant, lawTrace } from '../chunk-FXWDDNGD.js';
2
+ export { foldEvents, lawInvariant, lawTerminates, lawTrace } from '../chunk-FXWDDNGD.js';
3
+ import '../chunk-BVFS3ICC.js';
4
+ import { msgKeysOf, structuralHash } from '../chunk-A3QPMX5M.js';
5
+ import * as fc3 from 'fast-check';
4
6
 
5
7
  // src/pbt/arbitraries/ctx.ts
6
8
  function stubCtxThrowingProxy() {
@@ -33,93 +35,332 @@ function arbMsg(table, opts) {
33
35
  arbitrary: arb,
34
36
  weight: weights?.[key] ?? 1
35
37
  }));
36
- return fc.oneof(...weighted);
38
+ return fc3.oneof(...weighted);
37
39
  }
38
40
  function arbConstantMsg(type) {
39
- return fc.constant({ type });
41
+ return fc3.constant({ type });
40
42
  }
41
43
  function arbRecordMsg(type, fields) {
42
44
  const recordArbitraries = {
43
- type: fc.constant(type),
45
+ type: fc3.constant(type),
44
46
  ...fields
45
47
  };
46
- return fc.record(recordArbitraries);
48
+ return fc3.record(recordArbitraries);
47
49
  }
48
50
  function arbMsgSequence(msgArb, opts) {
49
51
  const minLength = opts?.minLength ?? 0;
50
52
  const maxLength = opts?.maxLength ?? 30;
51
53
  const prefix = opts?.prefix ?? [];
52
- const tail = fc.array(msgArb, { minLength, maxLength });
54
+ const tail = fc3.array(msgArb, { minLength, maxLength, size: opts?.size });
53
55
  if (prefix.length === 0) return tail;
54
56
  return tail.map((arr) => [...prefix, ...arr]);
55
57
  }
56
- function arbGuidedSequence(_machine, _ctx, _cells, _opts) {
57
- throw new Error(
58
- "@demlik/tea/pbt: arbGuidedSequence is not implemented in v1. Use arbMsgSequence with an unguided arbMsg table for now; states that don't accept a given msg should noop in the reducer (mapped-type discipline)."
58
+ function arbGuidedSequence(machine, ctx, cells, opts) {
59
+ const outside = Object.values(cells.outside ?? {});
60
+ const answers = Object.entries(cells.answers ?? {});
61
+ const answerers = answers.map(
62
+ ([cmdType, cell]) => ({ cmdType, make: cell.make })
59
63
  );
64
+ const arms = [];
65
+ if (outside.length > 0) {
66
+ arms.push({
67
+ weight: 1,
68
+ arbitrary: fc3.oneof(...outside).map((msg) => ({ kind: "outside", msg }))
69
+ });
70
+ }
71
+ if (answers.length > 0) {
72
+ arms.push({
73
+ weight: 2,
74
+ arbitrary: fc3.tuple(
75
+ fc3.nat(MAX_PICK),
76
+ fc3.tuple(...answers.map(([, cell]) => cell.draw))
77
+ ).map(
78
+ ([pick, values]) => ({
79
+ kind: "answer",
80
+ pick,
81
+ values
82
+ })
83
+ )
84
+ });
85
+ }
86
+ if (arms.length === 0) {
87
+ throw new Error(
88
+ "@demlik/tea/pbt: arbGuidedSequence got no cells, in `outside` or `answers`, so it could only draw empty lists."
89
+ );
90
+ }
91
+ const loaded = opts?.loaded ?? null;
92
+ return fc3.array(fc3.oneof(...arms), {
93
+ maxLength: opts?.maxLength ?? 60,
94
+ size: opts?.size ?? "max"
95
+ }).map((events) => resolveGuided(machine, ctx, loaded, answerers, events));
60
96
  }
61
97
 
62
- // src/pbt/runners/replay-fold.ts
63
- function foldEvents(machine, ctx, loaded, msgs) {
64
- const { state: initialState } = replay(machine, {
65
- msgs: [],
66
- ctx,
67
- loaded: loaded ?? null
68
- });
69
- const states = [initialState];
70
- const steps = [];
71
- let current = initialState;
72
- for (const msg of msgs) {
73
- const [next, emitted] = applyCell(machine, current, msg);
74
- steps.push({ prev: current, msg, next, cmds: [...emitted] });
75
- states.push(next);
76
- current = next;
98
+ // src/pbt/runners/msg-tally.ts
99
+ function outline(value) {
100
+ if (Array.isArray(value)) return "[";
101
+ if (typeof value === "object" && value !== null) {
102
+ const proto = Object.getPrototypeOf(value);
103
+ if (proto === Object.prototype || proto === null) return "{";
104
+ }
105
+ return structuralHash(value);
106
+ }
107
+ function differs(a, b) {
108
+ if (a === b) return false;
109
+ const shape = outline(a);
110
+ if (shape !== outline(b)) return true;
111
+ if (shape === "[") return listsDiffer(a, b);
112
+ if (shape === "{") {
113
+ return recordsDiffer(
114
+ a,
115
+ b
116
+ );
117
+ }
118
+ return false;
119
+ }
120
+ var slotsOf = (list) => list.length === 1 && !(0 in list) ? [] : list;
121
+ function listsDiffer(a, b) {
122
+ const left = slotsOf(a);
123
+ const right = slotsOf(b);
124
+ if (left.length !== right.length) return true;
125
+ for (let i = 0; i < left.length; i++) {
126
+ if (i in left !== i in right || differs(left[i], right[i])) return true;
77
127
  }
78
- return { states, steps, finalState: current };
128
+ return false;
79
129
  }
130
+ var seenAt = (record2, key) => Object.prototype.propertyIsEnumerable.call(record2, key) ? record2[key] : void 0;
131
+ function recordsDiffer(a, b) {
132
+ for (const key of /* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])) {
133
+ if (differs(seenAt(a, key), seenAt(b, key))) return true;
134
+ }
135
+ return false;
136
+ }
137
+ function classify(step) {
138
+ if (step.cmds.length > 0) return { acted: true, refusal: null };
139
+ try {
140
+ return { acted: differs(step.prev, step.next), refusal: null };
141
+ } catch (refusal) {
142
+ return { acted: true, refusal };
143
+ }
144
+ }
145
+ var MsgTally = class {
146
+ #counts = /* @__PURE__ */ new Map();
147
+ #closed = false;
148
+ #refusal = null;
149
+ /** @param msgTypes The machine's Msg types, so one never drawn still reads zero. */
150
+ constructor(msgTypes) {
151
+ for (const type of msgTypes) this.#counts.set(type, { drawn: 0, acted: 0 });
152
+ }
153
+ /** Count one list's steps, unless the run has already failed. */
154
+ add(steps) {
155
+ if (this.#closed) return;
156
+ for (const step of steps) {
157
+ const { acted, refusal } = classify(step);
158
+ const count = this.#counts.get(step.msg.type) ?? { drawn: 0, acted: 0 };
159
+ this.#counts.set(step.msg.type, {
160
+ drawn: count.drawn + 1,
161
+ acted: count.acted + (acted ? 1 : 0)
162
+ });
163
+ this.#refusal ??= refusal;
164
+ }
165
+ }
166
+ /** The run has failed. Whatever comes next is shrinking. */
167
+ close() {
168
+ this.#closed = true;
169
+ }
170
+ /** Each Msg type's count: the machine's types first, then any other drawn. */
171
+ get counts() {
172
+ return new Map(this.#counts);
173
+ }
174
+ /**
175
+ * What `structuralHash` threw on the first value the comparison reached and
176
+ * couldn't read. Such a step counts as acted, since nothing shows it didn't, so
177
+ * "never acted" can't be trusted here.
178
+ */
179
+ get refusal() {
180
+ return this.#refusal;
181
+ }
182
+ /** The Msg types at zero acted, each with what it drew. */
183
+ get neverActed() {
184
+ return [...this.#counts].filter(([, count]) => count.acted === 0);
185
+ }
186
+ };
80
187
 
81
188
  // src/pbt/runners/property.ts
82
- function resolveFcParams(opts) {
83
- return {
84
- numRuns: opts?.numRuns ?? 200,
85
- ...opts?.seed !== void 0 ? { seed: opts.seed } : {}
189
+ var PropertyFailure = class extends Error {
190
+ constructor(report, run, options) {
191
+ super(report, options);
192
+ this.run = run;
193
+ }
194
+ run;
195
+ name = "PropertyFailure";
196
+ _tag = "PropertyFailure";
197
+ };
198
+ var BrokenLaw = class extends Error {
199
+ constructor(report, reason) {
200
+ super(`${report}
201
+ reason: ${reason}`);
202
+ this.report = report;
203
+ this.reason = reason;
204
+ this.name = "Error";
205
+ }
206
+ report;
207
+ reason;
208
+ toString() {
209
+ return `${this.name}: ${this.report}`;
210
+ }
211
+ };
212
+ function assertHolds(answer, report) {
213
+ if (answer === true || answer === null) return;
214
+ if (answer === false || answer === "") throw new Error(report());
215
+ throw new BrokenLaw(report(), answer);
216
+ }
217
+ function assertLaw(runner, broken) {
218
+ if (broken === null) return;
219
+ const report = `${runner}: ${broken.report}`;
220
+ throw broken.reason === null ? new Error(report) : new BrokenLaw(report, broken.reason);
221
+ }
222
+ function cmdFault(cmd, declared) {
223
+ const { type } = Object(cmd);
224
+ if (typeof cmd !== "object" || typeof type !== "string") {
225
+ return `${fc3.stringify(cmd)} isn't a Cmd: it has no string \`type\``;
226
+ }
227
+ if (declared === null || declared.has(type)) return null;
228
+ return `${fc3.stringify(cmd)} isn't in machine.cmds: [${[...declared].join(", ")}]`;
229
+ }
230
+ function assertSentCmds({ initCmds, steps }, declared) {
231
+ for (const cmd of initCmds) {
232
+ assertHolds(cmdFault(cmd, declared), () => "init sent a bad Cmd");
233
+ }
234
+ for (const { msg, cmds } of steps) {
235
+ for (const cmd of cmds) {
236
+ assertHolds(
237
+ cmdFault(cmd, declared),
238
+ () => `step msg=${fc3.stringify(msg)} sent a bad Cmd`
239
+ );
240
+ }
241
+ }
242
+ }
243
+ function isArbitrary(loaded) {
244
+ if (typeof loaded !== "object" || loaded === null) return false;
245
+ const { generate, shrink, canShrinkWithoutContext } = loaded;
246
+ return typeof generate === "function" && typeof shrink === "function" && typeof canShrinkWithoutContext === "function";
247
+ }
248
+ function withoutUndefined(settings) {
249
+ return Object.fromEntries(
250
+ Object.entries(settings).filter(([, value]) => value !== void 0)
251
+ );
252
+ }
253
+ function causeOf(details) {
254
+ const { errorWithCause, includeErrorInReport } = details.runConfiguration;
255
+ const major = Number(fc3.__version.split(".")[0]);
256
+ return (major >= 4 ? !includeErrorInReport : errorWithCause) ? { cause: details.errorInstance } : void 0;
257
+ }
258
+ function settle(details, tally) {
259
+ const run = {
260
+ numRuns: details.numRuns,
261
+ numShrinks: details.numShrinks,
262
+ seed: details.seed,
263
+ path: details.counterexamplePath,
264
+ msgCounts: tally.counts
86
265
  };
266
+ const { reporter } = fc3.readConfigureGlobal();
267
+ if (reporter) {
268
+ reporter(details);
269
+ return run;
270
+ }
271
+ const report = fc3.defaultReportMessage(details);
272
+ if (report === void 0) return run;
273
+ const cause = causeOf(details);
274
+ const broken = details.errorInstance;
275
+ throw new PropertyFailure(
276
+ cause && broken instanceof BrokenLaw ? `${report}
277
+
278
+ reason: ${broken.reason}` : report,
279
+ run,
280
+ cause
281
+ );
87
282
  }
88
- function runProperty(machine, ctx, seqArb, opts, check) {
89
- fc.assert(
90
- fc.property(seqArb, (msgs) => {
91
- check(foldEvents(machine, ctx, opts?.loaded ?? null, msgs));
92
- }),
93
- resolveFcParams(opts)
283
+ function assertEveryTypeActed(run, tally) {
284
+ const { refusal, neverActed } = tally;
285
+ const ranOver = `after ${run.numRuns} runs, seed ${run.seed}`;
286
+ if (refusal !== null) {
287
+ const why = refusal instanceof Error ? refusal.message : String(refusal);
288
+ throw new PropertyFailure(
289
+ `Property failed ${ranOver}: failOnNeverActed can't tell what acted, because a state isn't plain data.
290
+
291
+ ${why}`,
292
+ run
293
+ );
294
+ }
295
+ if (neverActed.length === 0) return;
296
+ const named = neverActed.map(
297
+ ([type, { drawn }]) => ` ${type} (drawn ${drawn})`
298
+ );
299
+ throw new PropertyFailure(
300
+ `Property failed ${ranOver}: ${neverActed.length} Msg type(s) never acted:
301
+ ${named.join("\n")}`,
302
+ run
94
303
  );
95
304
  }
96
- function propertyTerminates(machine, ctx, seqArb, terminal, opts) {
97
- runProperty(machine, ctx, seqArb, opts, ({ finalState }) => {
98
- if (!terminal(finalState)) {
99
- throw new Error(
100
- `propertyTerminates: final state did not match terminal predicate. Final: ${JSON.stringify(finalState)}`
101
- );
305
+ function runProperty(machine, ctx, seqArb, opts, check2) {
306
+ const { loaded, failOnNeverActed, failOnUndeclaredCmd, ...settings } = opts ?? {};
307
+ const params = {
308
+ ...withoutUndefined(settings),
309
+ numRuns: settings.numRuns ?? 200
310
+ };
311
+ const tally = new MsgTally(msgKeysOf(machine));
312
+ const declared = failOnUndeclaredCmd && machine.cmds ? new Set(machine.cmds.map((def) => def.cmdType)) : null;
313
+ const runList = (msgs, start) => {
314
+ let steps = [];
315
+ try {
316
+ const result = foldEvents(machine, ctx, start, msgs);
317
+ steps = result.steps;
318
+ assertSentCmds(result, declared);
319
+ check2(result);
320
+ } catch (error) {
321
+ if (!fc3.PreconditionFailure.isFailure(error)) {
322
+ tally.add(steps);
323
+ tally.close();
324
+ }
325
+ throw error;
102
326
  }
327
+ tally.add(steps);
328
+ };
329
+ const checkActed = failOnNeverActed && !settings.path;
330
+ const finish = (details) => {
331
+ const run = settle(details, tally);
332
+ if (checkActed && !details.failed) assertEveryTypeActed(run, tally);
333
+ return run;
334
+ };
335
+ return isArbitrary(loaded) ? finish(
336
+ fc3.check(
337
+ fc3.property(seqArb, loaded, (msgs, drawn) => {
338
+ runList(msgs, drawn);
339
+ }),
340
+ params
341
+ )
342
+ ) : finish(
343
+ fc3.check(
344
+ fc3.property(seqArb, (msgs) => {
345
+ runList(msgs, loaded ?? null);
346
+ }),
347
+ params
348
+ )
349
+ );
350
+ }
351
+ function propertyTerminates(machine, ctx, seqArb, terminal, opts) {
352
+ return runProperty(machine, ctx, seqArb, opts, (fold) => {
353
+ assertLaw("propertyTerminates", lawTerminates(fold, terminal));
103
354
  });
104
355
  }
105
356
  function propertyInvariant(machine, ctx, seqArb, invariant, opts) {
106
- runProperty(machine, ctx, seqArb, opts, ({ steps }) => {
107
- for (const step of steps) {
108
- if (!invariant(step)) {
109
- throw new Error(
110
- `propertyInvariant: failed at step msg=${JSON.stringify(step.msg)} prev=${JSON.stringify(step.prev)} next=${JSON.stringify(step.next)} cmds=${JSON.stringify(step.cmds)}`
111
- );
112
- }
113
- }
357
+ return runProperty(machine, ctx, seqArb, opts, (fold) => {
358
+ assertLaw("propertyInvariant", lawInvariant(fold, invariant));
114
359
  });
115
360
  }
116
361
  function propertyTrace(machine, ctx, seqArb, predicate, opts) {
117
- runProperty(machine, ctx, seqArb, opts, ({ steps, finalState }) => {
118
- if (!predicate(steps, finalState)) {
119
- throw new Error(
120
- `propertyTrace: predicate failed on trace length=${steps.length}, final=${JSON.stringify(finalState)}`
121
- );
122
- }
362
+ return runProperty(machine, ctx, seqArb, opts, (fold) => {
363
+ assertLaw("propertyTrace", lawTrace(fold, predicate));
123
364
  });
124
365
  }
125
366
 
@@ -128,6 +369,6 @@ function msgTypeKeys(machine) {
128
369
  return msgKeysOf(machine);
129
370
  }
130
371
 
131
- export { arbConstantMsg, arbGuidedSequence, arbMsg, arbMsgSequence, arbRecordMsg, foldEvents, msgTypeKeys, propertyInvariant, propertyTerminates, propertyTrace, stubCtxThrowingProxy };
372
+ export { PropertyFailure, arbConstantMsg, arbGuidedSequence, arbMsg, arbMsgSequence, arbRecordMsg, msgTypeKeys, propertyInvariant, propertyTerminates, propertyTrace, stubCtxThrowingProxy };
132
373
  //# sourceMappingURL=index.js.map
133
374
  //# sourceMappingURL=index.js.map