@directive-run/core 1.3.0 → 1.5.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.
- package/dist/adapter-utils.cjs +1 -1
- package/dist/adapter-utils.d.cts +1 -1
- package/dist/adapter-utils.d.ts +1 -1
- package/dist/adapter-utils.js +1 -1
- package/dist/{chunk-FK7BD7XT.js → chunk-EH2Q754B.js} +3 -3
- package/dist/chunk-EH2Q754B.js.map +1 -0
- package/dist/chunk-HAF5JCET.js +16 -0
- package/dist/chunk-HAF5JCET.js.map +1 -0
- package/dist/{chunk-4CMO5OVZ.js → chunk-M5KZXNZX.js} +2 -2
- package/dist/chunk-M5KZXNZX.js.map +1 -0
- package/dist/chunk-PGUTGWUI.cjs +3 -0
- package/dist/chunk-PGUTGWUI.cjs.map +1 -0
- package/dist/{chunk-DDUARSUH.cjs → chunk-S3CFYDIB.cjs} +3 -3
- package/dist/chunk-S3CFYDIB.cjs.map +1 -0
- package/dist/chunk-SQVKCJHE.cjs +16 -0
- package/dist/chunk-SQVKCJHE.cjs.map +1 -0
- package/dist/chunk-YCCQ73C6.js +3 -0
- package/dist/chunk-YCCQ73C6.js.map +1 -0
- package/dist/{chunk-BEJ6ICA7.cjs → chunk-ZHS3EW2Z.cjs} +2 -2
- package/dist/chunk-ZHS3EW2Z.cjs.map +1 -0
- package/dist/{helpers-CfZCxxkR.d.ts → helpers-B1MiHave.d.cts} +12 -2
- package/dist/{helpers-CCljEIsG.d.cts → helpers-h9PR2JSJ.d.ts} +12 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +183 -5
- package/dist/index.d.ts +183 -5
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +1 -1
- package/dist/internals.d.cts +63 -22
- package/dist/internals.d.ts +63 -22
- package/dist/internals.js +1 -1
- package/dist/plugins/index.cjs +1 -1
- package/dist/plugins/index.cjs.map +1 -1
- package/dist/plugins/index.d.cts +11 -8
- package/dist/plugins/index.d.ts +11 -8
- package/dist/plugins/index.js +1 -1
- package/dist/plugins/index.js.map +1 -1
- package/dist/{plugins-CLZ3xci0.d.ts → plugins-Bakr7js6.d.cts} +376 -17
- package/dist/{plugins-CLZ3xci0.d.cts → plugins-Bakr7js6.d.ts} +376 -17
- package/dist/system-744ZPPES.js +2 -0
- package/dist/{system-F2QGHEG7.js.map → system-744ZPPES.js.map} +1 -1
- package/dist/system-CK3SHMXZ.cjs +2 -0
- package/dist/{system-LZMEZBOA.cjs.map → system-CK3SHMXZ.cjs.map} +1 -1
- package/dist/testing.cjs +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/worker.cjs +1 -1
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.d.cts +1 -1
- package/dist/worker.d.ts +1 -1
- package/dist/worker.js +1 -1
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-4CMO5OVZ.js.map +0 -1
- package/dist/chunk-BEJ6ICA7.cjs.map +0 -1
- package/dist/chunk-DDUARSUH.cjs.map +0 -1
- package/dist/chunk-FK7BD7XT.js.map +0 -1
- package/dist/chunk-GVVNFVEX.js +0 -3
- package/dist/chunk-GVVNFVEX.js.map +0 -1
- package/dist/chunk-JYGG4RIL.js +0 -16
- package/dist/chunk-JYGG4RIL.js.map +0 -1
- package/dist/chunk-RCCTZCZZ.cjs +0 -3
- package/dist/chunk-RCCTZCZZ.cjs.map +0 -1
- package/dist/chunk-U3DN2WML.cjs +0 -16
- package/dist/chunk-U3DN2WML.cjs.map +0 -1
- package/dist/system-F2QGHEG7.js +0 -2
- package/dist/system-LZMEZBOA.cjs +0 -2
|
@@ -226,6 +226,260 @@ interface DefinitionMeta {
|
|
|
226
226
|
[key: string]: unknown;
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Data-configuration predicates and templates.
|
|
231
|
+
*
|
|
232
|
+
* A {@link FactPredicate} is a declarative, serializable boolean spec over a
|
|
233
|
+
* module's fact + derivation namespace — the data form of a constraint
|
|
234
|
+
* `when`, an effect `on`, or a boolean derivation. A {@link FactTemplate} is
|
|
235
|
+
* the value-producing counterpart: a fact-interpolating string.
|
|
236
|
+
*
|
|
237
|
+
* Convention: `$` marks an operator/expression node inside a predicate or
|
|
238
|
+
* template body (`$eq`, `$gte`, `$all`, `$template`, `$set`, `$ref`).
|
|
239
|
+
* Definition arms (`compute`, `handler`, `patch`) stay sigil-free.
|
|
240
|
+
*
|
|
241
|
+
* Operators are `$`-prefixed so they can never collide with a fact key —
|
|
242
|
+
* schema keys starting with `$` are rejected at registration.
|
|
243
|
+
*/
|
|
244
|
+
/** Comparison operator names — the `$`-prefixed keys inside an operator object. */
|
|
245
|
+
type PredicateOp = "$eq" | "$ne" | "$in" | "$nin" | "$exists" | "$gt" | "$gte" | "$lt" | "$lte" | "$between" | "$matches" | "$startsWith" | "$endsWith" | "$contains" | "$changed";
|
|
246
|
+
/** Combinator node keys. */
|
|
247
|
+
type PredicateCombinatorKey = "$all" | "$any" | "$not";
|
|
248
|
+
/**
|
|
249
|
+
* `true` when `V` supports relational operators (`$gt` … `$between`).
|
|
250
|
+
* `[V]` tuple-wrapping suppresses distribution over union-typed facts.
|
|
251
|
+
*/
|
|
252
|
+
type IsOrderable<V> = [V] extends [number | bigint | Date] ? true : [V] extends [string] ? true : false;
|
|
253
|
+
/**
|
|
254
|
+
* The operator object permitted for a fact of type `V`. Built as a
|
|
255
|
+
* **per-operator union** (one operator per member) rather than an
|
|
256
|
+
* intersection — a typo'd operator (`$eqq`) then matches no member and is a
|
|
257
|
+
* compile error, and a relational operator on a non-orderable fact resolves
|
|
258
|
+
* to `never`.
|
|
259
|
+
*
|
|
260
|
+
* One operator per object — for two operators on the same fact, write the
|
|
261
|
+
* array form or `$all`. This is by design (the type is the source of truth).
|
|
262
|
+
*
|
|
263
|
+
* `$matches` accepts a `RegExp` only — string operands cannot express flags
|
|
264
|
+
* (case-insensitivity, dotall, etc.), so the type rejects them. Pass a real
|
|
265
|
+
* `RegExp` instance for flag control. (The runtime still accepts a string
|
|
266
|
+
* operand for one cycle for back-compat, but emits a dev-warn.)
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* const op1: OperatorObject<number> = { $gte: 30 };
|
|
271
|
+
* const op2: OperatorObject<string> = { $matches: /^J/i };
|
|
272
|
+
* const op3: OperatorObject<string> = { $in: ["red", "yellow"] };
|
|
273
|
+
* const op4: OperatorObject<string> = { $startsWith: "Ada" };
|
|
274
|
+
* const op5: OperatorObject<string> = { $endsWith: ".com" };
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
277
|
+
type OperatorObject<V> = {
|
|
278
|
+
$eq: V;
|
|
279
|
+
} | {
|
|
280
|
+
$ne: V;
|
|
281
|
+
} | {
|
|
282
|
+
$in: readonly V[];
|
|
283
|
+
} | {
|
|
284
|
+
$nin: readonly V[];
|
|
285
|
+
} | {
|
|
286
|
+
$exists: boolean;
|
|
287
|
+
} | {
|
|
288
|
+
$changed: true;
|
|
289
|
+
} | (IsOrderable<V> extends true ? {
|
|
290
|
+
$gt: V;
|
|
291
|
+
} | {
|
|
292
|
+
$gte: V;
|
|
293
|
+
} | {
|
|
294
|
+
$lt: V;
|
|
295
|
+
} | {
|
|
296
|
+
$lte: V;
|
|
297
|
+
} | {
|
|
298
|
+
$between: readonly [V, V];
|
|
299
|
+
} : never) | ([V] extends [string] ? {
|
|
300
|
+
$matches: RegExp;
|
|
301
|
+
} | {
|
|
302
|
+
$contains: string;
|
|
303
|
+
} | {
|
|
304
|
+
$startsWith: string;
|
|
305
|
+
} | {
|
|
306
|
+
$endsWith: string;
|
|
307
|
+
} : never) | ([V] extends [readonly (infer E)[]] ? {
|
|
308
|
+
$contains: E;
|
|
309
|
+
} : never);
|
|
310
|
+
/**
|
|
311
|
+
* The spec for a single fact key: a bare value (equality), an operator
|
|
312
|
+
* object, or — for an object-typed fact — a nested predicate (partial match).
|
|
313
|
+
*/
|
|
314
|
+
type PredicateField<V> = V | OperatorObject<V> | ([V] extends [readonly unknown[]] ? never : [V] extends [object] ? PredicateObject<V> : never);
|
|
315
|
+
/**
|
|
316
|
+
* Object form — every key is a fact/derivation name, every value a
|
|
317
|
+
* {@link PredicateField}. Multiple keys are AND-ed. A nested object value
|
|
318
|
+
* recurses (partial match), which is how cross-module namespaced predicates
|
|
319
|
+
* (`{ self: { phase: "red" }, auth: { token: { $exists: true } } }`) work.
|
|
320
|
+
*/
|
|
321
|
+
type PredicateObject<F> = {
|
|
322
|
+
[K in keyof F]?: PredicateField<F[K]>;
|
|
323
|
+
};
|
|
324
|
+
/** Array form — explicit clauses, AND-ed. The codegen/devtools-friendly form. */
|
|
325
|
+
type PredicateClause<F> = {
|
|
326
|
+
[K in keyof F]: {
|
|
327
|
+
readonly fact: K;
|
|
328
|
+
readonly op: PredicateOp;
|
|
329
|
+
readonly value: unknown;
|
|
330
|
+
};
|
|
331
|
+
}[keyof F];
|
|
332
|
+
/** Combinator node — exactly one of `$all` / `$any` / `$not`. */
|
|
333
|
+
type PredicateCombinator<F> = {
|
|
334
|
+
$all: readonly FactPredicate<F>[];
|
|
335
|
+
$any?: never;
|
|
336
|
+
$not?: never;
|
|
337
|
+
} | {
|
|
338
|
+
$any: readonly FactPredicate<F>[];
|
|
339
|
+
$all?: never;
|
|
340
|
+
$not?: never;
|
|
341
|
+
} | {
|
|
342
|
+
$not: FactPredicate<F>;
|
|
343
|
+
$all?: never;
|
|
344
|
+
$any?: never;
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* A declarative boolean spec over a fact namespace `F`. The data form of a
|
|
348
|
+
* constraint `when`, an effect `on`, or a boolean derivation. Accepts an
|
|
349
|
+
* object form, an array-of-clauses form, or a combinator node.
|
|
350
|
+
*
|
|
351
|
+
* Keys are **fact names only** — derivations are not addressable from inside
|
|
352
|
+
* a predicate. To gate on a derivation, either reference the underlying fact
|
|
353
|
+
* the derivation reads, or fall back to the function form of `when` / `on`.
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* ```ts
|
|
357
|
+
* // Object form (the common case)
|
|
358
|
+
* const p1: FactPredicate<{ phase: string; elapsed: number }> = {
|
|
359
|
+
* phase: "red",
|
|
360
|
+
* elapsed: { $gte: 30 },
|
|
361
|
+
* };
|
|
362
|
+
*
|
|
363
|
+
* // Combinator form
|
|
364
|
+
* const p2: FactPredicate<{ phase: string }> = {
|
|
365
|
+
* $any: [{ phase: "red" }, { phase: "yellow" }],
|
|
366
|
+
* };
|
|
367
|
+
* ```
|
|
368
|
+
*/
|
|
369
|
+
type FactPredicate<F> = PredicateObject<F> | readonly PredicateClause<F>[] | PredicateCombinator<F>;
|
|
370
|
+
/**
|
|
371
|
+
* A fact-interpolating string expression. `${key}` placeholders are replaced
|
|
372
|
+
* with the named fact's value; `$${` emits a literal `${`. The value-producing
|
|
373
|
+
* counterpart to {@link FactPredicate} — usable as a string derivation, a
|
|
374
|
+
* constraint `require` field value, or an event `patch` value.
|
|
375
|
+
*
|
|
376
|
+
* @example { $template: "Phase ${phase} for ${elapsed}s" }
|
|
377
|
+
*/
|
|
378
|
+
interface FactTemplate {
|
|
379
|
+
readonly $template: string;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* A resolver dedup key written as data: an ordered list of requirement-payload
|
|
383
|
+
* field names. `key: ["type", "to"]` dedupes requirements by those fields.
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```ts
|
|
387
|
+
* resolvers: {
|
|
388
|
+
* fetch: {
|
|
389
|
+
* requirement: "FETCH",
|
|
390
|
+
* key: ["url", "method"] satisfies KeySelector<{ url: string; method: string }>,
|
|
391
|
+
* resolve: doFetch,
|
|
392
|
+
* },
|
|
393
|
+
* }
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
type KeySelector<R> = readonly (keyof R & string)[];
|
|
397
|
+
/**
|
|
398
|
+
* A typed single-field copy from an event payload. Lives in the patch-spec
|
|
399
|
+
* namespace — used inside a {@link PatchSpec} `$set` value.
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* ```ts
|
|
403
|
+
* patch: { $set: { userId: { $ref: "id" } satisfies PayloadRef<{ id: string }> } }
|
|
404
|
+
* ```
|
|
405
|
+
*/
|
|
406
|
+
interface PayloadRef<P> {
|
|
407
|
+
readonly $ref: keyof P & string;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* A patch value: a literal, a typed payload copy, or (for string facts) a
|
|
411
|
+
* template. Lives in the patch-spec namespace — used inside a {@link PatchSpec}
|
|
412
|
+
* `$set` block.
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* ```ts
|
|
416
|
+
* const v1: PatchValue<boolean, { active: boolean }> = true;
|
|
417
|
+
* const v2: PatchValue<string, { name: string }> = { $ref: "name" };
|
|
418
|
+
* const v3: PatchValue<string, { name: string }> = { $template: "user ${name}" };
|
|
419
|
+
* ```
|
|
420
|
+
*/
|
|
421
|
+
type PatchValue<V, P> = V | PayloadRef<P> | ([V] extends [string] ? FactTemplate : never);
|
|
422
|
+
/**
|
|
423
|
+
* An event handler written as data: assigns facts from literals, payload
|
|
424
|
+
* fields (`$ref`), or interpolated strings (`$template`).
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```ts
|
|
428
|
+
* const spec: PatchSpec<{ status: string; label: string }, { name: string }> = {
|
|
429
|
+
* $set: {
|
|
430
|
+
* status: "active",
|
|
431
|
+
* label: { $template: "user ${name}" },
|
|
432
|
+
* },
|
|
433
|
+
* };
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
interface PatchSpec<F, P> {
|
|
437
|
+
readonly $set: {
|
|
438
|
+
[K in keyof F]?: PatchValue<F[K], P>;
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* The per-clause result of an explained predicate evaluation. One entry per
|
|
443
|
+
* leaf operator (`$eq`, `$gte`, …); combinator nodes (`$all`, `$any`, `$not`)
|
|
444
|
+
* may also appear as headers when the runtime emits them — hence the union
|
|
445
|
+
* over {@link PredicateCombinatorKey}.
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
* ```ts
|
|
449
|
+
* const result: ClauseResult = {
|
|
450
|
+
* path: "elapsed",
|
|
451
|
+
* op: "$gte",
|
|
452
|
+
* expected: 30,
|
|
453
|
+
* actual: 20,
|
|
454
|
+
* pass: false,
|
|
455
|
+
* };
|
|
456
|
+
* ```
|
|
457
|
+
*/
|
|
458
|
+
interface ClauseResult {
|
|
459
|
+
/** Dotted path to the fact (`elapsed`, `auth.token`). */
|
|
460
|
+
readonly path: string;
|
|
461
|
+
/** The operator applied (`$gte`, `$eq`, …) — `$eq` for a bare value. */
|
|
462
|
+
readonly op: PredicateOp | PredicateCombinatorKey;
|
|
463
|
+
/**
|
|
464
|
+
* The value the predicate expected. For combinator clauses (`$all`,
|
|
465
|
+
* `$any`, `$not`) this is the child count.
|
|
466
|
+
*/
|
|
467
|
+
readonly expected: unknown;
|
|
468
|
+
/**
|
|
469
|
+
* The actual fact value at evaluation time. For combinator clauses this
|
|
470
|
+
* is the number of child clauses that passed.
|
|
471
|
+
*/
|
|
472
|
+
readonly actual: unknown;
|
|
473
|
+
/** Whether this clause passed. */
|
|
474
|
+
readonly pass: boolean;
|
|
475
|
+
/**
|
|
476
|
+
* Children of a combinator clause (`$all`, `$any`, `$not`). Preserves the
|
|
477
|
+
* tree shape of the original predicate so renderers (devtools,
|
|
478
|
+
* `system.explain()`) can indent nested clauses.
|
|
479
|
+
*/
|
|
480
|
+
readonly children?: ClauseResult[];
|
|
481
|
+
}
|
|
482
|
+
|
|
229
483
|
/**
|
|
230
484
|
* Requirement Types - Type definitions for requirements and constraints
|
|
231
485
|
*/
|
|
@@ -274,8 +528,17 @@ interface ConstraintDef<S extends Schema, R extends Requirement = Requirement> {
|
|
|
274
528
|
priority?: number;
|
|
275
529
|
/** Mark this constraint as async (avoids runtime detection) */
|
|
276
530
|
async?: boolean;
|
|
277
|
-
/**
|
|
278
|
-
|
|
531
|
+
/**
|
|
532
|
+
* Condition the constraint requires. Either:
|
|
533
|
+
* - a function (sync or async) `(facts) => boolean`, or
|
|
534
|
+
* - a declarative {@link FactPredicate} spec — serializable, inspectable,
|
|
535
|
+
* always synchronous; e.g. `{ phase: "red", elapsed: { $gte: 30 } }`.
|
|
536
|
+
*
|
|
537
|
+
* A data `when` is normalized to a wrapper function at registration; the
|
|
538
|
+
* wrapper still reads through the tracked facts proxy, so auto-tracking
|
|
539
|
+
* captures both fact and derivation deps correctly.
|
|
540
|
+
*/
|
|
541
|
+
when: ((facts: Facts<S>) => boolean | Promise<boolean>) | FactPredicate<InferSchema<S>>;
|
|
279
542
|
/**
|
|
280
543
|
* Requirement(s) to produce when condition is met.
|
|
281
544
|
* - Single requirement: `{ type: "RESTOCK", sku: "ABC" }`
|
|
@@ -286,6 +549,24 @@ interface ConstraintDef<S extends Schema, R extends Requirement = Requirement> {
|
|
|
286
549
|
require: RequirementOutput$1<R> | ((facts: Facts<S>) => RequirementOutput$1<R>);
|
|
287
550
|
/** Timeout for async constraints (ms) */
|
|
288
551
|
timeout?: number;
|
|
552
|
+
/**
|
|
553
|
+
* Names the facts the resolver dispatched by this constraint *owns*:
|
|
554
|
+
* a write from that resolver to an
|
|
555
|
+
* owned fact is dropped — and the resolver aborted — if the fact was
|
|
556
|
+
* changed by anything else since the resolver last wrote it. Writes to
|
|
557
|
+
* facts not listed always land; `when()` is not consulted. Omit for no
|
|
558
|
+
* binding (default). Ignored on async constraints.
|
|
559
|
+
*
|
|
560
|
+
* @example
|
|
561
|
+
* ```ts
|
|
562
|
+
* executeAction: {
|
|
563
|
+
* when: (f) => f.status === 'mutating',
|
|
564
|
+
* require: { type: 'EXECUTE_ACTION' },
|
|
565
|
+
* owns: ['status'], // the resolver owns `status`
|
|
566
|
+
* }
|
|
567
|
+
* ```
|
|
568
|
+
*/
|
|
569
|
+
owns?: readonly string[];
|
|
289
570
|
/**
|
|
290
571
|
* Constraint IDs whose resolvers must complete before this constraint is evaluated.
|
|
291
572
|
* If a dependency's `when()` returns false (no requirements), this constraint proceeds.
|
|
@@ -386,6 +667,15 @@ interface EffectDef<S extends Schema> {
|
|
|
386
667
|
run(facts: Facts<S>, prev: InferSchema<S> | null): void | EffectCleanup | Promise<void | EffectCleanup>;
|
|
387
668
|
/** Optional explicit dependencies for optimization */
|
|
388
669
|
deps?: Array<keyof InferSchema<S>>;
|
|
670
|
+
/**
|
|
671
|
+
* Optional declarative trigger — a {@link FactPredicate} that gates whether
|
|
672
|
+
* `run()` fires: even when a dependency changes, the effect runs only if
|
|
673
|
+
* the predicate currently holds. Mutually exclusive with `deps` — the
|
|
674
|
+
* predicate supplies its own deps via static extraction.
|
|
675
|
+
*
|
|
676
|
+
* @example on: { phase: "red", elapsed: { $gte: 30 } }
|
|
677
|
+
*/
|
|
678
|
+
on?: FactPredicate<InferSchema<S>>;
|
|
389
679
|
/** Optional metadata for debugging and devtools (never read on hot path). */
|
|
390
680
|
meta?: DefinitionMeta;
|
|
391
681
|
}
|
|
@@ -571,8 +861,13 @@ interface ResolverDef<S extends Schema, R extends Requirement = Requirement> {
|
|
|
571
861
|
* - Function: type guard predicate (e.g., `requirement: (req) => req.type === "FETCH_USER"`)
|
|
572
862
|
*/
|
|
573
863
|
requirement: string | ((req: Requirement) => req is R);
|
|
574
|
-
/**
|
|
575
|
-
|
|
864
|
+
/**
|
|
865
|
+
* Custom dedup key for the resolver. Either:
|
|
866
|
+
* - a `RequirementKeyFn<R>` function, or
|
|
867
|
+
* - a {@link KeySelector} array of requirement-payload field names:
|
|
868
|
+
* `key: ["type", "to"]` builds a stable dedup key from those fields.
|
|
869
|
+
*/
|
|
870
|
+
key?: RequirementKeyFn<R> | KeySelector<R>;
|
|
576
871
|
/** Retry policy */
|
|
577
872
|
retry?: RetryPolicy;
|
|
578
873
|
/** Timeout for resolver execution (ms) */
|
|
@@ -1339,9 +1634,10 @@ type TypedDerivationFn<M extends ModuleSchema, K extends keyof GetDerivationsSch
|
|
|
1339
1634
|
* Typed derivations definition using the module schema.
|
|
1340
1635
|
* Each derivation key must match schema.derivations and return the declared type.
|
|
1341
1636
|
*/
|
|
1637
|
+
type TypedDerivationT<M extends ModuleSchema, K extends keyof GetDerivationsSchema<M>> = InferSchemaType<GetDerivationsSchema<M>[K]>;
|
|
1342
1638
|
type TypedDerivationsDef<M extends ModuleSchema> = {
|
|
1343
1639
|
[K in keyof GetDerivationsSchema<M>]: TypedDerivationFn<M, K> | {
|
|
1344
|
-
compute: TypedDerivationFn<M, K
|
|
1640
|
+
compute: TypedDerivationFn<M, K> | ([TypedDerivationT<M, K>] extends [boolean] ? FactPredicate<InferFacts<M>> : never) | ([TypedDerivationT<M, K>] extends [string] ? FactTemplate : never);
|
|
1345
1641
|
meta?: DefinitionMeta;
|
|
1346
1642
|
};
|
|
1347
1643
|
};
|
|
@@ -1358,6 +1654,15 @@ type TypedEventsDef<M extends ModuleSchema> = {
|
|
|
1358
1654
|
[K in keyof GetEventsSchema<M>]: TypedEventHandlerFn<M, K> | {
|
|
1359
1655
|
handler: TypedEventHandlerFn<M, K>;
|
|
1360
1656
|
meta?: DefinitionMeta;
|
|
1657
|
+
} | {
|
|
1658
|
+
/**
|
|
1659
|
+
* Declarative event body: assigns facts from literals, payload
|
|
1660
|
+
* fields ({@link KeySelector}), or interpolated strings
|
|
1661
|
+
* ({@link FactTemplate}). Use instead of `handler` for simple
|
|
1662
|
+
* "set facts from event payload" events.
|
|
1663
|
+
*/
|
|
1664
|
+
patch: PatchSpec<InferFacts<M>, InferEventPayloadFromSchema<GetEventsSchema<M>[K]>>;
|
|
1665
|
+
meta?: DefinitionMeta;
|
|
1361
1666
|
};
|
|
1362
1667
|
};
|
|
1363
1668
|
/**
|
|
@@ -1372,14 +1677,24 @@ interface TypedConstraintDef<M extends ModuleSchema> {
|
|
|
1372
1677
|
priority?: number;
|
|
1373
1678
|
/** Mark this constraint as async */
|
|
1374
1679
|
async?: boolean;
|
|
1375
|
-
/**
|
|
1376
|
-
|
|
1680
|
+
/**
|
|
1681
|
+
* Condition the constraint requires. Either a function (sync or async)
|
|
1682
|
+
* `(facts) => boolean`, or a declarative {@link FactPredicate} spec
|
|
1683
|
+
* (e.g. `{ phase: "red", elapsed: { $gte: 30 } }`).
|
|
1684
|
+
*/
|
|
1685
|
+
when: ((facts: Facts<M["facts"]>) => boolean | Promise<boolean>) | FactPredicate<InferFacts<M>>;
|
|
1377
1686
|
/**
|
|
1378
1687
|
* Requirement(s) to produce when condition is met.
|
|
1379
1688
|
*/
|
|
1380
1689
|
require: RequirementOutput<InferRequirements<M>> | ((facts: Facts<M["facts"]>) => RequirementOutput<InferRequirements<M>>);
|
|
1381
1690
|
/** Timeout for async constraints (ms) */
|
|
1382
1691
|
timeout?: number;
|
|
1692
|
+
/**
|
|
1693
|
+
* Names the facts the resolver dispatched by this constraint owns — an
|
|
1694
|
+
* external clobber of one of them drops the resolver's write. Omit for no
|
|
1695
|
+
* binding (default). Ignored on async constraints.
|
|
1696
|
+
*/
|
|
1697
|
+
owns?: readonly string[];
|
|
1383
1698
|
/**
|
|
1384
1699
|
* Constraint IDs whose resolvers must complete before this constraint is evaluated.
|
|
1385
1700
|
* If a dependency's `when()` returns false (no requirements), this constraint proceeds.
|
|
@@ -1412,14 +1727,24 @@ interface CrossModuleConstraintDef<M extends ModuleSchema, Deps extends CrossMod
|
|
|
1412
1727
|
priority?: number;
|
|
1413
1728
|
/** Mark this constraint as async */
|
|
1414
1729
|
async?: boolean;
|
|
1415
|
-
/**
|
|
1416
|
-
|
|
1730
|
+
/**
|
|
1731
|
+
* Condition the constraint requires. Either a function (sync or async)
|
|
1732
|
+
* with cross-module facts access, or a nested {@link FactPredicate}:
|
|
1733
|
+
* `{ self: { phase: "red" }, auth: { token: { $exists: true } } }`.
|
|
1734
|
+
*/
|
|
1735
|
+
when: ((facts: CrossModuleFactsWithSelf<M, Deps>) => boolean | Promise<boolean>) | FactPredicate<CrossModuleFactsWithSelf<M, Deps>>;
|
|
1417
1736
|
/**
|
|
1418
1737
|
* Requirement(s) to produce when condition is met.
|
|
1419
1738
|
*/
|
|
1420
1739
|
require: RequirementOutput<InferRequirements<M>> | ((facts: CrossModuleFactsWithSelf<M, Deps>) => RequirementOutput<InferRequirements<M>>);
|
|
1421
1740
|
/** Timeout for async constraints (ms) */
|
|
1422
1741
|
timeout?: number;
|
|
1742
|
+
/**
|
|
1743
|
+
* Names the facts the resolver dispatched by this constraint owns —
|
|
1744
|
+
* an external clobber of one of them drops the resolver's write. Omit
|
|
1745
|
+
* for no binding (default). Ignored on async constraints.
|
|
1746
|
+
*/
|
|
1747
|
+
owns?: readonly string[];
|
|
1423
1748
|
/**
|
|
1424
1749
|
* Constraint IDs whose resolvers must complete before this constraint is evaluated.
|
|
1425
1750
|
* If a dependency's `when()` returns false (no requirements), this constraint proceeds.
|
|
@@ -1452,6 +1777,11 @@ interface CrossModuleEffectDef<M extends ModuleSchema, Deps extends CrossModuleD
|
|
|
1452
1777
|
run: (facts: CrossModuleFactsWithSelf<M, Deps>, prev: CrossModuleFactsWithSelf<M, Deps> | undefined) => void | EffectCleanup | Promise<void | EffectCleanup>;
|
|
1453
1778
|
/** Optional dependency keys to filter when effect runs */
|
|
1454
1779
|
deps?: string[];
|
|
1780
|
+
/**
|
|
1781
|
+
* Optional declarative trigger — a {@link FactPredicate} that gates whether
|
|
1782
|
+
* `run()` fires. Mutually exclusive with `deps`.
|
|
1783
|
+
*/
|
|
1784
|
+
on?: FactPredicate<CrossModuleFactsWithSelf<M, Deps>>;
|
|
1455
1785
|
/** Optional metadata for debugging and devtools (never read on hot path). */
|
|
1456
1786
|
meta?: DefinitionMeta;
|
|
1457
1787
|
}
|
|
@@ -1473,7 +1803,7 @@ type CrossModuleDerivationFn<M extends ModuleSchema, Deps extends CrossModuleDep
|
|
|
1473
1803
|
*/
|
|
1474
1804
|
type CrossModuleDerivationsDef<M extends ModuleSchema, Deps extends CrossModuleDeps> = {
|
|
1475
1805
|
[K in keyof GetDerivationsSchema<M>]: CrossModuleDerivationFn<M, Deps, K> | {
|
|
1476
|
-
compute: CrossModuleDerivationFn<M, Deps, K
|
|
1806
|
+
compute: CrossModuleDerivationFn<M, Deps, K> | ([TypedDerivationT<M, K>] extends [boolean] ? FactPredicate<CrossModuleFactsWithSelf<M, Deps>> : never) | ([TypedDerivationT<M, K>] extends [string] ? FactTemplate : never);
|
|
1477
1807
|
meta?: DefinitionMeta;
|
|
1478
1808
|
};
|
|
1479
1809
|
};
|
|
@@ -1524,8 +1854,12 @@ type ExtractRequirement<M extends ModuleSchema, T extends keyof GetRequirementsS
|
|
|
1524
1854
|
interface TypedResolverDef<M extends ModuleSchema, T extends keyof GetRequirementsSchema<M> & string> {
|
|
1525
1855
|
/** Requirement type to handle */
|
|
1526
1856
|
requirement: T;
|
|
1527
|
-
/**
|
|
1528
|
-
|
|
1857
|
+
/**
|
|
1858
|
+
* Custom dedup key. Either a `(req) => string` function, or a
|
|
1859
|
+
* {@link KeySelector} array of requirement-payload field names
|
|
1860
|
+
* (`["type", "to"]`) that builds a stable key from those fields.
|
|
1861
|
+
*/
|
|
1862
|
+
key?: ((req: ExtractRequirement<M, T>) => string) | KeySelector<ExtractRequirement<M, T>>;
|
|
1529
1863
|
/** Retry policy */
|
|
1530
1864
|
retry?: RetryPolicy;
|
|
1531
1865
|
/** Timeout for resolver execution (ms) */
|
|
@@ -1786,6 +2120,11 @@ interface SystemInspection {
|
|
|
1786
2120
|
hitCount: number;
|
|
1787
2121
|
lastActiveAt: number | null;
|
|
1788
2122
|
meta?: DefinitionMeta;
|
|
2123
|
+
/**
|
|
2124
|
+
* The data-form predicate spec (when the constraint's `when` is declarative),
|
|
2125
|
+
* exposed for devtools and `explain()` rendering.
|
|
2126
|
+
*/
|
|
2127
|
+
whenSpec?: FactPredicate<Record<string, unknown>>;
|
|
1789
2128
|
}>;
|
|
1790
2129
|
resolvers: Record<string, ResolverStatus>;
|
|
1791
2130
|
/** All defined resolver names and their requirement types */
|
|
@@ -2036,7 +2375,7 @@ interface ResolversControl<M extends ModuleSchema = ModuleSchema> {
|
|
|
2036
2375
|
interface DynamicConstraintDef<M extends ModuleSchema = ModuleSchema> {
|
|
2037
2376
|
priority?: number;
|
|
2038
2377
|
async?: boolean;
|
|
2039
|
-
when: (facts: Readonly<InferSchema<M["facts"]>>) => boolean | Promise<boolean
|
|
2378
|
+
when: ((facts: Readonly<InferSchema<M["facts"]>>) => boolean | Promise<boolean>) | FactPredicate<InferSchema<M["facts"]>>;
|
|
2040
2379
|
require: {
|
|
2041
2380
|
type: string;
|
|
2042
2381
|
[key: string]: unknown;
|
|
@@ -2059,15 +2398,27 @@ interface DynamicConstraintDef<M extends ModuleSchema = ModuleSchema> {
|
|
|
2059
2398
|
interface DynamicEffectDef<M extends ModuleSchema = ModuleSchema> {
|
|
2060
2399
|
run: (facts: Readonly<InferSchema<M["facts"]>>, prev: InferSchema<M["facts"]> | null) => void | (() => void) | Promise<void | (() => void)>;
|
|
2061
2400
|
deps?: Array<string & keyof InferSchema<M["facts"]>>;
|
|
2401
|
+
/**
|
|
2402
|
+
* Optional declarative trigger — a {@link FactPredicate} that gates whether
|
|
2403
|
+
* `run()` fires. Mutually exclusive with `deps`.
|
|
2404
|
+
*/
|
|
2405
|
+
on?: FactPredicate<InferSchema<M["facts"]>>;
|
|
2062
2406
|
meta?: DefinitionMeta;
|
|
2063
2407
|
}
|
|
2064
2408
|
/** Resolver definition for dynamic registration — typed context.facts, relaxed requirement */
|
|
2065
2409
|
interface DynamicResolverDef<M extends ModuleSchema = ModuleSchema> {
|
|
2066
2410
|
requirement: string;
|
|
2067
|
-
|
|
2411
|
+
/**
|
|
2412
|
+
* Custom dedup key. Either a `(req) => string` function, or a
|
|
2413
|
+
* {@link KeySelector} array of requirement-payload field names.
|
|
2414
|
+
*/
|
|
2415
|
+
key?: ((req: {
|
|
2416
|
+
type: string;
|
|
2417
|
+
[key: string]: unknown;
|
|
2418
|
+
}) => string) | KeySelector<{
|
|
2068
2419
|
type: string;
|
|
2069
2420
|
[key: string]: unknown;
|
|
2070
|
-
}
|
|
2421
|
+
}>;
|
|
2071
2422
|
retry?: RetryPolicy;
|
|
2072
2423
|
timeout?: number;
|
|
2073
2424
|
batch?: BatchConfig;
|
|
@@ -2126,6 +2477,11 @@ type ObservationEvent = {
|
|
|
2126
2477
|
type: "constraint.evaluate";
|
|
2127
2478
|
id: string;
|
|
2128
2479
|
active: boolean;
|
|
2480
|
+
/**
|
|
2481
|
+
* Per-clause breakdown of a data-form predicate evaluation. Present
|
|
2482
|
+
* only when the constraint's `when` is a {@link FactPredicate}.
|
|
2483
|
+
*/
|
|
2484
|
+
whenExplain?: ClauseResult[];
|
|
2129
2485
|
} | {
|
|
2130
2486
|
type: "constraint.error";
|
|
2131
2487
|
id: string;
|
|
@@ -2458,8 +2814,11 @@ interface Plugin<M extends ModuleSchema = ModuleSchema> {
|
|
|
2458
2814
|
* Called after a constraint's `when` function is evaluated.
|
|
2459
2815
|
* @param id - The constraint ID
|
|
2460
2816
|
* @param active - Whether the constraint is active (when returned true)
|
|
2817
|
+
* @param whenExplain - For data-form constraints, the per-clause breakdown
|
|
2818
|
+
* (which clauses passed, which failed, against what fact values). Omitted
|
|
2819
|
+
* for function-form `when`.
|
|
2461
2820
|
*/
|
|
2462
|
-
onConstraintEvaluate?: (id: string, active: boolean) => void;
|
|
2821
|
+
onConstraintEvaluate?: (id: string, active: boolean, whenExplain?: ClauseResult[]) => void;
|
|
2463
2822
|
/**
|
|
2464
2823
|
* Called when a constraint's `when` function throws an error.
|
|
2465
2824
|
* @param id - The constraint ID
|
|
@@ -2584,4 +2943,4 @@ interface Plugin<M extends ModuleSchema = ModuleSchema> {
|
|
|
2584
2943
|
onTraceComplete?: (entry: TraceEntry) => void;
|
|
2585
2944
|
}
|
|
2586
2945
|
|
|
2587
|
-
export { type
|
|
2946
|
+
export { type OperatorObject as $, type AnySystem as A, type BatchConfig as B, type ClauseResult as C, type DefinitionMeta as D, type EffectsDef as E, type FactTemplate as F, type FactsSnapshot as G, type HistoryAPI as H, type HistoryOption as I, type HistoryState as J, type InferDerivations as K, type InferEvents as L, type ModuleSchema as M, type NamespacedSystem as N, type InferFacts as O, type PatchSpec as P, type InferRequirementTypes as Q, type RequirementWithId as R, type SchemaType as S, type TypedDerivationsDef as T, type InferRequirements as U, type InferSchemaType as V, type InferSelectorState as W, type KeySelector as X, type MetaAccessor as Y, type MetaMatch as Z, type ObservationEvent as _, type Facts as a, type RequirementsSchema as a$, type PatchValue as a0, type PayloadRef as a1, type PredicateClause as a2, type PredicateCombinator as a3, type PredicateCombinatorKey as a4, type PredicateObject as a5, type PredicateOp as a6, type RetryPolicy as a7, type Schema as a8, type Snapshot as a9, type DerivationReturnType as aA, type DerivationsControl as aB, type DerivationsSchema as aC, type DeriveAccessor as aD, type DispatchEventsFromSchema as aE, type EffectCleanup as aF, type EffectsControl as aG, type EventPayloadSchema as aH, type EventsAccessor as aI, type EventsAccessorFromSchema as aJ, type EventsDef as aK, type EventsSchema as aL, type FactKeys as aM, type FactReturnType as aN, type FlexibleEventHandler as aO, type HistoryConfig as aP, type InferEventPayloadFromSchema as aQ, type InferRequirementPayloadFromSchema as aR, type InferSchema as aS, type MutableNamespacedFacts as aT, type NamespacedDerivations as aU, type NamespacedEventsAccessor as aV, type NamespacedFacts as aW, type ObservableKeys as aX, type RequirementExplanation as aY, type RequirementOutput as aZ, type RequirementPayloadSchema$1 as a_, type System as aa, type SystemConfig as ab, type SystemInspection as ac, type SystemMode as ad, type SystemSnapshot as ae, type TraceEntry as af, isNamespacedSystem as ag, isSingleModuleSystem as ah, type FactsStore as ai, type ConstraintsDef as aj, type ConstraintState as ak, type ResolversDef as al, type ResolverStatus as am, type FactChange as an, type ReconcileResult as ao, type RecoveryStrategy as ap, type ErrorSource as aq, type RetryLaterConfig as ar, type BatchItemResult as as, type BatchResolveResults as at, type ConstraintsControl as au, type CrossModuleConstraintDef as av, type CrossModuleDerivationFn as aw, type CrossModuleEffectDef as ax, type CrossModuleFactsWithSelf as ay, type DerivationKeys as az, type TypedEventsDef as b, type ResolverContext as b0, type ResolversControl as b1, type SnapshotMeta as b2, type SystemEvent as b3, type TraceConfig as b4, type TypedConstraintDef as b5, type TypedResolverContext as b6, type TypedResolverDef as b7, type UnionEvents as b8, type RequirementOutput$1 as b9, type TypedConstraintsDef as c, type TypedResolversDef as d, type ModuleHooks as e, type CrossModuleDeps as f, type CrossModuleDerivationsDef as g, type CrossModuleEffectsDef as h, type CrossModuleConstraintsDef as i, type ModuleDef as j, type CreateSystemOptionsSingle as k, type SingleModuleSystem as l, type ModulesMap as m, type CreateSystemOptionsNamed as n, type Plugin as o, type TraceOption as p, type ErrorBoundaryConfig as q, type Requirement as r, type RequirementKeyFn as s, DirectiveError as t, type DistributableSnapshot as u, type DistributableSnapshotOptions as v, type DynamicConstraintDef as w, type DynamicEffectDef as x, type DynamicResolverDef as y, type FactPredicate as z };
|