@directive-run/core 1.22.0 → 1.23.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 (84) hide show
  1. package/dist/adapter-utils.cjs +1 -1
  2. package/dist/adapter-utils.d.cts +1 -1
  3. package/dist/adapter-utils.d.ts +1 -1
  4. package/dist/adapter-utils.js +1 -1
  5. package/dist/{chunk-YJEDX2JX.js → chunk-AFPLATPV.js} +3 -3
  6. package/dist/chunk-AFPLATPV.js.map +1 -0
  7. package/dist/{chunk-OAPD3HIG.cjs → chunk-FCCJUQB2.cjs} +3 -3
  8. package/dist/chunk-FCCJUQB2.cjs.map +1 -0
  9. package/dist/chunk-IZNOPHPL.js +3 -0
  10. package/dist/chunk-IZNOPHPL.js.map +1 -0
  11. package/dist/chunk-LN5H74CU.js +2 -0
  12. package/dist/{chunk-RBF653NR.js.map → chunk-LN5H74CU.js.map} +1 -1
  13. package/dist/chunk-PJIIBQTK.js +2 -0
  14. package/dist/chunk-PJIIBQTK.js.map +1 -0
  15. package/dist/chunk-PTT4MWNL.cjs +3 -0
  16. package/dist/chunk-PTT4MWNL.cjs.map +1 -0
  17. package/dist/{chunk-GKMJ7NMP.cjs → chunk-RD2HO5NZ.cjs} +2 -2
  18. package/dist/{chunk-GKMJ7NMP.cjs.map → chunk-RD2HO5NZ.cjs.map} +1 -1
  19. package/dist/{chunk-GACC2DMS.cjs → chunk-S6W6Y44G.cjs} +2 -2
  20. package/dist/{chunk-GACC2DMS.cjs.map → chunk-S6W6Y44G.cjs.map} +1 -1
  21. package/dist/{chunk-6PF2FRBG.js → chunk-WD47DB52.js} +2 -2
  22. package/dist/{chunk-6PF2FRBG.js.map → chunk-WD47DB52.js.map} +1 -1
  23. package/dist/chunk-WKGNK4QK.cjs +2 -0
  24. package/dist/chunk-WKGNK4QK.cjs.map +1 -0
  25. package/dist/chunk-WVP3GOY2.js +3 -0
  26. package/dist/chunk-WVP3GOY2.js.map +1 -0
  27. package/dist/chunk-XKXTRVJF.cjs +3 -0
  28. package/dist/chunk-XKXTRVJF.cjs.map +1 -0
  29. package/dist/{index-BgKC_ZT_.d.ts → index-DpvgHVHR.d.cts} +29 -2
  30. package/dist/{index-DRPkZ8HE.d.cts → index-n8oQmdOZ.d.ts} +29 -2
  31. package/dist/index.cjs +2 -2
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +6 -128
  34. package/dist/index.d.ts +6 -128
  35. package/dist/index.js +2 -2
  36. package/dist/index.js.map +1 -1
  37. package/dist/internals.cjs +1 -1
  38. package/dist/internals.d.cts +10 -4
  39. package/dist/internals.d.ts +10 -4
  40. package/dist/internals.js +1 -1
  41. package/dist/plugins/index.cjs +2 -2
  42. package/dist/plugins/index.cjs.map +1 -1
  43. package/dist/plugins/index.d.cts +202 -3
  44. package/dist/plugins/index.d.ts +202 -3
  45. package/dist/plugins/index.js +2 -2
  46. package/dist/plugins/index.js.map +1 -1
  47. package/dist/{plugins-5Supk7it.d.cts → plugins-CaPMTICa.d.cts} +323 -2
  48. package/dist/{plugins-5Supk7it.d.ts → plugins-CaPMTICa.d.ts} +323 -2
  49. package/dist/{predicate-DYb-3Mvl.d.cts → predicate-CU0YC1i6.d.cts} +1 -1
  50. package/dist/{predicate-C9oMO_ny.d.ts → predicate-CgpwJqf4.d.ts} +1 -1
  51. package/dist/system-HOP37Z4V.js +2 -0
  52. package/dist/{system-6YWCXQOQ.js.map → system-HOP37Z4V.js.map} +1 -1
  53. package/dist/system-VZUHL56W.cjs +2 -0
  54. package/dist/{system-5FKUBLLV.cjs.map → system-VZUHL56W.cjs.map} +1 -1
  55. package/dist/testing.cjs +1 -1
  56. package/dist/testing.cjs.map +1 -1
  57. package/dist/testing.d.cts +1 -1
  58. package/dist/testing.d.ts +1 -1
  59. package/dist/testing.js +1 -1
  60. package/dist/testing.js.map +1 -1
  61. package/dist/worker.cjs +1 -1
  62. package/dist/worker.cjs.map +1 -1
  63. package/dist/worker.d.cts +1 -1
  64. package/dist/worker.d.ts +1 -1
  65. package/dist/worker.js +1 -1
  66. package/dist/worker.js.map +1 -1
  67. package/package.json +1 -1
  68. package/dist/chunk-6NCC6RBC.js +0 -3
  69. package/dist/chunk-6NCC6RBC.js.map +0 -1
  70. package/dist/chunk-GBCWXTXW.cjs +0 -3
  71. package/dist/chunk-GBCWXTXW.cjs.map +0 -1
  72. package/dist/chunk-KGTBTGOY.js +0 -2
  73. package/dist/chunk-KGTBTGOY.js.map +0 -1
  74. package/dist/chunk-MARZI3EY.cjs +0 -2
  75. package/dist/chunk-MARZI3EY.cjs.map +0 -1
  76. package/dist/chunk-OAPD3HIG.cjs.map +0 -1
  77. package/dist/chunk-QTY2FXZY.cjs +0 -3
  78. package/dist/chunk-QTY2FXZY.cjs.map +0 -1
  79. package/dist/chunk-RBF653NR.js +0 -2
  80. package/dist/chunk-SFUVPP4L.js +0 -3
  81. package/dist/chunk-SFUVPP4L.js.map +0 -1
  82. package/dist/chunk-YJEDX2JX.js.map +0 -1
  83. package/dist/system-5FKUBLLV.cjs +0 -2
  84. package/dist/system-6YWCXQOQ.js +0 -2
@@ -1075,6 +1075,60 @@ type EventsDef<S extends Schema> = Record<string, FlexibleEventHandler<S>>;
1075
1075
  type JitterStrategy = "none" | "full" | "equal" | {
1076
1076
  maxMs: number;
1077
1077
  };
1078
+ /**
1079
+ * Why a resolver attempt was aborted, surfaced to {@link RetryPolicy.shouldRetry}
1080
+ * so the policy can distinguish "retry on race-loss" from "fail loud on bug."
1081
+ *
1082
+ * - `"clobbered"` — an `abortOn`-listed fact was written by something
1083
+ * outside the resolver between the resolver's baseline read and its
1084
+ * next write (RFC 0003 optimistic-concurrency check). The retry is
1085
+ * typically safe — the resolver re-reads the current value and tries
1086
+ * again with fresh context.
1087
+ * - `"timeout"` — the resolver's `timeout` ms elapsed. Retrying may
1088
+ * succeed if the underlying I/O was just slow; may fail again if the
1089
+ * timeout is set too tight for the workload.
1090
+ * - `"cancelled"` — `system.stop()` was called, or external code aborted
1091
+ * the resolver's `ctx.signal`. Retrying is almost always wrong — the
1092
+ * cancellation was the caller's explicit intent.
1093
+ * - `"error"` — the resolver threw. Default for back-compat: any abort
1094
+ * without a more specific reason maps here.
1095
+ *
1096
+ * Core has no supersession concept today; if a future package wants to
1097
+ * surface supersession, it can widen the union additively without
1098
+ * breaking back-compat.
1099
+ *
1100
+ * @public
1101
+ */
1102
+ type ResolverAbortReason = "clobbered" | "timeout" | "cancelled" | "error";
1103
+ /**
1104
+ * Context object passed as the optional third argument to
1105
+ * {@link RetryPolicy.shouldRetry}. Lets the policy decide based on WHY
1106
+ * the attempt failed — not just the thrown error.
1107
+ *
1108
+ * Two-argument `shouldRetry(error, attempt)` continues to work; the
1109
+ * context argument is additive. Existing callers see no behavior change.
1110
+ *
1111
+ * @public
1112
+ */
1113
+ interface ShouldRetryContext {
1114
+ /**
1115
+ * Why the attempt was aborted. Undefined when the engine couldn't
1116
+ * classify the cause (very rare — defaults to `"error"` in practice).
1117
+ */
1118
+ reason?: ResolverAbortReason;
1119
+ /**
1120
+ * Populated only when `reason === "clobbered"`. Names the `abortOn`
1121
+ * fact whose mid-flight change tripped the binding, plus the expected
1122
+ * baseline value and the actual current value. Useful for
1123
+ * `shouldRetry: (_, _, ctx) => ctx?.clobber?.fact === "cart.discount"`
1124
+ * patterns that only retry contention on specific facts.
1125
+ */
1126
+ clobber?: {
1127
+ fact: string;
1128
+ expected: unknown;
1129
+ actual: unknown;
1130
+ };
1131
+ }
1078
1132
  /** Retry policy configuration */
1079
1133
  interface RetryPolicy {
1080
1134
  /** Maximum number of attempts */
@@ -1101,10 +1155,24 @@ interface RetryPolicy {
1101
1155
  * Return `true` to retry, `false` to stop immediately.
1102
1156
  * If omitted, all errors are retried (up to `attempts`).
1103
1157
  *
1158
+ * The optional third `context` argument carries the abort reason and,
1159
+ * for clobbers, the fact + expected/actual values. Existing two-arg
1160
+ * callers continue to work — the third arg is undefined when omitted.
1161
+ *
1162
+ * @example Retry on contention, fail loud on bug
1163
+ * ```ts
1164
+ * shouldRetry: (err, attempt, ctx) => {
1165
+ * if (ctx?.reason === "clobbered") return attempt < 5;
1166
+ * if (ctx?.reason === "timeout") return attempt < 2;
1167
+ * return false; // "error" / "cancelled" → don't retry
1168
+ * }
1169
+ * ```
1170
+ *
1104
1171
  * @param error - The error that occurred
1105
1172
  * @param attempt - The attempt number that just failed (1-based)
1173
+ * @param context - Optional abort context (added v1.23.0); undefined for callers that don't pass it
1106
1174
  */
1107
- shouldRetry?: (error: Error, attempt: number) => boolean;
1175
+ shouldRetry?: (error: Error, attempt: number, context?: ShouldRetryContext) => boolean;
1108
1176
  }
1109
1177
  /** Batch configuration */
1110
1178
  interface BatchConfig {
@@ -1315,6 +1383,128 @@ type ResolverStatus = {
1315
1383
  canceledAt: number;
1316
1384
  };
1317
1385
 
1386
+ /**
1387
+ * Structural diff between two snapshots of a system's constraint `whenSpec`
1388
+ * map. The "git diff for business rules" — operates on the predicate AST
1389
+ * instead of source-text lines.
1390
+ *
1391
+ * A predicate is a tree of leaf clauses (`{ fact: operator(value) }`) and
1392
+ * combinators (`$all` / `$any` / `$not`). `diffRules` flattens both trees
1393
+ * into path-keyed leaf lists and compares: missing path → added/removed,
1394
+ * same path with different operand → changed (with relaxed/tightened
1395
+ * classification for numeric thresholds).
1396
+ *
1397
+ * Pure module — imports only utils. No engine / store / predicate-runtime
1398
+ * dependency: predicates are walked as plain JSON.
1399
+ */
1400
+ /** A leaf clause extracted from a predicate tree, keyed by its dotted path. */
1401
+ interface LeafClause {
1402
+ /** Dotted path through the predicate. E.g. `phase`, `$all[0].elapsed`, `$not.paused`. */
1403
+ path: string;
1404
+ /** Operator name. `$eq` is implied for bare-value equality. */
1405
+ op: string;
1406
+ /** Operand. */
1407
+ value: unknown;
1408
+ }
1409
+ /** Kind of change observed for a single clause. */
1410
+ type ChangeKind = "added" | "removed" | "changed" | "relaxed" | "tightened";
1411
+ /** A single change between two predicates at a specific path. */
1412
+ interface Change {
1413
+ path: string;
1414
+ kind: ChangeKind;
1415
+ before?: {
1416
+ op: string;
1417
+ value: unknown;
1418
+ };
1419
+ after?: {
1420
+ op: string;
1421
+ value: unknown;
1422
+ };
1423
+ }
1424
+ /** Status of a single constraint across the two snapshots. */
1425
+ type ConstraintStatus = "added" | "removed" | "changed" | "unchanged";
1426
+ interface ConstraintDiff {
1427
+ id: string;
1428
+ status: ConstraintStatus;
1429
+ /** Empty for `unchanged`. For `added` / `removed`, every leaf is listed once. */
1430
+ changes: Change[];
1431
+ }
1432
+ interface RulesDiffReport {
1433
+ constraints: ConstraintDiff[];
1434
+ summary: {
1435
+ added: number;
1436
+ removed: number;
1437
+ changed: number;
1438
+ unchanged: number;
1439
+ totalClauseChanges: number;
1440
+ };
1441
+ }
1442
+ interface DiffRulesOptions {
1443
+ before: RulesMapInput;
1444
+ after: RulesMapInput;
1445
+ }
1446
+ /**
1447
+ * Accepted shapes for the `before` / `after` predicate maps:
1448
+ * - A plain map `{ [constraintId]: whenSpec }`
1449
+ * - The `system.inspect().constraints` array form `Array<{ id, whenSpec? }>`
1450
+ * - Either wrapped as `{ constraints: <one-of-the-above> }`
1451
+ *
1452
+ * Anything else throws at `toRulesMap` so a bad input fails loud.
1453
+ */
1454
+ type RulesMapInput = unknown;
1455
+ /**
1456
+ * Coerce supported input shapes into a flat `Record<constraintId, whenSpec>`.
1457
+ * Constraints without a `whenSpec` (function-form `when`) are dropped with
1458
+ * an undefined entry so callers can distinguish them from absent constraints
1459
+ * if they care; the diff treats `undefined` as "no data" and skips clause
1460
+ * walking.
1461
+ */
1462
+ declare function toRulesMap(raw: RulesMapInput): Record<string, unknown>;
1463
+ /**
1464
+ * Walk a predicate tree and emit every leaf clause with its dotted path.
1465
+ * Combinators (`$all` / `$any` / `$not`) become indexed path segments.
1466
+ * Bare-value equality (`{ phase: "red" }`) emits as `op: "$eq"`.
1467
+ *
1468
+ * Array-form predicates (`[{ fact, op, value }, ...]`) are also accepted —
1469
+ * each clause's `fact` becomes the path, the operator is `op`, and the
1470
+ * value is `value`.
1471
+ *
1472
+ * **What gets dropped:** non-object combinator children (e.g. `$not: "red"`
1473
+ * with a string operand instead of a predicate object), function-form
1474
+ * predicates (the engine accepts a function for `when`; this walker only
1475
+ * sees data), and bare primitive predicates (a top-level `true` or `"x"`).
1476
+ * The walker is a tree visitor — anything not shaped like a predicate node
1477
+ * is silently skipped, never thrown on.
1478
+ */
1479
+ declare function flattenPredicate(spec: unknown, pathPrefix?: string, out?: LeafClause[]): LeafClause[];
1480
+ /**
1481
+ * Diff two snapshots of a system's constraint whenSpec map.
1482
+ *
1483
+ * @example
1484
+ * ```ts
1485
+ * const report = diffRules({
1486
+ * before: { blockCheckout: { cartTotal: { $gte: 100 } } },
1487
+ * after: { blockCheckout: { cartTotal: { $gte: 50 } } },
1488
+ * });
1489
+ *
1490
+ * report.constraints[0].status; // "changed"
1491
+ * report.constraints[0].changes[0].kind; // "relaxed"
1492
+ * report.summary.totalClauseChanges; // 1
1493
+ * ```
1494
+ *
1495
+ * The input shape is forgiving — either a flat `{ id: whenSpec }` map, the
1496
+ * `system.inspect().constraints` array form, or either wrapped as
1497
+ * `{ constraints: ... }`. Constraints whose `when` is a function (no
1498
+ * `whenSpec`) are tracked as added/removed but cannot be clause-diffed
1499
+ * (the function form is opaque).
1500
+ */
1501
+ declare function diffRules(options: DiffRulesOptions): RulesDiffReport;
1502
+ /**
1503
+ * Diff two predicate trees and return the list of leaf-level changes.
1504
+ * Exported for reuse beyond the full per-constraint report.
1505
+ */
1506
+ declare function diffClauses(before: unknown, after: unknown): Change[];
1507
+
1318
1508
  /**
1319
1509
  * Error Types - Type definitions for error handling
1320
1510
  */
@@ -3077,6 +3267,46 @@ interface MetaAccessor {
3077
3267
  /** Find all definitions matching a tag across all types. */
3078
3268
  byTag(tag: string): MetaMatch[];
3079
3269
  }
3270
+ /**
3271
+ * Discriminated proof of why two resolvers' `when:` predicates fire on
3272
+ * the same state — attached to `resolver.clobber.loop.detected` events
3273
+ * so the warning can point at the specific clauses that co-fire instead
3274
+ * of stopping at "these resolvers fight."
3275
+ *
3276
+ * - `matched` — both predicates have identical structural clauses.
3277
+ * The strongest verdict; the rules are syntactic duplicates.
3278
+ * - `overlap` — clauses share at least one path and at least one
3279
+ * pairwise comparison says they co-fire (with no direct
3280
+ * contradictions). Strong verdict, slightly weaker than `matched`.
3281
+ * - `indeterminate` — a non-COMPARABLE operator (`$regex`, `$elemMatch`,
3282
+ * `$matches`, custom) appeared. The proof builder declines to assert
3283
+ * overlap; the message says so explicitly rather than falsely
3284
+ * reporting a contradiction.
3285
+ * - `function-form-opaque` — at least one constraint uses a function
3286
+ * `when:` (`(facts) => ...`), so structural comparison is impossible.
3287
+ * The warning text disclaims; if audit-ledger is mounted and its
3288
+ * `whenSourceCache` is available, identifying hashes of the function
3289
+ * source are included for cross-version diffing.
3290
+ *
3291
+ * @public
3292
+ */
3293
+ type PredicateOverlapProof = {
3294
+ verdict: "matched";
3295
+ coFireClauses: readonly LeafClause[];
3296
+ conflictingClauses: readonly never[];
3297
+ } | {
3298
+ verdict: "overlap";
3299
+ coFireClauses: readonly LeafClause[];
3300
+ conflictingClauses: readonly LeafClause[];
3301
+ } | {
3302
+ verdict: "indeterminate";
3303
+ reason: "non-comparable-operator";
3304
+ coFireClauses: readonly LeafClause[];
3305
+ } | {
3306
+ verdict: "function-form-opaque";
3307
+ reason: "one-or-both-when-is-a-function";
3308
+ whenSourceHashes?: readonly string[];
3309
+ };
3080
3310
  /** Typed events emitted by system.observe(). */
3081
3311
  type ObservationEvent = {
3082
3312
  type: "fact.change";
@@ -3188,6 +3418,52 @@ type ObservationEvent = {
3188
3418
  requirementId: string;
3189
3419
  reason: "clobbered";
3190
3420
  dropped: number;
3421
+ }
3422
+ /**
3423
+ * v1.23.0 — fires when `clobberLoopPlugin` detects a sustained pattern
3424
+ * of clobbers on a fact involving the same set of resolvers above
3425
+ * threshold within a time window. A single clobber is fine; the
3426
+ * binding catches the race and the audit ledger records it. A *loop*
3427
+ * is two or more resolvers whose `when:` predicates both satisfy a
3428
+ * shared state and rewrite the fact every reconcile tick.
3429
+ *
3430
+ * `participants` is the unordered, distinct set of resolver IDs
3431
+ * contributing to the loop. `predicateOverlap` (when both sides use a
3432
+ * data-form `when:`) explains WHY the loop occurs — which clauses
3433
+ * co-fire — so the suggested fix (add `priority:`, narrow `when:`,
3434
+ * merge) is grounded in the actual rules, not a guess.
3435
+ */
3436
+ | {
3437
+ type: "resolver.clobber.loop.detected";
3438
+ systemId: string;
3439
+ fact: string;
3440
+ participants: readonly string[];
3441
+ participantModules: readonly string[];
3442
+ count: number;
3443
+ windowMs: number;
3444
+ firstAt: number;
3445
+ lastAt: number;
3446
+ predicateOverlap?: PredicateOverlapProof;
3447
+ severity: "warn" | "error";
3448
+ factTags: readonly string[];
3449
+ suppressedSinceLastEmit: number;
3450
+ rejectionSeqs: readonly number[];
3451
+ }
3452
+ /**
3453
+ * v1.23.0 — fires when a previously-detected clobber loop closes
3454
+ * cleanly, so dashboards can show "5 active loops" not "47
3455
+ * historical loops". A loop is considered resolved when the
3456
+ * `(fact, participantSet)` goes a quiet window without further
3457
+ * `resolver.write.rejected` events, OR a participant is unregistered,
3458
+ * OR a constraint re-registration changes a participant's `whenSpec`.
3459
+ */
3460
+ | {
3461
+ type: "resolver.clobber.loop.resolved";
3462
+ systemId: string;
3463
+ fact: string;
3464
+ participants: readonly string[];
3465
+ durationMs: number;
3466
+ resolution: "no-recurrence-in-window" | "participant-disabled" | "predicate-narrowed";
3191
3467
  } | {
3192
3468
  type: "effect.run";
3193
3469
  id: string;
@@ -3375,6 +3651,31 @@ interface System<M extends ModuleSchema = ModuleSchema> {
3375
3651
  */
3376
3652
  readonly notify: {
3377
3653
  guardrailBlocked(plugin: string, key: string, kind: "redact" | "alert" | "detect", count: number, category?: string): void;
3654
+ /**
3655
+ * v1.23.0 — plugin authoring surface for emitting the
3656
+ * `"resolver.clobber.loop.detected"` ObservationEvent. Used by
3657
+ * `clobberLoopPlugin` (and any compatible third-party detector). The
3658
+ * call fans out to all registered plugins' `onClobberLoopDetected`
3659
+ * hooks (including the synthetic plugins that back `system.observe()`)
3660
+ * so audit-ledger, devtools, and OTel exporters capture the event
3661
+ * without taking a dependency on the originating detector.
3662
+ *
3663
+ * Application code should never call this directly — use
3664
+ * `system.observe()` to subscribe.
3665
+ */
3666
+ clobberLoopDetected(event: ObservationEvent & {
3667
+ type: "resolver.clobber.loop.detected";
3668
+ }): void;
3669
+ /**
3670
+ * v1.23.0 — companion to {@link clobberLoopDetected}. Fires when a
3671
+ * previously-detected loop is considered resolved (quiet window
3672
+ * elapsed, participant unregistered, or predicate narrowed). Lets
3673
+ * monitoring dashboards show "active loops" rather than
3674
+ * "historical loops."
3675
+ */
3676
+ clobberLoopResolved(event: ObservationEvent & {
3677
+ type: "resolver.clobber.loop.resolved";
3678
+ }): void;
3378
3679
  };
3379
3680
  /** Per-run trace entries (null if trace is not enabled) */
3380
3681
  readonly trace: TraceEntry[] | null;
@@ -3874,6 +4175,26 @@ interface Plugin<M extends ModuleSchema = ModuleSchema> {
3874
4175
  * payloads.
3875
4176
  */
3876
4177
  onGuardrailBlocked?: (plugin: string, key: string, kind: "redact" | "alert" | "detect", count: number, category?: string) => void;
4178
+ /**
4179
+ * Called when `clobberLoopPlugin` (or any equivalent detector) publishes
4180
+ * a structured loop event through `system.notify.clobberLoopDetected(...)`.
4181
+ * Surfaces as the `"resolver.clobber.loop.detected"` `ObservationEvent`
4182
+ * for `system.observe()` subscribers + audit-ledger + devtools, so
4183
+ * downstream backends can capture loops without taking a direct
4184
+ * dependency on `clobberLoopPlugin`.
4185
+ */
4186
+ onClobberLoopDetected?: (event: ObservationEvent & {
4187
+ type: "resolver.clobber.loop.detected";
4188
+ }) => void;
4189
+ /**
4190
+ * Called when a previously-detected loop is considered resolved (quiet
4191
+ * window elapsed, participant unregistered, or predicate narrowed).
4192
+ * Pairs with `onClobberLoopDetected` so dashboards can show "active
4193
+ * loops" rather than "historical loops."
4194
+ */
4195
+ onClobberLoopResolved?: (event: ObservationEvent & {
4196
+ type: "resolver.clobber.loop.resolved";
4197
+ }) => void;
3877
4198
  /**
3878
4199
  * Called when a history snapshot is taken.
3879
4200
  * @param snapshot - The snapshot that was captured
@@ -3932,4 +4253,4 @@ interface Plugin<M extends ModuleSchema = ModuleSchema> {
3932
4253
  onTraceComplete?: (entry: TraceEntry) => void;
3933
4254
  }
3934
4255
 
3935
- export { type InferSchemaType as $, type AnySystem as A, type BatchConfig as B, type ClauseResult as C, type DefinitionMeta as D, type EffectsDef as E, type FactPredicate as F, type DynamicConstraintDef as G, type DynamicEffectDef as H, type DynamicResolverDef as I, type EffectDef as J, type EventsDef as K, type FactTemplate as L, type ModuleSchema as M, type NamespacedSystem as N, type FactsSnapshot as O, type Plugin as P, type HistoryAPI as Q, type RequirementWithId as R, type SchemaType as S, type TypedDerivationsDef as T, type HistoryOption as U, type HistoryState as V, type InferDerivations as W, type InferEvents as X, type InferFacts as Y, type InferRequirementTypes as Z, type InferRequirements as _, type Facts as a, type FactReturnType as a$, type InferSelectorState as a0, type KeySelector as a1, type MetaAccessor as a2, type MetaMatch as a3, type ObservationEvent as a4, type OperatorObject as a5, type PatchSpec as a6, type PatchValue as a7, type PayloadRef as a8, type PredicateClause as a9, isSingleModuleSystem as aA, type FactsStore as aB, type ConstraintState as aC, type ResolverStatus as aD, type FactChange as aE, type ReconcileResult as aF, type RecoveryStrategy as aG, type ErrorSource as aH, type RetryLaterConfig as aI, type BatchItemResult as aJ, type BatchResolveResults as aK, type ConstraintsControl as aL, type CrossModuleDerivationFn as aM, type CrossModuleFactsWithSelf as aN, type DerivationKeys as aO, type DerivationReturnType as aP, type DerivationsControl as aQ, type DerivationsSchema as aR, type DeriveAccessor as aS, type DispatchEventsFromSchema as aT, type EffectCleanup as aU, type EffectsControl as aV, type EventPayloadSchema as aW, type EventsAccessor as aX, type EventsAccessorFromSchema as aY, type EventsSchema as aZ, type FactKeys as a_, type PredicateCombinator as aa, type PredicateCombinatorKey as ab, type PredicateObject as ac, type PredicateOp as ad, type ResolverDef as ae, type ResolversDef as af, type RetryPolicy as ag, type Schema as ah, type SchemaTypedResolversDef as ai, type Snapshot as aj, type SourceDef as ak, type SourceDropReason as al, type SourcePublish as am, type SourceReportError as an, type SourceUnsubscribe as ao, type System as ap, type SystemConfig as aq, type SystemDerived as ar, type SystemFacts as as, type SystemInspection as at, type SystemMode as au, type SystemSnapshot as av, type TraceEntry as aw, type TypedConstraintDef as ax, type TypedResolverDef as ay, isNamespacedSystem as az, type TypedEventsDef as b, type FlexibleEventHandler as b0, type HistoryConfig as b1, type InferEventPayloadFromSchema as b2, type InferRequirementPayloadFromSchema as b3, type InferSchema as b4, type MutableNamespacedFacts as b5, type NamespacedDerivations as b6, type NamespacedEventsAccessor as b7, type NamespacedFacts as b8, type ObservableKeys as b9, type RequirementExplanation as ba, type RequirementOutput as bb, type RequirementPayloadSchema$1 as bc, type RequirementsSchema as bd, type ResolverContext as be, type ResolversControl as bf, type SnapshotMeta as bg, type SystemEvent as bh, type TraceConfig as bi, type TypedResolverContext as bj, type UnionEvents as bk, type RequirementOutput$1 as bl, type SourcesDef as c, type TypedConstraintsDef as d, type TypedResolversDef as e, type ModuleHooks as f, type CrossModuleDeps as g, type CrossModuleDerivationsDef as h, type CrossModuleEffectsDef as i, type CrossModuleConstraintsDef as j, type ModuleDef as k, type CreateSystemOptionsSingle as l, type SingleModuleSystem as m, type ModulesMap as n, type CreateSystemOptionsNamed as o, type TraceOption as p, type ErrorBoundaryConfig as q, type Requirement as r, type RequirementKeyFn as s, type ConstraintDef as t, type ConstraintsDef as u, type CrossModuleConstraintDef as v, type CrossModuleEffectDef as w, DirectiveError as x, type DistributableSnapshot as y, type DistributableSnapshotOptions as z };
4256
+ export { type InferDerivations as $, type AnySystem as A, type BatchConfig as B, type ClauseResult as C, type DefinitionMeta as D, type EffectsDef as E, type FactPredicate as F, type CrossModuleEffectDef as G, type DiffRulesOptions as H, DirectiveError as I, type DistributableSnapshot as J, type DistributableSnapshotOptions as K, type DynamicConstraintDef as L, type ModuleSchema as M, type NamespacedSystem as N, type DynamicEffectDef as O, type Plugin as P, type DynamicResolverDef as Q, type RequirementWithId as R, type SchemaType as S, type TypedDerivationsDef as T, type EffectDef as U, type EventsDef as V, type FactTemplate as W, type FactsSnapshot as X, type HistoryAPI as Y, type HistoryOption as Z, type HistoryState as _, type Facts as a, type CrossModuleDerivationFn as a$, type InferEvents as a0, type InferFacts as a1, type InferRequirementTypes as a2, type InferRequirements as a3, type InferSchemaType as a4, type InferSelectorState as a5, type KeySelector as a6, type LeafClause as a7, type MetaAccessor as a8, type MetaMatch as a9, type System as aA, type SystemConfig as aB, type SystemDerived as aC, type SystemFacts as aD, type SystemInspection as aE, type SystemMode as aF, type SystemSnapshot as aG, type TraceEntry as aH, type TypedConstraintDef as aI, type TypedResolverDef as aJ, diffClauses as aK, diffRules as aL, flattenPredicate as aM, isNamespacedSystem as aN, isSingleModuleSystem as aO, toRulesMap as aP, type FactsStore as aQ, type ConstraintState as aR, type ResolverStatus as aS, type FactChange as aT, type ReconcileResult as aU, type RecoveryStrategy as aV, type ErrorSource as aW, type RetryLaterConfig as aX, type BatchItemResult as aY, type BatchResolveResults as aZ, type ConstraintsControl as a_, type ObservationEvent as aa, type OperatorObject as ab, type PatchSpec as ac, type PatchValue as ad, type PayloadRef as ae, type PredicateClause as af, type PredicateCombinator as ag, type PredicateCombinatorKey as ah, type PredicateObject as ai, type PredicateOp as aj, type PredicateOverlapProof as ak, type ResolverAbortReason as al, type ResolverDef as am, type ResolversDef as an, type RetryPolicy as ao, type RulesDiffReport as ap, type RulesMapInput as aq, type Schema as ar, type SchemaTypedResolversDef as as, type ShouldRetryContext as at, type Snapshot as au, type SourceDef as av, type SourceDropReason as aw, type SourcePublish as ax, type SourceReportError as ay, type SourceUnsubscribe as az, type TypedEventsDef as b, type CrossModuleFactsWithSelf as b0, type DerivationKeys as b1, type DerivationReturnType as b2, type DerivationsControl as b3, type DerivationsSchema as b4, type DeriveAccessor as b5, type DispatchEventsFromSchema as b6, type EffectCleanup as b7, type EffectsControl as b8, type EventPayloadSchema as b9, type RequirementOutput$1 as bA, type EventsAccessor as ba, type EventsAccessorFromSchema as bb, type EventsSchema as bc, type FactKeys as bd, type FactReturnType as be, type FlexibleEventHandler as bf, type HistoryConfig as bg, type InferEventPayloadFromSchema as bh, type InferRequirementPayloadFromSchema as bi, type InferSchema as bj, type MutableNamespacedFacts as bk, type NamespacedDerivations as bl, type NamespacedEventsAccessor as bm, type NamespacedFacts as bn, type ObservableKeys as bo, type RequirementExplanation as bp, type RequirementOutput as bq, type RequirementPayloadSchema$1 as br, type RequirementsSchema as bs, type ResolverContext as bt, type ResolversControl as bu, type SnapshotMeta as bv, type SystemEvent as bw, type TraceConfig as bx, type TypedResolverContext as by, type UnionEvents as bz, type SourcesDef as c, type TypedConstraintsDef as d, type TypedResolversDef as e, type ModuleHooks as f, type CrossModuleDeps as g, type CrossModuleDerivationsDef as h, type CrossModuleEffectsDef as i, type CrossModuleConstraintsDef as j, type ModuleDef as k, type CreateSystemOptionsSingle as l, type SingleModuleSystem as m, type ModulesMap as n, type CreateSystemOptionsNamed as o, type TraceOption as p, type ErrorBoundaryConfig as q, type Requirement as r, type RequirementKeyFn as s, type Change as t, type ChangeKind as u, type ConstraintDef as v, type ConstraintDiff as w, type ConstraintStatus as x, type ConstraintsDef as y, type CrossModuleConstraintDef as z };
@@ -1,4 +1,4 @@
1
- import { ah as Schema, a as Facts, F as FactPredicate, b4 as InferSchema, L as FactTemplate, D as DefinitionMeta, r as Requirement, bl as RequirementOutput, ag as RetryPolicy, B as BatchConfig, be as ResolverContext, ad as PredicateOp, a6 as PatchSpec, C as ClauseResult } from './plugins-5Supk7it.cjs';
1
+ import { ar as Schema, a as Facts, F as FactPredicate, bj as InferSchema, W as FactTemplate, D as DefinitionMeta, r as Requirement, bA as RequirementOutput, ao as RetryPolicy, B as BatchConfig, bt as ResolverContext, aj as PredicateOp, ac as PatchSpec, C as ClauseResult } from './plugins-CaPMTICa.cjs';
2
2
 
3
3
  /**
4
4
  * Derivation Types - Type definitions for derivations
@@ -1,4 +1,4 @@
1
- import { ah as Schema, a as Facts, F as FactPredicate, b4 as InferSchema, L as FactTemplate, D as DefinitionMeta, r as Requirement, bl as RequirementOutput, ag as RetryPolicy, B as BatchConfig, be as ResolverContext, ad as PredicateOp, a6 as PatchSpec, C as ClauseResult } from './plugins-5Supk7it.js';
1
+ import { ar as Schema, a as Facts, F as FactPredicate, bj as InferSchema, W as FactTemplate, D as DefinitionMeta, r as Requirement, bA as RequirementOutput, ao as RetryPolicy, B as BatchConfig, bt as ResolverContext, aj as PredicateOp, ac as PatchSpec, C as ClauseResult } from './plugins-CaPMTICa.js';
2
2
 
3
3
  /**
4
4
  * Derivation Types - Type definitions for derivations
@@ -0,0 +1,2 @@
1
+ export{a as createSystem}from'./chunk-AFPLATPV.js';import'./chunk-WVP3GOY2.js';import'./chunk-LN5H74CU.js';import'./chunk-WD47DB52.js';import'./chunk-IZNOPHPL.js';//# sourceMappingURL=system-HOP37Z4V.js.map
2
+ //# sourceMappingURL=system-HOP37Z4V.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"system-6YWCXQOQ.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"system-HOP37Z4V.js"}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkFCCJUQB2_cjs=require('./chunk-FCCJUQB2.cjs');require('./chunk-XKXTRVJF.cjs'),require('./chunk-S6W6Y44G.cjs'),require('./chunk-RD2HO5NZ.cjs'),require('./chunk-PTT4MWNL.cjs');Object.defineProperty(exports,"createSystem",{enumerable:true,get:function(){return chunkFCCJUQB2_cjs.a}});//# sourceMappingURL=system-VZUHL56W.cjs.map
2
+ //# sourceMappingURL=system-VZUHL56W.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"system-5FKUBLLV.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"system-VZUHL56W.cjs"}
package/dist/testing.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkOAPD3HIG_cjs=require('./chunk-OAPD3HIG.cjs');require('./chunk-QTY2FXZY.cjs'),require('./chunk-GACC2DMS.cjs'),require('./chunk-GKMJ7NMP.cjs'),require('./chunk-GBCWXTXW.cjs');async function R(){for(let e=0;e<10;e++)await Promise.resolve();}async function T(){for(let e=0;e<10;e++)await Promise.resolve();await new Promise(e=>setTimeout(e,0));for(let e=0;e<10;e++)await Promise.resolve();await new Promise(e=>setTimeout(e,0));for(let e=0;e<10;e++)await Promise.resolve();}async function D(e,s,r={}){let{totalTime:o=5e3,stepSize:c=10,maxIterations:l=1e3}=r,m=0,d=0;for(;m<o&&d<l;){if(await R(),e.inspect().inflight.length===0){await R();return}s(c),m+=c,d++;}let v=e.inspect();if(v.inflight.length>0){let f=v.inflight.map(p=>p.resolverId).join(", ");throw new Error(`[Directive] settleWithFakeTimers did not settle after ${o}ms. ${v.inflight.length} resolvers still inflight: ${f}`)}}function C(){let e=0,s=[];return {async advance(r){let o=e+r;for(;s.length>0&&s[0].time<=o;){let c=s.shift();e=c.time,c.callback(),await Promise.resolve();}e=o;},async next(){if(s.length===0)return;let r=s.shift();e=r.time,r.callback(),await Promise.resolve();},async runAll(){for(;s.length>0;)await this.next();},now(){return e},reset(){e=0,s.length=0;}}}function b(e){let s=typeof e=="string"?{requirement:(o=>o.type===e)}:e,r=s.calls??[];return {requirement:s.requirement??(o=>true),async resolve(o,c){if(r.push(o),s.delay&&await new Promise(l=>setTimeout(l,s.delay)),s.error)throw typeof s.error=="string"?new Error(s.error):s.error;s.resolve&&await s.resolve(o,c);}}}function E(e){let s=[],r=[];return {...{get calls(){return s},get pending(){return r},resolve(l){let m=r.shift();m&&m.resolve(l);},reject(l){let m=r.shift();m&&m.reject(l);},resolveAll(l){for(;r.length>0;)this.resolve(l);},rejectAll(l){for(;r.length>0;)this.reject(l);},reset(){s.length=0,r.length=0;}},handler:(l,m)=>(s.push(l),new Promise((d,v)=>{r.push({requirement:l,resolve:f=>d(f),reject:v});}))}}function P(e){return "module"in e?x(e):M(e)}function x(e){let s=[],r=new Map,o=[],c=[],l={};if(e.mocks?.resolvers)for(let[i,t]of Object.entries(e.mocks.resolvers)){let n=[];r.set(i,n),l[i]=b({...t,calls:n});}let m={...e.module,resolvers:{...e.module.resolvers,...l}},v=chunkOAPD3HIG_cjs.a({...e,module:m,plugins:[{name:"__test-tracking__",onFactSet:(i,t,n)=>{c.push({key:i,fullKey:i,namespace:void 0,previousValue:n,newValue:t,timestamp:Date.now()});},onRequirementCreated:i=>{o.push(i);}},...e.plugins??[]]}),f=v.dispatch.bind(v);return v.dispatch=i=>{s.push(i),f(i);},{...v,eventHistory:s,resolverCalls:r,get allRequirements(){return o},getFactsHistory(){return [...c]},resetFactsHistory(){c.length=0;},async waitForIdle(i=5e3){let t=Date.now(),n=async()=>{await new Promise(u=>setTimeout(u,0));let a=v.inspect();if(a.inflight.length>0){if(Date.now()-t>i){let u=a.inflight.map(g=>g.id).join(", ");throw new Error(`[Directive] waitForIdle timed out after ${i}ms. ${a.inflight.length} resolvers still inflight: ${u}`)}return await new Promise(u=>setTimeout(u,10)),n()}};return n()},assertRequirement(i){if(!o.some(n=>n.requirement.type===i))throw new Error(`[Directive] Expected requirement of type "${i}" but none found`)},assertResolverCalled(i,t){let n=r.get(i)??[];if(t!==void 0){if(n.length!==t)throw new Error(`[Directive] Expected resolver "${i}" to be called ${t} times but was called ${n.length} times`)}else if(n.length===0)throw new Error(`[Directive] Expected resolver "${i}" to be called but it was not`)},assertFactSet(i,t){let n=c.filter(a=>a.key===i);if(n.length===0)throw new Error(`[Directive] Expected fact "${i}" to be set but it was not`);if(t!==void 0&&!n.some(u=>u.newValue===t)){let u=n.map(g=>JSON.stringify(g.newValue)).join(", ");throw new Error(`[Directive] Expected fact "${i}" to be set to ${JSON.stringify(t)} but got: ${u}`)}},assertFactChanges(i,t){let n=c.filter(a=>a.key===i);if(n.length!==t)throw new Error(`[Directive] Expected fact "${i}" to change ${t} times but it changed ${n.length} times`)}}}function M(e){let s=[],r=new Map,o=[],c=[],l={};if(e.mocks?.resolvers)for(let[t,n]of Object.entries(e.mocks.resolvers)){let a=[];r.set(t,a),l[t]=b({...n,calls:a});}let m={};for(let[t,n]of Object.entries(e.modules))m[t]={...n,resolvers:{...n.resolvers,...l}};let d=new Set(Object.keys(e.modules)),f=chunkOAPD3HIG_cjs.a({...e,modules:m,plugins:[{name:"__test-tracking__",onFactSet:(t,n,a)=>{let g=t.indexOf("::"),y,h;if(g>0){let S=t.substring(0,g);d.has(S)?(y=S,h=t.substring(g+2)):h=t;}else h=t;c.push({key:h,fullKey:t,namespace:y,previousValue:a,newValue:n,timestamp:Date.now()});},onRequirementCreated:t=>{o.push(t);}},...e.plugins??[]]}),p=f.dispatch.bind(f);return f.dispatch=t=>{s.push(t),p(t);},{...f,eventHistory:s,resolverCalls:r,get allRequirements(){return o},getFactsHistory(){return [...c]},resetFactsHistory(){c.length=0;},async waitForIdle(t=5e3){let n=Date.now(),a=async()=>{await new Promise(g=>setTimeout(g,0));let u=f.inspect();if(u.inflight.length>0){if(Date.now()-n>t){let g=u.inflight.map(y=>y.id).join(", ");throw new Error(`[Directive] waitForIdle timed out after ${t}ms. ${u.inflight.length} resolvers still inflight: ${g}`)}return await new Promise(g=>setTimeout(g,10)),a()}};return a()},assertRequirement(t){if(!o.some(a=>a.requirement.type===t))throw new Error(`[Directive] Expected requirement of type "${t}" but none found`)},assertResolverCalled(t,n){let a=r.get(t)??[];if(n!==void 0){if(a.length!==n)throw new Error(`[Directive] Expected resolver "${t}" to be called ${n} times but was called ${a.length} times`)}else if(a.length===0)throw new Error(`[Directive] Expected resolver "${t}" to be called but it was not`)},assertFactSet(t,n){let a=c.filter(u=>u.key===t);if(a.length===0)throw new Error(`[Directive] Expected fact "${t}" to be set but it was not`);if(n!==void 0&&!a.some(g=>g.newValue===n)){let g=a.map(y=>JSON.stringify(y.newValue)).join(", ");throw new Error(`[Directive] Expected fact "${t}" to be set to ${JSON.stringify(n)} but got: ${g}`)}},assertFactChanges(t,n){let a=c.filter(u=>u.key===t);if(a.length!==n)throw new Error(`[Directive] Expected fact "${t}" to change ${n} times but it changed ${a.length} times`)}}}function O(e,s,r){if(!k(e,s,r))throw new Error(`[Directive] Expected ${s} "${r}" to be dynamic, but it is not.`)}function $(e,s,r){if(k(e,s,r))throw new Error(`[Directive] Expected ${s} "${r}" to NOT be dynamic, but it is.`)}function k(e,s,r){switch(s){case "constraint":return e.constraints.isDynamic(r);case "resolver":return e.resolvers.isDynamic(r);case "derivation":return e.derive.isDynamic(r);case "effect":return e.effects.isDynamic(r)}}function F(e){let s=new Set,r=new Set,o=new Set,c=new Set,l=null;return {async run(m){l=e.observe(d=>{switch(d.type){case "constraint.evaluate":d.active&&s.add(d.id);break;case "resolver.start":r.add(d.resolver);break;case "effect.run":o.add(d.id);break;case "derivation.compute":c.add(d.id);break}});try{await m();}finally{l?.(),l=null;}},report(){let m=e.inspect(),d=new Set(m.constraints.map(i=>i.id)),v=new Set(m.resolverDefs.map(i=>i.id)),f=new Set;for(let i of d)s.has(i)||f.add(i);let p=new Set;for(let i of v)r.has(i)||p.add(i);return {constraintsHit:s,constraintsMissed:f,resolversRun:r,resolversMissed:p,effectsRun:o,derivationsComputed:c,constraintCoverage:d.size===0?1:s.size/d.size,resolverCoverage:v.size===0?1:r.size/v.size,effectCoverage:m.effects.length===0?1:o.size/m.effects.length,derivationCoverage:m.derivations.length===0?1:c.size/m.derivations.length}}}}function I(e){let s=[],r=e.observe(o=>s.push(o));return {events:s,ofType(o){return s.filter(c=>c.type===o)},clear(){s.length=0;},dispose(){r();}}}exports.assertDynamic=O;exports.assertNotDynamic=$;exports.createCoverageTracker=F;exports.createFakeTimers=C;exports.createMockResolver=b;exports.createTestObserver=I;exports.createTestSystem=P;exports.flushAsync=T;exports.flushMicrotasks=R;exports.mockResolver=E;exports.settleWithFakeTimers=D;//# sourceMappingURL=testing.cjs.map
1
+ 'use strict';var chunkFCCJUQB2_cjs=require('./chunk-FCCJUQB2.cjs');require('./chunk-XKXTRVJF.cjs'),require('./chunk-S6W6Y44G.cjs'),require('./chunk-RD2HO5NZ.cjs'),require('./chunk-PTT4MWNL.cjs');async function R(){for(let e=0;e<10;e++)await Promise.resolve();}async function T(){for(let e=0;e<10;e++)await Promise.resolve();await new Promise(e=>setTimeout(e,0));for(let e=0;e<10;e++)await Promise.resolve();await new Promise(e=>setTimeout(e,0));for(let e=0;e<10;e++)await Promise.resolve();}async function D(e,s,r={}){let{totalTime:o=5e3,stepSize:c=10,maxIterations:l=1e3}=r,m=0,d=0;for(;m<o&&d<l;){if(await R(),e.inspect().inflight.length===0){await R();return}s(c),m+=c,d++;}let v=e.inspect();if(v.inflight.length>0){let f=v.inflight.map(p=>p.resolverId).join(", ");throw new Error(`[Directive] settleWithFakeTimers did not settle after ${o}ms. ${v.inflight.length} resolvers still inflight: ${f}`)}}function C(){let e=0,s=[];return {async advance(r){let o=e+r;for(;s.length>0&&s[0].time<=o;){let c=s.shift();e=c.time,c.callback(),await Promise.resolve();}e=o;},async next(){if(s.length===0)return;let r=s.shift();e=r.time,r.callback(),await Promise.resolve();},async runAll(){for(;s.length>0;)await this.next();},now(){return e},reset(){e=0,s.length=0;}}}function b(e){let s=typeof e=="string"?{requirement:(o=>o.type===e)}:e,r=s.calls??[];return {requirement:s.requirement??(o=>true),async resolve(o,c){if(r.push(o),s.delay&&await new Promise(l=>setTimeout(l,s.delay)),s.error)throw typeof s.error=="string"?new Error(s.error):s.error;s.resolve&&await s.resolve(o,c);}}}function E(e){let s=[],r=[];return {...{get calls(){return s},get pending(){return r},resolve(l){let m=r.shift();m&&m.resolve(l);},reject(l){let m=r.shift();m&&m.reject(l);},resolveAll(l){for(;r.length>0;)this.resolve(l);},rejectAll(l){for(;r.length>0;)this.reject(l);},reset(){s.length=0,r.length=0;}},handler:(l,m)=>(s.push(l),new Promise((d,v)=>{r.push({requirement:l,resolve:f=>d(f),reject:v});}))}}function P(e){return "module"in e?x(e):M(e)}function x(e){let s=[],r=new Map,o=[],c=[],l={};if(e.mocks?.resolvers)for(let[i,t]of Object.entries(e.mocks.resolvers)){let n=[];r.set(i,n),l[i]=b({...t,calls:n});}let m={...e.module,resolvers:{...e.module.resolvers,...l}},v=chunkFCCJUQB2_cjs.a({...e,module:m,plugins:[{name:"__test-tracking__",onFactSet:(i,t,n)=>{c.push({key:i,fullKey:i,namespace:void 0,previousValue:n,newValue:t,timestamp:Date.now()});},onRequirementCreated:i=>{o.push(i);}},...e.plugins??[]]}),f=v.dispatch.bind(v);return v.dispatch=i=>{s.push(i),f(i);},{...v,eventHistory:s,resolverCalls:r,get allRequirements(){return o},getFactsHistory(){return [...c]},resetFactsHistory(){c.length=0;},async waitForIdle(i=5e3){let t=Date.now(),n=async()=>{await new Promise(u=>setTimeout(u,0));let a=v.inspect();if(a.inflight.length>0){if(Date.now()-t>i){let u=a.inflight.map(g=>g.id).join(", ");throw new Error(`[Directive] waitForIdle timed out after ${i}ms. ${a.inflight.length} resolvers still inflight: ${u}`)}return await new Promise(u=>setTimeout(u,10)),n()}};return n()},assertRequirement(i){if(!o.some(n=>n.requirement.type===i))throw new Error(`[Directive] Expected requirement of type "${i}" but none found`)},assertResolverCalled(i,t){let n=r.get(i)??[];if(t!==void 0){if(n.length!==t)throw new Error(`[Directive] Expected resolver "${i}" to be called ${t} times but was called ${n.length} times`)}else if(n.length===0)throw new Error(`[Directive] Expected resolver "${i}" to be called but it was not`)},assertFactSet(i,t){let n=c.filter(a=>a.key===i);if(n.length===0)throw new Error(`[Directive] Expected fact "${i}" to be set but it was not`);if(t!==void 0&&!n.some(u=>u.newValue===t)){let u=n.map(g=>JSON.stringify(g.newValue)).join(", ");throw new Error(`[Directive] Expected fact "${i}" to be set to ${JSON.stringify(t)} but got: ${u}`)}},assertFactChanges(i,t){let n=c.filter(a=>a.key===i);if(n.length!==t)throw new Error(`[Directive] Expected fact "${i}" to change ${t} times but it changed ${n.length} times`)}}}function M(e){let s=[],r=new Map,o=[],c=[],l={};if(e.mocks?.resolvers)for(let[t,n]of Object.entries(e.mocks.resolvers)){let a=[];r.set(t,a),l[t]=b({...n,calls:a});}let m={};for(let[t,n]of Object.entries(e.modules))m[t]={...n,resolvers:{...n.resolvers,...l}};let d=new Set(Object.keys(e.modules)),f=chunkFCCJUQB2_cjs.a({...e,modules:m,plugins:[{name:"__test-tracking__",onFactSet:(t,n,a)=>{let g=t.indexOf("::"),y,h;if(g>0){let S=t.substring(0,g);d.has(S)?(y=S,h=t.substring(g+2)):h=t;}else h=t;c.push({key:h,fullKey:t,namespace:y,previousValue:a,newValue:n,timestamp:Date.now()});},onRequirementCreated:t=>{o.push(t);}},...e.plugins??[]]}),p=f.dispatch.bind(f);return f.dispatch=t=>{s.push(t),p(t);},{...f,eventHistory:s,resolverCalls:r,get allRequirements(){return o},getFactsHistory(){return [...c]},resetFactsHistory(){c.length=0;},async waitForIdle(t=5e3){let n=Date.now(),a=async()=>{await new Promise(g=>setTimeout(g,0));let u=f.inspect();if(u.inflight.length>0){if(Date.now()-n>t){let g=u.inflight.map(y=>y.id).join(", ");throw new Error(`[Directive] waitForIdle timed out after ${t}ms. ${u.inflight.length} resolvers still inflight: ${g}`)}return await new Promise(g=>setTimeout(g,10)),a()}};return a()},assertRequirement(t){if(!o.some(a=>a.requirement.type===t))throw new Error(`[Directive] Expected requirement of type "${t}" but none found`)},assertResolverCalled(t,n){let a=r.get(t)??[];if(n!==void 0){if(a.length!==n)throw new Error(`[Directive] Expected resolver "${t}" to be called ${n} times but was called ${a.length} times`)}else if(a.length===0)throw new Error(`[Directive] Expected resolver "${t}" to be called but it was not`)},assertFactSet(t,n){let a=c.filter(u=>u.key===t);if(a.length===0)throw new Error(`[Directive] Expected fact "${t}" to be set but it was not`);if(n!==void 0&&!a.some(g=>g.newValue===n)){let g=a.map(y=>JSON.stringify(y.newValue)).join(", ");throw new Error(`[Directive] Expected fact "${t}" to be set to ${JSON.stringify(n)} but got: ${g}`)}},assertFactChanges(t,n){let a=c.filter(u=>u.key===t);if(a.length!==n)throw new Error(`[Directive] Expected fact "${t}" to change ${n} times but it changed ${a.length} times`)}}}function O(e,s,r){if(!k(e,s,r))throw new Error(`[Directive] Expected ${s} "${r}" to be dynamic, but it is not.`)}function $(e,s,r){if(k(e,s,r))throw new Error(`[Directive] Expected ${s} "${r}" to NOT be dynamic, but it is.`)}function k(e,s,r){switch(s){case "constraint":return e.constraints.isDynamic(r);case "resolver":return e.resolvers.isDynamic(r);case "derivation":return e.derive.isDynamic(r);case "effect":return e.effects.isDynamic(r)}}function F(e){let s=new Set,r=new Set,o=new Set,c=new Set,l=null;return {async run(m){l=e.observe(d=>{switch(d.type){case "constraint.evaluate":d.active&&s.add(d.id);break;case "resolver.start":r.add(d.resolver);break;case "effect.run":o.add(d.id);break;case "derivation.compute":c.add(d.id);break}});try{await m();}finally{l?.(),l=null;}},report(){let m=e.inspect(),d=new Set(m.constraints.map(i=>i.id)),v=new Set(m.resolverDefs.map(i=>i.id)),f=new Set;for(let i of d)s.has(i)||f.add(i);let p=new Set;for(let i of v)r.has(i)||p.add(i);return {constraintsHit:s,constraintsMissed:f,resolversRun:r,resolversMissed:p,effectsRun:o,derivationsComputed:c,constraintCoverage:d.size===0?1:s.size/d.size,resolverCoverage:v.size===0?1:r.size/v.size,effectCoverage:m.effects.length===0?1:o.size/m.effects.length,derivationCoverage:m.derivations.length===0?1:c.size/m.derivations.length}}}}function I(e){let s=[],r=e.observe(o=>s.push(o));return {events:s,ofType(o){return s.filter(c=>c.type===o)},clear(){s.length=0;},dispose(){r();}}}exports.assertDynamic=O;exports.assertNotDynamic=$;exports.createCoverageTracker=F;exports.createFakeTimers=C;exports.createMockResolver=b;exports.createTestObserver=I;exports.createTestSystem=P;exports.flushAsync=T;exports.flushMicrotasks=R;exports.mockResolver=E;exports.settleWithFakeTimers=D;//# sourceMappingURL=testing.cjs.map
2
2
  //# sourceMappingURL=testing.cjs.map