@elabs-ai/components-process 4.2.0 → 5.0.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 (144) hide show
  1. package/README.md +8 -1
  2. package/dist/core/index.d.ts +801 -3
  3. package/dist/core/index.js +1334 -0
  4. package/dist/core/index.js.map +1 -1
  5. package/dist/index.d.ts +1889 -34
  6. package/dist/index.js +5512 -196
  7. package/dist/index.js.map +1 -1
  8. package/dist/test/index.d.ts +223 -5
  9. package/dist/test/index.js +346 -191
  10. package/dist/test/index.js.map +1 -1
  11. package/package.json +14 -13
  12. package/src/__contract__/case-table.contract.test.tsx +49 -0
  13. package/src/__contract__/compare-kpi-strip.contract.test.tsx +49 -0
  14. package/src/__contract__/conformance-overlay.contract.test.tsx +49 -0
  15. package/src/__contract__/happy-path-editor.contract.test.tsx +49 -0
  16. package/src/__contract__/violation-list.contract.test.tsx +49 -0
  17. package/src/abstraction-controls/abstraction-controls-per-type.test.tsx +80 -0
  18. package/src/abstraction-controls/abstraction-controls.stories.tsx +43 -1
  19. package/src/abstraction-controls/abstraction-controls.tsx +198 -5
  20. package/src/case-table/case-table.stories.tsx +89 -0
  21. package/src/case-table/case-table.test.tsx +148 -0
  22. package/src/case-table/case-table.tsx +144 -0
  23. package/src/case-table/columns.ts +116 -0
  24. package/src/case-table/index.ts +11 -0
  25. package/src/case-timeline/case-timeline-model.test.ts +72 -0
  26. package/src/case-timeline/case-timeline-model.ts +112 -0
  27. package/src/case-timeline/case-timeline.stories.tsx +94 -0
  28. package/src/case-timeline/case-timeline.test.tsx +51 -0
  29. package/src/case-timeline/case-timeline.tsx +109 -0
  30. package/src/case-timeline/index.ts +9 -0
  31. package/src/conformance-overlay/conformance-fixture.ts +59 -0
  32. package/src/conformance-overlay/conformance-legend.tsx +109 -0
  33. package/src/conformance-overlay/conformance-overlay.stories.tsx +116 -0
  34. package/src/conformance-overlay/conformance-overlay.test.tsx +88 -0
  35. package/src/conformance-overlay/conformance-overlay.tsx +107 -0
  36. package/src/conformance-overlay/conformance-state.test.ts +79 -0
  37. package/src/conformance-overlay/conformance-state.ts +220 -0
  38. package/src/conformance-overlay/index.ts +4 -0
  39. package/src/core/activity-color-scale.test.ts +107 -0
  40. package/src/core/activity-color-scale.ts +133 -0
  41. package/src/core/adapters/ocel.test.ts +112 -0
  42. package/src/core/adapters/ocel.ts +359 -0
  43. package/src/core/adapters/xes.test.ts +293 -0
  44. package/src/core/adapters/xes.ts +384 -0
  45. package/src/core/cases-from-log.test.ts +72 -0
  46. package/src/core/cases-from-log.ts +85 -0
  47. package/src/core/conformance.test.ts +80 -0
  48. package/src/core/conformance.ts +91 -0
  49. package/src/core/diff-graphs.test.ts +151 -0
  50. package/src/core/diff-graphs.ts +118 -0
  51. package/src/core/discover-object-centric-graph.test.ts +94 -0
  52. package/src/core/discover-object-centric-graph.ts +296 -0
  53. package/src/core/fixtures/ocel-sample.ts +82 -0
  54. package/src/core/fixtures/sample.xes +68 -0
  55. package/src/core/index.ts +113 -0
  56. package/src/core/reference-model.test.ts +43 -0
  57. package/src/core/reference-model.ts +116 -0
  58. package/src/core/replay-timeline.test.ts +161 -0
  59. package/src/core/replay-timeline.ts +260 -0
  60. package/src/core/segments.test.ts +185 -0
  61. package/src/core/segments.ts +153 -0
  62. package/src/core/token-replay.test.ts +218 -0
  63. package/src/core/token-replay.ts +456 -0
  64. package/src/core/types.ts +2 -2
  65. package/src/dotted-chart/compute-dots.test.ts +176 -0
  66. package/src/dotted-chart/compute-dots.ts +241 -0
  67. package/src/dotted-chart/dotted-chart-labels.ts +93 -0
  68. package/src/dotted-chart/dotted-chart.stories.tsx +182 -0
  69. package/src/dotted-chart/dotted-chart.test.tsx +135 -0
  70. package/src/dotted-chart/dotted-chart.tsx +841 -0
  71. package/src/dotted-chart/index.ts +23 -0
  72. package/src/dotted-chart/use-element-size.ts +33 -0
  73. package/src/happy-path-editor/happy-path-editor-context.ts +81 -0
  74. package/src/happy-path-editor/happy-path-editor.stories.tsx +116 -0
  75. package/src/happy-path-editor/happy-path-editor.test.tsx +142 -0
  76. package/src/happy-path-editor/happy-path-editor.tsx +239 -0
  77. package/src/happy-path-editor/happy-path-step-node.tsx +175 -0
  78. package/src/happy-path-editor/index.ts +4 -0
  79. package/src/index.ts +51 -1
  80. package/src/performance-spectrum/aggregate-segments.test.ts +107 -0
  81. package/src/performance-spectrum/aggregate-segments.ts +174 -0
  82. package/src/performance-spectrum/index.ts +25 -0
  83. package/src/performance-spectrum/performance-spectrum-context.tsx +116 -0
  84. package/src/performance-spectrum/performance-spectrum.stories.tsx +128 -0
  85. package/src/performance-spectrum/performance-spectrum.test.tsx +190 -0
  86. package/src/performance-spectrum/performance-spectrum.tsx +870 -0
  87. package/src/process-compare/compare-kpi-strip.stories.tsx +48 -0
  88. package/src/process-compare/compare-kpi-strip.tsx +94 -0
  89. package/src/process-compare/compare-model.ts +83 -0
  90. package/src/process-compare/compare-side.tsx +42 -0
  91. package/src/process-compare/diff-to-graph.ts +104 -0
  92. package/src/process-compare/index.ts +23 -0
  93. package/src/process-compare/process-compare.stories.tsx +184 -0
  94. package/src/process-compare/process-compare.test.tsx +224 -0
  95. package/src/process-compare/process-compare.tsx +251 -0
  96. package/src/process-explorer.stories.tsx +1 -1
  97. package/src/process-filter-bar/index.ts +2 -0
  98. package/src/process-filter-bar/process-filter-bar.stories.tsx +156 -0
  99. package/src/process-filter-bar/process-filter-bar.test.tsx +201 -0
  100. package/src/process-filter-bar/process-filter-bar.tsx +167 -0
  101. package/src/process-kpi-strip/process-kpi-strip.stories.tsx +47 -0
  102. package/src/process-kpi-strip/process-kpi-strip.test.tsx +67 -0
  103. package/src/process-kpi-strip/process-kpi-strip.tsx +148 -8
  104. package/src/process-map/activity-accent.ts +25 -0
  105. package/src/process-map/index.ts +1 -0
  106. package/src/process-map/map-model.test.ts +16 -0
  107. package/src/process-map/map-model.ts +323 -1
  108. package/src/process-map/object-centric-map.test.tsx +132 -0
  109. package/src/process-map/process-activity-node.tsx +152 -14
  110. package/src/process-map/process-map-object-centric.stories.tsx +219 -0
  111. package/src/process-map/process-map.stories.tsx +64 -0
  112. package/src/process-map/process-map.tsx +240 -16
  113. package/src/process-map/process-transition-edge.test.tsx +47 -0
  114. package/src/process-map/process-transition-edge.tsx +134 -7
  115. package/src/process-map/use-process-layout.ts +30 -9
  116. package/src/process-replay/congestion-heat.tsx +107 -0
  117. package/src/process-replay/index.ts +14 -0
  118. package/src/process-replay/process-replay.stories.tsx +168 -0
  119. package/src/process-replay/process-replay.test.tsx +170 -0
  120. package/src/process-replay/process-replay.tsx +285 -0
  121. package/src/process-replay/replay-controls.tsx +147 -0
  122. package/src/process-replay/replay-format.ts +83 -0
  123. package/src/process-replay/replay-tokens-context.ts +30 -0
  124. package/src/process-replay/use-controllable-value.ts +30 -0
  125. package/src/templates-process-explorer.stories.tsx +1304 -0
  126. package/src/test/contract.test.ts +66 -0
  127. package/src/test/contract.ts +107 -6
  128. package/src/test/doubles.test.tsx +87 -1
  129. package/src/test/doubles.tsx +174 -3
  130. package/src/test/index.ts +25 -1
  131. package/src/use-process-explorer/use-process-explorer.test.ts +44 -0
  132. package/src/use-process-explorer/use-process-explorer.ts +34 -2
  133. package/src/variant-explorer/coverage-bar.tsx +36 -0
  134. package/src/variant-explorer/index.ts +16 -0
  135. package/src/variant-explorer/sequence-chips.tsx +103 -0
  136. package/src/variant-explorer/variant-explorer-model.ts +42 -0
  137. package/src/variant-explorer/variant-explorer.stories.tsx +226 -0
  138. package/src/variant-explorer/variant-explorer.test.tsx +302 -0
  139. package/src/variant-explorer/variant-explorer.tsx +567 -0
  140. package/src/variant-explorer/variant-row.tsx +137 -0
  141. package/src/violation-list/index.ts +2 -0
  142. package/src/violation-list/violation-list.stories.tsx +73 -0
  143. package/src/violation-list/violation-list.test.tsx +84 -0
  144. package/src/violation-list/violation-list.tsx +259 -0
@@ -11,10 +11,19 @@ type ProcessSelection = null | {
11
11
  };
12
12
  /** What {@link assertProcessContract} checks for one double. */
13
13
  interface ProcessContractSpec {
14
- /** Name of the prop carrying the double's primary data payload. */
15
- dataProp: "graph" | "variants";
14
+ /**
15
+ * Name of the prop carrying the double's primary data payload. `conformance` is a
16
+ * `ConformanceResult` and `value` a `HappyPath` (RM-062).
17
+ */
18
+ dataProp: "graph" | "variants" | "log" | "conformance" | "value";
16
19
  /** Other props the real component requires; the double must not silently accept `undefined`. */
17
20
  requiredProps?: string[];
21
+ /**
22
+ * PerformanceSpectrum — RM-060: the `order` prop (default `"frequency"`) must resolve to
23
+ * at least one segment that actually occurs in `log`, or the real view renders only its
24
+ * empty panel — almost always a test wired to the wrong activity names.
25
+ */
26
+ segmentOrder?: boolean;
18
27
  }
19
28
  /** Thrown by {@link assertProcessContract} when a double is used with an invalid prop shape. */
20
29
  declare class ProcessContractError extends Error {
@@ -47,8 +56,8 @@ declare function readProcessDoubleProps(el: Element): ProcessDoublePayload | nul
47
56
  * additive: a required field added here is a breaking change for five items at once.
48
57
  *
49
58
  * NOTHING in this module — or anywhere under `src/core/` — may import React, React Flow,
50
- * visx, d3 or an `@elabs-ai/components-*` package. See `.claude/rules/process-components.md`
51
- * and `pnpm process:reuse:check`.
59
+ * visx, d3 or an `@elabs-ai/components-*` package. See `.claude/rules/data.md` ("Process
60
+ * mining" section) and `pnpm check --rule process-reuse`.
52
61
  */
53
62
  /**
54
63
  * One raw row of an event log, before normalization.
@@ -164,6 +173,137 @@ interface Variant {
164
173
  duration: DurationStats;
165
174
  }
166
175
 
176
+ /**
177
+ * Reference model — RM-061.
178
+ *
179
+ * A HAPPY PATH (the prescribed sequence of activities an owner or auditor expects) lifted
180
+ * to the smallest workflow-net-like structure token replay can run against: one place
181
+ * between consecutive steps, one visible transition per step, a silent SKIP transition
182
+ * beside every optional step and a SELF-LOOP transition after every repeatable one.
183
+ *
184
+ * Scope boundary (analysis §9 risk 2): this is deliberately NOT a general Petri-net
185
+ * importer. No BPMN, no parallel gateways, no alignments beyond skip/repeat. A host that
186
+ * needs full alignment-based conformance brings a backend; this module never grows one.
187
+ *
188
+ * Framework-free, deterministic: no React, no `@elabs-ai/components-*` import.
189
+ */
190
+ /** One prescribed step of a happy path. */
191
+ interface HappyPathStep {
192
+ /** Activity name, matched exactly against `EventRow.activity`. */
193
+ activity: string;
194
+ /** The step may be left out without a deviation (a silent skip arc is added). */
195
+ optional?: boolean;
196
+ /** The step may run several times in a row without a deviation (a self-loop is added). */
197
+ repeatable?: boolean;
198
+ }
199
+ /** A prescribed process: an ordered list of steps. */
200
+ interface HappyPath {
201
+ id: string;
202
+ label: string;
203
+ steps: HappyPathStep[];
204
+ }
205
+
206
+ /**
207
+ * Token-based replay — RM-061.
208
+ *
209
+ * Replays each case of an event log against a {@link ReplayModel} (a lifted happy path)
210
+ * and scores it with the classic produced / consumed / missing / remaining token counts:
211
+ *
212
+ * fitness = ½ · (1 − missing / consumed) + ½ · (1 − remaining / produced)
213
+ *
214
+ * The replay procedure — seed the initial marking, fire an enabled transition per event,
215
+ * enable a disabled one through silent transitions first, force-insert missing tokens
216
+ * only when that fails, then consume the final marking and count what is left over —
217
+ * follows the token-based replay algorithm published in pm4js (BSD-3-Clause, credited in
218
+ * `scripts/attributions.sources.json`). It is re-typed in TypeScript for the restricted
219
+ * nets `liftHappyPath` builds; no pm4js code is copied, and nothing here derives from the
220
+ * AGPL Python reference implementation.
221
+ *
222
+ * Deviation typing is this module's own layer on top of the counts: every forced token
223
+ * (and every unreachable final token) is explained by at least one
224
+ * {@link Deviation}, so a violation list can say WHY a case lost fitness.
225
+ *
226
+ * Scope boundary (analysis §9 risk 2): no alignment search. Replay is greedy and
227
+ * single-pass per trace.
228
+ *
229
+ * Framework-free, deterministic: no React, no `@elabs-ai/components-*` import.
230
+ */
231
+
232
+ /**
233
+ * Why a case lost fitness.
234
+ *
235
+ * - `undesired` — the activity is not in the model at all.
236
+ * - `skipped` — a required modelled activity was jumped over and never observed in the case.
237
+ * - `wrongOrder` — the activity is modelled but its preceding place was unmarked, and the
238
+ * gap is not explained by an unobserved step (it ran too early, too late, or again).
239
+ * - `wrongStart` — the first event of the case is not one the initial marking enables.
240
+ * - `incomplete` — the case ended before reaching the model's final marking.
241
+ */
242
+ type DeviationType = "undesired" | "skipped" | "wrongOrder" | "wrongStart" | "incomplete";
243
+ /** One deviation found while replaying a case. */
244
+ interface Deviation {
245
+ type: DeviationType;
246
+ /**
247
+ * The activity the deviation is about: the observed event for `undesired`/`wrongOrder`/
248
+ * `wrongStart`, the missing step for `skipped`, the last observed event for `incomplete`.
249
+ */
250
+ activity?: string;
251
+ /** The activity the model expected next at that point, when one is determinable. */
252
+ expected?: string;
253
+ /**
254
+ * Zero-based index into the case's ordered trace of the event where the deviation was
255
+ * detected. `incomplete` uses the trace length (the position after the last event).
256
+ */
257
+ at: number;
258
+ }
259
+ /** Replay result for one case. */
260
+ interface TraceReplayResult {
261
+ caseId: string;
262
+ produced: number;
263
+ consumed: number;
264
+ missing: number;
265
+ remaining: number;
266
+ /** `½(1 − missing/consumed) + ½(1 − remaining/produced)`, in `[0, 1]`. */
267
+ fitness: number;
268
+ deviations: Deviation[];
269
+ }
270
+
271
+ /**
272
+ * Conformance model — RM-061.
273
+ *
274
+ * The log-level result of replaying an event log against a reference model
275
+ * ({@link ConformanceResult}, produced by `tokenReplay`) and the fitness-over-time series a
276
+ * KPI sparkline plots ({@link conformanceRateSeries}).
277
+ *
278
+ * Scope boundary (analysis §9 risk 2): token replay against a lifted happy path only — no
279
+ * alignments, no BPMN import. A host needing either brings a backend.
280
+ *
281
+ * Framework-free, deterministic: no React, no `Date.now()`, no `@elabs-ai/components-*`
282
+ * import.
283
+ */
284
+
285
+ /** Log-level conformance of an event log against a reference model. */
286
+ interface ConformanceResult {
287
+ /** Mean trace fitness in `[0, 1]`; `0` for an empty log. */
288
+ overallFitness: number;
289
+ /** One result per case, in the log's case order. */
290
+ traces: TraceReplayResult[];
291
+ /** Total deviations per type across all cases; every type is present. */
292
+ deviationCounts: Record<DeviationType, number>;
293
+ /** Deviations charged to each activity. Sums to the total deviation count. */
294
+ perActivity: Record<string, {
295
+ deviations: number;
296
+ }>;
297
+ /**
298
+ * Deviations charged to each OBSERVED directly-follows edge, keyed
299
+ * `source + EDGE_KEY_SEPARATOR + target` — the same key `discoverGraph` gives the edge.
300
+ * Sums to at most the total deviation count.
301
+ */
302
+ perEdge: Record<string, {
303
+ deviations: number;
304
+ }>;
305
+ }
306
+
167
307
  interface DoubleOwnProps extends HTMLAttributes<HTMLDivElement> {
168
308
  selection?: ProcessSelection;
169
309
  onSelectionChange?: (selection: ProcessSelection) => void;
@@ -183,6 +323,84 @@ declare const ProcessMapDouble: react.ForwardRefExoticComponent<ProcessMapDouble
183
323
  declare const VariantExplorerDouble: react.ForwardRefExoticComponent<VariantExplorerDoubleProps & react.RefAttributes<HTMLDivElement>>;
184
324
  /** Stand-in for the future `ProcessKpiStrip` (RM-054). */
185
325
  declare const ProcessKpiStripDouble: react.ForwardRefExoticComponent<ProcessKpiStripDoubleProps & react.RefAttributes<HTMLDivElement>>;
326
+ interface DottedChartDoubleProps extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect"> {
327
+ log: EventLog;
328
+ selectedCaseIds?: readonly string[];
329
+ onSelect?: (caseIds: string[]) => void;
330
+ }
331
+ /** Stand-in for `DottedChart` (RM-059). Asserts a non-empty `log.events` with parsable timestamps. */
332
+ declare const DottedChartDouble: react.ForwardRefExoticComponent<DottedChartDoubleProps & react.RefAttributes<HTMLDivElement>>;
333
+ interface PerformanceSpectrumDoubleProps extends HTMLAttributes<HTMLDivElement> {
334
+ log: EventLog;
335
+ /** Explicit segments, `"frequency"` (the default) or `{ variantId }` — as the real prop. */
336
+ order?: Array<{
337
+ from: string;
338
+ to: string;
339
+ label?: string;
340
+ }> | "frequency" | {
341
+ variantId: string;
342
+ };
343
+ segmentLimit?: number;
344
+ mode?: "lines" | "aggregated";
345
+ binSize?: number;
346
+ onFilterIntent?: (intent: {
347
+ kind: "cases";
348
+ ids: string[];
349
+ }) => void;
350
+ height?: number;
351
+ tableView?: boolean;
352
+ loading?: boolean;
353
+ }
354
+ /** Stand-in for `PerformanceSpectrum` (RM-060); asserts `order` resolves to a segment present in `log`. */
355
+ declare const PerformanceSpectrumDouble: react.ForwardRefExoticComponent<PerformanceSpectrumDoubleProps & react.RefAttributes<HTMLDivElement>>;
356
+ interface ConformanceOverlayDoubleProps extends DoubleOwnProps {
357
+ graph: ProcessGraph;
358
+ conformance: ConformanceResult;
359
+ }
360
+ interface ViolationListDoubleProps extends HTMLAttributes<HTMLDivElement> {
361
+ conformance: ConformanceResult;
362
+ }
363
+ interface HappyPathEditorDoubleProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
364
+ value: HappyPath;
365
+ onChange: (path: HappyPath) => void;
366
+ }
367
+ /** Stand-in for `ConformanceOverlay` (RM-062): requires a graph AND a replay result. */
368
+ declare const ConformanceOverlayDouble: react.ForwardRefExoticComponent<ConformanceOverlayDoubleProps & react.RefAttributes<HTMLDivElement>>;
369
+ /** Stand-in for `ViolationList` (RM-062). */
370
+ declare const ViolationListDouble: react.ForwardRefExoticComponent<ViolationListDoubleProps & react.RefAttributes<HTMLDivElement>>;
371
+ /** Stand-in for `HappyPathEditor` (RM-062): a controlled editor, so `onChange` is required. */
372
+ declare const HappyPathEditorDouble: react.ForwardRefExoticComponent<HappyPathEditorDoubleProps & react.RefAttributes<HTMLDivElement>>;
373
+ interface ProcessReplayDoubleProps extends HTMLAttributes<HTMLDivElement> {
374
+ graph: ProcessGraph;
375
+ log: EventLog;
376
+ synchronizedStart?: boolean;
377
+ bucketMs?: number;
378
+ playing?: boolean;
379
+ defaultPlaying?: boolean;
380
+ onPlayingChange?: (playing: boolean) => void;
381
+ time?: number;
382
+ defaultTime?: number;
383
+ onTimeChange?: (time: number) => void;
384
+ speed?: number;
385
+ defaultSpeed?: number;
386
+ onSpeedChange?: (speed: number) => void;
387
+ congestionLimit?: number;
388
+ loading?: boolean;
389
+ }
390
+ /** Stand-in for `ProcessReplay` (RM-065): requires the log (per-case timing) AND the graph. */
391
+ declare const ProcessReplayDouble: react.ForwardRefExoticComponent<ProcessReplayDoubleProps & react.RefAttributes<HTMLDivElement>>;
392
+
393
+ interface ProcessCompareSideDoubleProps {
394
+ label: string;
395
+ graph?: ProcessGraph;
396
+ }
397
+ interface ProcessCompareDoubleProps extends HTMLAttributes<HTMLDivElement> {
398
+ a: ProcessCompareSideDoubleProps;
399
+ b: ProcessCompareSideDoubleProps;
400
+ mode?: "side-by-side" | "superimposed";
401
+ }
402
+ /** Stand-in for `ProcessCompare` (RM-064) — cheap enough to mount without a real canvas. */
403
+ declare const ProcessCompareDouble: react.ForwardRefExoticComponent<ProcessCompareDoubleProps & react.RefAttributes<HTMLDivElement>>;
186
404
 
187
405
  /** The derived triple most process stories/tests want from one raw log. */
188
406
  interface ProcessFixture {
@@ -193,4 +411,4 @@ interface ProcessFixture {
193
411
  /** Derive {@link ProcessFixture} from a raw event log. Pure — no caching, no I/O. */
194
412
  declare function withProcessFixture(log: EventLog): ProcessFixture;
195
413
 
196
- export { ProcessContractError, type ProcessContractSpec, type ProcessDoublePayload, type ProcessFixture, ProcessKpiStripDouble, type ProcessKpiStripDoubleProps, ProcessMapDouble, type ProcessMapDoubleProps, type ProcessSelection, VariantExplorerDouble, type VariantExplorerDoubleProps, assertProcessContract, buildProcessDoublePayload, readProcessDoubleProps, withProcessFixture };
414
+ export { ConformanceOverlayDouble, type ConformanceOverlayDoubleProps, DottedChartDouble, type DottedChartDoubleProps, HappyPathEditorDouble, type HappyPathEditorDoubleProps, PerformanceSpectrumDouble, type PerformanceSpectrumDoubleProps, ProcessCompareDouble, type ProcessCompareDoubleProps, ProcessContractError, type ProcessContractSpec, type ProcessDoublePayload, type ProcessFixture, ProcessKpiStripDouble, type ProcessKpiStripDoubleProps, ProcessMapDouble, type ProcessMapDoubleProps, ProcessReplayDouble, type ProcessReplayDoubleProps, type ProcessSelection, VariantExplorerDouble, type VariantExplorerDoubleProps, ViolationListDouble, type ViolationListDoubleProps, assertProcessContract, buildProcessDoublePayload, readProcessDoubleProps, withProcessFixture };