Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@directive-run/core

Package Overview
Dependencies
Maintainers
1
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@directive-run/core - npm Package Compare versions

Comparing version
1.12.0
to
1.13.0
+378
dist/audit-ledger-Dc6hAXam.d.cts
import { F as FactPredicate, C as ClauseResult, P as Plugin, M as ModuleSchema } from './plugins-BIzXaYbg.cjs';
/**
* createAuditLedger — append-only, queryable, hash-chained
* (djb2; SHA-256 reserved for v2) audit of every state change. For
* forensics and "show me why this user got that decision."
*
* Captures (per observation event):
*
* - `constraint.evaluate` → { whenSpec, whenExplain, active, whenSource? }
* - `resolver.write.rejected` (rejection + summary kinds)
* - `fact.change` → { key, prior, next }
* - `resolver.complete` → { resolverId, requirementId, duration }
* - `system.init` / `system.start` / `system.stop` / `system.destroy`
* - `system.snapshot` / `system.history.navigate` (lifecycle markers)
* - `system.truncated` (ring-buffer overflow marker)
* - `system.entry-erased` / `system.subject-erased` (GDPR Art.17 stub)
*
* Hash chain: each entry stores `prevHash` — the djb2 (`hashObject`)
* hash of the previous entry's stable-stringified payload. Tampering
* with any entry's payload breaks the next entry's `prevHash` link —
* visible in `verify()`. v1 ships sync djb2 only; `verify({ strong: true })`
* is reserved for v2 (SHA-256) and throws today.
*
* PII redaction: by default, fact keys whose meta carries the `pii`
* tag (via `system.meta.byTag("pii")`) have their values replaced with
* `"[redacted]"` in `whenExplain.actual`, `fact.change.prior`,
* `fact.change.next`, and the cached `whenSpec` operands. Opt out with
* `capturePII: true`.
*/
/** Hash algorithm tag — bumped if canonicalization or hash function changes. */
declare const HASH_ALGO: "djb2-1";
/**
* Entry schema version. Bumped if `AuditEntry` field shape changes in
* a way that breaks back-compat parsers. Persisted on every entry so
* exports remain self-describing across library upgrades. (F-5)
*/
declare const SCHEMA_VERSION: 1;
/**
* Private sentinel stamped onto tombstone entries by {@link createAuditLedger.erase}.
* Never exported, never serialized — `verify()` checks for it before
* accepting a `system.entry-erased` entry as a legitimate chain break.
*
* (N7) Without this, a caller holding a raw `AuditLedgerSink` reference
* could write `{ kind: "system.entry-erased", … }` directly into the
* sink to mask real tampering as legitimate erasure. The sentinel
* raises the bar so only the in-process ledger plugin (which lives in
* this module's closure) can mint a valid tombstone.
*/
declare const LEDGER_INTERNAL_TOKEN: unique symbol;
type AuditEntryKind = "constraint.evaluate" | "resolver.write.rejected" | "fact.change" | "resolver.complete" | "resolver.error" | "system.init" | "system.start" | "system.stop" | "system.destroy" | "system.snapshot" | "system.history.navigate" | "system.truncated" | "system.entry-erased" | "system.subject-erased";
interface AuditEntryBase {
/** Monotonic sequence number, starting at 0. */
readonly seq: number;
/** Wall-clock timestamp (ms epoch). */
readonly ts: number;
/** Discriminator. */
readonly kind: AuditEntryKind;
/** Hash of the previous entry's full payload. null on the genesis entry. */
readonly prevHash: string | null;
/**
* Hash algorithm tag identifying the canonicalization + hash
* function in use. Bumped if the algorithm or canonical form
* changes, so exports remain verifiable across versions.
*/
readonly hashAlgo: typeof HASH_ALGO;
/**
* Entry schema version — bumped if any `AuditEntry` field shape
* changes in a way that breaks back-compat. Pair with `hashAlgo`
* when migrating older exports. (F-5)
*/
readonly schemaVersion: typeof SCHEMA_VERSION;
/**
* Private sentinel — present (and equal to the in-module token) only
* on legitimate tombstones minted by `ledger.erase()`. Filtered out
* of all public read paths (`query`, `recent`, `toJSON`, etc.) so
* consumers never see or copy it. (N7)
*
* NOT serialized. NOT exported. Forging this from outside the module
* is impossible without the symbol reference; `verify()` rejects any
* `system.entry-erased` entry that lacks it.
*
* @internal
*/
readonly __internal?: typeof LEDGER_INTERNAL_TOKEN;
}
type AuditEntry = (AuditEntryBase & {
kind: "constraint.evaluate";
constraintId: string;
active: boolean;
/** Cached at ledger start from `system.inspect().constraints[].whenSpec`. Refreshed on `register()`/`assign()`/`unregister()`. May be undefined for function-form constraints (see `whenSource`). PII operands redacted unless `capturePII: true`. */
whenSpec?: FactPredicate<unknown>;
whenExplain?: readonly ClauseResult[];
/**
* For function-form constraints (no `whenSpec`), a tamper-evident
* identity for the function. We DO NOT capture the raw source —
* closures routinely reference secrets, API keys, or PII (e.g.
* `if (apiKey === "sk-live-xxx")`) and a preview would leak them
* into the audit log. Instead, we capture a djb2 hash of the
* stringified function (`hashObject(String(fn))`). Auditors can
* detect "the function changed between deploys" by comparing
* hashes across entries, without ever seeing the function body.
*
* Informational only — NOT replayable. (N5, M22)
*/
whenSource?: {
kind: "function";
sourceHash: string;
};
}) | (AuditEntryBase & {
kind: "resolver.write.rejected";
rejection: "rejection" | "summary";
resolverId: string;
requirementId: string;
reason: string;
fact?: string;
expected?: unknown;
actual?: unknown;
dropped?: number;
}) | (AuditEntryBase & {
kind: "fact.change";
key: string;
prior: unknown;
next: unknown;
}) | (AuditEntryBase & {
kind: "resolver.complete";
resolverId: string;
requirementId: string;
duration: number;
}) | (AuditEntryBase & {
kind: "resolver.error";
resolverId: string;
requirementId: string;
error: string;
}) | (AuditEntryBase & {
kind: "system.init" | "system.start" | "system.stop" | "system.destroy";
}) | (AuditEntryBase & {
kind: "system.snapshot";
snapshotId: number;
trigger: string;
}) | (AuditEntryBase & {
kind: "system.history.navigate";
from: number;
to: number;
}) | (AuditEntryBase & {
kind: "system.truncated";
droppedSeq: number;
droppedCount: number;
}) | (AuditEntryBase & {
kind: "system.entry-erased";
originalKind: AuditEntryKind;
erasedAt: number;
}) | (AuditEntryBase & {
kind: "system.subject-erased";
/**
* djb2 hash of the filter (via `hashObject(filter)`). PII-safe —
* the raw filter values never land in the ledger. Pair with
* `filterShape` to see which filter fields were used. (N2)
*/
filterHash: string;
/**
* Stripped-values shape of the filter — captures WHICH fields were
* present without recording their values. (N2)
*/
filterShape: {
factPath: boolean;
constraintId: boolean;
kind: AuditEntryKind | readonly AuditEntryKind[] | undefined;
changedBetween: "[range]" | undefined;
};
erased: number;
});
interface QueryFilter {
/** Exact-match fact path. */
factPath?: string;
/** Filter by constraint id. */
constraintId?: string;
/** Filter by entry kind. */
kind?: AuditEntryKind | readonly AuditEntryKind[];
/** Time range as `[startMs, endMs]`, ISO strings, or epoch numbers. */
changedBetween?: [string | number | Date, string | number | Date];
/** Maximum entries returned. Default 1000. */
limit?: number;
}
/**
* Verify result — chain valid OR a break with full context for tamper visualization.
*
* Erased entries (via `ledger.erase()`) appear as legitimate chain breaks —
* `verify()` reports them in `erasedSeqs` and continues the walk from the
* tombstone's own hash. Real tamper still surfaces as `valid: false`.
*
* Forged tombstones (a caller writes `kind: "system.entry-erased"`
* directly via `sink.write()` to mask tamper as erasure) are detected:
* legitimate tombstones carry an in-module sentinel that forgeries
* cannot mint, so `verify()` reports them as tamper. (N7)
*/
type VerifyResult = {
valid: true;
entryCount: number;
/**
* Seq numbers of entries legitimately broken by `erase()`
* tombstones. NOT timestamps — each entry pairs this seq with
* the per-entry `system.entry-erased.erasedAt` (ms epoch) for
* the timestamp. Empty unless the chain contains erasures.
* (N1 + M1; renamed from `erasedAt` in R3)
*/
erasedSeqs?: number[];
} | {
valid: false;
brokenAt: number;
expectedHash: string;
actualHash: string;
entry: AuditEntry;
/**
* Human-readable reason for the break — populated for cases
* where the cause is more specific than "hash mismatch" (e.g.
* tombstone forgery detected via missing sentinel).
*/
reason?: string;
};
interface AuditLedgerSink {
write(entry: AuditEntry): void;
query(filter: QueryFilter): readonly AuditEntry[];
recent(n: number): readonly AuditEntry[];
forFact(path: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
forConstraint(id: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
toJSON(): {
entries: readonly AuditEntry[];
capturedAt: number;
};
clear(): void;
destroy(): void;
/**
* Replace matching entries with tombstones IN PLACE (preserving seq +
* prevHash so the hash chain still verifies). v1 implementation
* matches on the same `QueryFilter` shape used by `query()`.
* Returns the count of entries replaced.
*
* WARNING: erases only from this sink. Any external copies (toJSON
* exports, downstream pipelines) must be erased separately.
*/
erase?(filter: QueryFilter, tombstoneFactory: (e: AuditEntry) => AuditEntry): number;
/**
* Optional hook fired by the sink BEFORE shifting the oldest entry
* out of a bounded ring buffer. The ledger plugin uses this to emit
* a `system.truncated` marker so an auditor sees that the log was
* truncated and where. (M23)
*/
onTruncate?(handler: (droppedSeq: number, droppedCount: number) => void): void;
}
/**
* In-memory bounded ring-buffer sink. Drops oldest entries past
* `capacity` (default 10,000). Use this as the default sink for dev,
* tests, and StackBlitz demos.
*/
declare function memorySink(opts?: {
capacity?: number;
}): AuditLedgerSink;
interface AuditLedgerOptions {
/** Sink to write entries to. Default: in-memory ring buffer (capacity 10k). */
sink?: AuditLedgerSink;
/**
* Whether to capture raw fact values (`prior`/`next` on fact.change,
* `actual` in whenExplain). Default `false` — PII-tagged facts are
* redacted by default. Set `true` to opt out of redaction.
*/
capturePII?: boolean;
/**
* Optional caller-supplied redactor. Runs AFTER the default
* pii-tag-based redaction. Useful for additional sanitization.
*/
redact?: (entry: AuditEntry) => AuditEntry;
}
interface AuditLedger {
/** The plugin to pass to `createSystem({ plugins: [...] })`. */
readonly plugin: Plugin<ModuleSchema>;
/** Query entries matching the filter. */
query(filter?: QueryFilter): readonly AuditEntry[];
/** Most recent N entries (chronological). */
recent(n: number): readonly AuditEntry[];
/** All entries that touch this fact path (exact match). */
forFact(path: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
/** All entries for this constraint id. */
forConstraint(id: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
/** Full ledger snapshot for export / serialization. */
toJSON(): {
entries: readonly AuditEntry[];
capturedAt: number;
};
/**
* Walk the hash chain genesis → tip. Returns `{ valid: true }` iff
* every entry's `prevHash` matches the (sync, djb2-based) hash of
* the previous entry. On break, returns the index of the first
* broken link plus the expected vs actual hashes — feed into a
* "TAMPERED" visualization.
*
* Erased entries (via `ledger.erase()`) appear as legitimate chain
* breaks — `verify()` reports them in `erasedSeqs` and continues
* the walk from the tombstone's actual hash. Real tamper still
* surfaces as `valid: false`. (N1 + M1)
*
* Forged tombstones — `kind: "system.entry-erased"` entries written
* directly via `sink.write()` to mask tamper — are detected as
* forgery. Legitimate tombstones carry an in-module sentinel that
* forgeries cannot mint. (N7)
*
* v1 ships sync djb2 only. `verify({ strong: true })` is reserved
* for v2 (SHA-256) and THROWS today — there is no silent fallback.
* Call `verify()` (no args) for tamper detection.
*/
verify(opts?: {
strong?: boolean;
}): VerifyResult;
/**
* Per-subject erasure (GDPR Art. 17 stub). Replaces matching entries
* in this sink with `system.entry-erased` tombstones (preserving
* seq + prevHash so verify() can resync), then appends a chained
* `system.subject-erased` marker entry that summarises the erasure.
*
* Returns `{ erased, markerEntry }` — `markerEntry` is the chained
* `system.subject-erased` summary (the N per-entry tombstones live
* in the sink, not on the return value). (M7)
*
* When `erased === 0` (filter matched nothing), `markerEntry` is
* `null` and no marker is emitted into the chain — avoids polluting
* the audit trail with empty "erased: 0" records. (MAJOR-3)
*
* WARNING: v1 erases only from THIS sink. External copies (toJSON
* exports, downstream pipelines, persisted backups) must be erased
* separately. (C8)
*/
erase(filter: QueryFilter): {
erased: number;
markerEntry: AuditEntry | null;
};
/** Empty the sink. */
clear(): void;
/** Unsubscribe + drop the sink. */
destroy(): void;
}
/**
* Create an audit ledger that subscribes to the given system's
* observation stream. Returns a `Plugin` to install + a query/verify
* API for the ledger.
*
* @example
* ```ts
* import { createAuditLedger } from "@directive-run/core/plugins";
*
* const ledger = createAuditLedger();
* const system = createSystem({ module, plugins: [ledger.plugin] });
* system.start();
*
* // Six months later — auditor asks "what changed cart-total in March?"
* ledger.query({
* factPath: "cartTotal",
* changedBetween: ["2026-03-01", "2026-04-01"],
* });
*
* // Verify nobody tampered with the ledger
* const verdict = await ledger.verify();
* if (!verdict.valid) {
* console.error("Tamper at entry", verdict.brokenAt);
* }
* ```
*/
declare function createAuditLedger(opts?: AuditLedgerOptions): AuditLedger;
export { type AuditEntry as A, type QueryFilter as Q, type VerifyResult as V, type AuditEntryKind as a, type AuditLedger as b, type AuditLedgerOptions as c, type AuditLedgerSink as d, createAuditLedger as e, memorySink as m };
import { F as FactPredicate, C as ClauseResult, P as Plugin, M as ModuleSchema } from './plugins-BIzXaYbg.js';
/**
* createAuditLedger — append-only, queryable, hash-chained
* (djb2; SHA-256 reserved for v2) audit of every state change. For
* forensics and "show me why this user got that decision."
*
* Captures (per observation event):
*
* - `constraint.evaluate` → { whenSpec, whenExplain, active, whenSource? }
* - `resolver.write.rejected` (rejection + summary kinds)
* - `fact.change` → { key, prior, next }
* - `resolver.complete` → { resolverId, requirementId, duration }
* - `system.init` / `system.start` / `system.stop` / `system.destroy`
* - `system.snapshot` / `system.history.navigate` (lifecycle markers)
* - `system.truncated` (ring-buffer overflow marker)
* - `system.entry-erased` / `system.subject-erased` (GDPR Art.17 stub)
*
* Hash chain: each entry stores `prevHash` — the djb2 (`hashObject`)
* hash of the previous entry's stable-stringified payload. Tampering
* with any entry's payload breaks the next entry's `prevHash` link —
* visible in `verify()`. v1 ships sync djb2 only; `verify({ strong: true })`
* is reserved for v2 (SHA-256) and throws today.
*
* PII redaction: by default, fact keys whose meta carries the `pii`
* tag (via `system.meta.byTag("pii")`) have their values replaced with
* `"[redacted]"` in `whenExplain.actual`, `fact.change.prior`,
* `fact.change.next`, and the cached `whenSpec` operands. Opt out with
* `capturePII: true`.
*/
/** Hash algorithm tag — bumped if canonicalization or hash function changes. */
declare const HASH_ALGO: "djb2-1";
/**
* Entry schema version. Bumped if `AuditEntry` field shape changes in
* a way that breaks back-compat parsers. Persisted on every entry so
* exports remain self-describing across library upgrades. (F-5)
*/
declare const SCHEMA_VERSION: 1;
/**
* Private sentinel stamped onto tombstone entries by {@link createAuditLedger.erase}.
* Never exported, never serialized — `verify()` checks for it before
* accepting a `system.entry-erased` entry as a legitimate chain break.
*
* (N7) Without this, a caller holding a raw `AuditLedgerSink` reference
* could write `{ kind: "system.entry-erased", … }` directly into the
* sink to mask real tampering as legitimate erasure. The sentinel
* raises the bar so only the in-process ledger plugin (which lives in
* this module's closure) can mint a valid tombstone.
*/
declare const LEDGER_INTERNAL_TOKEN: unique symbol;
type AuditEntryKind = "constraint.evaluate" | "resolver.write.rejected" | "fact.change" | "resolver.complete" | "resolver.error" | "system.init" | "system.start" | "system.stop" | "system.destroy" | "system.snapshot" | "system.history.navigate" | "system.truncated" | "system.entry-erased" | "system.subject-erased";
interface AuditEntryBase {
/** Monotonic sequence number, starting at 0. */
readonly seq: number;
/** Wall-clock timestamp (ms epoch). */
readonly ts: number;
/** Discriminator. */
readonly kind: AuditEntryKind;
/** Hash of the previous entry's full payload. null on the genesis entry. */
readonly prevHash: string | null;
/**
* Hash algorithm tag identifying the canonicalization + hash
* function in use. Bumped if the algorithm or canonical form
* changes, so exports remain verifiable across versions.
*/
readonly hashAlgo: typeof HASH_ALGO;
/**
* Entry schema version — bumped if any `AuditEntry` field shape
* changes in a way that breaks back-compat. Pair with `hashAlgo`
* when migrating older exports. (F-5)
*/
readonly schemaVersion: typeof SCHEMA_VERSION;
/**
* Private sentinel — present (and equal to the in-module token) only
* on legitimate tombstones minted by `ledger.erase()`. Filtered out
* of all public read paths (`query`, `recent`, `toJSON`, etc.) so
* consumers never see or copy it. (N7)
*
* NOT serialized. NOT exported. Forging this from outside the module
* is impossible without the symbol reference; `verify()` rejects any
* `system.entry-erased` entry that lacks it.
*
* @internal
*/
readonly __internal?: typeof LEDGER_INTERNAL_TOKEN;
}
type AuditEntry = (AuditEntryBase & {
kind: "constraint.evaluate";
constraintId: string;
active: boolean;
/** Cached at ledger start from `system.inspect().constraints[].whenSpec`. Refreshed on `register()`/`assign()`/`unregister()`. May be undefined for function-form constraints (see `whenSource`). PII operands redacted unless `capturePII: true`. */
whenSpec?: FactPredicate<unknown>;
whenExplain?: readonly ClauseResult[];
/**
* For function-form constraints (no `whenSpec`), a tamper-evident
* identity for the function. We DO NOT capture the raw source —
* closures routinely reference secrets, API keys, or PII (e.g.
* `if (apiKey === "sk-live-xxx")`) and a preview would leak them
* into the audit log. Instead, we capture a djb2 hash of the
* stringified function (`hashObject(String(fn))`). Auditors can
* detect "the function changed between deploys" by comparing
* hashes across entries, without ever seeing the function body.
*
* Informational only — NOT replayable. (N5, M22)
*/
whenSource?: {
kind: "function";
sourceHash: string;
};
}) | (AuditEntryBase & {
kind: "resolver.write.rejected";
rejection: "rejection" | "summary";
resolverId: string;
requirementId: string;
reason: string;
fact?: string;
expected?: unknown;
actual?: unknown;
dropped?: number;
}) | (AuditEntryBase & {
kind: "fact.change";
key: string;
prior: unknown;
next: unknown;
}) | (AuditEntryBase & {
kind: "resolver.complete";
resolverId: string;
requirementId: string;
duration: number;
}) | (AuditEntryBase & {
kind: "resolver.error";
resolverId: string;
requirementId: string;
error: string;
}) | (AuditEntryBase & {
kind: "system.init" | "system.start" | "system.stop" | "system.destroy";
}) | (AuditEntryBase & {
kind: "system.snapshot";
snapshotId: number;
trigger: string;
}) | (AuditEntryBase & {
kind: "system.history.navigate";
from: number;
to: number;
}) | (AuditEntryBase & {
kind: "system.truncated";
droppedSeq: number;
droppedCount: number;
}) | (AuditEntryBase & {
kind: "system.entry-erased";
originalKind: AuditEntryKind;
erasedAt: number;
}) | (AuditEntryBase & {
kind: "system.subject-erased";
/**
* djb2 hash of the filter (via `hashObject(filter)`). PII-safe —
* the raw filter values never land in the ledger. Pair with
* `filterShape` to see which filter fields were used. (N2)
*/
filterHash: string;
/**
* Stripped-values shape of the filter — captures WHICH fields were
* present without recording their values. (N2)
*/
filterShape: {
factPath: boolean;
constraintId: boolean;
kind: AuditEntryKind | readonly AuditEntryKind[] | undefined;
changedBetween: "[range]" | undefined;
};
erased: number;
});
interface QueryFilter {
/** Exact-match fact path. */
factPath?: string;
/** Filter by constraint id. */
constraintId?: string;
/** Filter by entry kind. */
kind?: AuditEntryKind | readonly AuditEntryKind[];
/** Time range as `[startMs, endMs]`, ISO strings, or epoch numbers. */
changedBetween?: [string | number | Date, string | number | Date];
/** Maximum entries returned. Default 1000. */
limit?: number;
}
/**
* Verify result — chain valid OR a break with full context for tamper visualization.
*
* Erased entries (via `ledger.erase()`) appear as legitimate chain breaks —
* `verify()` reports them in `erasedSeqs` and continues the walk from the
* tombstone's own hash. Real tamper still surfaces as `valid: false`.
*
* Forged tombstones (a caller writes `kind: "system.entry-erased"`
* directly via `sink.write()` to mask tamper as erasure) are detected:
* legitimate tombstones carry an in-module sentinel that forgeries
* cannot mint, so `verify()` reports them as tamper. (N7)
*/
type VerifyResult = {
valid: true;
entryCount: number;
/**
* Seq numbers of entries legitimately broken by `erase()`
* tombstones. NOT timestamps — each entry pairs this seq with
* the per-entry `system.entry-erased.erasedAt` (ms epoch) for
* the timestamp. Empty unless the chain contains erasures.
* (N1 + M1; renamed from `erasedAt` in R3)
*/
erasedSeqs?: number[];
} | {
valid: false;
brokenAt: number;
expectedHash: string;
actualHash: string;
entry: AuditEntry;
/**
* Human-readable reason for the break — populated for cases
* where the cause is more specific than "hash mismatch" (e.g.
* tombstone forgery detected via missing sentinel).
*/
reason?: string;
};
interface AuditLedgerSink {
write(entry: AuditEntry): void;
query(filter: QueryFilter): readonly AuditEntry[];
recent(n: number): readonly AuditEntry[];
forFact(path: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
forConstraint(id: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
toJSON(): {
entries: readonly AuditEntry[];
capturedAt: number;
};
clear(): void;
destroy(): void;
/**
* Replace matching entries with tombstones IN PLACE (preserving seq +
* prevHash so the hash chain still verifies). v1 implementation
* matches on the same `QueryFilter` shape used by `query()`.
* Returns the count of entries replaced.
*
* WARNING: erases only from this sink. Any external copies (toJSON
* exports, downstream pipelines) must be erased separately.
*/
erase?(filter: QueryFilter, tombstoneFactory: (e: AuditEntry) => AuditEntry): number;
/**
* Optional hook fired by the sink BEFORE shifting the oldest entry
* out of a bounded ring buffer. The ledger plugin uses this to emit
* a `system.truncated` marker so an auditor sees that the log was
* truncated and where. (M23)
*/
onTruncate?(handler: (droppedSeq: number, droppedCount: number) => void): void;
}
/**
* In-memory bounded ring-buffer sink. Drops oldest entries past
* `capacity` (default 10,000). Use this as the default sink for dev,
* tests, and StackBlitz demos.
*/
declare function memorySink(opts?: {
capacity?: number;
}): AuditLedgerSink;
interface AuditLedgerOptions {
/** Sink to write entries to. Default: in-memory ring buffer (capacity 10k). */
sink?: AuditLedgerSink;
/**
* Whether to capture raw fact values (`prior`/`next` on fact.change,
* `actual` in whenExplain). Default `false` — PII-tagged facts are
* redacted by default. Set `true` to opt out of redaction.
*/
capturePII?: boolean;
/**
* Optional caller-supplied redactor. Runs AFTER the default
* pii-tag-based redaction. Useful for additional sanitization.
*/
redact?: (entry: AuditEntry) => AuditEntry;
}
interface AuditLedger {
/** The plugin to pass to `createSystem({ plugins: [...] })`. */
readonly plugin: Plugin<ModuleSchema>;
/** Query entries matching the filter. */
query(filter?: QueryFilter): readonly AuditEntry[];
/** Most recent N entries (chronological). */
recent(n: number): readonly AuditEntry[];
/** All entries that touch this fact path (exact match). */
forFact(path: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
/** All entries for this constraint id. */
forConstraint(id: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
/** Full ledger snapshot for export / serialization. */
toJSON(): {
entries: readonly AuditEntry[];
capturedAt: number;
};
/**
* Walk the hash chain genesis → tip. Returns `{ valid: true }` iff
* every entry's `prevHash` matches the (sync, djb2-based) hash of
* the previous entry. On break, returns the index of the first
* broken link plus the expected vs actual hashes — feed into a
* "TAMPERED" visualization.
*
* Erased entries (via `ledger.erase()`) appear as legitimate chain
* breaks — `verify()` reports them in `erasedSeqs` and continues
* the walk from the tombstone's actual hash. Real tamper still
* surfaces as `valid: false`. (N1 + M1)
*
* Forged tombstones — `kind: "system.entry-erased"` entries written
* directly via `sink.write()` to mask tamper — are detected as
* forgery. Legitimate tombstones carry an in-module sentinel that
* forgeries cannot mint. (N7)
*
* v1 ships sync djb2 only. `verify({ strong: true })` is reserved
* for v2 (SHA-256) and THROWS today — there is no silent fallback.
* Call `verify()` (no args) for tamper detection.
*/
verify(opts?: {
strong?: boolean;
}): VerifyResult;
/**
* Per-subject erasure (GDPR Art. 17 stub). Replaces matching entries
* in this sink with `system.entry-erased` tombstones (preserving
* seq + prevHash so verify() can resync), then appends a chained
* `system.subject-erased` marker entry that summarises the erasure.
*
* Returns `{ erased, markerEntry }` — `markerEntry` is the chained
* `system.subject-erased` summary (the N per-entry tombstones live
* in the sink, not on the return value). (M7)
*
* When `erased === 0` (filter matched nothing), `markerEntry` is
* `null` and no marker is emitted into the chain — avoids polluting
* the audit trail with empty "erased: 0" records. (MAJOR-3)
*
* WARNING: v1 erases only from THIS sink. External copies (toJSON
* exports, downstream pipelines, persisted backups) must be erased
* separately. (C8)
*/
erase(filter: QueryFilter): {
erased: number;
markerEntry: AuditEntry | null;
};
/** Empty the sink. */
clear(): void;
/** Unsubscribe + drop the sink. */
destroy(): void;
}
/**
* Create an audit ledger that subscribes to the given system's
* observation stream. Returns a `Plugin` to install + a query/verify
* API for the ledger.
*
* @example
* ```ts
* import { createAuditLedger } from "@directive-run/core/plugins";
*
* const ledger = createAuditLedger();
* const system = createSystem({ module, plugins: [ledger.plugin] });
* system.start();
*
* // Six months later — auditor asks "what changed cart-total in March?"
* ledger.query({
* factPath: "cartTotal",
* changedBetween: ["2026-03-01", "2026-04-01"],
* });
*
* // Verify nobody tampered with the ledger
* const verdict = await ledger.verify();
* if (!verdict.valid) {
* console.error("Tamper at entry", verdict.brokenAt);
* }
* ```
*/
declare function createAuditLedger(opts?: AuditLedgerOptions): AuditLedger;
export { type AuditEntry as A, type QueryFilter as Q, type VerifyResult as V, type AuditEntryKind as a, type AuditLedger as b, type AuditLedgerOptions as c, type AuditLedgerSink as d, createAuditLedger as e, memorySink as m };
import {a,e}from'./chunk-PXRV64PA.js';var g=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),Q=new Set(["$all","$any","$not"]);var T=new Set(["number","string","boolean","bigint","date","unknown"]);function P(e){if(!e)return {kind:"unknown"};let n=/^Branded<(.+)>$/.exec(e);return n?{kind:"branded",inner:P(n[1])}:e.endsWith(" | null")||e.endsWith(" | undefined")?{...P(e.replace(/ \| (null|undefined)$/,"")),nullable:true}:T.has(e)?{kind:e}:/^(email|uuid|url|cuid|datetime|iso\b)/i.test(e)?{kind:"string"}:e.includes(" | ")?{kind:"union",members:e.split(" | ").map(P)}:e==="array"?{kind:"array",element:{kind:"unknown"}}:e==="object"?{kind:"object",shape:{}}:e==="record"?{kind:"record",value:{kind:"unknown"}}:e==="tuple"?{kind:"tuple",elements:[]}:e==="union"?{kind:"union",members:[]}:{kind:"unknown"}}function z(e){if(e==null)return {kind:"unknown"};if(typeof e=="function")return a&&console.warn("[Directive] getKind: received a function \u2014 did you forget () on a t.* builder? Example: write `t.number()`, not `t.number`."),{kind:"unknown"};if(typeof e!="object")return {kind:"unknown"};let n=e,r;try{r=n._kind;}catch{return {kind:"unknown"}}if(r)return r;let i;try{i=n._typeName;}catch{return {kind:"unknown"}}return P(i)}function H(e){let n=new Map;if(!e||typeof e!="object")return n;let r=e,t="facts"in r&&r.facts&&typeof r.facts=="object"?r.facts:r;for(let[a,s]of Object.entries(t)){if(!s||typeof s!="object")continue;let o;try{o=z(s);}catch{continue}if(n.set(a,o),o.kind==="object")for(let[c,l]of Object.entries(o.shape))n.set(`${a}.${c}`,l);}return n.size===0&&a&&console.warn("[Directive] getSchemaFieldKinds: schema appears empty (no introspectable keys). Did you pass the module instead of its schema? Pass `myModule.schema`, not `myModule`."),n}var k=["$eq","$ne","$in","$nin","$exists"],D=["$gt","$gte","$lt","$lte","$between"],W=["$matches","$startsWith","$endsWith","$contains"];function w(e){switch(e.kind){case "number":case "bigint":case "date":return [...k,...D];case "string":return [...k,...D,...W];case "boolean":case "unknown":return k;case "array":return [...k,"$contains"];case "object":case "record":case "tuple":return k;case "literal":case "enum":return w(e.primitive==="number"?{kind:"number"}:e.primitive==="boolean"?{kind:"boolean"}:e.primitive==="null"?{kind:"unknown"}:{kind:"string"});case "branded":return w(e.inner);case "union":{if(e.members.length===0)return k;let n=e.members.map(t=>new Set(w(t))),r=n[0],i=[];for(let t of r)n.every(a=>a.has(t))&&i.push(t);return i}default:{return k}}}function X(){return Array.from(g)}var O=64;function u(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function x(e){if(typeof e!="object"||e===null||Array.isArray(e))return false;let n=Object.getPrototypeOf(e);return n===Object.prototype||n===null}function E(e){if(!u(e))return false;let n=0,r=false;for(let i of Object.keys(e)){if(i.startsWith("$"))r=true,g.has(i)||f(`predicate: unknown operator "${i}" \u2014 looks like a typo. Known operators: ${[...g].join(", ")}`);else if(r||n===0)return false;n++;}return r?n>0:false}function re(e){return e===null?false:Array.isArray(e)?e.every(n=>x(n)&&"fact"in n&&"op"in n):x(e)}function h(e,n,r="",i=new WeakSet,t=0){if(t>O){a&&console.warn(`[Directive] predicate depth limit (${O}) exceeded \u2014 flatten the predicate or split it into multiple constraints. If this is unexpected, check for a cyclic spec object.`),n.bail?.("depth");return}if(Array.isArray(e)){e.forEach((s,o)=>{if(!u(s))return;let c=s;if(typeof c.fact=="string"&&typeof c.op=="string"){let l=r?`${r}[${o}]`:`[${o}]`;n.operator?.(r?`${r}.${c.fact}`:c.fact,c.op,c.value,`${l}.value`);}});return}if(!u(e))return;if(i.has(e)){a&&console.warn("[Directive] walkPredicate: cyclic predicate spec"),n.bail?.("cycle");return}i.add(e);let a$1=e;for(let s of ["$all","$any","$not"])if(s in a$1){if(n.combinator?.(s)===false)return;let c=s==="$not"?[a$1.$not]:a$1[s]??[];for(let l of c)h(l,n,r,i,t+1);return}for(let s of Object.keys(a$1)){let o=r?`${r}.${s}`:s;if(s.startsWith("$")){n.strayOperatorKey?.(s,o);continue}let c=a$1[s];if(E(c)){let l=c;for(let p of Object.keys(l))n.operator?.(o,p,l[p],`${o}.${p}`);continue}if(x(c)){if(n.nested?.(s)===false)continue;h(c,n,o,i,t+1);continue}n.literal?.(o,c);}}function ie(e){if(!x(e))return false;let n=false;return h(e,{operator(){n=true;},literal(){n=true;},combinator(){n=true;},strayOperatorKey(){n=true;},bail(){n=true;}}),!n}function I(e){return u(e)&&Object.hasOwn(e,"$template")&&typeof e.$template=="string"}function oe(e,n=""){function r(t,a,s,o){if(typeof t=="bigint")throw new Error(`[Directive] validatePredicate: bigint operand at "${a}" is not JSON-serializable (JSON.stringify throws on bigint).`);if(t instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand at "${a}" is not JSON-serializable (serializes to {} and loses all members).`);if(t instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand at "${a}" is not JSON-serializable (serializes to {} and loses all entries).`);if(t instanceof RegExp)throw new Error(`[Directive] validatePredicate: RegExp operand at "${a}" is not JSON-serializable (a regex lost to JSON.parse becomes {}). Only a direct $matches operand may be a RegExp.`);if(!(t===null||typeof t!="object")&&!(o>O)&&!s.has(t)){if(s.add(t),Array.isArray(t)){t.forEach((c,l)=>{r(c,`${a}[${l}]`,s,o+1);});return}for(let c of Object.keys(t))r(t[c],a?`${a}.${c}`:c,s,o+1);}}function i(t,a,s){if(typeof t=="bigint")throw new Error(`[Directive] validatePredicate: bigint operand at "${s}" is not JSON-serializable (JSON.stringify throws on bigint).`);if(t instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand at "${s}" is not JSON-serializable (serializes to {} and loses all members).`);if(t instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand at "${s}" is not JSON-serializable (serializes to {} and loses all entries).`);if(a==="$matches"&&!(t instanceof RegExp))throw new Error(`[Directive] validatePredicate: $matches operand at "${s}" must be a RegExp; got ${t===null?"null":typeof t}. A regex lost to JSON.parse becomes {} \u2014 reify with new RegExp(pattern, flags) before installing.`);if(Array.isArray(t))t.forEach((o,c)=>{r(o,`${s}[${c}]`,new WeakSet,1);});else if(x(t))for(let o of Object.keys(t))r(t[o],`${s}.${o}`,new WeakSet,1);}if(e instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand${n?` at "${n}"`:""} is not JSON-serializable (serializes to {} and loses all members).`);if(e instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand${n?` at "${n}"`:""} is not JSON-serializable (serializes to {} and loses all entries).`);h(e,{operator(t,a,s,o){i(s,a,n?`${n}.${o}`:o);},literal(t,a){i(a,"",n?`${n}.${t}`:t);}});}function M(e){return typeof e!="string"||e.length===0?false:!!(/\)(?:[+*]\??|\{\d+,?\d*\})\s*[+*?]\s*[+*]/.test(e)||/\(([^()]*?[+*]|[^()]*?\{\d+,?\d*\})[^()]*\)\s*[+*]/.test(e)||/\(\??:?([^()|]+)\|\1\)\s*[+*]/.test(e))}function se(e,n,r={}){let i=[],t=0,a=r.maxOperatorCount,s=r.maxArrayOperandLength;return h(e,{operator(o,c,l,p){if(t++,a!==void 0&&t>a){i.some($=>$.reason.includes("maxOperatorCount"))||i.push({path:o,op:c,reason:`Predicate exceeds maxOperatorCount=${a} \u2014 too many clauses (DoS guard).`});return}if(s!==void 0&&(c==="$in"||c==="$nin")&&Array.isArray(l)&&l.length>s){i.push({path:o,op:c,reason:`Operator ${c} operand exceeds maxArrayOperandLength=${s} (got ${l.length}) \u2014 too large for a query planner.`});return}if(c==="$matches"){let $;if(l instanceof RegExp?$=l.source:typeof l=="string"&&($=l),$!==void 0&&M($)){i.push({path:o,op:c,reason:`Operator $matches operand at "${o}" contains nested quantifiers (ReDoS risk: ${JSON.stringify($)}). Reject untrusted regex or rewrite without nested + / *.`});return}}let m=n.get(o);if(!m){i.push({path:o,op:c,reason:`Unknown fact "${o}" \u2014 not in schema. Known facts: ${n.size===0?"(empty schema)":Array.from(n.keys()).join(", ")}`});return}let y=w(m);y.includes(c)||i.push({path:o,op:c,kind:m,allowedOps:y,reason:`Operator "${c}" is not allowed on fact "${o}" of kind "${m.kind}". Allowed operators for this kind: ${y.join(", ")}.`});},literal(o,c){t++,n.has(o)||i.push({path:o,op:"$eq",reason:`Unknown fact "${o}" \u2014 not in schema.`});},strayOperatorKey(o,c){i.push({path:c,op:o,reason:`Stray operator key "${o}" at "${c}" \u2014 operators must live inside a fact's operator object, not at the predicate top level.`});}}),i.length===0?{ok:true,operatorCount:t}:{ok:false,errors:i,operatorCount:t}}function _(){return {ids:new WeakMap,next:{v:1},pairs:new Set}}function v(e,n){let r=e.ids.get(n);return r===void 0&&(r=e.next.v++,e.ids.set(n,r)),r}function d(e,n,r){if(Object.is(e,n))return true;if(e instanceof Date&&n instanceof Date)return e.getTime()===n.getTime();if(typeof e!="object"||typeof n!="object"||e===null||n===null)return false;let i=r??_(),t=`${v(i,e)}:${v(i,n)}`;if(i.pairs.has(t))return true;if(i.pairs.add(t),Array.isArray(e)||Array.isArray(n))return !Array.isArray(e)||!Array.isArray(n)||e.length!==n.length?false:e.every((o,c)=>d(o,n[c],i));if(e instanceof Set||n instanceof Set){if(!(e instanceof Set)||!(n instanceof Set)||e.size!==n.size)return false;let o=[...n];return [...e].every(c=>o.some(l=>d(c,l,i)))}if(e instanceof Map||n instanceof Map){if(!(e instanceof Map)||!(n instanceof Map)||e.size!==n.size)return false;let o=[...n.entries()],c=new Array(o.length).fill(false);for(let[l,p]of e){let m=false;for(let y=0;y<o.length;y++){if(c[y])continue;let[$,N]=o[y];if(d(l,$,i)&&d(p,N,i)){c[y]=true,m=true;break}}if(!m)return false}return true}let a=Object.keys(e),s=Object.keys(n);return a.length!==s.length?false:a.every(o=>Object.hasOwn(n,o)&&d(e[o],n[o],i))}function j(e){if(e instanceof Date)return e.getTime();if(typeof e=="number"||typeof e=="bigint"||typeof e=="string")return e}function A(e,n,r){let i=j(n),t=j(r);if(i===void 0||t===void 0||typeof i!=typeof t)return false;switch(e){case "$gt":return i>t;case "$gte":return i>=t;case "$lt":return i<t;case "$lte":return i<=t;default:return false}}function R(e,n,r,i){switch(e){case "$eq":return d(n,r);case "$ne":return !d(n,r);case "$in":return Array.isArray(r)&&r.some(t=>d(n,t));case "$nin":return Array.isArray(r)&&!r.some(t=>d(n,t));case "$exists":return r===(n!==void 0);case "$changed":return !d(n,i);case "$gt":case "$gte":case "$lt":case "$lte":return A(e,n,r);case "$between":{if(!Array.isArray(r)||r.length!==2)return false;let t=j(r[0]),a=j(r[1]);return t!==void 0&&a!==void 0&&typeof t==typeof a&&t>a?(f("$between: reversed pair \u2014 [min, max] required"),false):A("$gte",n,r[0])&&A("$lte",n,r[1])}case "$matches":{if(!(r instanceof RegExp))throw new Error("[Directive] $matches: operand must be a RegExp (string operands are no longer accepted; pass /pattern/flags directly).");return typeof n!="string"?false:r.test(n)}case "$startsWith":return typeof n!="string"?false:n.startsWith(String(r));case "$endsWith":return typeof n!="string"?false:n.endsWith(String(r));case "$contains":return typeof n=="string"?n.includes(String(r)):Array.isArray(n)?n.some(t=>d(t,r)):n instanceof Set?n.has(r):false;default:return false}}function f(e){a&&console.warn(`[Directive] ${e}`);}function q(e,n,r,i){if(E(e)){let t=Object.keys(e);t.length>1&&f(`predicate: operator object has ${t.length} operators (${t.join(", ")}) \u2014 write the array form or $all instead. The runtime ANDs them as a best-effort fallback.`);for(let a of t)if(!R(a,n,e[a],r))return false;return true}return u(e)?S(e,u(n)?n:Object.create(null),u(r)?r:void 0,i+1):d(n,e)}function S(e,n,r,i=0){if(i>O)return f(`predicate depth limit (${O}) exceeded \u2014 flatten the predicate or split it into multiple constraints. If this is unexpected, check for a cyclic spec object.`),false;if(Array.isArray(e))return e.every(t=>{if(!u(t))return false;let{fact:a,op:s,value:o}=t;return R(s,n?.[a],o,r?.[a])});if(!u(e))return !!e;if("$all"in e)return e.$all.every(t=>S(t,n,r,i+1));if("$any"in e)return e.$any.some(t=>S(t,n,r,i+1));if("$not"in e)return !S(e.$not,n,r,i+1);for(let t of Object.keys(e)){if(g.has(t))return f(`predicate: operator "${t}" mixed with fact keys \u2014 wrap operators in a per-fact object`),false;if(!q(e[t],n?.[t],r?.[t],i))return false}return true}function V(e,n,r,i=""){let t=[];if(Array.isArray(e)){for(let a of e){if(!u(a))continue;let{fact:s,op:o,value:c}=a,l=n?.[s];t.push({path:i+s,op:o,expected:c,actual:l,pass:R(o,l,c,r?.[s])});}return t}if(!u(e))return t;for(let a of ["$all","$any","$not"])if(a in e){let s=a==="$not"?[e.$not]:e[a],o=[];for(let p of s)o.push(...V(p,n,r,i));let c=o.filter(p=>p.pass).length,l;return a==="$all"?l=o.length===0||c===o.length:a==="$any"?l=o.length>0&&c>0:l=!o.every(p=>p.pass),t.push({path:i||a,op:a,expected:s.length,actual:c,pass:l,children:o}),t}for(let a of Object.keys(e)){if(g.has(a))continue;let s=e[a],o=n?.[a],c=i+a;if(E(s))for(let l of Object.keys(s))t.push({path:c,op:l,expected:s[l],actual:o,pass:R(l,o,s[l],r?.[a])});else u(s)?t.push(...V(s,u(o)?o:Object.create(null),u(r?.[a])?r?.[a]:void 0,`${c}.`)):t.push({path:c,op:"$eq",expected:s,actual:o,pass:d(o,s)});}return t}var F=new WeakMap;function ce(e){if(e===null||typeof e!="object")throw new Error(`[Directive] memoizePredicate: predicate must be a plain object or array; got ${typeof e}`);let n=F.get(e);if(n)return n;let r=(i,t)=>S(e,i,t);return F.set(e,r),r}function le(e,n=""){let r=new Set;return h(e,{operator(i){r.add(n+i);},literal(i){r.add(n+i);},strayOperatorKey(i){g.has(i)||f(`extractDeps: unknown operator "${i}" \u2014 skipping. Known operators: ${[...g].join(", ")}`);}}),r}var C=/^[A-Za-z_][A-Za-z0-9_]*$/;function J(e){return typeof e=="symbol"||e==null?"":String(e)}function B(e,n){return typeof e=="symbol"?(f("template: cannot interpolate a symbol value \u2014 using empty string"),""):e===void 0?(f(`template: ${n?`key "${n}" is `:""}undefined \u2014 using empty string`),""):e===null?(f(`template: ${n?`key "${n}" is `:""}null \u2014 using empty string`),""):String(e)}function L(e,n){let r=e.$template,i="",t=0;for(;t<r.length;){if(r[t]==="$"&&r[t+1]==="$"&&r[t+2]==="{"){i+="${",t+=3;continue}if(r[t]==="$"&&r[t+1]==="{"){let a=r.indexOf("}",t+2);if(a===-1){f(`template: unterminated "\${" in ${JSON.stringify(r)}`),i+=r.slice(t);break}let s=r.slice(t+2,a);if(!C.test(s))f(`template: invalid placeholder "\${${s}}" \u2014 not an identifier`);else {let o=n!=null&&Object.hasOwn(n,s),c=o?n[s]:void 0;o?i+=B(c,s):(f(`template: unknown key "${s}"`),i+=J(c));}t=a+1;continue}i+=r[t],t++;}return i}function ue(e){let n=new Set,r=e.$template,i=0;for(;i<r.length;){if(r[i]==="$"&&r[i+1]==="$"&&r[i+2]==="{"){i+=3;continue}if(r[i]==="$"&&r[i+1]==="{"){let t=r.indexOf("}",i+2);if(t===-1)break;let a=r.slice(i+2,t);C.test(a)&&n.add(a),i=t+1;continue}i++;}return n}function de(e$1,n){return e$1.map(r=>e(n?.[r])).join("|")}function fe(e,n,r){let i=e.$set,t=r??{};for(let a of Object.keys(i)){let s=i[a];if(I(s))n[a]=L(s,t);else if(u(s)&&Object.hasOwn(s,"$ref")&&typeof s.$ref=="string"){let o=s.$ref;Object.hasOwn(t,o)||f(`applyPatch: $ref "${o}" is missing from event payload \u2014 assigning undefined to fact "${a}"`),n[a]=t[o];}else n[a]=s;}}export{g as a,Q as b,z as c,H as d,w as e,X as f,O as g,re as h,h as i,ie as j,I as k,oe as l,M as m,se as n,S as o,V as p,ce as q,le as r,L as s,ue as t,de as u,fe as v};//# sourceMappingURL=chunk-2FF6QGOA.js.map
//# sourceMappingURL=chunk-2FF6QGOA.js.map

Sorry, the diff of this file is too big to display

'use strict';var b=typeof process<"u"&&process.env?.NODE_ENV!=="production";function m(n,o=new WeakSet){if(n===null||typeof n!="object")return n;let r=n;if(o.has(r)||Object.isFrozen(r))return n;if(o.add(r),Array.isArray(r))for(let s of r)m(s,o);else for(let s of Object.keys(r))m(r[s],o);return Object.freeze(r),n}function A(n){return m(n)}function x(n,o,r){return (...s)=>{try{return r(...s)}catch(u){throw u instanceof Error&&u.message.startsWith("[Directive] ")?new Error(`[Directive] ${n} '${o}': ${u.message.slice(12)}`,{cause:u}):u}}}async function T(n,o,r){let s,u=new Promise((g,d)=>{s=setTimeout(()=>d(new Error(r)),o);});try{return await Promise.race([n,u])}finally{clearTimeout(s);}}function l(n,o=50){let r=new WeakSet;function s(t){if(t===null)return "null";if(t===void 0)return "undefined";let e=typeof t;if(e==="string")return JSON.stringify(t);if(e==="number"||e==="boolean")return String(t);if(e==="function")return '"[function]"';if(e==="symbol")return '"[symbol]"'}function u(t,e){if(r.has(t))return '"[circular]"';r.add(t);let i=e();return r.delete(t),i}function g(t,e){return u(t,()=>`[${t.map(i=>c(i,e+1)).join(",")}]`)}function d(t,e){return u(t,()=>`{${Object.keys(t).sort().map(f=>`${JSON.stringify(f)}:${c(t[f],e+1)}`).join(",")}}`)}function c(t,e){if(e>o)return '"[max depth exceeded]"';if(typeof t=="bigint")return `${t.toString()}n`;let i=s(t);if(i!==void 0)return i;if(t instanceof Date)return `D:${t.toISOString()}`;if(t instanceof RegExp)return `R:${t.source}:${t.flags}`;if(t instanceof Map){let a=[...t.entries()].sort();return `M:${c(a,e+1)}`}if(t instanceof Set){let a=[...t].sort();return `S:${c(a,e+1)}`}return Array.isArray(t)?g(t,e):typeof t=="object"?d(t,e):'"[unknown]"'}return c(n,0)}function D(n,o=50){let r=new Set(["__proto__","constructor","prototype"]),s=new WeakSet;function u(t,e){if(s.has(t))return true;s.add(t);let i=e();return s.delete(t),i}function g(t,e){for(let i of t)if(!c(i,e+1))return false;return true}function d(t,e){for(let i of Object.keys(t))if(r.has(i)||!c(t[i],e+1))return false;return true}function c(t,e){if(e>o)return false;if(t==null||typeof t!="object")return true;let i=t;return Array.isArray(i)?u(i,()=>g(i,e)):u(i,()=>d(i,e))}return c(n,0)}function E(n,o){if(n===o)return true;if(!n||!o)return false;let r=Object.keys(n),s=Object.keys(o);if(r.length!==s.length)return false;for(let u of r)if(n[u]!==o[u])return false;return true}function $(n){let o=l(n),r=5381;for(let s=0;s<o.length;s++)r=(r<<5)+r^o.charCodeAt(s);return (r>>>0).toString(16)}function h(n,o=Date.now()){return n.expiresAt!==void 0&&o>n.expiresAt}function R(n,o=Date.now()){if(!n||typeof n!="object")throw new Error("[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.");if(!("data"in n))throw new Error("[Directive] Invalid snapshot: missing required 'data' property.");if(!("createdAt"in n)||typeof n.createdAt!="number")throw new Error("[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).");if(h(n,o)){let r=new Date(n.expiresAt).toISOString();throw new Error(`[Directive] Snapshot expired at ${r}. Obtain a fresh snapshot from the source.`)}return n.data}function P(n,o){let r=[];function s(e,i,a,f){r.push({path:e,oldValue:i,newValue:a,type:f});}function u(e,i,a){return e==null?(i!=null&&s(a,e,i,"added"),true):i==null?(s(a,e,i,"removed"),true):false}function g(e,i,a){if(e.length!==i.length){s(a,e,i,"changed");return}for(let f=0;f<e.length;f++)c(e[f],i[f],`${a}[${f}]`);}function d(e,i,a){let f=new Set([...Object.keys(e),...Object.keys(i)]);for(let y of f){let p=a?`${a}.${y}`:y;y in e?y in i?c(e[y],i[y],p):s(p,e[y],void 0,"removed"):s(p,void 0,i[y],"added");}}function c(e,i,a){if(!u(e,i,a)){if(typeof e!="object"||typeof i!="object"){Object.is(e,i)||s(a,e,i,"changed");return}if(Array.isArray(e)&&Array.isArray(i)){g(e,i,a);return}d(e,i,a);}}c(n.data,o.data,"");let t=n.version!==o.version&&(n.version!==void 0||o.version!==void 0);return {identical:r.length===0,changes:r,versionChanged:t,oldVersion:n.version,newVersion:o.version}}function C(n){return "signature"in n&&typeof n.signature=="string"}async function v(n,o){let r=l({data:n.data,createdAt:n.createdAt,expiresAt:n.expiresAt,version:n.version,metadata:n.metadata}),s=await k(r,o);return {...n,signature:s,algorithm:"hmac-sha256"}}async function I(n,o){if(!n.signature||n.algorithm!=="hmac-sha256")return false;let r=l({data:n.data,createdAt:n.createdAt,expiresAt:n.expiresAt,version:n.version,metadata:n.metadata}),s=await k(r,o);return w(n.signature,s)}async function k(n,o){let r=typeof o=="string"?new TextEncoder().encode(o):o,s={name:"HMAC",hash:{name:"SHA-256"}},u=await crypto.subtle.importKey("raw",r,s,false,["sign"]),g=new TextEncoder().encode(n),d=await crypto.subtle.sign("HMAC",u,g);return Array.from(new Uint8Array(d)).map(c=>c.toString(16).padStart(2,"0")).join("")}function w(n,o){if(n.length!==o.length)return false;let r=0;for(let s=0;s<n.length;s++)r|=n.charCodeAt(s)^o.charCodeAt(s);return r===0}function L(n,o=500){try{let r=JSON.stringify(n,(s,u)=>typeof u=="bigint"?`${u}n`:u,2);return r?r.length<=o?r:`${r.slice(0,o)}
... (truncated, ${r.length} chars total)`:"[undefined]"}catch{return "[unserializable]"}}exports.a=b;exports.b=A;exports.c=x;exports.d=T;exports.e=l;exports.f=D;exports.g=E;exports.h=$;exports.i=h;exports.j=R;exports.k=P;exports.l=C;exports.m=v;exports.n=I;exports.o=L;//# sourceMappingURL=chunk-4MNQDXH7.cjs.map
//# sourceMappingURL=chunk-4MNQDXH7.cjs.map
{"version":3,"sources":["../src/dev-true.ts","../src/utils/utils.ts"],"names":["dev_true_default","deepFreeze","value","seen","obj","item","key","freezeSpec","spec","attributeError","category","id","fn","args","e","withTimeout","promise","ms","errorMessage","timeoutId","timeoutPromise","_","reject","stableStringify","maxDepth","stringifyPrimitive","val","type","withCircularGuard","result","stringifyArray","depth","v","stringify","stringifyObject","k","primitive","entries","items","isPrototypeSafe","dangerousKeys","objVal","checkArray","arr","check","checkObject","shallowEqual","a","b","keysA","keysB","hashObject","str","hash","i","isSnapshotExpired","snapshot","now","validateSnapshot","expiredAt","diffSnapshots","oldSnapshot","newSnapshot","changes","pushChange","path","oldValue","newValue","compareNullish","oldObj","newObj","compareArrays","oldArr","newArr","compare","compareObjects","oldRecord","newRecord","allKeys","childPath","versionChanged","isSignedSnapshot","signSnapshot","secret","payload","signature","hmacSha256","verifySnapshotSignature","signedSnapshot","expectedSignature","timingSafeEqual","message","secretBytes","algorithm","messageBytes","safeStringify","data","maxLen","_key"],"mappings":"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","file":"chunk-4MNQDXH7.cjs","sourcesContent":["// Runtime check that bundlers (webpack, esbuild, turbopack, rollup) inline\n// based on the consumer's NODE_ENV. Without this, the published bundle bakes\n// in `true` and dev-mode validation runs in every consumer's production\n// build — a real footgun the v1.5/v1.6 release hit.\nexport default typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\";\n","/**\n * Shared utilities for Directive\n */\n\n// ============================================================================\n// Deep freeze\n// ============================================================================\n\n/**\n * Recursively `Object.freeze` an object including nested objects, arrays, and\n * array elements. Uses a `WeakSet` to handle cycles. Skips primitives and\n * already-frozen values to avoid wasted work.\n *\n * Used at definition-registration sites (constraints, derivations, effects,\n * events, prefixed specs) so post-registration mutation of a nested operand\n * cannot silently change the compiled closure's behavior. Prefer\n * {@link freezeSpec} at registration sites — it documents the convention.\n */\nexport function deepFreeze<T>(\n value: T,\n seen: WeakSet<object> = new WeakSet(),\n): T {\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n const obj = value as unknown as object;\n if (seen.has(obj) || Object.isFrozen(obj)) {\n return value;\n }\n seen.add(obj);\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n deepFreeze(item, seen);\n }\n } else {\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n\n Object.freeze(obj);\n return value;\n}\n\n/**\n * Freeze a definition spec at registration. Centralizes the deepFreeze\n * convention so a new definition arm cannot forget it — every constraint,\n * derivation, effect, event, and prefixed-spec registration funnels through\n * this single helper.\n *\n * @param spec - The definition spec to freeze (mutated in place, returned)\n * @returns The same `spec` value, now deeply frozen\n *\n * @example\n * ```ts\n * // At registration time, freeze user-supplied specs so post-registration\n * // mutation cannot silently change the compiled closure's behavior.\n * const spec = freezeSpec(userPredicate);\n * memoizePredicate(spec);\n * ```\n */\nexport function freezeSpec<T>(spec: T): T {\n return deepFreeze(spec);\n}\n\n/**\n * Wrap a synthesized definition function so a `[Directive]`-prefixed error\n * thrown from inside it is re-thrown with the owning definition's category +\n * id injected, and the original error preserved as `cause`. Non-`[Directive]`\n * errors (user code, native) pass through untouched.\n *\n * Centralizes the owner-attribution wrap shared by the data-form `when`\n * (constraints), `on` (effects), and `compute` (derivations) closures — a\n * `[Directive]`-prefixed throw (e.g. `$matches: string`) is re-pointed at the\n * owning definition so the stack trace blames user config, not the runtime.\n *\n * @param category - The owning definition kind, used in the re-thrown message.\n * @param id - The owning definition's id.\n * @param fn - The synthesized function to wrap.\n * @returns A function with identical signature that re-attributes Directive errors.\n */\nexport function attributeError<A extends unknown[], R>(\n category: \"constraint\" | \"effect\" | \"derivation\",\n id: string,\n fn: (...args: A) => R,\n): (...args: A) => R {\n // Synchronous by design: the wrapped definition functions (memoized\n // predicate `when`/`on` closures, template closures) always return\n // synchronously. A `try/catch` only re-attributes a synchronous throw — an\n // async-returning fn's rejected promise would escape un-re-attributed.\n return (...args: A): R => {\n try {\n return fn(...args);\n } catch (e) {\n if (e instanceof Error && e.message.startsWith(\"[Directive] \")) {\n throw new Error(\n `[Directive] ${category} '${id}': ${e.message.slice(\"[Directive] \".length)}`,\n { cause: e },\n );\n }\n throw e;\n }\n };\n}\n\n/**\n * Execute a promise with a timeout, properly cleaning up the timer.\n * Used by both constraints and resolvers for timeout handling.\n *\n * @param promise - The promise to wrap with a timeout\n * @param ms - Timeout duration in milliseconds\n * @param errorMessage - Error message if timeout occurs\n * @returns The promise result\n * @throws Error if timeout is exceeded\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n errorMessage: string,\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error(errorMessage)), ms);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\n/**\n * Normalize an error to an Error instance.\n * Ensures consistent error handling throughout the library.\n *\n * @param error - The error to normalize (can be anything)\n * @returns An Error instance\n */\nexport function normalizeError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n}\n\n/**\n * Create a stable JSON string with sorted keys.\n * Handles circular references and deeply nested objects safely.\n *\n * @param value - The value to stringify\n * @param maxDepth - Maximum nesting depth (default: 50)\n * @returns A stable JSON string\n */\nexport function stableStringify(value: unknown, maxDepth = 50): string {\n const seen = new WeakSet();\n\n /** Stringify a primitive value (null, undefined, string, number, boolean, function, symbol). */\n function stringifyPrimitive(val: unknown): string | undefined {\n if (val === null) return \"null\";\n if (val === undefined) return \"undefined\";\n\n const type = typeof val;\n if (type === \"string\") return JSON.stringify(val);\n if (type === \"number\" || type === \"boolean\") return String(val);\n if (type === \"function\") return '\"[function]\"';\n if (type === \"symbol\") return '\"[symbol]\"';\n\n return undefined;\n }\n\n /** Guard against circular references using a seen-set, then delegate to fn. */\n function withCircularGuard(obj: object, fn: () => string): string {\n if (seen.has(obj)) {\n return '\"[circular]\"';\n }\n seen.add(obj);\n const result = fn();\n seen.delete(obj);\n\n return result;\n }\n\n /** Stringify an array with circular reference protection. */\n function stringifyArray(val: unknown[], depth: number): string {\n return withCircularGuard(\n val,\n () => `[${val.map((v) => stringify(v, depth + 1)).join(\",\")}]`,\n );\n }\n\n /** Stringify an object with sorted keys and circular reference protection. */\n function stringifyObject(\n obj: Record<string, unknown>,\n depth: number,\n ): string {\n return withCircularGuard(obj, () => {\n const keys = Object.keys(obj).sort();\n const pairs = keys.map(\n (k) => `${JSON.stringify(k)}:${stringify(obj[k], depth + 1)}`,\n );\n\n return `{${pairs.join(\",\")}}`;\n });\n }\n\n /** Recursively stringify a value with depth limit and circular detection. */\n function stringify(val: unknown, depth: number): string {\n if (depth > maxDepth) {\n return '\"[max depth exceeded]\"';\n }\n\n // BigInt is not JSON-serializable; encode with a trailing 'n' to remain\n // distinct from numeric strings.\n if (typeof val === \"bigint\") {\n return `${val.toString()}n`;\n }\n\n const primitive = stringifyPrimitive(val);\n if (primitive !== undefined) {\n return primitive;\n }\n\n // Typed-value branches: each prefix is bare (no outer quotes) so it can\n // never collide with a JSON-encoded string. `JSON.stringify(\"D:...\")`\n // emits `\"D:...\"` (the wrapping quotes ARE part of the output string),\n // whereas the Date branch emits `D:...` (no quotes). Distinct outputs.\n if (val instanceof Date) {\n return `D:${val.toISOString()}`;\n }\n if (val instanceof RegExp) {\n return `R:${val.source}:${val.flags}`;\n }\n if (val instanceof Map) {\n const entries = [...val.entries()].sort();\n return `M:${stringify(entries, depth + 1)}`;\n }\n if (val instanceof Set) {\n const items = [...val].sort();\n return `S:${stringify(items, depth + 1)}`;\n }\n\n if (Array.isArray(val)) {\n return stringifyArray(val, depth);\n }\n\n if (typeof val === \"object\") {\n return stringifyObject(val as Record<string, unknown>, depth);\n }\n\n return '\"[unknown]\"';\n }\n\n return stringify(value, 0);\n}\n\n/**\n * Check for prototype pollution in an object, including nested objects.\n * Returns true if the object is safe, false if dangerous keys are found.\n *\n * @param obj - The object to check\n * @param maxDepth - Maximum nesting depth to check (default: 50)\n * @returns True if safe, false if dangerous keys found\n */\nexport function isPrototypeSafe(obj: unknown, maxDepth = 50): boolean {\n const dangerousKeys = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n const seen = new WeakSet();\n\n /** Guard against circular references using a seen-set, then delegate to fn. */\n function withCircularGuard(objVal: object, fn: () => boolean): boolean {\n if (seen.has(objVal)) return true;\n seen.add(objVal);\n const result = fn();\n seen.delete(objVal);\n\n return result;\n }\n\n /** Check array elements for prototype pollution keys. */\n function checkArray(arr: unknown[], depth: number): boolean {\n for (const item of arr) {\n if (!check(item, depth + 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Check object keys and values for prototype pollution. */\n function checkObject(\n objVal: Record<string, unknown>,\n depth: number,\n ): boolean {\n for (const key of Object.keys(objVal)) {\n if (dangerousKeys.has(key)) {\n return false;\n }\n if (!check(objVal[key], depth + 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Recursively check a value tree for dangerous prototype keys. */\n function check(val: unknown, depth: number): boolean {\n if (depth > maxDepth) return false; // Fail safe at max depth - don't assume safety\n if (val === null || val === undefined) return true;\n if (typeof val !== \"object\") return true;\n\n const objVal = val as Record<string, unknown>;\n\n if (Array.isArray(objVal)) {\n return withCircularGuard(objVal, () => checkArray(objVal, depth));\n }\n\n return withCircularGuard(objVal, () => checkObject(objVal, depth));\n }\n\n return check(obj, 0);\n}\n\n/**\n * Shallow equality comparison for objects.\n * Used by React hooks to avoid unnecessary re-renders.\n *\n * @param a - First object\n * @param b - Second object\n * @returns True if objects are shallowly equal\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n a: T,\n b: T,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (a[key] !== b[key]) return false;\n }\n\n return true;\n}\n\n/**\n * Generate a simple hash string from an object.\n * Uses djb2 algorithm on the stable stringified value.\n *\n * **Limitations:**\n * - 32-bit hash output means collision probability increases with data set size\n * (birthday paradox: ~50% collision chance at ~77,000 distinct values)\n * - Suitable for: cache invalidation, change detection, deduplication of small sets\n * - NOT suitable for: cryptographic use, security-sensitive operations, large-scale deduplication\n *\n * For security-sensitive use cases requiring stronger collision resistance,\n * consider using a cryptographic hash like SHA-256.\n *\n * @param value - The value to hash\n * @returns A hex hash string (8 characters, 32 bits)\n */\nexport function hashObject(value: unknown): string {\n const str = stableStringify(value);\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n // Convert to unsigned 32-bit and then to hex\n return (hash >>> 0).toString(16);\n}\n\n// ============================================================================\n// Distributable Snapshot Utilities\n// ============================================================================\n\n/**\n * Distributable snapshot type for type-safe helper functions.\n */\nexport interface DistributableSnapshotLike<T = Record<string, unknown>> {\n data: T;\n createdAt: number;\n expiresAt?: number;\n version?: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Check if a distributable snapshot has expired.\n * Returns false if the snapshot has no expiresAt field.\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({ ttlSeconds: 3600 });\n * // ... later ...\n * if (isSnapshotExpired(snapshot)) {\n * // Refresh the snapshot\n * }\n * ```\n *\n * @param snapshot - The snapshot to check\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns True if the snapshot has expired, false otherwise\n */\nexport function isSnapshotExpired<T>(\n snapshot: DistributableSnapshotLike<T>,\n now: number = Date.now(),\n): boolean {\n return snapshot.expiresAt !== undefined && now > snapshot.expiresAt;\n}\n\n/**\n * Validate a distributable snapshot and return its data.\n * Throws if the snapshot is malformed or has expired.\n *\n * @example\n * ```typescript\n * const cached = JSON.parse(await redis.get(`entitlements:${userId}`));\n * try {\n * const data = validateSnapshot(cached);\n * // Use data.canUseFeature, etc.\n * } catch (e) {\n * // Snapshot invalid or expired, refresh it\n * }\n * ```\n *\n * @example Using custom timestamp for testing\n * ```typescript\n * const snapshot = { data: { test: true }, createdAt: 1000, expiresAt: 2000 };\n * validateSnapshot(snapshot, 1500); // Returns { test: true }\n * validateSnapshot(snapshot, 2500); // Throws: Snapshot expired\n * ```\n *\n * @param snapshot - The snapshot to validate\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns The snapshot data if valid\n * @throws Error if the snapshot is malformed or has expired\n */\nexport function validateSnapshot<T>(\n snapshot: DistributableSnapshotLike<T>,\n now: number = Date.now(),\n): T {\n // Structural validation\n if (!snapshot || typeof snapshot !== \"object\") {\n throw new Error(\n \"[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.\",\n );\n }\n if (!(\"data\" in snapshot)) {\n throw new Error(\n \"[Directive] Invalid snapshot: missing required 'data' property.\",\n );\n }\n if (!(\"createdAt\" in snapshot) || typeof snapshot.createdAt !== \"number\") {\n throw new Error(\n \"[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).\",\n );\n }\n\n // Expiration validation\n if (isSnapshotExpired(snapshot, now)) {\n const expiredAt = new Date(snapshot.expiresAt!).toISOString();\n throw new Error(\n `[Directive] Snapshot expired at ${expiredAt}. Obtain a fresh snapshot from the source.`,\n );\n }\n return snapshot.data;\n}\n\n/**\n * Diff result for a single changed value.\n */\nexport interface SnapshotDiffEntry {\n /** The key path that changed (e.g., \"canUseApi\" or \"limits.apiCalls\") */\n path: string;\n /** The value in the old snapshot */\n oldValue: unknown;\n /** The value in the new snapshot */\n newValue: unknown;\n /** Type of change: \"added\", \"removed\", or \"changed\" */\n type: \"added\" | \"removed\" | \"changed\";\n}\n\n/**\n * Result of diffing two snapshots.\n */\nexport interface SnapshotDiff {\n /** Whether the snapshots are identical */\n identical: boolean;\n /** List of changes between snapshots */\n changes: SnapshotDiffEntry[];\n /** Whether the version changed (if both have versions) */\n versionChanged: boolean;\n /** Old version (if available) */\n oldVersion?: string;\n /** New version (if available) */\n newVersion?: string;\n}\n\n/**\n * Compare two distributable snapshots and return the differences.\n * Useful for debugging, audit logs, and webhook payloads.\n *\n * @example\n * ```typescript\n * const oldSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n * system.dispatch({ type: \"upgradePlan\", plan: \"pro\" });\n * const newSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n *\n * const diff = diffSnapshots(oldSnapshot, newSnapshot);\n * if (!diff.identical) {\n * console.log(\"Changes:\", diff.changes);\n * // [{ path: \"canUseApi\", oldValue: false, newValue: true, type: \"changed\" }]\n * }\n * ```\n *\n * @param oldSnapshot - The previous snapshot\n * @param newSnapshot - The new snapshot\n * @returns A diff result with all changes\n */\nexport function diffSnapshots<T = Record<string, unknown>>(\n oldSnapshot: DistributableSnapshotLike<T>,\n newSnapshot: DistributableSnapshotLike<T>,\n): SnapshotDiff {\n const changes: SnapshotDiffEntry[] = [];\n\n /** Push a change entry to the diff results. */\n function pushChange(\n path: string,\n oldValue: unknown,\n newValue: unknown,\n type: SnapshotDiffEntry[\"type\"],\n ): void {\n changes.push({ path, oldValue, newValue, type });\n }\n\n /** Handle null/undefined comparison cases. Returns true if fully handled. */\n function compareNullish(\n oldObj: unknown,\n newObj: unknown,\n path: string,\n ): boolean {\n if (oldObj === null || oldObj === undefined) {\n if (newObj !== null && newObj !== undefined) {\n pushChange(path, oldObj, newObj, \"added\");\n }\n\n return true;\n }\n if (newObj === null || newObj === undefined) {\n pushChange(path, oldObj, newObj, \"removed\");\n\n return true;\n }\n\n return false;\n }\n\n /** Compare two arrays element by element, recursing into each. */\n function compareArrays(\n oldArr: unknown[],\n newArr: unknown[],\n path: string,\n ): void {\n if (oldArr.length !== newArr.length) {\n pushChange(path, oldArr, newArr, \"changed\");\n\n return;\n }\n for (let i = 0; i < oldArr.length; i++) {\n compare(oldArr[i], newArr[i], `${path}[${i}]`);\n }\n }\n\n /** Compare two objects by key union, detecting added/removed/changed. */\n function compareObjects(\n oldRecord: Record<string, unknown>,\n newRecord: Record<string, unknown>,\n path: string,\n ): void {\n const allKeys = new Set([\n ...Object.keys(oldRecord),\n ...Object.keys(newRecord),\n ]);\n\n for (const key of allKeys) {\n const childPath = path ? `${path}.${key}` : key;\n if (!(key in oldRecord)) {\n pushChange(childPath, undefined, newRecord[key], \"added\");\n } else if (!(key in newRecord)) {\n pushChange(childPath, oldRecord[key], undefined, \"removed\");\n } else {\n compare(oldRecord[key], newRecord[key], childPath);\n }\n }\n }\n\n /** Recursively compare two values and record differences. */\n function compare(oldObj: unknown, newObj: unknown, path: string): void {\n if (compareNullish(oldObj, newObj, path)) {\n return;\n }\n\n // Handle primitives\n if (typeof oldObj !== \"object\" || typeof newObj !== \"object\") {\n if (!Object.is(oldObj, newObj)) {\n pushChange(path, oldObj, newObj, \"changed\");\n }\n\n return;\n }\n\n // Handle arrays\n if (Array.isArray(oldObj) && Array.isArray(newObj)) {\n compareArrays(oldObj, newObj, path);\n\n return;\n }\n\n // Handle objects\n compareObjects(\n oldObj as Record<string, unknown>,\n newObj as Record<string, unknown>,\n path,\n );\n }\n\n // Compare data\n compare(oldSnapshot.data, newSnapshot.data, \"\");\n\n // Check version change\n const versionChanged =\n oldSnapshot.version !== newSnapshot.version &&\n (oldSnapshot.version !== undefined || newSnapshot.version !== undefined);\n\n return {\n identical: changes.length === 0,\n changes,\n versionChanged,\n oldVersion: oldSnapshot.version,\n newVersion: newSnapshot.version,\n };\n}\n\n// ============================================================================\n// Snapshot Signing (HMAC)\n// ============================================================================\n\n/**\n * A signed distributable snapshot.\n * Contains the original snapshot plus a cryptographic signature.\n */\nexport interface SignedSnapshot<T = Record<string, unknown>>\n extends DistributableSnapshotLike<T> {\n /** HMAC-SHA256 signature in hex format */\n signature: string;\n /** Signing algorithm used */\n algorithm: \"hmac-sha256\";\n}\n\n/**\n * Check if a snapshot is signed.\n *\n * @param snapshot - The snapshot to check\n * @returns True if the snapshot has a signature\n */\nexport function isSignedSnapshot<T>(\n snapshot: DistributableSnapshotLike<T> | SignedSnapshot<T>,\n): snapshot is SignedSnapshot<T> {\n return \"signature\" in snapshot && typeof snapshot.signature === \"string\";\n}\n\n/**\n * Sign a distributable snapshot using HMAC-SHA256.\n * Creates a tamper-proof signature that can be verified later.\n *\n * **Security Notes:**\n * - Use a cryptographically random secret of at least 32 bytes\n * - Store the secret securely (environment variable, secrets manager)\n * - Never expose the secret to clients\n * - The signature covers all snapshot fields for integrity\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({\n * includeDerivations: ['canUseFeature', 'limits'],\n * ttlSeconds: 3600,\n * });\n *\n * // Sign the snapshot (server-side only)\n * const signed = await signSnapshot(snapshot, process.env.SNAPSHOT_SECRET);\n *\n * // Store in JWT, Redis, or send to client\n * const jwt = createJWT({ snapshot: signed });\n *\n * // Later, verify the signature\n * const isValid = await verifySnapshotSignature(signed, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Snapshot has been tampered with');\n * }\n * ```\n *\n * @param snapshot - The snapshot to sign\n * @param secret - The HMAC secret (string or Uint8Array)\n * @returns A signed snapshot with the signature attached\n */\nexport async function signSnapshot<T>(\n snapshot: DistributableSnapshotLike<T>,\n secret: string | Uint8Array,\n): Promise<SignedSnapshot<T>> {\n // Create a canonical representation for signing\n const payload = stableStringify({\n data: snapshot.data,\n createdAt: snapshot.createdAt,\n expiresAt: snapshot.expiresAt,\n version: snapshot.version,\n metadata: snapshot.metadata,\n });\n\n const signature = await hmacSha256(payload, secret);\n\n return {\n ...snapshot,\n signature,\n algorithm: \"hmac-sha256\",\n };\n}\n\n/**\n * Verify the signature of a signed snapshot.\n * Returns true if the signature is valid, false otherwise.\n *\n * **Important:** Always verify signatures before trusting snapshot data,\n * especially if the snapshot was received from an untrusted source (client, cache).\n *\n * @example\n * ```typescript\n * // Receive signed snapshot from client or cache\n * const snapshot = JSON.parse(cachedData);\n *\n * // Verify before using\n * const isValid = await verifySnapshotSignature(snapshot, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Invalid snapshot signature - possible tampering');\n * }\n *\n * // Now safe to use snapshot.data\n * if (snapshot.data.canUseFeature.api) {\n * // Grant access\n * }\n * ```\n *\n * @param signedSnapshot - The signed snapshot to verify\n * @param secret - The HMAC secret (must match the signing secret)\n * @returns True if signature is valid, false otherwise\n */\nexport async function verifySnapshotSignature<T>(\n signedSnapshot: SignedSnapshot<T>,\n secret: string | Uint8Array,\n): Promise<boolean> {\n if (!signedSnapshot.signature || signedSnapshot.algorithm !== \"hmac-sha256\") {\n return false;\n }\n\n // Recreate the canonical payload (same as signing)\n const payload = stableStringify({\n data: signedSnapshot.data,\n createdAt: signedSnapshot.createdAt,\n expiresAt: signedSnapshot.expiresAt,\n version: signedSnapshot.version,\n metadata: signedSnapshot.metadata,\n });\n\n const expectedSignature = await hmacSha256(payload, secret);\n\n // Use timing-safe comparison\n return timingSafeEqual(signedSnapshot.signature, expectedSignature);\n}\n\n/**\n * Create HMAC-SHA256 signature of a message.\n * Uses Web Crypto API for cross-platform support (Node.js, browsers, Deno, Bun).\n */\nasync function hmacSha256(\n message: string,\n secret: string | Uint8Array,\n): Promise<string> {\n // Convert secret to Uint8Array if string\n const secretBytes: Uint8Array =\n typeof secret === \"string\" ? new TextEncoder().encode(secret) : secret;\n\n // Import key for HMAC\n const algorithm: HmacImportParams = {\n name: \"HMAC\",\n hash: { name: \"SHA-256\" },\n };\n const key = await crypto.subtle.importKey(\n \"raw\",\n secretBytes as unknown as ArrayBuffer,\n algorithm,\n false,\n [\"sign\"],\n );\n\n // Sign the message\n const messageBytes = new TextEncoder().encode(message);\n const signature = await crypto.subtle.sign(\"HMAC\", key, messageBytes);\n\n // Convert to hex string\n return Array.from(new Uint8Array(signature))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Timing-safe string comparison to prevent timing attacks.\n * Both strings should be the same length (hex signatures from same algorithm).\n */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n\n/**\n * Safely stringify any value for display. Handles circular references,\n * BigInt, throwing toJSON, and optional truncation.\n *\n * This is the canonical implementation – all packages should import this\n * instead of maintaining local copies.\n */\nexport function safeStringify(data: unknown, maxLen = 500): string {\n try {\n const str = JSON.stringify(\n data,\n (_key, value) => {\n if (typeof value === \"bigint\") {\n return `${value}n`;\n }\n\n return value;\n },\n 2,\n );\n if (!str) {\n return \"[undefined]\";\n }\n if (str.length <= maxLen) {\n return str;\n }\n\n return `${str.slice(0, maxLen)}\\n... (truncated, ${str.length} chars total)`;\n } catch {\n return \"[unserializable]\";\n }\n}\n"]}
import {z,a as a$1}from'./chunk-R2GHSCTR.js';import {k as k$1,h,q,s,v}from'./chunk-2FF6QGOA.js';import {k,l,m as m$1}from'./chunk-I722BZA5.js';import {a,f,b as b$1}from'./chunk-PXRV64PA.js';var m="::",he=Symbol.for("nodejs.util.inspect.custom");function we(e){if(!e.ownKeys)return {};let n={};for(let t of e.ownKeys())n[t]=e.get(t);return n}function D(e){return new Proxy({},{get(n,t){if(typeof t=="symbol")return t===he?()=>we(e):void 0;if(!k.has(t))return e.get(t)},set(n,t,s){return typeof t=="symbol"||k.has(t)?false:e.set?e.set(t,s):false},has(n,t){return typeof t=="symbol"||k.has(t)?false:e.has?e.has(t):false},deleteProperty(n,t){return typeof t=="symbol"||k.has(t)?false:e.delete?e.delete(t):false},ownKeys(){return e.ownKeys?e.ownKeys():[]},getOwnPropertyDescriptor(n,t){if(typeof t!="symbol"&&e.has&&typeof t=="string"&&e.has(t))return {configurable:true,enumerable:true}},defineProperty(){return false},getPrototypeOf(){return null},setPrototypeOf(){return false}})}var Z=new WeakMap,Q=new WeakMap,X=new WeakMap,ee=new WeakMap,ne=new WeakMap,te=new WeakMap;function $(e,n){let t=Z.get(e);if(t){let r=t.get(n);if(r)return r}else t=new Map,Z.set(e,t);let s=D({get:r=>r==="$store"||r==="$snapshot"?e[r]:e[`${n}${m}${r}`],set:(r,u)=>{if(a){let i=l(u);i&&m$1(`${n}.${r}`,i);}return e[`${n}${m}${r}`]=u,true},has:r=>`${n}${m}${r}`in e,delete:r=>(delete e[`${n}${m}${r}`],true)});return t.set(n,s),s}function re(e,n,t){let s=Q.get(e);if(s)return s;let r=D({get:u=>{if(Object.hasOwn(n,u))return $(e,u)},has:u=>Object.hasOwn(n,u),ownKeys:()=>t()});return Q.set(e,r),r}function oe(e,n,t){let s=`${n}|${t.join(",")}`,r=ne.get(e);if(r){let o=r.get(s);if(o)return o}else r=new Map,ne.set(e,r);let u=new Set(t),i=["self",...t],c=D({get:o=>{if(o==="self")return $(e,n);if(u.has(o))return $(e,o);a&&console.warn(`[Directive] Module "${n}" accessed undeclared cross-module property "${o}". Add it to crossModuleDeps or use "facts.self.${o}" for own module facts.`);},has:o=>o==="self"||u.has(o),ownKeys:()=>i});return r.set(s,c),c}function B(e,n){let t=ee.get(e);if(t){let r=t.get(n);if(r)return r}else t=new Map,ee.set(e,t);let s=D({get:r=>e[`${n}${m}${r}`],has:r=>`${n}${m}${r}`in e});return t.set(n,s),s}function se(e,n,t){let s=X.get(e);if(s)return s;let r=D({get:u=>{if(Object.hasOwn(n,u))return B(e,u)},has:u=>Object.hasOwn(n,u),ownKeys:()=>t()});return X.set(e,r),r}function ie(e,n,t){let s=te.get(e);return s||(s=new Map,te.set(e,s)),D({get:r=>{if(!Object.hasOwn(n,r))return;let u=s.get(r);if(u)return u;let i=D({get:c=>o=>{e.dispatch({type:`${r}${m}${c}`,...o});}});return s.set(r,i),i},has:r=>Object.hasOwn(n,r),ownKeys:()=>t()})}function R(e){if(e.includes(".")){let[n,...t]=e.split(".");return `${n}${m}${t.join(m)}`}return e}function H(e){let n={};for(let[t,s]of Object.entries(e)){let r=t.indexOf(m);if(r>0){let u=t.slice(0,r),i=t.slice(r+m.length);n[u]||(n[u]={}),n[u][i]=s;}else n._root||(n._root={}),n._root[t]=s;}return n}function P(e,n,t,s){return t?oe(e,n,s):$(e,n)}function b(e,n){return `${e}${m}${n}`}function ae(e){return e.includes(m)}function E(e,n,t){if(Array.isArray(e)){let i=e.map(c=>{if(c&&typeof c=="object"&&typeof c.fact=="string"){let o=c.fact;return ae(o)?c:{...c,fact:b(n,o)}}return c});return b$1(i),i}if(!e||typeof e!="object")return e;let s=e;if("$all"in s||"$any"in s){let i="$all"in s?"$all":"$any",c=s[i],o={[i]:c.map(f=>E(f,n,t))};return b$1(o),o}if("$not"in s){let i={$not:E(s.$not,n,t)};return b$1(i),i}function r(i,c){return E(i,c,ce)}let u={};for(let i of Object.keys(s)){if(i.startsWith("$")||ae(i)){u[i]=s[i];continue}if(i==="self"){let c=s[i];if(c&&typeof c=="object"){let o=r(c,n);if(o&&typeof o=="object"&&!Array.isArray(o)){for(let[f,l]of Object.entries(o))u[f]=l;continue}}}if(t.has(i)){let c=s[i];if(c&&typeof c=="object"){let o=r(c,i);if(o&&typeof o=="object"&&!Array.isArray(o)){for(let[f,l]of Object.entries(o))u[f]=l;continue}}}u[b(n,i)]=s[i];}return b$1(u),u}var ce=new Set;function me(e,n){let t=e.crossModuleDeps?new Set(Object.keys(e.crossModuleDeps)):ce,s$1=e.constraints;if(s$1){let c=false,o={};for(let[f,l]of Object.entries(s$1)){let d=l;if(d.when!==void 0&&typeof d.when!="function"){o[f]={...d,when:E(d.when,n,t)},c=true;continue}o[f]=l;}c&&(s$1=o);}let r=e.derive;if(r){let c=false,o={};for(let[f,l]of Object.entries(r)){let d=l&&typeof l=="object"&&Object.hasOwn(l,"compute")?l:null;if(!d){o[f]=l;continue}let g=d.compute;if(typeof g=="function"){o[f]=l;continue}if(k$1(g)){b$1(g);let k=w=>s(g,w);o[f]=d.meta?{compute:k,meta:d.meta}:k,c=true;continue}if(h(g)){b$1(g);let k=q(g),w=j=>k(j);o[f]=d.meta?{compute:w,meta:d.meta}:w,c=true;continue}o[f]=l;}c&&(r=o);}let u=e.events;if(u){let c=false,o={};for(let[f,l]of Object.entries(u)){if(l&&typeof l=="object"){let d=Object.hasOwn(l,"handler"),g=Object.hasOwn(l,"patch");if(d&&g&&a&&console.warn(`[Directive] event "${f}": both \`handler\` and \`patch\` provided \u2014 using \`handler\` (patch is ignored).`),g&&!d){let k=l;b$1(k.patch);let w=(j,O)=>v(k.patch,j,O??{});o[f]=k.meta?{handler:w,meta:k.meta}:w,c=true;continue}}o[f]=l;}c&&(u=o);}let i=e.effects;if(i){let c=false,o={};for(let[f,l]of Object.entries(i)){let d=l;if(d.on!==void 0&&h(d.on)){o[f]={...d,on:E(d.on,n,t)},c=true;continue}o[f]=l;}c&&(i=o);}return s$1===e.constraints&&r===e.derive&&u===e.events&&i===e.effects?e:{...e,constraints:s$1,derive:r,events:u,effects:i}}function C(e){return Object.keys(e).length>0?e:void 0}function ke(e,n){let t={};for(let[s,r]of Object.entries(e.schema.facts))t[b(n,s)]=r;return t}function pe(e,n){if(e.init)return t=>{let s=$(t,n);e.init(s);}}function ve(e,n,t,s){if(!e.derive)return;let r={};for(let[u,i]of Object.entries(e.derive)){let c=a$1(i),o=c?i.compute:i,f=c?i.meta:void 0,l=(d,g)=>{let k=P(d,n,t,s),w=B(g,n);return o(k,w)};r[b(n,u)]=f?{compute:l,meta:f}:l;}return C(r)}function be(e,n){if(!e.events)return;let t={};for(let[s,r]of Object.entries(e.events)){let u=typeof r=="object"&&r!==null&&Object.hasOwn(r,"handler"),i=u?r.handler:r,c=u?r.meta:void 0,o=(f,l)=>{let d=$(f,n);i(d,l);};t[b(n,s)]=c?{handler:o,meta:c}:o;}return C(t)}function Me(e,n,t,s){if(!e.constraints)return;let r={};for(let[u,i]of Object.entries(e.constraints)){let c=i,o=typeof c.when=="function";r[b(n,u)]={...c,deps:c.deps?.map(f=>b(n,f)),after:c.after?.map(f=>f.includes(m)?f:b(n,f)),owns:c.owns?.map(f=>f.includes(m)?f:b(n,f)),when:o?f=>{let l=P(f,n,t,s);return c.when(l)}:c.when,require:typeof c.require=="function"?f=>{let l=P(f,n,t,s);return c.require(l)}:c.require};}return C(r)}function Re(e,n,t,s){if(!e.resolvers)return;let r={};for(let[i,c]of Object.entries(e.resolvers)){let f=function(l){return {facts:P(l.facts,n,t,s),signal:l.signal}};let o=c;r[b(n,i)]={...o,...o.resolve&&{resolve:async(l,d)=>{await o.resolve(l,f(d));}},...o.resolveBatch&&{resolveBatch:async(l,d)=>{await o.resolveBatch(l,f(d));}},...o.resolveBatchWithResults&&{resolveBatchWithResults:async(l,d)=>o.resolveBatchWithResults(l,f(d))}};}return C(r)}function Se(e,n,t,s){if(!e.effects)return;let r={};for(let[u,i]of Object.entries(e.effects)){let c=i;r[b(n,u)]={...c,run:(o,f)=>{let l=P(o,n,t,s),d=f?P(f,n,t,s):void 0;return c.run(l,d)},deps:c.deps?.map(o=>b(n,o))};}return C(r)}function Oe(e,n,t){return {snapshotEvents:t&&!t.has(n)?[]:e.history?.snapshotEvents?.map(s=>b(n,s))}}function I(e){let{mod:n,namespace:t,snapshotModulesSet:s}=e,r=me(n,t),u=!!(r.crossModuleDeps&&Object.keys(r.crossModuleDeps).length>0),i=u?Object.keys(r.crossModuleDeps):[];return {id:r.id,schema:ke(r,t),requirements:r.schema.requirements??{},init:pe(r,t),derive:ve(r,t,u,i),events:be(r,t),effects:Se(r,t,u,i),constraints:Me(r,t,u,i),resolvers:Re(r,t,u,i),hooks:r.hooks,meta:r.meta,history:Oe(r,t,s)}}function xe(e){let n=Object.keys(e),t=new Set(n),s=new Set,r=new Set,u=[],i=[];function c(o){if(s.has(o))return;if(r.has(o)){let l=i.indexOf(o),d=[...i.slice(l),o].join(" \u2192 ");throw new Error(`[Directive] Circular dependency detected: ${d}. Modules cannot have circular crossModuleDeps. Break the cycle by removing one of the cross-module references.`)}r.add(o),i.push(o);let f=e[o];if(f?.crossModuleDeps)for(let l of Object.keys(f.crossModuleDeps))t.has(l)&&c(l);i.pop(),r.delete(o),s.add(o),u.push(o);}for(let o of n)c(o);return u}function ue(e,n){let t=[];for(let s of Object.keys(n.schema.facts))t.push(`${e}${m}${s}`);if(n.schema.derivations)for(let s of Object.keys(n.schema.derivations))t.push(`${e}${m}${s}`);return t}function ze(e){if("module"in e){if(!e.module)throw new Error("[Directive] createSystem requires a module. Got: "+typeof e.module);return $e(e)}let n=e;if(Array.isArray(n.modules))throw new Error(`[Directive] createSystem expects modules as an object, not an array.
Instead of:
createSystem({ modules: [authModule, dataModule] })
Use:
createSystem({ modules: { auth: authModule, data: dataModule } })
Or for a single module:
createSystem({ module: counterModule })`);let t=n.modules;if(t&&typeof t=="object"&&"id"in t&&"schema"in t)throw new Error(`[Directive] A single module was passed to \`modules:\`. For a single module, use \`module:\` instead:
createSystem({ module: myModule })
For multiple modules, wrap in an object:
createSystem({ modules: { myName: myModule } })`);return De(n)}function De(e){let n=e.modules,t=new Set(Object.keys(n)),s=typeof e.history=="object"?e.history:null,r=s?.snapshotModules?new Set(s.snapshotModules):null;if(e.tickMs!==void 0&&e.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(a){for(let[a,y]of Object.entries(n))if(y.crossModuleDeps)for(let h of Object.keys(y.crossModuleDeps))h===a?console.warn(`[Directive] Module "${a}" references itself in crossModuleDeps. Use "facts.self" to access own module's facts instead.`):t.has(h)||console.warn(`[Directive] Module "${a}" declares crossModuleDeps.${h}, but no module with namespace "${h}" exists in the system. Available modules: ${[...t].join(", ")}`);}if(a&&s?.snapshotModules)for(let a of s.snapshotModules)t.has(a)||console.warn(`[Directive] history.snapshotModules entry "${a}" doesn't match any module. Available modules: ${[...t].join(", ")}`);let u,i=e.initOrder??"auto";if(Array.isArray(i)){let a=i,y=Object.keys(n).filter(h=>!a.includes(h));if(y.length>0)throw new Error(`[Directive] initOrder is missing modules: ${y.join(", ")}. All modules must be included in the explicit order.`);u=a;}else i==="declaration"?u=Object.keys(n):u=xe(n);let{history:c,trace:o,errorBoundary:f$1}=de(e);for(let a of Object.keys(n)){if(a.includes(m))throw new Error(`[Directive] Module name "${a}" contains the reserved separator "${m}". Module names cannot contain "${m}".`);let y=n[a];if(y){for(let h of Object.keys(y.schema.facts))if(h.includes(m))throw new Error(`[Directive] Schema key "${h}" in module "${a}" contains the reserved separator "${m}". Schema keys cannot contain "${m}".`)}}let l={names:null};function d(){return l.names===null&&(l.names=Object.keys(n)),l.names}let g=u.map(a=>{let y=n[a];return y?I({mod:y,namespace:a,snapshotModulesSet:r}):null}).filter(a=>a!==null);a&&e.tickMs&&e.tickMs>0&&(g.some(y=>y.events&&Object.keys(y.events).some(h=>h.endsWith(`${m}tick`)))||console.warn(`[Directive] tickMs is set to ${e.tickMs}ms but no module defines a "tick" event handler.`));let k$1=null,w=null;function j(a$1){for(let[y,h]of Object.entries(a$1)){if(k.has(y)){a&&console.warn(`[Directive] initialFacts/hydrate contains blocked namespace "${y}". Skipping.`);continue}if(!t.has(y)){a&&console.warn(`[Directive] initialFacts/hydrate contains unknown namespace "${y}". Available modules: ${[...t].join(", ")}`);continue}if(h&&typeof h=="object"&&!f(h))throw new Error(`[Directive] initialFacts/hydrate for namespace "${y}" contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.`);for(let[M,x]of Object.entries(h))k.has(M)||(w.facts[`${y}${m}${M}`]=x);}}w=z({modules:g,plugins:e.plugins,history:c,trace:o,errorBoundary:f$1,tickMs:e.tickMs,cloud:e.cloud,onAfterModuleInit:()=>{e.initialFacts&&j(e.initialFacts),k$1&&(j(k$1),k$1=null);}});let O=new Map;for(let a of Object.keys(n)){let y=n[a];y&&O.set(a,ue(a,y));}let q=re(w.facts,n,d),ye=se(w.derive,n,d),ge=ie(w,n,d),A=null,F=e.tickMs,_={_mode:"namespaced",facts:q,history:w.history,derive:ye,events:ge,constraints:w.constraints,effects:w.effects,resolvers:w.resolvers,async hydrate(a){if(w.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let y=await a();y&&typeof y=="object"&&(k$1=y);},initialize(){w.initialize();},start(){if(w.start(),F&&F>0){let a;for(let y of g)if(y?.events&&(a=Object.keys(y.events).find(h=>h.endsWith(`${m}tick`)),a))break;if(a){let y=a;A=setInterval(()=>{w.dispatch({type:y});},F);}}},stop(){A&&(clearInterval(A),A=null),w.stop();},destroy(){this.stop(),w.destroy();},dispatch(a){w.dispatch(a);},read(a){return w.read(R(a))},subscribe(a$1,y){let h=[];for(let M of a$1)if(M.endsWith(".*")){let x=M.slice(0,-2),W=O.get(x);W?h.push(...W):a&&console.warn(`[Directive] subscribe wildcard "${M}" \u2014 namespace "${x}" not found.`);}else h.push(R(M));return w.subscribe(h,y)},subscribeModule(a$1,y){let h=O.get(a$1);return !h||h.length===0?(a&&console.warn(`[Directive] subscribeModule("${a$1}") \u2014 namespace not found. Available: ${[...O.keys()].join(", ")}`),()=>{}):w.subscribe(h,y)},watch(a,y,h){return w.watch(R(a),y,h)},when(a,y){return w.when(()=>a(q),y)},getDistributableSnapshot(a){let y={...a,includeDerivations:a?.includeDerivations?.map(R),excludeDerivations:a?.excludeDerivations?.map(R),includeFacts:a?.includeFacts?.map(R)},h=w.getDistributableSnapshot(y);return {...h,data:H(h.data)}},watchDistributableSnapshot(a,y){let h={...a,includeDerivations:a?.includeDerivations?.map(R),excludeDerivations:a?.excludeDerivations?.map(R),includeFacts:a?.includeFacts?.map(R)};return w.watchDistributableSnapshot(h,M=>{y({...M,data:H(M.data)});})},registerModule(a,y){if(t.has(a))throw new Error(`[Directive] Module namespace "${a}" already exists. Cannot register a duplicate namespace.`);if(a.includes(m))throw new Error(`[Directive] Module name "${a}" contains the reserved separator "${m}".`);if(k.has(a))throw new Error(`[Directive] Module name "${a}" is a blocked property.`);for(let x of Object.keys(y.schema.facts))if(x.includes(m))throw new Error(`[Directive] Schema key "${x}" in module "${a}" contains the reserved separator "${m}".`);let h=y,M=I({mod:h,namespace:a,snapshotModulesSet:r});t.add(a),n[a]=h,l.names=null,O.set(a,ue(a,h)),w.registerModule(M);}};return le(_,w),fe(_),_}function de(e){let n=e.history,t=e.trace,s=e.errorBoundary;return e.zeroConfig&&(n=n??a,s={onConstraintError:"skip",onResolverError:"skip",onEffectError:"skip",onDerivationError:"skip",...e.errorBoundary}),{history:n,trace:t,errorBoundary:s}}function le(e,n){Object.defineProperties(e,{trace:{get(){return n.trace},enumerable:true,configurable:true},meta:{value:n.meta,enumerable:true,configurable:true},isRunning:{get(){return n.isRunning},enumerable:true,configurable:true},isSettled:{get(){return n.isSettled},enumerable:true,configurable:true},isInitialized:{get(){return n.isInitialized},enumerable:true,configurable:true},isReady:{get(){return n.isReady},enumerable:true,configurable:true}}),e.whenReady=n.whenReady.bind(n),e.batch=n.batch.bind(n),e.onSettledChange=n.onSettledChange.bind(n),e.onHistoryChange=n.onHistoryChange.bind(n),e.inspect=n.inspect.bind(n),e.settle=n.settle.bind(n),e.explain=n.explain.bind(n),e.getSnapshot=n.getSnapshot.bind(n),e.restore=n.restore.bind(n),e.observe=n.observe.bind(n);let t=["dispatch","read","subscribe","watch","when","getDistributableSnapshot","watchDistributableSnapshot"];for(let s of t)s in e||(e[s]=n[s].bind(n));}function fe(e){a&&(typeof process>"u"||process.env?.NODE_ENV!=="test")&&setTimeout(()=>{!e.isRunning&&!e.isInitialized&&console.warn("[Directive] System created but start() was never called. Constraints, resolvers, and effects will not run until you call system.start().");},0);}function $e(e){let n=e.module;if(!n)throw new Error("[Directive] createSystem requires a module. Got: "+typeof n);if(e.tickMs!==void 0&&e.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(e.initialFacts&&!f(e.initialFacts))throw new Error("[Directive] initialFacts contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.");a&&(n.crossModuleDeps&&Object.keys(n.crossModuleDeps).length>0&&console.warn("[Directive] Single module mode ignores crossModuleDeps. Use multiple modules if cross-module access is needed: createSystem({ modules: { ... } })"),e.tickMs&&e.tickMs>0&&(n.events&&"tick"in n.events||console.warn(`[Directive] tickMs is set to ${e.tickMs}ms but module has no "tick" event handler.`)),(typeof e.history=="object"?e.history:null)?.snapshotModules&&console.warn("[Directive] history.snapshotModules has no effect in single-module mode. Use history.snapshotEvents on the module definition instead, or switch to createSystem({ modules: { ... } }) for multi-module filtering."));let{history:t,trace:s,errorBoundary:r}=de(e),u=null,i=null;i=z({modules:[{id:n.id,schema:n.schema.facts,requirements:n.schema.requirements,init:n.init,derive:n.derive,events:n.events,effects:n.effects,constraints:n.constraints,resolvers:n.resolvers,hooks:n.hooks,meta:n.meta,history:n.history}],plugins:e.plugins,history:t,trace:s,errorBoundary:r,tickMs:e.tickMs,cloud:e.cloud,onAfterModuleInit:()=>{if(e.initialFacts)for(let[d,g]of Object.entries(e.initialFacts))k.has(d)||(i.facts[d]=g);if(u){if(!f(u))a&&console.warn("[Directive] hydrate() data contains potentially dangerous keys. Skipping.");else for(let[d,g]of Object.entries(u))k.has(d)||(i.facts[d]=g);u=null;}}});let c=new Proxy({},{get(d,g){if(typeof g!="symbol"&&!k.has(g))return k=>{i.dispatch({type:g,...k});}},has(d,g){return typeof g=="symbol"||k.has(g)?false:n.events?g in n.events:false},ownKeys(){return n.events?Object.keys(n.events):[]},getOwnPropertyDescriptor(d,g){if(typeof g!="symbol"&&!k.has(g)&&n.events&&g in n.events)return {configurable:true,enumerable:true}},set(){return false},deleteProperty(){return false},defineProperty(){return false},getPrototypeOf(){return null},setPrototypeOf(){return false}}),o=null,f$1=e.tickMs,l={_mode:"single",facts:i.facts,history:i.history,derive:i.derive,events:c,constraints:i.constraints,effects:i.effects,resolvers:i.resolvers,async hydrate(d){if(i.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let g=await d();g&&typeof g=="object"&&(u=g);},initialize(){i.initialize();},start(){i.start(),f$1&&f$1>0&&n.events&&"tick"in n.events&&(o=setInterval(()=>{i.dispatch({type:"tick"});},f$1));},stop(){o&&(clearInterval(o),o=null),i.stop();},destroy(){this.stop(),i.destroy();},registerModule(d){i.registerModule({id:d.id,schema:d.schema.facts,requirements:d.schema.requirements,init:d.init,derive:d.derive,events:d.events,effects:d.effects,constraints:d.constraints,resolvers:d.resolvers,hooks:d.hooks,history:d.history});}};return le(l,i),fe(l),l}export{ze as a};//# sourceMappingURL=chunk-644QZVTT.js.map
//# sourceMappingURL=chunk-644QZVTT.js.map

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

function a(e,t,r){e[t]=r;}function c(e,t){return e[t]}function u(e,t){return {name:e,onRequirementCreated:t.onRequirementCreated?r=>t.onRequirementCreated(r.requirement):void 0,onRequirementMet:t.onRequirementResolved?r=>t.onRequirementResolved(r.requirement):void 0,onError:t.onError}}function d(e){return t=>t.type===e}function p(e){let t=new Set(e);return r=>t.has(r.type)}var n=[];function m(){let e=n.length;return e===0?null:n[e-1]}function l(){return n.length>0}function R(e){let t=new Set;n.push(t);try{return {value:e(),deps:t}}finally{n.pop();}}function S(e){let t=n.splice(0,n.length);try{return e()}finally{for(let r of t)n.push(r);}}function g(e){let t=n.length;t!==0&&n[t-1].add(e);}var q=Object.freeze(new Set(["__proto__","constructor","prototype"]));function x(e){if(e===null||typeof e!="object")return null;if(e instanceof Date)return "Date";if(e instanceof Set)return "Set";if(e instanceof Map)return "Map";if(typeof File<"u"&&e instanceof File)return "File";if(Array.isArray(e))return null;let t=Object.getPrototypeOf(e);return t!==null&&t!==Object.prototype?"ClassInstance":null}var o=new Set,s={Date:".getTime() for timestamps",Set:"[...set] for arrays",Map:"Object.fromEntries(map) for plain objects",File:"{ name, size, type, lastModified } for metadata",ClassInstance:"a plain-object snapshot"};function y(e,t){let r=`${e}|${t}`;if(o.has(r))return;o.add(r);let i=s[t]??"a JSON-roundtrippable value";console.warn(`[Directive] Fact "${e}" assigned a ${t} instance.
Facts must be JSON-roundtrippable for reactivity to work correctly.
${t} mutations are not tracked.
Use ${i} instead.
See: https://directive.run/docs/facts#json-rule`);}
export{a,c as b,u as c,d,p as e,m as f,l as g,R as h,S as i,g as j,q as k,x as l,y as m};//# sourceMappingURL=chunk-I722BZA5.js.map
//# sourceMappingURL=chunk-I722BZA5.js.map
{"version":3,"sources":["../src/core/types/adapter-utils.ts","../src/core/tracking.ts"],"names":["setBridgeFact","facts","key","value","getBridgeFact","createCallbackPlugin","name","callbacks","req","requirementGuard","type","requirementGuardMultiple","types","typeSet","depStack","getCurrentDeps","len","isTracking","withTracking","fn","deps","withoutTracking","saved","ctx","trackAccess","BLOCKED_PROPS","detectNonJsonValueType","proto","nonJsonWarningCache","nonJsonHints","warnNonJsonFactAssignment","factPath","valueType","cacheKey","hint"],"mappings":"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","file":"chunk-I722BZA5.js","sourcesContent":["/**\n * Adapter Type Utilities - Shared types and helpers for framework adapters\n *\n * These utilities reduce type assertions in adapters by providing:\n * - Schema composition types\n * - Constraint/resolver converters\n * - Plugin factory helpers\n */\n\nimport type { Facts } from \"./facts.js\";\nimport type { Plugin } from \"./plugins.js\";\nimport type { ConstraintDef, Requirement } from \"./requirements.js\";\nimport type { ResolverContext, ResolverDef } from \"./resolvers.js\";\nimport type { InferSchema, Schema } from \"./schema.js\";\n\n// ============================================================================\n// Schema Composition Types\n// ============================================================================\n\n/**\n * Merge two schemas into one.\n * Useful for adapters that add bridge-specific facts to user schemas.\n *\n * @example\n * ```typescript\n * type BridgeFields = { __state: SchemaType<Record<string, unknown>> };\n * type Combined = MergedSchema<UserSchema, BridgeFields>;\n * ```\n */\nexport type MergedSchema<Base extends Schema, Extra extends Schema> = Base &\n Extra;\n\n/**\n * Create a schema type from a fields definition.\n * Helper for defining adapter bridge schemas.\n *\n * @example\n * ```typescript\n * type AdapterBridgeSchema = BridgeSchema<{\n * __adapterState: SchemaType<Record<string, unknown>>;\n * }>;\n * ```\n */\nexport type BridgeSchema<Fields extends Schema> = Fields;\n\n// ============================================================================\n// Bridge Schema Helper\n// ============================================================================\n\n/**\n * Create a bridge schema definition for adapters.\n * Returns a schema object compatible with createModule().\n *\n * @example\n * ```typescript\n * const bridgeSchema = createBridgeSchema({\n * __state: t.object<Record<string, unknown>>(),\n * });\n * ```\n */\nexport function createBridgeSchema<S extends Schema>(schema: S): S {\n return schema;\n}\n\n// ============================================================================\n// Type-Safe Fact Mutation\n// ============================================================================\n\n/**\n * Type-safe fact setter for known schema keys.\n * Use when you have a typed schema and want to set a specific fact.\n *\n * @example\n * ```typescript\n * setFact(facts, \"count\", 10); // Type-checked\n * ```\n */\nexport function setFact<S extends Schema, K extends keyof InferSchema<S>>(\n facts: Facts<S>,\n key: K,\n value: InferSchema<S>[K],\n): void {\n (facts as Record<string, unknown>)[key as string] = value;\n}\n\n/**\n * Set a bridge fact without strict typing.\n * Use for adapter-internal bridge fields like `__adapterState`.\n *\n * @example\n * ```typescript\n * setBridgeFact(facts, \"__adapterState\", currentState);\n * ```\n */\nexport function setBridgeFact<V>(\n facts: Facts<Schema>,\n key: string,\n value: V,\n): void {\n (facts as Record<string, unknown>)[key] = value;\n}\n\n/**\n * Get a bridge fact without strict typing.\n * Use for adapter-internal bridge fields.\n *\n * @example\n * ```typescript\n * const state = getBridgeFact<MyState>(facts, \"__adapterState\");\n * ```\n */\nexport function getBridgeFact<V>(facts: Facts<Schema>, key: string): V {\n return (facts as Record<string, unknown>)[key] as V;\n}\n\n// ============================================================================\n// Constraint Converters\n// ============================================================================\n\n/**\n * Adapter constraint definition (generic form used by adapters).\n */\nexport interface AdapterConstraint<TState> {\n when: (state: TState) => boolean | Promise<boolean>;\n require: Requirement | ((state: TState) => Requirement | null);\n priority?: number;\n}\n\n/**\n * Convert adapter-style constraints to Directive format.\n * Maps adapter constraints that work with external state (TState) to\n * Directive constraints that work with Facts<Schema>.\n *\n * @param constraints - Adapter constraints keyed by name\n * @param extractState - Function to extract adapter state from facts\n *\n * @example\n * ```typescript\n * const directiveConstraints = convertConstraints<MyState, BridgeSchema>(\n * adapterConstraints,\n * (facts) => getBridgeFact<MyState>(facts, \"__state\"),\n * );\n * ```\n */\nexport function convertConstraints<TState, S extends Schema>(\n constraints: Record<string, AdapterConstraint<TState>>,\n extractState: (facts: Facts<S>) => TState,\n): Record<string, ConstraintDef<S, Requirement>> {\n const result: Record<string, ConstraintDef<S, Requirement>> = {};\n\n for (const [id, constraint] of Object.entries(constraints)) {\n result[id] = {\n priority: constraint.priority ?? 0,\n when: (facts) => constraint.when(extractState(facts)),\n require: (facts) => {\n const req =\n typeof constraint.require === \"function\"\n ? constraint.require(extractState(facts))\n : constraint.require;\n return req;\n },\n };\n }\n\n return result;\n}\n\n// ============================================================================\n// Resolver Converters\n// ============================================================================\n\n/**\n * Adapter resolver context (generic form used by adapters).\n */\nexport interface AdapterResolverContext<TContext> {\n context: TContext;\n signal: AbortSignal;\n}\n\n/**\n * Adapter resolver definition (generic form used by adapters).\n */\nexport interface AdapterResolver<\n TContext,\n R extends Requirement = Requirement,\n> {\n requirement: (req: Requirement) => req is R;\n key?: (req: R) => string;\n resolve: (\n req: R,\n ctx: AdapterResolverContext<TContext>,\n ) => void | Promise<void>;\n}\n\n/**\n * Convert adapter-style resolvers to Directive format.\n * Maps adapter resolvers that work with external context (TContext) to\n * Directive resolvers that work with ResolverContext<Schema>.\n *\n * @param resolvers - Adapter resolvers keyed by name\n * @param createContext - Function to create adapter context from Directive context\n *\n * @example\n * ```typescript\n * const directiveResolvers = convertResolvers<MyContext, BridgeSchema>(\n * adapterResolvers,\n * (ctx) => ({\n * getState: () => getBridgeFact<MyState>(ctx.facts, \"__state\"),\n * setState: (update) => setBridgeFact(ctx.facts, \"__state\", update),\n * signal: ctx.signal,\n * }),\n * );\n * ```\n */\nexport function convertResolvers<TContext, S extends Schema>(\n resolvers: Record<string, AdapterResolver<TContext, Requirement>>,\n createContext: (ctx: ResolverContext<S>) => TContext,\n): Record<string, ResolverDef<S, Requirement>> {\n const result: Record<string, ResolverDef<S, Requirement>> = {};\n\n for (const [id, resolver] of Object.entries(resolvers)) {\n result[id] = {\n requirement: resolver.requirement,\n key: resolver.key,\n resolve: async (req, ctx) => {\n const adapterCtx = createContext(ctx);\n await resolver.resolve(req, {\n context: adapterCtx,\n signal: ctx.signal,\n });\n },\n };\n }\n\n return result;\n}\n\n// ============================================================================\n// Plugin Factory\n// ============================================================================\n\n/**\n * Callback definitions for adapter plugins.\n */\nexport interface AdapterCallbacks {\n onRequirementCreated?: (req: Requirement) => void;\n onRequirementResolved?: (req: Requirement) => void;\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a callback plugin for adapter events.\n * Wraps adapter callbacks in a Directive plugin.\n *\n * @param name - Plugin name (for debugging)\n * @param callbacks - Callback functions to invoke\n *\n * @example\n * ```typescript\n * const callbackPlugin = createCallbackPlugin(\"adapter-callbacks\", {\n * onRequirementCreated: (req) => console.log(\"Created:\", req),\n * onRequirementResolved: (req) => console.log(\"Resolved:\", req),\n * });\n * ```\n */\n// biome-ignore lint/suspicious/noExplicitAny: Plugins work with any schema type\nexport function createCallbackPlugin(\n name: string,\n callbacks: AdapterCallbacks,\n): Plugin<any> {\n return {\n name,\n onRequirementCreated: callbacks.onRequirementCreated\n ? (req) => callbacks.onRequirementCreated!(req.requirement)\n : undefined,\n onRequirementMet: callbacks.onRequirementResolved\n ? (req) => callbacks.onRequirementResolved!(req.requirement)\n : undefined,\n onError: callbacks.onError,\n };\n}\n\n// ============================================================================\n// Module Config Helpers\n// ============================================================================\n\n/**\n * Cast constraints to the correct type for createModule.\n * Use this when TypeScript can't infer the constraint types correctly.\n */\nexport function asConstraints<S extends Schema>(\n constraints: Record<string, ConstraintDef<S, Requirement>>,\n): Record<string, ConstraintDef<S, Requirement>> {\n return constraints;\n}\n\n/**\n * Cast resolvers to the correct type for createModule.\n * Use this when TypeScript can't infer the resolver types correctly.\n */\nexport function asResolvers<S extends Schema>(\n resolvers: Record<string, ResolverDef<S, Requirement>>,\n): Record<string, ResolverDef<S, Requirement>> {\n return resolvers;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Create a type guard for a specific requirement type.\n * Simplifies the common pattern of checking req.type.\n *\n * @example\n * ```typescript\n * const isResetReq = requirementGuard<ResetReq>(\"RESET\");\n * // Use in resolver:\n * { requirement: isResetReq, resolve: ... }\n * ```\n */\nexport function requirementGuard<R extends Requirement>(\n type: R[\"type\"],\n): (req: Requirement) => req is R {\n return (req): req is R => req.type === type;\n}\n\n/**\n * Create a type guard that matches multiple requirement types.\n *\n * @example\n * ```typescript\n * const isDataReq = requirementGuardMultiple<FetchReq | RefreshReq>([\"FETCH\", \"REFRESH\"]);\n * ```\n */\nexport function requirementGuardMultiple<R extends Requirement>(\n types: Array<R[\"type\"]>,\n): (req: Requirement) => req is R {\n const typeSet = new Set(types);\n return (req): req is R => typeSet.has(req.type);\n}\n","/**\n * Dependency tracking context for auto-tracking derivations\n *\n * Uses a stack-based approach to handle nested derivation computations.\n * When a derivation accesses a fact, the tracking context records it.\n */\n\n/** Stack of active dependency sets (bare Sets for zero-allocation hot path) */\nconst depStack: Set<string>[] = [];\n\n/**\n * Get the current dependency set, or null if not tracking.\n *\n * @returns The active dependency Set, or `null` if no tracking is active.\n *\n * @internal\n */\nexport function getCurrentDeps(): Set<string> | null {\n const len = depStack.length;\n return len === 0 ? null : depStack[len - 1]!;\n}\n\n/**\n * Check if dependency tracking is currently active.\n *\n * @returns `true` if inside a {@link withTracking} call, `false` otherwise.\n *\n * @internal\n */\nexport function isTracking(): boolean {\n return depStack.length > 0;\n}\n\n/**\n * Run a function with dependency tracking.\n *\n * @remarks\n * Pushes a fresh Set onto the stack, executes `fn`, then pops it.\n * Any fact reads inside `fn` are recorded as dependencies.\n * Nesting is supported — inner calls get their own independent Set.\n *\n * @param fn - The function to execute under tracking.\n * @returns An object with the computed `value` and a `deps` Set of accessed\n * fact keys.\n *\n * @internal\n */\nexport function withTracking<T>(fn: () => T): { value: T; deps: Set<string> } {\n const deps = new Set<string>();\n depStack.push(deps);\n\n try {\n const value = fn();\n return { value, deps };\n } finally {\n depStack.pop();\n }\n}\n\n/**\n * Run a function without tracking.\n *\n * @remarks\n * Temporarily clears the tracking stack so that fact reads inside `fn` do\n * not register as dependencies. The stack is restored after `fn` returns\n * (even on error). Useful for side-effect reads that should not trigger\n * derivation invalidation.\n *\n * @param fn - The function to execute without tracking.\n * @returns The return value of `fn`.\n *\n * @internal\n */\nexport function withoutTracking<T>(fn: () => T): T {\n const saved = depStack.splice(0, depStack.length);\n\n try {\n return fn();\n } finally {\n for (const ctx of saved) {\n depStack.push(ctx);\n }\n }\n}\n\n/**\n * Track a specific key in the current context.\n *\n * @remarks\n * No-op if no tracking context is active.\n *\n * @param key - The fact key to record as a dependency.\n *\n * @internal\n */\nexport function trackAccess(key: string): void {\n const len = depStack.length;\n if (len === 0) {\n return;\n }\n depStack[len - 1]!.add(key);\n}\n\n/**\n * Prototype pollution guard — shared across all proxy handlers.\n *\n * @remarks\n * Contains `__proto__`, `constructor`, and `prototype`. Every proxy `get`\n * and `has` trap checks this set and returns `undefined` / `false` for\n * matching keys, preventing prototype pollution via proxy-based objects.\n *\n * @internal\n */\nexport const BLOCKED_PROPS: ReadonlySet<string> = Object.freeze(\n new Set([\"__proto__\", \"constructor\", \"prototype\"]),\n);\n\n// ============================================================================\n// Non-JSON value-type detection (MIGRATION_FEEDBACK item 20)\n// ============================================================================\n\n/**\n * Detect whether `value` is a non-JSON-roundtrippable type whose mutations\n * the facts proxy cannot track for reactivity.\n *\n * Returns the kind label (`\"Date\"`, `\"Set\"`, `\"Map\"`, `\"File\"`, or\n * `\"ClassInstance\"`) when one is detected, or `null` for plain objects,\n * arrays, primitives, and `null`/`undefined`.\n *\n * The `File` check is SSR-safe: if the runtime has no `File` global the\n * branch is skipped without throwing.\n *\n * The `ClassInstance` check fires for any object whose prototype is not\n * `Object.prototype` and which is not an array — e.g. instances of user\n * classes whose mutations bypass reactivity.\n *\n * @internal\n */\nexport function detectNonJsonValueType(value: unknown): string | null {\n if (value === null || typeof value !== \"object\") {\n return null;\n }\n if (value instanceof Date) {\n return \"Date\";\n }\n if (value instanceof Set) {\n return \"Set\";\n }\n if (value instanceof Map) {\n return \"Map\";\n }\n if (typeof File !== \"undefined\" && value instanceof File) {\n return \"File\";\n }\n // Plain objects and arrays are JSON-friendly.\n if (Array.isArray(value)) {\n return null;\n }\n // Class instances: prototype is not Object.prototype.\n // Plain `{}` literals have prototype `Object.prototype`; objects created\n // via `Object.create(null)` have a `null` prototype which we treat as\n // \"plain\" (it's still JSON-roundtrippable).\n const proto = Object.getPrototypeOf(value);\n if (proto !== null && proto !== Object.prototype) {\n return \"ClassInstance\";\n }\n\n return null;\n}\n\n/**\n * Per-(path, valueType) dedupe cache — once a warning fires for a given\n * combo we never re-emit. Keeps the dev console quiet under loops that\n * assign the same Date 100 times in a row.\n *\n * @internal\n */\nconst nonJsonWarningCache = new Set<string>();\n\nconst nonJsonHints: Record<string, string> = {\n Date: \".getTime() for timestamps\",\n Set: \"[...set] for arrays\",\n Map: \"Object.fromEntries(map) for plain objects\",\n File: \"{ name, size, type, lastModified } for metadata\",\n ClassInstance: \"a plain-object snapshot\",\n};\n\n/**\n * Emit a one-time dev-mode warning when a non-JSON value is assigned to a\n * fact. Called from the proxy `set` traps in both `createFactsProxy`\n * (single-module / standalone facts) and `createModuleFactsProxy`\n * (system-namespaced facts). No-ops in production builds — the call sites\n * are gated on `isDevelopment` so this entire helper is tree-shakable.\n *\n * @param factPath - Display path for the warning (e.g. `auth.token` or\n * bare `token` for non-namespaced stores).\n * @param valueType - The label returned from {@link detectNonJsonValueType}.\n *\n * @internal\n */\nexport function warnNonJsonFactAssignment(\n factPath: string,\n valueType: string,\n): void {\n const cacheKey = `${factPath}|${valueType}`;\n if (nonJsonWarningCache.has(cacheKey)) {\n return;\n }\n nonJsonWarningCache.add(cacheKey);\n\n const hint = nonJsonHints[valueType] ?? \"a JSON-roundtrippable value\";\n console.warn(\n `[Directive] Fact \"${factPath}\" assigned a ${valueType} instance.\\n` +\n `Facts must be JSON-roundtrippable for reactivity to work correctly.\\n` +\n `${valueType} mutations are not tracked.\\n` +\n `Use ${hint} instead.\\n` +\n `See: https://directive.run/docs/facts#json-rule`,\n );\n}\n\n/**\n * Reset the warning dedupe cache. Test-only — exported via internals for\n * vitest spec setup. Not part of the public API.\n *\n * @internal\n */\nexport function _resetNonJsonWarningCache(): void {\n nonJsonWarningCache.clear();\n}\n"]}
'use strict';var chunkT4TRJEJN_cjs=require('./chunk-T4TRJEJN.cjs'),chunk4MNQDXH7_cjs=require('./chunk-4MNQDXH7.cjs');var $="djb2-1",F=1,x=Symbol("directive.audit-ledger.internal");function B(t,r,i){if(t===null||typeof t!="object")return;let o=[];for(let a of r.split(".")){if(!a)continue;let l=a.match(/^\[(\d+)\](.*)$/);if(l){o.push(Number(l[1])),l[2]&&o.push(l[2].replace(/^\./,""));continue}let f=a.match(/^([^[]+)\[(\d+)\](.*)$/);if(f){o.push(f[1]),o.push(Number(f[2])),f[3]&&o.push(f[3].replace(/^\./,""));continue}o.push(a);}let m=t;for(let a=0;a<o.length-1;a++){let l=o[a];if(m===null||typeof m!="object")return;m=m[l];}if(m===null||typeof m!="object")return;let d=o[o.length-1];d!==void 0&&(m[d]=i);}function N(t){for(let r of Object.keys(t)){let i=t[r];if(i!==null&&typeof i=="object"){if(Array.isArray(i)&&r==="whenExplain")for(let o of i)o!==null&&typeof o=="object"&&Object.freeze(o);Object.freeze(i);}}return Object.freeze(t),t}var U=1e4,G=1e3;function P(t){if(t instanceof Date)return t.getTime();if(typeof t=="number"){if(!Number.isFinite(t))throw new Error("[Directive] audit-ledger: changedBetween bound must be a finite number, ISO string, or Date.");return t}if(typeof t=="string"){let r=Date.parse(t);if(!Number.isFinite(r))throw new Error(`[Directive] audit-ledger: changedBetween bound "${t}" is not a parseable ISO date string.`);return r}throw new Error("[Directive] audit-ledger: changedBetween bound must be a number, ISO string, or Date.")}function T(t,r){if(r.kind&&!(Array.isArray(r.kind)?r.kind:[r.kind]).includes(t.kind))return false;if(r.factPath!==void 0)if(t.kind==="fact.change"){if(t.key!==r.factPath)return false}else if(t.kind==="resolver.write.rejected"){if(t.fact!==r.factPath)return false}else return false;if(r.constraintId!==void 0&&(t.kind!=="constraint.evaluate"||t.constraintId!==r.constraintId))return false;if(r.changedBetween){let[i,o]=r.changedBetween,m=P(i),d=P(o);if(t.ts<m||t.ts>d)return false}return true}function Y(t={}){let r=t.capacity??U,i=[],o=null;return {write(d){if(i.length>=r){let a=i[0];o?.(a.seq,1),i.shift();}for(i.push(d);i.length>r;)i.shift();},query(d){let a=d.limit??G,l=[];for(let f=i.length-1;f>=0;f--){let g=i[f];if(T(g,d)&&(l.push(g),l.length>=a))break}return l},recent(d){let a=Math.max(0,i.length-d);return i.slice(a)},forFact(d,a={}){return this.query({factPath:d,limit:a.limit})},forConstraint(d,a={}){return this.query({constraintId:d,limit:a.limit})},toJSON(){return {entries:i.slice(),capturedAt:Date.now()}},clear(){i=[];},destroy(){i=[],o=null;},erase(d,a){let l=0;for(let f=0;f<i.length;f++){let g=i[f];T(g,d)&&(i[f]=a(g),l++);}return l},onTruncate(d){o=d;}}}function W(t){return chunk4MNQDXH7_cjs.h(t)}function _(t){if(t.hashAlgo==="djb2-1")return W(t);throw new Error(`[Directive] audit-ledger: unknown hashAlgo "${String(t.hashAlgo)}" on entry seq=${t.seq}. Cannot verify chain integrity. Known algorithms: "djb2-1".`)}function ee(t={}){let r=t.sink??Y(),i=t.capturePII??false,o=t.redact,m=0,d=null,a=null,l=null,f=new Map,g=new Map,k=new Set;function L(e){if(i||k.size===0||e===null||typeof e!="object")return e;let n;try{n=JSON.parse(JSON.stringify(e));}catch{return e}return chunkT4TRJEJN_cjs.i(n,{operator(s,u,y,c){k.has(s)&&B(n,c,"[redacted]");},literal(s){k.has(s)&&B(n,s,"[redacted]");}}),n}function w(){if(f.clear(),g.clear(),!!a)try{let e=a.inspect;if(typeof e!="function")return;let s=e()?.constraints??[],u=a.$internal?.mergedConstraints;for(let y of s)if(y.whenSpec!==void 0)f.set(y.id,L(y.whenSpec));else {let c=u?.[y.id],h=c&&typeof c.when=="function"?c.when:void 0;h?g.set(y.id,chunk4MNQDXH7_cjs.h(String(h))):y.when!==void 0&&typeof y.when=="function"?g.set(y.id,chunk4MNQDXH7_cjs.h(String(y.when))):g.set(y.id,chunk4MNQDXH7_cjs.h("[function]"));}}catch{}}function j(){if(k.clear(),!(i||!a))try{let e=a.meta;if(!e||typeof e.byTag!="function")return;let n=e.byTag("pii")??[];for(let s of n)k.add(s.id);}catch{}}function E(e,n){return i?n:k.has(e)?"[redacted]":n}function C(e){if(!e||i||k.size===0)return e;let n=false,s=e.map(u=>{if(k.has(u.path))return n=true,{...u,actual:"[redacted]"};if(u.children){let y=C(u.children);if(y!==u.children)return n=true,{...u,children:y}}return u});return n?s:e}function p(e){let n={...e,seq:m++,ts:Date.now(),prevHash:d,hashAlgo:$,schemaVersion:F},s=o?o(n):n;return N(s),r.write(s),d=_(s),s}function M(e){switch(e.type){case "constraint.evaluate":{let n=f.get(e.id),s=g.get(e.id),u={kind:"constraint.evaluate",constraintId:e.id,active:e.active,whenExplain:C(e.whenExplain)};n!==void 0?u.whenSpec=n:s!==void 0&&(u.whenSource={kind:"function",sourceHash:s}),p(u);break}case "fact.change":p({kind:"fact.change",key:e.key,prior:E(e.key,e.prev),next:E(e.key,e.next)});break;case "resolver.write.rejected":e.kind==="summary"?p({kind:"resolver.write.rejected",rejection:"summary",resolverId:e.resolver,requirementId:e.requirementId,reason:e.reason,dropped:e.dropped}):p({kind:"resolver.write.rejected",rejection:"rejection",resolverId:e.resolver,requirementId:e.requirementId,reason:e.reason,fact:e.fact,expected:E(e.fact,e.expected),actual:E(e.fact,e.actual)});break;case "resolver.complete":p({kind:"resolver.complete",resolverId:e.resolver,requirementId:e.requirementId,duration:e.duration});break;case "resolver.error":p({kind:"resolver.error",resolverId:e.resolver,requirementId:e.requirementId,error:String(e.error)});break;case "system.init":case "system.start":case "system.stop":case "system.destroy":p({kind:e.type});break;}}let v=false;function K(e){a=e,j(),w(),l=e.observe(M),r.onTruncate?.((n,s)=>{if(!v){v=true;try{p({kind:"system.truncated",droppedSeq:n,droppedCount:s});}finally{v=false;}}});}function H(){l&&(l(),l=null),a=null,f.clear(),g.clear(),k.clear();}let V={name:"audit-ledger",onInit(e){K(e);},onStop(){l&&(l(),l=null);},onDestroy(){H();},onDefinitionRegister(e,n){e==="constraint"&&w(),(e==="constraint"||e==="resolver"||e==="effect")&&j();},onDefinitionAssign(e,n){e==="constraint"&&w();},onDefinitionUnregister(e,n){e==="constraint"&&w();},onSnapshot(e){p({kind:"system.snapshot",snapshotId:e.id,trigger:e.trigger});},onHistoryNavigate(e,n){p({kind:"system.history.navigate",from:e,to:n});}};function J(e){if(e.__internal===void 0)return e;let n={...e};return delete n.__internal,n}function b(e){let n=false;for(let s of e)if(s.__internal!==void 0){n=true;break}return n?e.map(J):e}return {plugin:V,query:(e={})=>b(r.query(e)),recent:e=>b(r.recent(e)),forFact:(e,n)=>b(r.forFact(e,n)),forConstraint:(e,n)=>b(r.forConstraint(e,n)),toJSON:()=>{let e=r.toJSON();return {entries:b(e.entries),capturedAt:e.capturedAt}},verify(e){if(e?.strong===true)throw new Error("[Directive] verify({ strong: true }) is reserved for v2 \u2014 v1 ships sync djb2 chain only. Use verify() (sync) for tamper detection.");let{entries:n}=r.toJSON();if(n.length===0)return {valid:true,entryCount:0};let s=new Set,u=null;for(let c=0;c<n.length;c++){let h=n[c];if(h.prevHash!==u){let S=c>0?n[c-1]:null,I=h.kind==="system.entry-erased",O=S?.kind==="system.entry-erased";if(I||O){let q=[];I&&q.push(h),O&&S!==null&&q.push(S);let R=q.find(Q=>Q.__internal!==x);if(R)return {valid:false,brokenAt:c,expectedHash:u??"<genesis>",actualHash:h.prevHash??"<genesis>",entry:R,reason:"tombstone forgery detected \u2014 missing internal sentinel. A 'system.entry-erased' entry was written via sink.write() rather than ledger.erase(); rejected as tamper."};let z=I?h:S;s.add(z.seq),u=_(h);continue}return {valid:false,brokenAt:c,expectedHash:u??"<genesis>",actualHash:h.prevHash??"<genesis>",entry:h}}u=_(h);}let y={valid:true,entryCount:n.length};return s.size>0&&(y.erasedSeqs=[...s].sort((c,h)=>c-h)),y},erase(e){let n=Date.now(),s=0;if(typeof r.erase=="function"&&(s=r.erase(e,c=>{let h={seq:c.seq,ts:c.ts,kind:"system.entry-erased",prevHash:c.prevHash,hashAlgo:c.hashAlgo,schemaVersion:c.schemaVersion??F,originalKind:c.kind,erasedAt:n,__internal:x};return N(h),h})),s===0)return {erased:0,markerEntry:null};let u={factPath:e.factPath!==void 0,constraintId:e.constraintId!==void 0,kind:e.kind,changedBetween:e.changedBetween!==void 0?"[range]":void 0},y=p({kind:"system.subject-erased",filterHash:chunk4MNQDXH7_cjs.h(e),filterShape:u,erased:s});return {erased:s,markerEntry:y}},clear(){r.clear(),m=0,d=null;},destroy(){H(),r.destroy();}}}exports.a=Y;exports.b=ee;//# sourceMappingURL=chunk-IXRS4LM4.cjs.map
//# sourceMappingURL=chunk-IXRS4LM4.cjs.map

Sorry, the diff of this file is too big to display

'use strict';var chunkENZEHIL7_cjs=require('./chunk-ENZEHIL7.cjs'),chunkT4TRJEJN_cjs=require('./chunk-T4TRJEJN.cjs'),chunkX7G7UBXU_cjs=require('./chunk-X7G7UBXU.cjs'),chunk4MNQDXH7_cjs=require('./chunk-4MNQDXH7.cjs');var m="::",he=Symbol.for("nodejs.util.inspect.custom");function we(e){if(!e.ownKeys)return {};let n={};for(let t of e.ownKeys())n[t]=e.get(t);return n}function D(e){return new Proxy({},{get(n,t){if(typeof t=="symbol")return t===he?()=>we(e):void 0;if(!chunkX7G7UBXU_cjs.k.has(t))return e.get(t)},set(n,t,s){return typeof t=="symbol"||chunkX7G7UBXU_cjs.k.has(t)?false:e.set?e.set(t,s):false},has(n,t){return typeof t=="symbol"||chunkX7G7UBXU_cjs.k.has(t)?false:e.has?e.has(t):false},deleteProperty(n,t){return typeof t=="symbol"||chunkX7G7UBXU_cjs.k.has(t)?false:e.delete?e.delete(t):false},ownKeys(){return e.ownKeys?e.ownKeys():[]},getOwnPropertyDescriptor(n,t){if(typeof t!="symbol"&&e.has&&typeof t=="string"&&e.has(t))return {configurable:true,enumerable:true}},defineProperty(){return false},getPrototypeOf(){return null},setPrototypeOf(){return false}})}var Z=new WeakMap,Q=new WeakMap,X=new WeakMap,ee=new WeakMap,ne=new WeakMap,te=new WeakMap;function $(e,n){let t=Z.get(e);if(t){let r=t.get(n);if(r)return r}else t=new Map,Z.set(e,t);let s=D({get:r=>r==="$store"||r==="$snapshot"?e[r]:e[`${n}${m}${r}`],set:(r,u)=>{if(chunk4MNQDXH7_cjs.a){let i=chunkX7G7UBXU_cjs.l(u);i&&chunkX7G7UBXU_cjs.m(`${n}.${r}`,i);}return e[`${n}${m}${r}`]=u,true},has:r=>`${n}${m}${r}`in e,delete:r=>(delete e[`${n}${m}${r}`],true)});return t.set(n,s),s}function re(e,n,t){let s=Q.get(e);if(s)return s;let r=D({get:u=>{if(Object.hasOwn(n,u))return $(e,u)},has:u=>Object.hasOwn(n,u),ownKeys:()=>t()});return Q.set(e,r),r}function oe(e,n,t){let s=`${n}|${t.join(",")}`,r=ne.get(e);if(r){let o=r.get(s);if(o)return o}else r=new Map,ne.set(e,r);let u=new Set(t),i=["self",...t],c=D({get:o=>{if(o==="self")return $(e,n);if(u.has(o))return $(e,o);chunk4MNQDXH7_cjs.a&&console.warn(`[Directive] Module "${n}" accessed undeclared cross-module property "${o}". Add it to crossModuleDeps or use "facts.self.${o}" for own module facts.`);},has:o=>o==="self"||u.has(o),ownKeys:()=>i});return r.set(s,c),c}function B(e,n){let t=ee.get(e);if(t){let r=t.get(n);if(r)return r}else t=new Map,ee.set(e,t);let s=D({get:r=>e[`${n}${m}${r}`],has:r=>`${n}${m}${r}`in e});return t.set(n,s),s}function se(e,n,t){let s=X.get(e);if(s)return s;let r=D({get:u=>{if(Object.hasOwn(n,u))return B(e,u)},has:u=>Object.hasOwn(n,u),ownKeys:()=>t()});return X.set(e,r),r}function ie(e,n,t){let s=te.get(e);return s||(s=new Map,te.set(e,s)),D({get:r=>{if(!Object.hasOwn(n,r))return;let u=s.get(r);if(u)return u;let i=D({get:c=>o=>{e.dispatch({type:`${r}${m}${c}`,...o});}});return s.set(r,i),i},has:r=>Object.hasOwn(n,r),ownKeys:()=>t()})}function R(e){if(e.includes(".")){let[n,...t]=e.split(".");return `${n}${m}${t.join(m)}`}return e}function H(e){let n={};for(let[t,s]of Object.entries(e)){let r=t.indexOf(m);if(r>0){let u=t.slice(0,r),i=t.slice(r+m.length);n[u]||(n[u]={}),n[u][i]=s;}else n._root||(n._root={}),n._root[t]=s;}return n}function P(e,n,t,s){return t?oe(e,n,s):$(e,n)}function b(e,n){return `${e}${m}${n}`}function ae(e){return e.includes(m)}function E(e,n,t){if(Array.isArray(e)){let i=e.map(c=>{if(c&&typeof c=="object"&&typeof c.fact=="string"){let o=c.fact;return ae(o)?c:{...c,fact:b(n,o)}}return c});return chunk4MNQDXH7_cjs.b(i),i}if(!e||typeof e!="object")return e;let s=e;if("$all"in s||"$any"in s){let i="$all"in s?"$all":"$any",c=s[i],o={[i]:c.map(f=>E(f,n,t))};return chunk4MNQDXH7_cjs.b(o),o}if("$not"in s){let i={$not:E(s.$not,n,t)};return chunk4MNQDXH7_cjs.b(i),i}function r(i,c){return E(i,c,ce)}let u={};for(let i of Object.keys(s)){if(i.startsWith("$")||ae(i)){u[i]=s[i];continue}if(i==="self"){let c=s[i];if(c&&typeof c=="object"){let o=r(c,n);if(o&&typeof o=="object"&&!Array.isArray(o)){for(let[f,l]of Object.entries(o))u[f]=l;continue}}}if(t.has(i)){let c=s[i];if(c&&typeof c=="object"){let o=r(c,i);if(o&&typeof o=="object"&&!Array.isArray(o)){for(let[f,l]of Object.entries(o))u[f]=l;continue}}}u[b(n,i)]=s[i];}return chunk4MNQDXH7_cjs.b(u),u}var ce=new Set;function me(e,n){let t=e.crossModuleDeps?new Set(Object.keys(e.crossModuleDeps)):ce,s=e.constraints;if(s){let c=false,o={};for(let[f,l]of Object.entries(s)){let d=l;if(d.when!==void 0&&typeof d.when!="function"){o[f]={...d,when:E(d.when,n,t)},c=true;continue}o[f]=l;}c&&(s=o);}let r=e.derive;if(r){let c=false,o={};for(let[f,l]of Object.entries(r)){let d=l&&typeof l=="object"&&Object.hasOwn(l,"compute")?l:null;if(!d){o[f]=l;continue}let g=d.compute;if(typeof g=="function"){o[f]=l;continue}if(chunkT4TRJEJN_cjs.k(g)){chunk4MNQDXH7_cjs.b(g);let k=w=>chunkT4TRJEJN_cjs.s(g,w);o[f]=d.meta?{compute:k,meta:d.meta}:k,c=true;continue}if(chunkT4TRJEJN_cjs.h(g)){chunk4MNQDXH7_cjs.b(g);let k=chunkT4TRJEJN_cjs.q(g),w=j=>k(j);o[f]=d.meta?{compute:w,meta:d.meta}:w,c=true;continue}o[f]=l;}c&&(r=o);}let u=e.events;if(u){let c=false,o={};for(let[f,l]of Object.entries(u)){if(l&&typeof l=="object"){let d=Object.hasOwn(l,"handler"),g=Object.hasOwn(l,"patch");if(d&&g&&chunk4MNQDXH7_cjs.a&&console.warn(`[Directive] event "${f}": both \`handler\` and \`patch\` provided \u2014 using \`handler\` (patch is ignored).`),g&&!d){let k=l;chunk4MNQDXH7_cjs.b(k.patch);let w=(j,O)=>chunkT4TRJEJN_cjs.v(k.patch,j,O??{});o[f]=k.meta?{handler:w,meta:k.meta}:w,c=true;continue}}o[f]=l;}c&&(u=o);}let i=e.effects;if(i){let c=false,o={};for(let[f,l]of Object.entries(i)){let d=l;if(d.on!==void 0&&chunkT4TRJEJN_cjs.h(d.on)){o[f]={...d,on:E(d.on,n,t)},c=true;continue}o[f]=l;}c&&(i=o);}return s===e.constraints&&r===e.derive&&u===e.events&&i===e.effects?e:{...e,constraints:s,derive:r,events:u,effects:i}}function C(e){return Object.keys(e).length>0?e:void 0}function ke(e,n){let t={};for(let[s,r]of Object.entries(e.schema.facts))t[b(n,s)]=r;return t}function pe(e,n){if(e.init)return t=>{let s=$(t,n);e.init(s);}}function ve(e,n,t,s){if(!e.derive)return;let r={};for(let[u,i]of Object.entries(e.derive)){let c=chunkENZEHIL7_cjs.a(i),o=c?i.compute:i,f=c?i.meta:void 0,l=(d,g)=>{let k=P(d,n,t,s),w=B(g,n);return o(k,w)};r[b(n,u)]=f?{compute:l,meta:f}:l;}return C(r)}function be(e,n){if(!e.events)return;let t={};for(let[s,r]of Object.entries(e.events)){let u=typeof r=="object"&&r!==null&&Object.hasOwn(r,"handler"),i=u?r.handler:r,c=u?r.meta:void 0,o=(f,l)=>{let d=$(f,n);i(d,l);};t[b(n,s)]=c?{handler:o,meta:c}:o;}return C(t)}function Me(e,n,t,s){if(!e.constraints)return;let r={};for(let[u,i]of Object.entries(e.constraints)){let c=i,o=typeof c.when=="function";r[b(n,u)]={...c,deps:c.deps?.map(f=>b(n,f)),after:c.after?.map(f=>f.includes(m)?f:b(n,f)),owns:c.owns?.map(f=>f.includes(m)?f:b(n,f)),when:o?f=>{let l=P(f,n,t,s);return c.when(l)}:c.when,require:typeof c.require=="function"?f=>{let l=P(f,n,t,s);return c.require(l)}:c.require};}return C(r)}function Re(e,n,t,s){if(!e.resolvers)return;let r={};for(let[i,c]of Object.entries(e.resolvers)){let f=function(l){return {facts:P(l.facts,n,t,s),signal:l.signal}};let o=c;r[b(n,i)]={...o,...o.resolve&&{resolve:async(l,d)=>{await o.resolve(l,f(d));}},...o.resolveBatch&&{resolveBatch:async(l,d)=>{await o.resolveBatch(l,f(d));}},...o.resolveBatchWithResults&&{resolveBatchWithResults:async(l,d)=>o.resolveBatchWithResults(l,f(d))}};}return C(r)}function Se(e,n,t,s){if(!e.effects)return;let r={};for(let[u,i]of Object.entries(e.effects)){let c=i;r[b(n,u)]={...c,run:(o,f)=>{let l=P(o,n,t,s),d=f?P(f,n,t,s):void 0;return c.run(l,d)},deps:c.deps?.map(o=>b(n,o))};}return C(r)}function Oe(e,n,t){return {snapshotEvents:t&&!t.has(n)?[]:e.history?.snapshotEvents?.map(s=>b(n,s))}}function I(e){let{mod:n,namespace:t,snapshotModulesSet:s}=e,r=me(n,t),u=!!(r.crossModuleDeps&&Object.keys(r.crossModuleDeps).length>0),i=u?Object.keys(r.crossModuleDeps):[];return {id:r.id,schema:ke(r,t),requirements:r.schema.requirements??{},init:pe(r,t),derive:ve(r,t,u,i),events:be(r,t),effects:Se(r,t,u,i),constraints:Me(r,t,u,i),resolvers:Re(r,t,u,i),hooks:r.hooks,meta:r.meta,history:Oe(r,t,s)}}function xe(e){let n=Object.keys(e),t=new Set(n),s=new Set,r=new Set,u=[],i=[];function c(o){if(s.has(o))return;if(r.has(o)){let l=i.indexOf(o),d=[...i.slice(l),o].join(" \u2192 ");throw new Error(`[Directive] Circular dependency detected: ${d}. Modules cannot have circular crossModuleDeps. Break the cycle by removing one of the cross-module references.`)}r.add(o),i.push(o);let f=e[o];if(f?.crossModuleDeps)for(let l of Object.keys(f.crossModuleDeps))t.has(l)&&c(l);i.pop(),r.delete(o),s.add(o),u.push(o);}for(let o of n)c(o);return u}function ue(e,n){let t=[];for(let s of Object.keys(n.schema.facts))t.push(`${e}${m}${s}`);if(n.schema.derivations)for(let s of Object.keys(n.schema.derivations))t.push(`${e}${m}${s}`);return t}function ze(e){if("module"in e){if(!e.module)throw new Error("[Directive] createSystem requires a module. Got: "+typeof e.module);return $e(e)}let n=e;if(Array.isArray(n.modules))throw new Error(`[Directive] createSystem expects modules as an object, not an array.
Instead of:
createSystem({ modules: [authModule, dataModule] })
Use:
createSystem({ modules: { auth: authModule, data: dataModule } })
Or for a single module:
createSystem({ module: counterModule })`);let t=n.modules;if(t&&typeof t=="object"&&"id"in t&&"schema"in t)throw new Error(`[Directive] A single module was passed to \`modules:\`. For a single module, use \`module:\` instead:
createSystem({ module: myModule })
For multiple modules, wrap in an object:
createSystem({ modules: { myName: myModule } })`);return De(n)}function De(e){let n=e.modules,t=new Set(Object.keys(n)),s=typeof e.history=="object"?e.history:null,r=s?.snapshotModules?new Set(s.snapshotModules):null;if(e.tickMs!==void 0&&e.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(chunk4MNQDXH7_cjs.a){for(let[a,y]of Object.entries(n))if(y.crossModuleDeps)for(let h of Object.keys(y.crossModuleDeps))h===a?console.warn(`[Directive] Module "${a}" references itself in crossModuleDeps. Use "facts.self" to access own module's facts instead.`):t.has(h)||console.warn(`[Directive] Module "${a}" declares crossModuleDeps.${h}, but no module with namespace "${h}" exists in the system. Available modules: ${[...t].join(", ")}`);}if(chunk4MNQDXH7_cjs.a&&s?.snapshotModules)for(let a of s.snapshotModules)t.has(a)||console.warn(`[Directive] history.snapshotModules entry "${a}" doesn't match any module. Available modules: ${[...t].join(", ")}`);let u,i=e.initOrder??"auto";if(Array.isArray(i)){let a=i,y=Object.keys(n).filter(h=>!a.includes(h));if(y.length>0)throw new Error(`[Directive] initOrder is missing modules: ${y.join(", ")}. All modules must be included in the explicit order.`);u=a;}else i==="declaration"?u=Object.keys(n):u=xe(n);let{history:c,trace:o,errorBoundary:f}=de(e);for(let a of Object.keys(n)){if(a.includes(m))throw new Error(`[Directive] Module name "${a}" contains the reserved separator "${m}". Module names cannot contain "${m}".`);let y=n[a];if(y){for(let h of Object.keys(y.schema.facts))if(h.includes(m))throw new Error(`[Directive] Schema key "${h}" in module "${a}" contains the reserved separator "${m}". Schema keys cannot contain "${m}".`)}}let l={names:null};function d(){return l.names===null&&(l.names=Object.keys(n)),l.names}let g=u.map(a=>{let y=n[a];return y?I({mod:y,namespace:a,snapshotModulesSet:r}):null}).filter(a=>a!==null);chunk4MNQDXH7_cjs.a&&e.tickMs&&e.tickMs>0&&(g.some(y=>y.events&&Object.keys(y.events).some(h=>h.endsWith(`${m}tick`)))||console.warn(`[Directive] tickMs is set to ${e.tickMs}ms but no module defines a "tick" event handler.`));let k=null,w=null;function j(a){for(let[y,h]of Object.entries(a)){if(chunkX7G7UBXU_cjs.k.has(y)){chunk4MNQDXH7_cjs.a&&console.warn(`[Directive] initialFacts/hydrate contains blocked namespace "${y}". Skipping.`);continue}if(!t.has(y)){chunk4MNQDXH7_cjs.a&&console.warn(`[Directive] initialFacts/hydrate contains unknown namespace "${y}". Available modules: ${[...t].join(", ")}`);continue}if(h&&typeof h=="object"&&!chunk4MNQDXH7_cjs.f(h))throw new Error(`[Directive] initialFacts/hydrate for namespace "${y}" contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.`);for(let[M,x]of Object.entries(h))chunkX7G7UBXU_cjs.k.has(M)||(w.facts[`${y}${m}${M}`]=x);}}w=chunkENZEHIL7_cjs.z({modules:g,plugins:e.plugins,history:c,trace:o,errorBoundary:f,tickMs:e.tickMs,cloud:e.cloud,onAfterModuleInit:()=>{e.initialFacts&&j(e.initialFacts),k&&(j(k),k=null);}});let O=new Map;for(let a of Object.keys(n)){let y=n[a];y&&O.set(a,ue(a,y));}let q=re(w.facts,n,d),ye=se(w.derive,n,d),ge=ie(w,n,d),A=null,F=e.tickMs,_={_mode:"namespaced",facts:q,history:w.history,derive:ye,events:ge,constraints:w.constraints,effects:w.effects,resolvers:w.resolvers,async hydrate(a){if(w.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let y=await a();y&&typeof y=="object"&&(k=y);},initialize(){w.initialize();},start(){if(w.start(),F&&F>0){let a;for(let y of g)if(y?.events&&(a=Object.keys(y.events).find(h=>h.endsWith(`${m}tick`)),a))break;if(a){let y=a;A=setInterval(()=>{w.dispatch({type:y});},F);}}},stop(){A&&(clearInterval(A),A=null),w.stop();},destroy(){this.stop(),w.destroy();},dispatch(a){w.dispatch(a);},read(a){return w.read(R(a))},subscribe(a,y){let h=[];for(let M of a)if(M.endsWith(".*")){let x=M.slice(0,-2),W=O.get(x);W?h.push(...W):chunk4MNQDXH7_cjs.a&&console.warn(`[Directive] subscribe wildcard "${M}" \u2014 namespace "${x}" not found.`);}else h.push(R(M));return w.subscribe(h,y)},subscribeModule(a,y){let h=O.get(a);return !h||h.length===0?(chunk4MNQDXH7_cjs.a&&console.warn(`[Directive] subscribeModule("${a}") \u2014 namespace not found. Available: ${[...O.keys()].join(", ")}`),()=>{}):w.subscribe(h,y)},watch(a,y,h){return w.watch(R(a),y,h)},when(a,y){return w.when(()=>a(q),y)},getDistributableSnapshot(a){let y={...a,includeDerivations:a?.includeDerivations?.map(R),excludeDerivations:a?.excludeDerivations?.map(R),includeFacts:a?.includeFacts?.map(R)},h=w.getDistributableSnapshot(y);return {...h,data:H(h.data)}},watchDistributableSnapshot(a,y){let h={...a,includeDerivations:a?.includeDerivations?.map(R),excludeDerivations:a?.excludeDerivations?.map(R),includeFacts:a?.includeFacts?.map(R)};return w.watchDistributableSnapshot(h,M=>{y({...M,data:H(M.data)});})},registerModule(a,y){if(t.has(a))throw new Error(`[Directive] Module namespace "${a}" already exists. Cannot register a duplicate namespace.`);if(a.includes(m))throw new Error(`[Directive] Module name "${a}" contains the reserved separator "${m}".`);if(chunkX7G7UBXU_cjs.k.has(a))throw new Error(`[Directive] Module name "${a}" is a blocked property.`);for(let x of Object.keys(y.schema.facts))if(x.includes(m))throw new Error(`[Directive] Schema key "${x}" in module "${a}" contains the reserved separator "${m}".`);let h=y,M=I({mod:h,namespace:a,snapshotModulesSet:r});t.add(a),n[a]=h,l.names=null,O.set(a,ue(a,h)),w.registerModule(M);}};return le(_,w),fe(_),_}function de(e){let n=e.history,t=e.trace,s=e.errorBoundary;return e.zeroConfig&&(n=n??chunk4MNQDXH7_cjs.a,s={onConstraintError:"skip",onResolverError:"skip",onEffectError:"skip",onDerivationError:"skip",...e.errorBoundary}),{history:n,trace:t,errorBoundary:s}}function le(e,n){Object.defineProperties(e,{trace:{get(){return n.trace},enumerable:true,configurable:true},meta:{value:n.meta,enumerable:true,configurable:true},isRunning:{get(){return n.isRunning},enumerable:true,configurable:true},isSettled:{get(){return n.isSettled},enumerable:true,configurable:true},isInitialized:{get(){return n.isInitialized},enumerable:true,configurable:true},isReady:{get(){return n.isReady},enumerable:true,configurable:true}}),e.whenReady=n.whenReady.bind(n),e.batch=n.batch.bind(n),e.onSettledChange=n.onSettledChange.bind(n),e.onHistoryChange=n.onHistoryChange.bind(n),e.inspect=n.inspect.bind(n),e.settle=n.settle.bind(n),e.explain=n.explain.bind(n),e.getSnapshot=n.getSnapshot.bind(n),e.restore=n.restore.bind(n),e.observe=n.observe.bind(n);let t=["dispatch","read","subscribe","watch","when","getDistributableSnapshot","watchDistributableSnapshot"];for(let s of t)s in e||(e[s]=n[s].bind(n));}function fe(e){chunk4MNQDXH7_cjs.a&&(typeof process>"u"||process.env?.NODE_ENV!=="test")&&setTimeout(()=>{!e.isRunning&&!e.isInitialized&&console.warn("[Directive] System created but start() was never called. Constraints, resolvers, and effects will not run until you call system.start().");},0);}function $e(e){let n=e.module;if(!n)throw new Error("[Directive] createSystem requires a module. Got: "+typeof n);if(e.tickMs!==void 0&&e.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(e.initialFacts&&!chunk4MNQDXH7_cjs.f(e.initialFacts))throw new Error("[Directive] initialFacts contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.");chunk4MNQDXH7_cjs.a&&(n.crossModuleDeps&&Object.keys(n.crossModuleDeps).length>0&&console.warn("[Directive] Single module mode ignores crossModuleDeps. Use multiple modules if cross-module access is needed: createSystem({ modules: { ... } })"),e.tickMs&&e.tickMs>0&&(n.events&&"tick"in n.events||console.warn(`[Directive] tickMs is set to ${e.tickMs}ms but module has no "tick" event handler.`)),(typeof e.history=="object"?e.history:null)?.snapshotModules&&console.warn("[Directive] history.snapshotModules has no effect in single-module mode. Use history.snapshotEvents on the module definition instead, or switch to createSystem({ modules: { ... } }) for multi-module filtering."));let{history:t,trace:s,errorBoundary:r}=de(e),u=null,i=null;i=chunkENZEHIL7_cjs.z({modules:[{id:n.id,schema:n.schema.facts,requirements:n.schema.requirements,init:n.init,derive:n.derive,events:n.events,effects:n.effects,constraints:n.constraints,resolvers:n.resolvers,hooks:n.hooks,meta:n.meta,history:n.history}],plugins:e.plugins,history:t,trace:s,errorBoundary:r,tickMs:e.tickMs,cloud:e.cloud,onAfterModuleInit:()=>{if(e.initialFacts)for(let[d,g]of Object.entries(e.initialFacts))chunkX7G7UBXU_cjs.k.has(d)||(i.facts[d]=g);if(u){if(!chunk4MNQDXH7_cjs.f(u))chunk4MNQDXH7_cjs.a&&console.warn("[Directive] hydrate() data contains potentially dangerous keys. Skipping.");else for(let[d,g]of Object.entries(u))chunkX7G7UBXU_cjs.k.has(d)||(i.facts[d]=g);u=null;}}});let c=new Proxy({},{get(d,g){if(typeof g!="symbol"&&!chunkX7G7UBXU_cjs.k.has(g))return k=>{i.dispatch({type:g,...k});}},has(d,g){return typeof g=="symbol"||chunkX7G7UBXU_cjs.k.has(g)?false:n.events?g in n.events:false},ownKeys(){return n.events?Object.keys(n.events):[]},getOwnPropertyDescriptor(d,g){if(typeof g!="symbol"&&!chunkX7G7UBXU_cjs.k.has(g)&&n.events&&g in n.events)return {configurable:true,enumerable:true}},set(){return false},deleteProperty(){return false},defineProperty(){return false},getPrototypeOf(){return null},setPrototypeOf(){return false}}),o=null,f=e.tickMs,l={_mode:"single",facts:i.facts,history:i.history,derive:i.derive,events:c,constraints:i.constraints,effects:i.effects,resolvers:i.resolvers,async hydrate(d){if(i.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let g=await d();g&&typeof g=="object"&&(u=g);},initialize(){i.initialize();},start(){i.start(),f&&f>0&&n.events&&"tick"in n.events&&(o=setInterval(()=>{i.dispatch({type:"tick"});},f));},stop(){o&&(clearInterval(o),o=null),i.stop();},destroy(){this.stop(),i.destroy();},registerModule(d){i.registerModule({id:d.id,schema:d.schema.facts,requirements:d.schema.requirements,init:d.init,derive:d.derive,events:d.events,effects:d.effects,constraints:d.constraints,resolvers:d.resolvers,hooks:d.hooks,history:d.history});}};return le(l,i),fe(l),l}exports.a=ze;//# sourceMappingURL=chunk-NPX5EKPP.cjs.map
//# sourceMappingURL=chunk-NPX5EKPP.cjs.map

Sorry, the diff of this file is too big to display

import {i}from'./chunk-2FF6QGOA.js';import {h}from'./chunk-PXRV64PA.js';var $="djb2-1",F=1,x=Symbol("directive.audit-ledger.internal");function B(t,r,i){if(t===null||typeof t!="object")return;let o=[];for(let a of r.split(".")){if(!a)continue;let l=a.match(/^\[(\d+)\](.*)$/);if(l){o.push(Number(l[1])),l[2]&&o.push(l[2].replace(/^\./,""));continue}let f=a.match(/^([^[]+)\[(\d+)\](.*)$/);if(f){o.push(f[1]),o.push(Number(f[2])),f[3]&&o.push(f[3].replace(/^\./,""));continue}o.push(a);}let m=t;for(let a=0;a<o.length-1;a++){let l=o[a];if(m===null||typeof m!="object")return;m=m[l];}if(m===null||typeof m!="object")return;let d=o[o.length-1];d!==void 0&&(m[d]=i);}function N(t){for(let r of Object.keys(t)){let i=t[r];if(i!==null&&typeof i=="object"){if(Array.isArray(i)&&r==="whenExplain")for(let o of i)o!==null&&typeof o=="object"&&Object.freeze(o);Object.freeze(i);}}return Object.freeze(t),t}var U=1e4,G=1e3;function P(t){if(t instanceof Date)return t.getTime();if(typeof t=="number"){if(!Number.isFinite(t))throw new Error("[Directive] audit-ledger: changedBetween bound must be a finite number, ISO string, or Date.");return t}if(typeof t=="string"){let r=Date.parse(t);if(!Number.isFinite(r))throw new Error(`[Directive] audit-ledger: changedBetween bound "${t}" is not a parseable ISO date string.`);return r}throw new Error("[Directive] audit-ledger: changedBetween bound must be a number, ISO string, or Date.")}function T(t,r){if(r.kind&&!(Array.isArray(r.kind)?r.kind:[r.kind]).includes(t.kind))return false;if(r.factPath!==void 0)if(t.kind==="fact.change"){if(t.key!==r.factPath)return false}else if(t.kind==="resolver.write.rejected"){if(t.fact!==r.factPath)return false}else return false;if(r.constraintId!==void 0&&(t.kind!=="constraint.evaluate"||t.constraintId!==r.constraintId))return false;if(r.changedBetween){let[i,o]=r.changedBetween,m=P(i),d=P(o);if(t.ts<m||t.ts>d)return false}return true}function Y(t={}){let r=t.capacity??U,i=[],o=null;return {write(d){if(i.length>=r){let a=i[0];o?.(a.seq,1),i.shift();}for(i.push(d);i.length>r;)i.shift();},query(d){let a=d.limit??G,l=[];for(let f=i.length-1;f>=0;f--){let g=i[f];if(T(g,d)&&(l.push(g),l.length>=a))break}return l},recent(d){let a=Math.max(0,i.length-d);return i.slice(a)},forFact(d,a={}){return this.query({factPath:d,limit:a.limit})},forConstraint(d,a={}){return this.query({constraintId:d,limit:a.limit})},toJSON(){return {entries:i.slice(),capturedAt:Date.now()}},clear(){i=[];},destroy(){i=[],o=null;},erase(d,a){let l=0;for(let f=0;f<i.length;f++){let g=i[f];T(g,d)&&(i[f]=a(g),l++);}return l},onTruncate(d){o=d;}}}function W(t){return h(t)}function _(t){if(t.hashAlgo==="djb2-1")return W(t);throw new Error(`[Directive] audit-ledger: unknown hashAlgo "${String(t.hashAlgo)}" on entry seq=${t.seq}. Cannot verify chain integrity. Known algorithms: "djb2-1".`)}function ee(t={}){let r=t.sink??Y(),i$1=t.capturePII??false,o=t.redact,m=0,d=null,a=null,l=null,f=new Map,g=new Map,k=new Set;function L(e){if(i$1||k.size===0||e===null||typeof e!="object")return e;let n;try{n=JSON.parse(JSON.stringify(e));}catch{return e}return i(n,{operator(s,u,y,c){k.has(s)&&B(n,c,"[redacted]");},literal(s){k.has(s)&&B(n,s,"[redacted]");}}),n}function w(){if(f.clear(),g.clear(),!!a)try{let e=a.inspect;if(typeof e!="function")return;let s=e()?.constraints??[],u=a.$internal?.mergedConstraints;for(let y of s)if(y.whenSpec!==void 0)f.set(y.id,L(y.whenSpec));else {let c=u?.[y.id],h$1=c&&typeof c.when=="function"?c.when:void 0;h$1?g.set(y.id,h(String(h$1))):y.when!==void 0&&typeof y.when=="function"?g.set(y.id,h(String(y.when))):g.set(y.id,h("[function]"));}}catch{}}function j(){if(k.clear(),!(i$1||!a))try{let e=a.meta;if(!e||typeof e.byTag!="function")return;let n=e.byTag("pii")??[];for(let s of n)k.add(s.id);}catch{}}function E(e,n){return i$1?n:k.has(e)?"[redacted]":n}function C(e){if(!e||i$1||k.size===0)return e;let n=false,s=e.map(u=>{if(k.has(u.path))return n=true,{...u,actual:"[redacted]"};if(u.children){let y=C(u.children);if(y!==u.children)return n=true,{...u,children:y}}return u});return n?s:e}function p(e){let n={...e,seq:m++,ts:Date.now(),prevHash:d,hashAlgo:$,schemaVersion:F},s=o?o(n):n;return N(s),r.write(s),d=_(s),s}function M(e){switch(e.type){case "constraint.evaluate":{let n=f.get(e.id),s=g.get(e.id),u={kind:"constraint.evaluate",constraintId:e.id,active:e.active,whenExplain:C(e.whenExplain)};n!==void 0?u.whenSpec=n:s!==void 0&&(u.whenSource={kind:"function",sourceHash:s}),p(u);break}case "fact.change":p({kind:"fact.change",key:e.key,prior:E(e.key,e.prev),next:E(e.key,e.next)});break;case "resolver.write.rejected":e.kind==="summary"?p({kind:"resolver.write.rejected",rejection:"summary",resolverId:e.resolver,requirementId:e.requirementId,reason:e.reason,dropped:e.dropped}):p({kind:"resolver.write.rejected",rejection:"rejection",resolverId:e.resolver,requirementId:e.requirementId,reason:e.reason,fact:e.fact,expected:E(e.fact,e.expected),actual:E(e.fact,e.actual)});break;case "resolver.complete":p({kind:"resolver.complete",resolverId:e.resolver,requirementId:e.requirementId,duration:e.duration});break;case "resolver.error":p({kind:"resolver.error",resolverId:e.resolver,requirementId:e.requirementId,error:String(e.error)});break;case "system.init":case "system.start":case "system.stop":case "system.destroy":p({kind:e.type});break;}}let v=false;function K(e){a=e,j(),w(),l=e.observe(M),r.onTruncate?.((n,s)=>{if(!v){v=true;try{p({kind:"system.truncated",droppedSeq:n,droppedCount:s});}finally{v=false;}}});}function H(){l&&(l(),l=null),a=null,f.clear(),g.clear(),k.clear();}let V={name:"audit-ledger",onInit(e){K(e);},onStop(){l&&(l(),l=null);},onDestroy(){H();},onDefinitionRegister(e,n){e==="constraint"&&w(),(e==="constraint"||e==="resolver"||e==="effect")&&j();},onDefinitionAssign(e,n){e==="constraint"&&w();},onDefinitionUnregister(e,n){e==="constraint"&&w();},onSnapshot(e){p({kind:"system.snapshot",snapshotId:e.id,trigger:e.trigger});},onHistoryNavigate(e,n){p({kind:"system.history.navigate",from:e,to:n});}};function J(e){if(e.__internal===void 0)return e;let n={...e};return delete n.__internal,n}function b(e){let n=false;for(let s of e)if(s.__internal!==void 0){n=true;break}return n?e.map(J):e}return {plugin:V,query:(e={})=>b(r.query(e)),recent:e=>b(r.recent(e)),forFact:(e,n)=>b(r.forFact(e,n)),forConstraint:(e,n)=>b(r.forConstraint(e,n)),toJSON:()=>{let e=r.toJSON();return {entries:b(e.entries),capturedAt:e.capturedAt}},verify(e){if(e?.strong===true)throw new Error("[Directive] verify({ strong: true }) is reserved for v2 \u2014 v1 ships sync djb2 chain only. Use verify() (sync) for tamper detection.");let{entries:n}=r.toJSON();if(n.length===0)return {valid:true,entryCount:0};let s=new Set,u=null;for(let c=0;c<n.length;c++){let h=n[c];if(h.prevHash!==u){let S=c>0?n[c-1]:null,I=h.kind==="system.entry-erased",O=S?.kind==="system.entry-erased";if(I||O){let q=[];I&&q.push(h),O&&S!==null&&q.push(S);let R=q.find(Q=>Q.__internal!==x);if(R)return {valid:false,brokenAt:c,expectedHash:u??"<genesis>",actualHash:h.prevHash??"<genesis>",entry:R,reason:"tombstone forgery detected \u2014 missing internal sentinel. A 'system.entry-erased' entry was written via sink.write() rather than ledger.erase(); rejected as tamper."};let z=I?h:S;s.add(z.seq),u=_(h);continue}return {valid:false,brokenAt:c,expectedHash:u??"<genesis>",actualHash:h.prevHash??"<genesis>",entry:h}}u=_(h);}let y={valid:true,entryCount:n.length};return s.size>0&&(y.erasedSeqs=[...s].sort((c,h)=>c-h)),y},erase(e){let n=Date.now(),s=0;if(typeof r.erase=="function"&&(s=r.erase(e,c=>{let h={seq:c.seq,ts:c.ts,kind:"system.entry-erased",prevHash:c.prevHash,hashAlgo:c.hashAlgo,schemaVersion:c.schemaVersion??F,originalKind:c.kind,erasedAt:n,__internal:x};return N(h),h})),s===0)return {erased:0,markerEntry:null};let u={factPath:e.factPath!==void 0,constraintId:e.constraintId!==void 0,kind:e.kind,changedBetween:e.changedBetween!==void 0?"[range]":void 0},y=p({kind:"system.subject-erased",filterHash:h(e),filterShape:u,erased:s});return {erased:s,markerEntry:y}},clear(){r.clear(),m=0,d=null;},destroy(){H(),r.destroy();}}}export{Y as a,ee as b};//# sourceMappingURL=chunk-PA6VC32N.js.map
//# sourceMappingURL=chunk-PA6VC32N.js.map

Sorry, the diff of this file is too big to display

var b=typeof process<"u"&&process.env?.NODE_ENV!=="production";function m(n,o=new WeakSet){if(n===null||typeof n!="object")return n;let r=n;if(o.has(r)||Object.isFrozen(r))return n;if(o.add(r),Array.isArray(r))for(let s of r)m(s,o);else for(let s of Object.keys(r))m(r[s],o);return Object.freeze(r),n}function A(n){return m(n)}function x(n,o,r){return (...s)=>{try{return r(...s)}catch(u){throw u instanceof Error&&u.message.startsWith("[Directive] ")?new Error(`[Directive] ${n} '${o}': ${u.message.slice(12)}`,{cause:u}):u}}}async function T(n,o,r){let s,u=new Promise((g,d)=>{s=setTimeout(()=>d(new Error(r)),o);});try{return await Promise.race([n,u])}finally{clearTimeout(s);}}function l(n,o=50){let r=new WeakSet;function s(t){if(t===null)return "null";if(t===void 0)return "undefined";let e=typeof t;if(e==="string")return JSON.stringify(t);if(e==="number"||e==="boolean")return String(t);if(e==="function")return '"[function]"';if(e==="symbol")return '"[symbol]"'}function u(t,e){if(r.has(t))return '"[circular]"';r.add(t);let i=e();return r.delete(t),i}function g(t,e){return u(t,()=>`[${t.map(i=>c(i,e+1)).join(",")}]`)}function d(t,e){return u(t,()=>`{${Object.keys(t).sort().map(f=>`${JSON.stringify(f)}:${c(t[f],e+1)}`).join(",")}}`)}function c(t,e){if(e>o)return '"[max depth exceeded]"';if(typeof t=="bigint")return `${t.toString()}n`;let i=s(t);if(i!==void 0)return i;if(t instanceof Date)return `D:${t.toISOString()}`;if(t instanceof RegExp)return `R:${t.source}:${t.flags}`;if(t instanceof Map){let a=[...t.entries()].sort();return `M:${c(a,e+1)}`}if(t instanceof Set){let a=[...t].sort();return `S:${c(a,e+1)}`}return Array.isArray(t)?g(t,e):typeof t=="object"?d(t,e):'"[unknown]"'}return c(n,0)}function D(n,o=50){let r=new Set(["__proto__","constructor","prototype"]),s=new WeakSet;function u(t,e){if(s.has(t))return true;s.add(t);let i=e();return s.delete(t),i}function g(t,e){for(let i of t)if(!c(i,e+1))return false;return true}function d(t,e){for(let i of Object.keys(t))if(r.has(i)||!c(t[i],e+1))return false;return true}function c(t,e){if(e>o)return false;if(t==null||typeof t!="object")return true;let i=t;return Array.isArray(i)?u(i,()=>g(i,e)):u(i,()=>d(i,e))}return c(n,0)}function E(n,o){if(n===o)return true;if(!n||!o)return false;let r=Object.keys(n),s=Object.keys(o);if(r.length!==s.length)return false;for(let u of r)if(n[u]!==o[u])return false;return true}function $(n){let o=l(n),r=5381;for(let s=0;s<o.length;s++)r=(r<<5)+r^o.charCodeAt(s);return (r>>>0).toString(16)}function h(n,o=Date.now()){return n.expiresAt!==void 0&&o>n.expiresAt}function R(n,o=Date.now()){if(!n||typeof n!="object")throw new Error("[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.");if(!("data"in n))throw new Error("[Directive] Invalid snapshot: missing required 'data' property.");if(!("createdAt"in n)||typeof n.createdAt!="number")throw new Error("[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).");if(h(n,o)){let r=new Date(n.expiresAt).toISOString();throw new Error(`[Directive] Snapshot expired at ${r}. Obtain a fresh snapshot from the source.`)}return n.data}function P(n,o){let r=[];function s(e,i,a,f){r.push({path:e,oldValue:i,newValue:a,type:f});}function u(e,i,a){return e==null?(i!=null&&s(a,e,i,"added"),true):i==null?(s(a,e,i,"removed"),true):false}function g(e,i,a){if(e.length!==i.length){s(a,e,i,"changed");return}for(let f=0;f<e.length;f++)c(e[f],i[f],`${a}[${f}]`);}function d(e,i,a){let f=new Set([...Object.keys(e),...Object.keys(i)]);for(let y of f){let p=a?`${a}.${y}`:y;y in e?y in i?c(e[y],i[y],p):s(p,e[y],void 0,"removed"):s(p,void 0,i[y],"added");}}function c(e,i,a){if(!u(e,i,a)){if(typeof e!="object"||typeof i!="object"){Object.is(e,i)||s(a,e,i,"changed");return}if(Array.isArray(e)&&Array.isArray(i)){g(e,i,a);return}d(e,i,a);}}c(n.data,o.data,"");let t=n.version!==o.version&&(n.version!==void 0||o.version!==void 0);return {identical:r.length===0,changes:r,versionChanged:t,oldVersion:n.version,newVersion:o.version}}function C(n){return "signature"in n&&typeof n.signature=="string"}async function v(n,o){let r=l({data:n.data,createdAt:n.createdAt,expiresAt:n.expiresAt,version:n.version,metadata:n.metadata}),s=await k(r,o);return {...n,signature:s,algorithm:"hmac-sha256"}}async function I(n,o){if(!n.signature||n.algorithm!=="hmac-sha256")return false;let r=l({data:n.data,createdAt:n.createdAt,expiresAt:n.expiresAt,version:n.version,metadata:n.metadata}),s=await k(r,o);return w(n.signature,s)}async function k(n,o){let r=typeof o=="string"?new TextEncoder().encode(o):o,s={name:"HMAC",hash:{name:"SHA-256"}},u=await crypto.subtle.importKey("raw",r,s,false,["sign"]),g=new TextEncoder().encode(n),d=await crypto.subtle.sign("HMAC",u,g);return Array.from(new Uint8Array(d)).map(c=>c.toString(16).padStart(2,"0")).join("")}function w(n,o){if(n.length!==o.length)return false;let r=0;for(let s=0;s<n.length;s++)r|=n.charCodeAt(s)^o.charCodeAt(s);return r===0}function L(n,o=500){try{let r=JSON.stringify(n,(s,u)=>typeof u=="bigint"?`${u}n`:u,2);return r?r.length<=o?r:`${r.slice(0,o)}
... (truncated, ${r.length} chars total)`:"[undefined]"}catch{return "[unserializable]"}}export{b as a,A as b,x as c,T as d,l as e,D as f,E as g,$ as h,h as i,R as j,P as k,C as l,v as m,I as n,L as o};//# sourceMappingURL=chunk-PXRV64PA.js.map
//# sourceMappingURL=chunk-PXRV64PA.js.map
{"version":3,"sources":["../src/dev-true.ts","../src/utils/utils.ts"],"names":["dev_true_default","deepFreeze","value","seen","obj","item","key","freezeSpec","spec","attributeError","category","id","fn","args","e","withTimeout","promise","ms","errorMessage","timeoutId","timeoutPromise","_","reject","stableStringify","maxDepth","stringifyPrimitive","val","type","withCircularGuard","result","stringifyArray","depth","v","stringify","stringifyObject","k","primitive","entries","items","isPrototypeSafe","dangerousKeys","objVal","checkArray","arr","check","checkObject","shallowEqual","a","b","keysA","keysB","hashObject","str","hash","i","isSnapshotExpired","snapshot","now","validateSnapshot","expiredAt","diffSnapshots","oldSnapshot","newSnapshot","changes","pushChange","path","oldValue","newValue","compareNullish","oldObj","newObj","compareArrays","oldArr","newArr","compare","compareObjects","oldRecord","newRecord","allKeys","childPath","versionChanged","isSignedSnapshot","signSnapshot","secret","payload","signature","hmacSha256","verifySnapshotSignature","signedSnapshot","expectedSignature","timingSafeEqual","message","secretBytes","algorithm","messageBytes","safeStringify","data","maxLen","_key"],"mappings":"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","file":"chunk-PXRV64PA.js","sourcesContent":["// Runtime check that bundlers (webpack, esbuild, turbopack, rollup) inline\n// based on the consumer's NODE_ENV. Without this, the published bundle bakes\n// in `true` and dev-mode validation runs in every consumer's production\n// build — a real footgun the v1.5/v1.6 release hit.\nexport default typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\";\n","/**\n * Shared utilities for Directive\n */\n\n// ============================================================================\n// Deep freeze\n// ============================================================================\n\n/**\n * Recursively `Object.freeze` an object including nested objects, arrays, and\n * array elements. Uses a `WeakSet` to handle cycles. Skips primitives and\n * already-frozen values to avoid wasted work.\n *\n * Used at definition-registration sites (constraints, derivations, effects,\n * events, prefixed specs) so post-registration mutation of a nested operand\n * cannot silently change the compiled closure's behavior. Prefer\n * {@link freezeSpec} at registration sites — it documents the convention.\n */\nexport function deepFreeze<T>(\n value: T,\n seen: WeakSet<object> = new WeakSet(),\n): T {\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n const obj = value as unknown as object;\n if (seen.has(obj) || Object.isFrozen(obj)) {\n return value;\n }\n seen.add(obj);\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n deepFreeze(item, seen);\n }\n } else {\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n\n Object.freeze(obj);\n return value;\n}\n\n/**\n * Freeze a definition spec at registration. Centralizes the deepFreeze\n * convention so a new definition arm cannot forget it — every constraint,\n * derivation, effect, event, and prefixed-spec registration funnels through\n * this single helper.\n *\n * @param spec - The definition spec to freeze (mutated in place, returned)\n * @returns The same `spec` value, now deeply frozen\n *\n * @example\n * ```ts\n * // At registration time, freeze user-supplied specs so post-registration\n * // mutation cannot silently change the compiled closure's behavior.\n * const spec = freezeSpec(userPredicate);\n * memoizePredicate(spec);\n * ```\n */\nexport function freezeSpec<T>(spec: T): T {\n return deepFreeze(spec);\n}\n\n/**\n * Wrap a synthesized definition function so a `[Directive]`-prefixed error\n * thrown from inside it is re-thrown with the owning definition's category +\n * id injected, and the original error preserved as `cause`. Non-`[Directive]`\n * errors (user code, native) pass through untouched.\n *\n * Centralizes the owner-attribution wrap shared by the data-form `when`\n * (constraints), `on` (effects), and `compute` (derivations) closures — a\n * `[Directive]`-prefixed throw (e.g. `$matches: string`) is re-pointed at the\n * owning definition so the stack trace blames user config, not the runtime.\n *\n * @param category - The owning definition kind, used in the re-thrown message.\n * @param id - The owning definition's id.\n * @param fn - The synthesized function to wrap.\n * @returns A function with identical signature that re-attributes Directive errors.\n */\nexport function attributeError<A extends unknown[], R>(\n category: \"constraint\" | \"effect\" | \"derivation\",\n id: string,\n fn: (...args: A) => R,\n): (...args: A) => R {\n // Synchronous by design: the wrapped definition functions (memoized\n // predicate `when`/`on` closures, template closures) always return\n // synchronously. A `try/catch` only re-attributes a synchronous throw — an\n // async-returning fn's rejected promise would escape un-re-attributed.\n return (...args: A): R => {\n try {\n return fn(...args);\n } catch (e) {\n if (e instanceof Error && e.message.startsWith(\"[Directive] \")) {\n throw new Error(\n `[Directive] ${category} '${id}': ${e.message.slice(\"[Directive] \".length)}`,\n { cause: e },\n );\n }\n throw e;\n }\n };\n}\n\n/**\n * Execute a promise with a timeout, properly cleaning up the timer.\n * Used by both constraints and resolvers for timeout handling.\n *\n * @param promise - The promise to wrap with a timeout\n * @param ms - Timeout duration in milliseconds\n * @param errorMessage - Error message if timeout occurs\n * @returns The promise result\n * @throws Error if timeout is exceeded\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n errorMessage: string,\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error(errorMessage)), ms);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\n/**\n * Normalize an error to an Error instance.\n * Ensures consistent error handling throughout the library.\n *\n * @param error - The error to normalize (can be anything)\n * @returns An Error instance\n */\nexport function normalizeError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n}\n\n/**\n * Create a stable JSON string with sorted keys.\n * Handles circular references and deeply nested objects safely.\n *\n * @param value - The value to stringify\n * @param maxDepth - Maximum nesting depth (default: 50)\n * @returns A stable JSON string\n */\nexport function stableStringify(value: unknown, maxDepth = 50): string {\n const seen = new WeakSet();\n\n /** Stringify a primitive value (null, undefined, string, number, boolean, function, symbol). */\n function stringifyPrimitive(val: unknown): string | undefined {\n if (val === null) return \"null\";\n if (val === undefined) return \"undefined\";\n\n const type = typeof val;\n if (type === \"string\") return JSON.stringify(val);\n if (type === \"number\" || type === \"boolean\") return String(val);\n if (type === \"function\") return '\"[function]\"';\n if (type === \"symbol\") return '\"[symbol]\"';\n\n return undefined;\n }\n\n /** Guard against circular references using a seen-set, then delegate to fn. */\n function withCircularGuard(obj: object, fn: () => string): string {\n if (seen.has(obj)) {\n return '\"[circular]\"';\n }\n seen.add(obj);\n const result = fn();\n seen.delete(obj);\n\n return result;\n }\n\n /** Stringify an array with circular reference protection. */\n function stringifyArray(val: unknown[], depth: number): string {\n return withCircularGuard(\n val,\n () => `[${val.map((v) => stringify(v, depth + 1)).join(\",\")}]`,\n );\n }\n\n /** Stringify an object with sorted keys and circular reference protection. */\n function stringifyObject(\n obj: Record<string, unknown>,\n depth: number,\n ): string {\n return withCircularGuard(obj, () => {\n const keys = Object.keys(obj).sort();\n const pairs = keys.map(\n (k) => `${JSON.stringify(k)}:${stringify(obj[k], depth + 1)}`,\n );\n\n return `{${pairs.join(\",\")}}`;\n });\n }\n\n /** Recursively stringify a value with depth limit and circular detection. */\n function stringify(val: unknown, depth: number): string {\n if (depth > maxDepth) {\n return '\"[max depth exceeded]\"';\n }\n\n // BigInt is not JSON-serializable; encode with a trailing 'n' to remain\n // distinct from numeric strings.\n if (typeof val === \"bigint\") {\n return `${val.toString()}n`;\n }\n\n const primitive = stringifyPrimitive(val);\n if (primitive !== undefined) {\n return primitive;\n }\n\n // Typed-value branches: each prefix is bare (no outer quotes) so it can\n // never collide with a JSON-encoded string. `JSON.stringify(\"D:...\")`\n // emits `\"D:...\"` (the wrapping quotes ARE part of the output string),\n // whereas the Date branch emits `D:...` (no quotes). Distinct outputs.\n if (val instanceof Date) {\n return `D:${val.toISOString()}`;\n }\n if (val instanceof RegExp) {\n return `R:${val.source}:${val.flags}`;\n }\n if (val instanceof Map) {\n const entries = [...val.entries()].sort();\n return `M:${stringify(entries, depth + 1)}`;\n }\n if (val instanceof Set) {\n const items = [...val].sort();\n return `S:${stringify(items, depth + 1)}`;\n }\n\n if (Array.isArray(val)) {\n return stringifyArray(val, depth);\n }\n\n if (typeof val === \"object\") {\n return stringifyObject(val as Record<string, unknown>, depth);\n }\n\n return '\"[unknown]\"';\n }\n\n return stringify(value, 0);\n}\n\n/**\n * Check for prototype pollution in an object, including nested objects.\n * Returns true if the object is safe, false if dangerous keys are found.\n *\n * @param obj - The object to check\n * @param maxDepth - Maximum nesting depth to check (default: 50)\n * @returns True if safe, false if dangerous keys found\n */\nexport function isPrototypeSafe(obj: unknown, maxDepth = 50): boolean {\n const dangerousKeys = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n const seen = new WeakSet();\n\n /** Guard against circular references using a seen-set, then delegate to fn. */\n function withCircularGuard(objVal: object, fn: () => boolean): boolean {\n if (seen.has(objVal)) return true;\n seen.add(objVal);\n const result = fn();\n seen.delete(objVal);\n\n return result;\n }\n\n /** Check array elements for prototype pollution keys. */\n function checkArray(arr: unknown[], depth: number): boolean {\n for (const item of arr) {\n if (!check(item, depth + 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Check object keys and values for prototype pollution. */\n function checkObject(\n objVal: Record<string, unknown>,\n depth: number,\n ): boolean {\n for (const key of Object.keys(objVal)) {\n if (dangerousKeys.has(key)) {\n return false;\n }\n if (!check(objVal[key], depth + 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Recursively check a value tree for dangerous prototype keys. */\n function check(val: unknown, depth: number): boolean {\n if (depth > maxDepth) return false; // Fail safe at max depth - don't assume safety\n if (val === null || val === undefined) return true;\n if (typeof val !== \"object\") return true;\n\n const objVal = val as Record<string, unknown>;\n\n if (Array.isArray(objVal)) {\n return withCircularGuard(objVal, () => checkArray(objVal, depth));\n }\n\n return withCircularGuard(objVal, () => checkObject(objVal, depth));\n }\n\n return check(obj, 0);\n}\n\n/**\n * Shallow equality comparison for objects.\n * Used by React hooks to avoid unnecessary re-renders.\n *\n * @param a - First object\n * @param b - Second object\n * @returns True if objects are shallowly equal\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n a: T,\n b: T,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (a[key] !== b[key]) return false;\n }\n\n return true;\n}\n\n/**\n * Generate a simple hash string from an object.\n * Uses djb2 algorithm on the stable stringified value.\n *\n * **Limitations:**\n * - 32-bit hash output means collision probability increases with data set size\n * (birthday paradox: ~50% collision chance at ~77,000 distinct values)\n * - Suitable for: cache invalidation, change detection, deduplication of small sets\n * - NOT suitable for: cryptographic use, security-sensitive operations, large-scale deduplication\n *\n * For security-sensitive use cases requiring stronger collision resistance,\n * consider using a cryptographic hash like SHA-256.\n *\n * @param value - The value to hash\n * @returns A hex hash string (8 characters, 32 bits)\n */\nexport function hashObject(value: unknown): string {\n const str = stableStringify(value);\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n // Convert to unsigned 32-bit and then to hex\n return (hash >>> 0).toString(16);\n}\n\n// ============================================================================\n// Distributable Snapshot Utilities\n// ============================================================================\n\n/**\n * Distributable snapshot type for type-safe helper functions.\n */\nexport interface DistributableSnapshotLike<T = Record<string, unknown>> {\n data: T;\n createdAt: number;\n expiresAt?: number;\n version?: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Check if a distributable snapshot has expired.\n * Returns false if the snapshot has no expiresAt field.\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({ ttlSeconds: 3600 });\n * // ... later ...\n * if (isSnapshotExpired(snapshot)) {\n * // Refresh the snapshot\n * }\n * ```\n *\n * @param snapshot - The snapshot to check\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns True if the snapshot has expired, false otherwise\n */\nexport function isSnapshotExpired<T>(\n snapshot: DistributableSnapshotLike<T>,\n now: number = Date.now(),\n): boolean {\n return snapshot.expiresAt !== undefined && now > snapshot.expiresAt;\n}\n\n/**\n * Validate a distributable snapshot and return its data.\n * Throws if the snapshot is malformed or has expired.\n *\n * @example\n * ```typescript\n * const cached = JSON.parse(await redis.get(`entitlements:${userId}`));\n * try {\n * const data = validateSnapshot(cached);\n * // Use data.canUseFeature, etc.\n * } catch (e) {\n * // Snapshot invalid or expired, refresh it\n * }\n * ```\n *\n * @example Using custom timestamp for testing\n * ```typescript\n * const snapshot = { data: { test: true }, createdAt: 1000, expiresAt: 2000 };\n * validateSnapshot(snapshot, 1500); // Returns { test: true }\n * validateSnapshot(snapshot, 2500); // Throws: Snapshot expired\n * ```\n *\n * @param snapshot - The snapshot to validate\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns The snapshot data if valid\n * @throws Error if the snapshot is malformed or has expired\n */\nexport function validateSnapshot<T>(\n snapshot: DistributableSnapshotLike<T>,\n now: number = Date.now(),\n): T {\n // Structural validation\n if (!snapshot || typeof snapshot !== \"object\") {\n throw new Error(\n \"[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.\",\n );\n }\n if (!(\"data\" in snapshot)) {\n throw new Error(\n \"[Directive] Invalid snapshot: missing required 'data' property.\",\n );\n }\n if (!(\"createdAt\" in snapshot) || typeof snapshot.createdAt !== \"number\") {\n throw new Error(\n \"[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).\",\n );\n }\n\n // Expiration validation\n if (isSnapshotExpired(snapshot, now)) {\n const expiredAt = new Date(snapshot.expiresAt!).toISOString();\n throw new Error(\n `[Directive] Snapshot expired at ${expiredAt}. Obtain a fresh snapshot from the source.`,\n );\n }\n return snapshot.data;\n}\n\n/**\n * Diff result for a single changed value.\n */\nexport interface SnapshotDiffEntry {\n /** The key path that changed (e.g., \"canUseApi\" or \"limits.apiCalls\") */\n path: string;\n /** The value in the old snapshot */\n oldValue: unknown;\n /** The value in the new snapshot */\n newValue: unknown;\n /** Type of change: \"added\", \"removed\", or \"changed\" */\n type: \"added\" | \"removed\" | \"changed\";\n}\n\n/**\n * Result of diffing two snapshots.\n */\nexport interface SnapshotDiff {\n /** Whether the snapshots are identical */\n identical: boolean;\n /** List of changes between snapshots */\n changes: SnapshotDiffEntry[];\n /** Whether the version changed (if both have versions) */\n versionChanged: boolean;\n /** Old version (if available) */\n oldVersion?: string;\n /** New version (if available) */\n newVersion?: string;\n}\n\n/**\n * Compare two distributable snapshots and return the differences.\n * Useful for debugging, audit logs, and webhook payloads.\n *\n * @example\n * ```typescript\n * const oldSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n * system.dispatch({ type: \"upgradePlan\", plan: \"pro\" });\n * const newSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n *\n * const diff = diffSnapshots(oldSnapshot, newSnapshot);\n * if (!diff.identical) {\n * console.log(\"Changes:\", diff.changes);\n * // [{ path: \"canUseApi\", oldValue: false, newValue: true, type: \"changed\" }]\n * }\n * ```\n *\n * @param oldSnapshot - The previous snapshot\n * @param newSnapshot - The new snapshot\n * @returns A diff result with all changes\n */\nexport function diffSnapshots<T = Record<string, unknown>>(\n oldSnapshot: DistributableSnapshotLike<T>,\n newSnapshot: DistributableSnapshotLike<T>,\n): SnapshotDiff {\n const changes: SnapshotDiffEntry[] = [];\n\n /** Push a change entry to the diff results. */\n function pushChange(\n path: string,\n oldValue: unknown,\n newValue: unknown,\n type: SnapshotDiffEntry[\"type\"],\n ): void {\n changes.push({ path, oldValue, newValue, type });\n }\n\n /** Handle null/undefined comparison cases. Returns true if fully handled. */\n function compareNullish(\n oldObj: unknown,\n newObj: unknown,\n path: string,\n ): boolean {\n if (oldObj === null || oldObj === undefined) {\n if (newObj !== null && newObj !== undefined) {\n pushChange(path, oldObj, newObj, \"added\");\n }\n\n return true;\n }\n if (newObj === null || newObj === undefined) {\n pushChange(path, oldObj, newObj, \"removed\");\n\n return true;\n }\n\n return false;\n }\n\n /** Compare two arrays element by element, recursing into each. */\n function compareArrays(\n oldArr: unknown[],\n newArr: unknown[],\n path: string,\n ): void {\n if (oldArr.length !== newArr.length) {\n pushChange(path, oldArr, newArr, \"changed\");\n\n return;\n }\n for (let i = 0; i < oldArr.length; i++) {\n compare(oldArr[i], newArr[i], `${path}[${i}]`);\n }\n }\n\n /** Compare two objects by key union, detecting added/removed/changed. */\n function compareObjects(\n oldRecord: Record<string, unknown>,\n newRecord: Record<string, unknown>,\n path: string,\n ): void {\n const allKeys = new Set([\n ...Object.keys(oldRecord),\n ...Object.keys(newRecord),\n ]);\n\n for (const key of allKeys) {\n const childPath = path ? `${path}.${key}` : key;\n if (!(key in oldRecord)) {\n pushChange(childPath, undefined, newRecord[key], \"added\");\n } else if (!(key in newRecord)) {\n pushChange(childPath, oldRecord[key], undefined, \"removed\");\n } else {\n compare(oldRecord[key], newRecord[key], childPath);\n }\n }\n }\n\n /** Recursively compare two values and record differences. */\n function compare(oldObj: unknown, newObj: unknown, path: string): void {\n if (compareNullish(oldObj, newObj, path)) {\n return;\n }\n\n // Handle primitives\n if (typeof oldObj !== \"object\" || typeof newObj !== \"object\") {\n if (!Object.is(oldObj, newObj)) {\n pushChange(path, oldObj, newObj, \"changed\");\n }\n\n return;\n }\n\n // Handle arrays\n if (Array.isArray(oldObj) && Array.isArray(newObj)) {\n compareArrays(oldObj, newObj, path);\n\n return;\n }\n\n // Handle objects\n compareObjects(\n oldObj as Record<string, unknown>,\n newObj as Record<string, unknown>,\n path,\n );\n }\n\n // Compare data\n compare(oldSnapshot.data, newSnapshot.data, \"\");\n\n // Check version change\n const versionChanged =\n oldSnapshot.version !== newSnapshot.version &&\n (oldSnapshot.version !== undefined || newSnapshot.version !== undefined);\n\n return {\n identical: changes.length === 0,\n changes,\n versionChanged,\n oldVersion: oldSnapshot.version,\n newVersion: newSnapshot.version,\n };\n}\n\n// ============================================================================\n// Snapshot Signing (HMAC)\n// ============================================================================\n\n/**\n * A signed distributable snapshot.\n * Contains the original snapshot plus a cryptographic signature.\n */\nexport interface SignedSnapshot<T = Record<string, unknown>>\n extends DistributableSnapshotLike<T> {\n /** HMAC-SHA256 signature in hex format */\n signature: string;\n /** Signing algorithm used */\n algorithm: \"hmac-sha256\";\n}\n\n/**\n * Check if a snapshot is signed.\n *\n * @param snapshot - The snapshot to check\n * @returns True if the snapshot has a signature\n */\nexport function isSignedSnapshot<T>(\n snapshot: DistributableSnapshotLike<T> | SignedSnapshot<T>,\n): snapshot is SignedSnapshot<T> {\n return \"signature\" in snapshot && typeof snapshot.signature === \"string\";\n}\n\n/**\n * Sign a distributable snapshot using HMAC-SHA256.\n * Creates a tamper-proof signature that can be verified later.\n *\n * **Security Notes:**\n * - Use a cryptographically random secret of at least 32 bytes\n * - Store the secret securely (environment variable, secrets manager)\n * - Never expose the secret to clients\n * - The signature covers all snapshot fields for integrity\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({\n * includeDerivations: ['canUseFeature', 'limits'],\n * ttlSeconds: 3600,\n * });\n *\n * // Sign the snapshot (server-side only)\n * const signed = await signSnapshot(snapshot, process.env.SNAPSHOT_SECRET);\n *\n * // Store in JWT, Redis, or send to client\n * const jwt = createJWT({ snapshot: signed });\n *\n * // Later, verify the signature\n * const isValid = await verifySnapshotSignature(signed, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Snapshot has been tampered with');\n * }\n * ```\n *\n * @param snapshot - The snapshot to sign\n * @param secret - The HMAC secret (string or Uint8Array)\n * @returns A signed snapshot with the signature attached\n */\nexport async function signSnapshot<T>(\n snapshot: DistributableSnapshotLike<T>,\n secret: string | Uint8Array,\n): Promise<SignedSnapshot<T>> {\n // Create a canonical representation for signing\n const payload = stableStringify({\n data: snapshot.data,\n createdAt: snapshot.createdAt,\n expiresAt: snapshot.expiresAt,\n version: snapshot.version,\n metadata: snapshot.metadata,\n });\n\n const signature = await hmacSha256(payload, secret);\n\n return {\n ...snapshot,\n signature,\n algorithm: \"hmac-sha256\",\n };\n}\n\n/**\n * Verify the signature of a signed snapshot.\n * Returns true if the signature is valid, false otherwise.\n *\n * **Important:** Always verify signatures before trusting snapshot data,\n * especially if the snapshot was received from an untrusted source (client, cache).\n *\n * @example\n * ```typescript\n * // Receive signed snapshot from client or cache\n * const snapshot = JSON.parse(cachedData);\n *\n * // Verify before using\n * const isValid = await verifySnapshotSignature(snapshot, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Invalid snapshot signature - possible tampering');\n * }\n *\n * // Now safe to use snapshot.data\n * if (snapshot.data.canUseFeature.api) {\n * // Grant access\n * }\n * ```\n *\n * @param signedSnapshot - The signed snapshot to verify\n * @param secret - The HMAC secret (must match the signing secret)\n * @returns True if signature is valid, false otherwise\n */\nexport async function verifySnapshotSignature<T>(\n signedSnapshot: SignedSnapshot<T>,\n secret: string | Uint8Array,\n): Promise<boolean> {\n if (!signedSnapshot.signature || signedSnapshot.algorithm !== \"hmac-sha256\") {\n return false;\n }\n\n // Recreate the canonical payload (same as signing)\n const payload = stableStringify({\n data: signedSnapshot.data,\n createdAt: signedSnapshot.createdAt,\n expiresAt: signedSnapshot.expiresAt,\n version: signedSnapshot.version,\n metadata: signedSnapshot.metadata,\n });\n\n const expectedSignature = await hmacSha256(payload, secret);\n\n // Use timing-safe comparison\n return timingSafeEqual(signedSnapshot.signature, expectedSignature);\n}\n\n/**\n * Create HMAC-SHA256 signature of a message.\n * Uses Web Crypto API for cross-platform support (Node.js, browsers, Deno, Bun).\n */\nasync function hmacSha256(\n message: string,\n secret: string | Uint8Array,\n): Promise<string> {\n // Convert secret to Uint8Array if string\n const secretBytes: Uint8Array =\n typeof secret === \"string\" ? new TextEncoder().encode(secret) : secret;\n\n // Import key for HMAC\n const algorithm: HmacImportParams = {\n name: \"HMAC\",\n hash: { name: \"SHA-256\" },\n };\n const key = await crypto.subtle.importKey(\n \"raw\",\n secretBytes as unknown as ArrayBuffer,\n algorithm,\n false,\n [\"sign\"],\n );\n\n // Sign the message\n const messageBytes = new TextEncoder().encode(message);\n const signature = await crypto.subtle.sign(\"HMAC\", key, messageBytes);\n\n // Convert to hex string\n return Array.from(new Uint8Array(signature))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Timing-safe string comparison to prevent timing attacks.\n * Both strings should be the same length (hex signatures from same algorithm).\n */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n\n/**\n * Safely stringify any value for display. Handles circular references,\n * BigInt, throwing toJSON, and optional truncation.\n *\n * This is the canonical implementation – all packages should import this\n * instead of maintaining local copies.\n */\nexport function safeStringify(data: unknown, maxLen = 500): string {\n try {\n const str = JSON.stringify(\n data,\n (_key, value) => {\n if (typeof value === \"bigint\") {\n return `${value}n`;\n }\n\n return value;\n },\n 2,\n );\n if (!str) {\n return \"[undefined]\";\n }\n if (str.length <= maxLen) {\n return str;\n }\n\n return `${str.slice(0, maxLen)}\\n... (truncated, ${str.length} chars total)`;\n } catch {\n return \"[unserializable]\";\n }\n}\n"]}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

'use strict';var chunk4MNQDXH7_cjs=require('./chunk-4MNQDXH7.cjs');var g=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),Q=new Set(["$all","$any","$not"]);var T=new Set(["number","string","boolean","bigint","date","unknown"]);function P(e){if(!e)return {kind:"unknown"};let n=/^Branded<(.+)>$/.exec(e);return n?{kind:"branded",inner:P(n[1])}:e.endsWith(" | null")||e.endsWith(" | undefined")?{...P(e.replace(/ \| (null|undefined)$/,"")),nullable:true}:T.has(e)?{kind:e}:/^(email|uuid|url|cuid|datetime|iso\b)/i.test(e)?{kind:"string"}:e.includes(" | ")?{kind:"union",members:e.split(" | ").map(P)}:e==="array"?{kind:"array",element:{kind:"unknown"}}:e==="object"?{kind:"object",shape:{}}:e==="record"?{kind:"record",value:{kind:"unknown"}}:e==="tuple"?{kind:"tuple",elements:[]}:e==="union"?{kind:"union",members:[]}:{kind:"unknown"}}function z(e){if(e==null)return {kind:"unknown"};if(typeof e=="function")return chunk4MNQDXH7_cjs.a&&console.warn("[Directive] getKind: received a function \u2014 did you forget () on a t.* builder? Example: write `t.number()`, not `t.number`."),{kind:"unknown"};if(typeof e!="object")return {kind:"unknown"};let n=e,r;try{r=n._kind;}catch{return {kind:"unknown"}}if(r)return r;let i;try{i=n._typeName;}catch{return {kind:"unknown"}}return P(i)}function H(e){let n=new Map;if(!e||typeof e!="object")return n;let r=e,t="facts"in r&&r.facts&&typeof r.facts=="object"?r.facts:r;for(let[a,s]of Object.entries(t)){if(!s||typeof s!="object")continue;let o;try{o=z(s);}catch{continue}if(n.set(a,o),o.kind==="object")for(let[c,l]of Object.entries(o.shape))n.set(`${a}.${c}`,l);}return n.size===0&&chunk4MNQDXH7_cjs.a&&console.warn("[Directive] getSchemaFieldKinds: schema appears empty (no introspectable keys). Did you pass the module instead of its schema? Pass `myModule.schema`, not `myModule`."),n}var k=["$eq","$ne","$in","$nin","$exists"],D=["$gt","$gte","$lt","$lte","$between"],W=["$matches","$startsWith","$endsWith","$contains"];function w(e){switch(e.kind){case "number":case "bigint":case "date":return [...k,...D];case "string":return [...k,...D,...W];case "boolean":case "unknown":return k;case "array":return [...k,"$contains"];case "object":case "record":case "tuple":return k;case "literal":case "enum":return w(e.primitive==="number"?{kind:"number"}:e.primitive==="boolean"?{kind:"boolean"}:e.primitive==="null"?{kind:"unknown"}:{kind:"string"});case "branded":return w(e.inner);case "union":{if(e.members.length===0)return k;let n=e.members.map(t=>new Set(w(t))),r=n[0],i=[];for(let t of r)n.every(a=>a.has(t))&&i.push(t);return i}default:{return k}}}function X(){return Array.from(g)}var O=64;function u(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function x(e){if(typeof e!="object"||e===null||Array.isArray(e))return false;let n=Object.getPrototypeOf(e);return n===Object.prototype||n===null}function E(e){if(!u(e))return false;let n=0,r=false;for(let i of Object.keys(e)){if(i.startsWith("$"))r=true,g.has(i)||f(`predicate: unknown operator "${i}" \u2014 looks like a typo. Known operators: ${[...g].join(", ")}`);else if(r||n===0)return false;n++;}return r?n>0:false}function re(e){return e===null?false:Array.isArray(e)?e.every(n=>x(n)&&"fact"in n&&"op"in n):x(e)}function h(e,n,r="",i=new WeakSet,t=0){if(t>O){chunk4MNQDXH7_cjs.a&&console.warn(`[Directive] predicate depth limit (${O}) exceeded \u2014 flatten the predicate or split it into multiple constraints. If this is unexpected, check for a cyclic spec object.`),n.bail?.("depth");return}if(Array.isArray(e)){e.forEach((s,o)=>{if(!u(s))return;let c=s;if(typeof c.fact=="string"&&typeof c.op=="string"){let l=r?`${r}[${o}]`:`[${o}]`;n.operator?.(r?`${r}.${c.fact}`:c.fact,c.op,c.value,`${l}.value`);}});return}if(!u(e))return;if(i.has(e)){chunk4MNQDXH7_cjs.a&&console.warn("[Directive] walkPredicate: cyclic predicate spec"),n.bail?.("cycle");return}i.add(e);let a=e;for(let s of ["$all","$any","$not"])if(s in a){if(n.combinator?.(s)===false)return;let c=s==="$not"?[a.$not]:a[s]??[];for(let l of c)h(l,n,r,i,t+1);return}for(let s of Object.keys(a)){let o=r?`${r}.${s}`:s;if(s.startsWith("$")){n.strayOperatorKey?.(s,o);continue}let c=a[s];if(E(c)){let l=c;for(let p of Object.keys(l))n.operator?.(o,p,l[p],`${o}.${p}`);continue}if(x(c)){if(n.nested?.(s)===false)continue;h(c,n,o,i,t+1);continue}n.literal?.(o,c);}}function ie(e){if(!x(e))return false;let n=false;return h(e,{operator(){n=true;},literal(){n=true;},combinator(){n=true;},strayOperatorKey(){n=true;},bail(){n=true;}}),!n}function I(e){return u(e)&&Object.hasOwn(e,"$template")&&typeof e.$template=="string"}function oe(e,n=""){function r(t,a,s,o){if(typeof t=="bigint")throw new Error(`[Directive] validatePredicate: bigint operand at "${a}" is not JSON-serializable (JSON.stringify throws on bigint).`);if(t instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand at "${a}" is not JSON-serializable (serializes to {} and loses all members).`);if(t instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand at "${a}" is not JSON-serializable (serializes to {} and loses all entries).`);if(t instanceof RegExp)throw new Error(`[Directive] validatePredicate: RegExp operand at "${a}" is not JSON-serializable (a regex lost to JSON.parse becomes {}). Only a direct $matches operand may be a RegExp.`);if(!(t===null||typeof t!="object")&&!(o>O)&&!s.has(t)){if(s.add(t),Array.isArray(t)){t.forEach((c,l)=>{r(c,`${a}[${l}]`,s,o+1);});return}for(let c of Object.keys(t))r(t[c],a?`${a}.${c}`:c,s,o+1);}}function i(t,a,s){if(typeof t=="bigint")throw new Error(`[Directive] validatePredicate: bigint operand at "${s}" is not JSON-serializable (JSON.stringify throws on bigint).`);if(t instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand at "${s}" is not JSON-serializable (serializes to {} and loses all members).`);if(t instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand at "${s}" is not JSON-serializable (serializes to {} and loses all entries).`);if(a==="$matches"&&!(t instanceof RegExp))throw new Error(`[Directive] validatePredicate: $matches operand at "${s}" must be a RegExp; got ${t===null?"null":typeof t}. A regex lost to JSON.parse becomes {} \u2014 reify with new RegExp(pattern, flags) before installing.`);if(Array.isArray(t))t.forEach((o,c)=>{r(o,`${s}[${c}]`,new WeakSet,1);});else if(x(t))for(let o of Object.keys(t))r(t[o],`${s}.${o}`,new WeakSet,1);}if(e instanceof Set)throw new Error(`[Directive] validatePredicate: Set operand${n?` at "${n}"`:""} is not JSON-serializable (serializes to {} and loses all members).`);if(e instanceof Map)throw new Error(`[Directive] validatePredicate: Map operand${n?` at "${n}"`:""} is not JSON-serializable (serializes to {} and loses all entries).`);h(e,{operator(t,a,s,o){i(s,a,n?`${n}.${o}`:o);},literal(t,a){i(a,"",n?`${n}.${t}`:t);}});}function M(e){return typeof e!="string"||e.length===0?false:!!(/\)(?:[+*]\??|\{\d+,?\d*\})\s*[+*?]\s*[+*]/.test(e)||/\(([^()]*?[+*]|[^()]*?\{\d+,?\d*\})[^()]*\)\s*[+*]/.test(e)||/\(\??:?([^()|]+)\|\1\)\s*[+*]/.test(e))}function se(e,n,r={}){let i=[],t=0,a=r.maxOperatorCount,s=r.maxArrayOperandLength;return h(e,{operator(o,c,l,p){if(t++,a!==void 0&&t>a){i.some($=>$.reason.includes("maxOperatorCount"))||i.push({path:o,op:c,reason:`Predicate exceeds maxOperatorCount=${a} \u2014 too many clauses (DoS guard).`});return}if(s!==void 0&&(c==="$in"||c==="$nin")&&Array.isArray(l)&&l.length>s){i.push({path:o,op:c,reason:`Operator ${c} operand exceeds maxArrayOperandLength=${s} (got ${l.length}) \u2014 too large for a query planner.`});return}if(c==="$matches"){let $;if(l instanceof RegExp?$=l.source:typeof l=="string"&&($=l),$!==void 0&&M($)){i.push({path:o,op:c,reason:`Operator $matches operand at "${o}" contains nested quantifiers (ReDoS risk: ${JSON.stringify($)}). Reject untrusted regex or rewrite without nested + / *.`});return}}let m=n.get(o);if(!m){i.push({path:o,op:c,reason:`Unknown fact "${o}" \u2014 not in schema. Known facts: ${n.size===0?"(empty schema)":Array.from(n.keys()).join(", ")}`});return}let y=w(m);y.includes(c)||i.push({path:o,op:c,kind:m,allowedOps:y,reason:`Operator "${c}" is not allowed on fact "${o}" of kind "${m.kind}". Allowed operators for this kind: ${y.join(", ")}.`});},literal(o,c){t++,n.has(o)||i.push({path:o,op:"$eq",reason:`Unknown fact "${o}" \u2014 not in schema.`});},strayOperatorKey(o,c){i.push({path:c,op:o,reason:`Stray operator key "${o}" at "${c}" \u2014 operators must live inside a fact's operator object, not at the predicate top level.`});}}),i.length===0?{ok:true,operatorCount:t}:{ok:false,errors:i,operatorCount:t}}function _(){return {ids:new WeakMap,next:{v:1},pairs:new Set}}function v(e,n){let r=e.ids.get(n);return r===void 0&&(r=e.next.v++,e.ids.set(n,r)),r}function d(e,n,r){if(Object.is(e,n))return true;if(e instanceof Date&&n instanceof Date)return e.getTime()===n.getTime();if(typeof e!="object"||typeof n!="object"||e===null||n===null)return false;let i=r??_(),t=`${v(i,e)}:${v(i,n)}`;if(i.pairs.has(t))return true;if(i.pairs.add(t),Array.isArray(e)||Array.isArray(n))return !Array.isArray(e)||!Array.isArray(n)||e.length!==n.length?false:e.every((o,c)=>d(o,n[c],i));if(e instanceof Set||n instanceof Set){if(!(e instanceof Set)||!(n instanceof Set)||e.size!==n.size)return false;let o=[...n];return [...e].every(c=>o.some(l=>d(c,l,i)))}if(e instanceof Map||n instanceof Map){if(!(e instanceof Map)||!(n instanceof Map)||e.size!==n.size)return false;let o=[...n.entries()],c=new Array(o.length).fill(false);for(let[l,p]of e){let m=false;for(let y=0;y<o.length;y++){if(c[y])continue;let[$,N]=o[y];if(d(l,$,i)&&d(p,N,i)){c[y]=true,m=true;break}}if(!m)return false}return true}let a=Object.keys(e),s=Object.keys(n);return a.length!==s.length?false:a.every(o=>Object.hasOwn(n,o)&&d(e[o],n[o],i))}function j(e){if(e instanceof Date)return e.getTime();if(typeof e=="number"||typeof e=="bigint"||typeof e=="string")return e}function A(e,n,r){let i=j(n),t=j(r);if(i===void 0||t===void 0||typeof i!=typeof t)return false;switch(e){case "$gt":return i>t;case "$gte":return i>=t;case "$lt":return i<t;case "$lte":return i<=t;default:return false}}function R(e,n,r,i){switch(e){case "$eq":return d(n,r);case "$ne":return !d(n,r);case "$in":return Array.isArray(r)&&r.some(t=>d(n,t));case "$nin":return Array.isArray(r)&&!r.some(t=>d(n,t));case "$exists":return r===(n!==void 0);case "$changed":return !d(n,i);case "$gt":case "$gte":case "$lt":case "$lte":return A(e,n,r);case "$between":{if(!Array.isArray(r)||r.length!==2)return false;let t=j(r[0]),a=j(r[1]);return t!==void 0&&a!==void 0&&typeof t==typeof a&&t>a?(f("$between: reversed pair \u2014 [min, max] required"),false):A("$gte",n,r[0])&&A("$lte",n,r[1])}case "$matches":{if(!(r instanceof RegExp))throw new Error("[Directive] $matches: operand must be a RegExp (string operands are no longer accepted; pass /pattern/flags directly).");return typeof n!="string"?false:r.test(n)}case "$startsWith":return typeof n!="string"?false:n.startsWith(String(r));case "$endsWith":return typeof n!="string"?false:n.endsWith(String(r));case "$contains":return typeof n=="string"?n.includes(String(r)):Array.isArray(n)?n.some(t=>d(t,r)):n instanceof Set?n.has(r):false;default:return false}}function f(e){chunk4MNQDXH7_cjs.a&&console.warn(`[Directive] ${e}`);}function q(e,n,r,i){if(E(e)){let t=Object.keys(e);t.length>1&&f(`predicate: operator object has ${t.length} operators (${t.join(", ")}) \u2014 write the array form or $all instead. The runtime ANDs them as a best-effort fallback.`);for(let a of t)if(!R(a,n,e[a],r))return false;return true}return u(e)?S(e,u(n)?n:Object.create(null),u(r)?r:void 0,i+1):d(n,e)}function S(e,n,r,i=0){if(i>O)return f(`predicate depth limit (${O}) exceeded \u2014 flatten the predicate or split it into multiple constraints. If this is unexpected, check for a cyclic spec object.`),false;if(Array.isArray(e))return e.every(t=>{if(!u(t))return false;let{fact:a,op:s,value:o}=t;return R(s,n?.[a],o,r?.[a])});if(!u(e))return !!e;if("$all"in e)return e.$all.every(t=>S(t,n,r,i+1));if("$any"in e)return e.$any.some(t=>S(t,n,r,i+1));if("$not"in e)return !S(e.$not,n,r,i+1);for(let t of Object.keys(e)){if(g.has(t))return f(`predicate: operator "${t}" mixed with fact keys \u2014 wrap operators in a per-fact object`),false;if(!q(e[t],n?.[t],r?.[t],i))return false}return true}function V(e,n,r,i=""){let t=[];if(Array.isArray(e)){for(let a of e){if(!u(a))continue;let{fact:s,op:o,value:c}=a,l=n?.[s];t.push({path:i+s,op:o,expected:c,actual:l,pass:R(o,l,c,r?.[s])});}return t}if(!u(e))return t;for(let a of ["$all","$any","$not"])if(a in e){let s=a==="$not"?[e.$not]:e[a],o=[];for(let p of s)o.push(...V(p,n,r,i));let c=o.filter(p=>p.pass).length,l;return a==="$all"?l=o.length===0||c===o.length:a==="$any"?l=o.length>0&&c>0:l=!o.every(p=>p.pass),t.push({path:i||a,op:a,expected:s.length,actual:c,pass:l,children:o}),t}for(let a of Object.keys(e)){if(g.has(a))continue;let s=e[a],o=n?.[a],c=i+a;if(E(s))for(let l of Object.keys(s))t.push({path:c,op:l,expected:s[l],actual:o,pass:R(l,o,s[l],r?.[a])});else u(s)?t.push(...V(s,u(o)?o:Object.create(null),u(r?.[a])?r?.[a]:void 0,`${c}.`)):t.push({path:c,op:"$eq",expected:s,actual:o,pass:d(o,s)});}return t}var F=new WeakMap;function ce(e){if(e===null||typeof e!="object")throw new Error(`[Directive] memoizePredicate: predicate must be a plain object or array; got ${typeof e}`);let n=F.get(e);if(n)return n;let r=(i,t)=>S(e,i,t);return F.set(e,r),r}function le(e,n=""){let r=new Set;return h(e,{operator(i){r.add(n+i);},literal(i){r.add(n+i);},strayOperatorKey(i){g.has(i)||f(`extractDeps: unknown operator "${i}" \u2014 skipping. Known operators: ${[...g].join(", ")}`);}}),r}var C=/^[A-Za-z_][A-Za-z0-9_]*$/;function J(e){return typeof e=="symbol"||e==null?"":String(e)}function B(e,n){return typeof e=="symbol"?(f("template: cannot interpolate a symbol value \u2014 using empty string"),""):e===void 0?(f(`template: ${n?`key "${n}" is `:""}undefined \u2014 using empty string`),""):e===null?(f(`template: ${n?`key "${n}" is `:""}null \u2014 using empty string`),""):String(e)}function L(e,n){let r=e.$template,i="",t=0;for(;t<r.length;){if(r[t]==="$"&&r[t+1]==="$"&&r[t+2]==="{"){i+="${",t+=3;continue}if(r[t]==="$"&&r[t+1]==="{"){let a=r.indexOf("}",t+2);if(a===-1){f(`template: unterminated "\${" in ${JSON.stringify(r)}`),i+=r.slice(t);break}let s=r.slice(t+2,a);if(!C.test(s))f(`template: invalid placeholder "\${${s}}" \u2014 not an identifier`);else {let o=n!=null&&Object.hasOwn(n,s),c=o?n[s]:void 0;o?i+=B(c,s):(f(`template: unknown key "${s}"`),i+=J(c));}t=a+1;continue}i+=r[t],t++;}return i}function ue(e){let n=new Set,r=e.$template,i=0;for(;i<r.length;){if(r[i]==="$"&&r[i+1]==="$"&&r[i+2]==="{"){i+=3;continue}if(r[i]==="$"&&r[i+1]==="{"){let t=r.indexOf("}",i+2);if(t===-1)break;let a=r.slice(i+2,t);C.test(a)&&n.add(a),i=t+1;continue}i++;}return n}function de(e,n){return e.map(r=>chunk4MNQDXH7_cjs.e(n?.[r])).join("|")}function fe(e,n,r){let i=e.$set,t=r??{};for(let a of Object.keys(i)){let s=i[a];if(I(s))n[a]=L(s,t);else if(u(s)&&Object.hasOwn(s,"$ref")&&typeof s.$ref=="string"){let o=s.$ref;Object.hasOwn(t,o)||f(`applyPatch: $ref "${o}" is missing from event payload \u2014 assigning undefined to fact "${a}"`),n[a]=t[o];}else n[a]=s;}}exports.a=g;exports.b=Q;exports.c=z;exports.d=H;exports.e=w;exports.f=X;exports.g=O;exports.h=re;exports.i=h;exports.j=ie;exports.k=I;exports.l=oe;exports.m=M;exports.n=se;exports.o=S;exports.p=V;exports.q=ce;exports.r=le;exports.s=L;exports.t=ue;exports.u=de;exports.v=fe;//# sourceMappingURL=chunk-T4TRJEJN.cjs.map
//# sourceMappingURL=chunk-T4TRJEJN.cjs.map

Sorry, the diff of this file is too big to display

'use strict';function a(e,t,r){e[t]=r;}function c(e,t){return e[t]}function u(e,t){return {name:e,onRequirementCreated:t.onRequirementCreated?r=>t.onRequirementCreated(r.requirement):void 0,onRequirementMet:t.onRequirementResolved?r=>t.onRequirementResolved(r.requirement):void 0,onError:t.onError}}function d(e){return t=>t.type===e}function p(e){let t=new Set(e);return r=>t.has(r.type)}var n=[];function m(){let e=n.length;return e===0?null:n[e-1]}function l(){return n.length>0}function R(e){let t=new Set;n.push(t);try{return {value:e(),deps:t}}finally{n.pop();}}function S(e){let t=n.splice(0,n.length);try{return e()}finally{for(let r of t)n.push(r);}}function g(e){let t=n.length;t!==0&&n[t-1].add(e);}var q=Object.freeze(new Set(["__proto__","constructor","prototype"]));function x(e){if(e===null||typeof e!="object")return null;if(e instanceof Date)return "Date";if(e instanceof Set)return "Set";if(e instanceof Map)return "Map";if(typeof File<"u"&&e instanceof File)return "File";if(Array.isArray(e))return null;let t=Object.getPrototypeOf(e);return t!==null&&t!==Object.prototype?"ClassInstance":null}var o=new Set,s={Date:".getTime() for timestamps",Set:"[...set] for arrays",Map:"Object.fromEntries(map) for plain objects",File:"{ name, size, type, lastModified } for metadata",ClassInstance:"a plain-object snapshot"};function y(e,t){let r=`${e}|${t}`;if(o.has(r))return;o.add(r);let i=s[t]??"a JSON-roundtrippable value";console.warn(`[Directive] Fact "${e}" assigned a ${t} instance.
Facts must be JSON-roundtrippable for reactivity to work correctly.
${t} mutations are not tracked.
Use ${i} instead.
See: https://directive.run/docs/facts#json-rule`);}
exports.a=a;exports.b=c;exports.c=u;exports.d=d;exports.e=p;exports.f=m;exports.g=l;exports.h=R;exports.i=S;exports.j=g;exports.k=q;exports.l=x;exports.m=y;//# sourceMappingURL=chunk-X7G7UBXU.cjs.map
//# sourceMappingURL=chunk-X7G7UBXU.cjs.map
{"version":3,"sources":["../src/core/types/adapter-utils.ts","../src/core/tracking.ts"],"names":["setBridgeFact","facts","key","value","getBridgeFact","createCallbackPlugin","name","callbacks","req","requirementGuard","type","requirementGuardMultiple","types","typeSet","depStack","getCurrentDeps","len","isTracking","withTracking","fn","deps","withoutTracking","saved","ctx","trackAccess","BLOCKED_PROPS","detectNonJsonValueType","proto","nonJsonWarningCache","nonJsonHints","warnNonJsonFactAssignment","factPath","valueType","cacheKey","hint"],"mappings":"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","file":"chunk-X7G7UBXU.cjs","sourcesContent":["/**\n * Adapter Type Utilities - Shared types and helpers for framework adapters\n *\n * These utilities reduce type assertions in adapters by providing:\n * - Schema composition types\n * - Constraint/resolver converters\n * - Plugin factory helpers\n */\n\nimport type { Facts } from \"./facts.js\";\nimport type { Plugin } from \"./plugins.js\";\nimport type { ConstraintDef, Requirement } from \"./requirements.js\";\nimport type { ResolverContext, ResolverDef } from \"./resolvers.js\";\nimport type { InferSchema, Schema } from \"./schema.js\";\n\n// ============================================================================\n// Schema Composition Types\n// ============================================================================\n\n/**\n * Merge two schemas into one.\n * Useful for adapters that add bridge-specific facts to user schemas.\n *\n * @example\n * ```typescript\n * type BridgeFields = { __state: SchemaType<Record<string, unknown>> };\n * type Combined = MergedSchema<UserSchema, BridgeFields>;\n * ```\n */\nexport type MergedSchema<Base extends Schema, Extra extends Schema> = Base &\n Extra;\n\n/**\n * Create a schema type from a fields definition.\n * Helper for defining adapter bridge schemas.\n *\n * @example\n * ```typescript\n * type AdapterBridgeSchema = BridgeSchema<{\n * __adapterState: SchemaType<Record<string, unknown>>;\n * }>;\n * ```\n */\nexport type BridgeSchema<Fields extends Schema> = Fields;\n\n// ============================================================================\n// Bridge Schema Helper\n// ============================================================================\n\n/**\n * Create a bridge schema definition for adapters.\n * Returns a schema object compatible with createModule().\n *\n * @example\n * ```typescript\n * const bridgeSchema = createBridgeSchema({\n * __state: t.object<Record<string, unknown>>(),\n * });\n * ```\n */\nexport function createBridgeSchema<S extends Schema>(schema: S): S {\n return schema;\n}\n\n// ============================================================================\n// Type-Safe Fact Mutation\n// ============================================================================\n\n/**\n * Type-safe fact setter for known schema keys.\n * Use when you have a typed schema and want to set a specific fact.\n *\n * @example\n * ```typescript\n * setFact(facts, \"count\", 10); // Type-checked\n * ```\n */\nexport function setFact<S extends Schema, K extends keyof InferSchema<S>>(\n facts: Facts<S>,\n key: K,\n value: InferSchema<S>[K],\n): void {\n (facts as Record<string, unknown>)[key as string] = value;\n}\n\n/**\n * Set a bridge fact without strict typing.\n * Use for adapter-internal bridge fields like `__adapterState`.\n *\n * @example\n * ```typescript\n * setBridgeFact(facts, \"__adapterState\", currentState);\n * ```\n */\nexport function setBridgeFact<V>(\n facts: Facts<Schema>,\n key: string,\n value: V,\n): void {\n (facts as Record<string, unknown>)[key] = value;\n}\n\n/**\n * Get a bridge fact without strict typing.\n * Use for adapter-internal bridge fields.\n *\n * @example\n * ```typescript\n * const state = getBridgeFact<MyState>(facts, \"__adapterState\");\n * ```\n */\nexport function getBridgeFact<V>(facts: Facts<Schema>, key: string): V {\n return (facts as Record<string, unknown>)[key] as V;\n}\n\n// ============================================================================\n// Constraint Converters\n// ============================================================================\n\n/**\n * Adapter constraint definition (generic form used by adapters).\n */\nexport interface AdapterConstraint<TState> {\n when: (state: TState) => boolean | Promise<boolean>;\n require: Requirement | ((state: TState) => Requirement | null);\n priority?: number;\n}\n\n/**\n * Convert adapter-style constraints to Directive format.\n * Maps adapter constraints that work with external state (TState) to\n * Directive constraints that work with Facts<Schema>.\n *\n * @param constraints - Adapter constraints keyed by name\n * @param extractState - Function to extract adapter state from facts\n *\n * @example\n * ```typescript\n * const directiveConstraints = convertConstraints<MyState, BridgeSchema>(\n * adapterConstraints,\n * (facts) => getBridgeFact<MyState>(facts, \"__state\"),\n * );\n * ```\n */\nexport function convertConstraints<TState, S extends Schema>(\n constraints: Record<string, AdapterConstraint<TState>>,\n extractState: (facts: Facts<S>) => TState,\n): Record<string, ConstraintDef<S, Requirement>> {\n const result: Record<string, ConstraintDef<S, Requirement>> = {};\n\n for (const [id, constraint] of Object.entries(constraints)) {\n result[id] = {\n priority: constraint.priority ?? 0,\n when: (facts) => constraint.when(extractState(facts)),\n require: (facts) => {\n const req =\n typeof constraint.require === \"function\"\n ? constraint.require(extractState(facts))\n : constraint.require;\n return req;\n },\n };\n }\n\n return result;\n}\n\n// ============================================================================\n// Resolver Converters\n// ============================================================================\n\n/**\n * Adapter resolver context (generic form used by adapters).\n */\nexport interface AdapterResolverContext<TContext> {\n context: TContext;\n signal: AbortSignal;\n}\n\n/**\n * Adapter resolver definition (generic form used by adapters).\n */\nexport interface AdapterResolver<\n TContext,\n R extends Requirement = Requirement,\n> {\n requirement: (req: Requirement) => req is R;\n key?: (req: R) => string;\n resolve: (\n req: R,\n ctx: AdapterResolverContext<TContext>,\n ) => void | Promise<void>;\n}\n\n/**\n * Convert adapter-style resolvers to Directive format.\n * Maps adapter resolvers that work with external context (TContext) to\n * Directive resolvers that work with ResolverContext<Schema>.\n *\n * @param resolvers - Adapter resolvers keyed by name\n * @param createContext - Function to create adapter context from Directive context\n *\n * @example\n * ```typescript\n * const directiveResolvers = convertResolvers<MyContext, BridgeSchema>(\n * adapterResolvers,\n * (ctx) => ({\n * getState: () => getBridgeFact<MyState>(ctx.facts, \"__state\"),\n * setState: (update) => setBridgeFact(ctx.facts, \"__state\", update),\n * signal: ctx.signal,\n * }),\n * );\n * ```\n */\nexport function convertResolvers<TContext, S extends Schema>(\n resolvers: Record<string, AdapterResolver<TContext, Requirement>>,\n createContext: (ctx: ResolverContext<S>) => TContext,\n): Record<string, ResolverDef<S, Requirement>> {\n const result: Record<string, ResolverDef<S, Requirement>> = {};\n\n for (const [id, resolver] of Object.entries(resolvers)) {\n result[id] = {\n requirement: resolver.requirement,\n key: resolver.key,\n resolve: async (req, ctx) => {\n const adapterCtx = createContext(ctx);\n await resolver.resolve(req, {\n context: adapterCtx,\n signal: ctx.signal,\n });\n },\n };\n }\n\n return result;\n}\n\n// ============================================================================\n// Plugin Factory\n// ============================================================================\n\n/**\n * Callback definitions for adapter plugins.\n */\nexport interface AdapterCallbacks {\n onRequirementCreated?: (req: Requirement) => void;\n onRequirementResolved?: (req: Requirement) => void;\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a callback plugin for adapter events.\n * Wraps adapter callbacks in a Directive plugin.\n *\n * @param name - Plugin name (for debugging)\n * @param callbacks - Callback functions to invoke\n *\n * @example\n * ```typescript\n * const callbackPlugin = createCallbackPlugin(\"adapter-callbacks\", {\n * onRequirementCreated: (req) => console.log(\"Created:\", req),\n * onRequirementResolved: (req) => console.log(\"Resolved:\", req),\n * });\n * ```\n */\n// biome-ignore lint/suspicious/noExplicitAny: Plugins work with any schema type\nexport function createCallbackPlugin(\n name: string,\n callbacks: AdapterCallbacks,\n): Plugin<any> {\n return {\n name,\n onRequirementCreated: callbacks.onRequirementCreated\n ? (req) => callbacks.onRequirementCreated!(req.requirement)\n : undefined,\n onRequirementMet: callbacks.onRequirementResolved\n ? (req) => callbacks.onRequirementResolved!(req.requirement)\n : undefined,\n onError: callbacks.onError,\n };\n}\n\n// ============================================================================\n// Module Config Helpers\n// ============================================================================\n\n/**\n * Cast constraints to the correct type for createModule.\n * Use this when TypeScript can't infer the constraint types correctly.\n */\nexport function asConstraints<S extends Schema>(\n constraints: Record<string, ConstraintDef<S, Requirement>>,\n): Record<string, ConstraintDef<S, Requirement>> {\n return constraints;\n}\n\n/**\n * Cast resolvers to the correct type for createModule.\n * Use this when TypeScript can't infer the resolver types correctly.\n */\nexport function asResolvers<S extends Schema>(\n resolvers: Record<string, ResolverDef<S, Requirement>>,\n): Record<string, ResolverDef<S, Requirement>> {\n return resolvers;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Create a type guard for a specific requirement type.\n * Simplifies the common pattern of checking req.type.\n *\n * @example\n * ```typescript\n * const isResetReq = requirementGuard<ResetReq>(\"RESET\");\n * // Use in resolver:\n * { requirement: isResetReq, resolve: ... }\n * ```\n */\nexport function requirementGuard<R extends Requirement>(\n type: R[\"type\"],\n): (req: Requirement) => req is R {\n return (req): req is R => req.type === type;\n}\n\n/**\n * Create a type guard that matches multiple requirement types.\n *\n * @example\n * ```typescript\n * const isDataReq = requirementGuardMultiple<FetchReq | RefreshReq>([\"FETCH\", \"REFRESH\"]);\n * ```\n */\nexport function requirementGuardMultiple<R extends Requirement>(\n types: Array<R[\"type\"]>,\n): (req: Requirement) => req is R {\n const typeSet = new Set(types);\n return (req): req is R => typeSet.has(req.type);\n}\n","/**\n * Dependency tracking context for auto-tracking derivations\n *\n * Uses a stack-based approach to handle nested derivation computations.\n * When a derivation accesses a fact, the tracking context records it.\n */\n\n/** Stack of active dependency sets (bare Sets for zero-allocation hot path) */\nconst depStack: Set<string>[] = [];\n\n/**\n * Get the current dependency set, or null if not tracking.\n *\n * @returns The active dependency Set, or `null` if no tracking is active.\n *\n * @internal\n */\nexport function getCurrentDeps(): Set<string> | null {\n const len = depStack.length;\n return len === 0 ? null : depStack[len - 1]!;\n}\n\n/**\n * Check if dependency tracking is currently active.\n *\n * @returns `true` if inside a {@link withTracking} call, `false` otherwise.\n *\n * @internal\n */\nexport function isTracking(): boolean {\n return depStack.length > 0;\n}\n\n/**\n * Run a function with dependency tracking.\n *\n * @remarks\n * Pushes a fresh Set onto the stack, executes `fn`, then pops it.\n * Any fact reads inside `fn` are recorded as dependencies.\n * Nesting is supported — inner calls get their own independent Set.\n *\n * @param fn - The function to execute under tracking.\n * @returns An object with the computed `value` and a `deps` Set of accessed\n * fact keys.\n *\n * @internal\n */\nexport function withTracking<T>(fn: () => T): { value: T; deps: Set<string> } {\n const deps = new Set<string>();\n depStack.push(deps);\n\n try {\n const value = fn();\n return { value, deps };\n } finally {\n depStack.pop();\n }\n}\n\n/**\n * Run a function without tracking.\n *\n * @remarks\n * Temporarily clears the tracking stack so that fact reads inside `fn` do\n * not register as dependencies. The stack is restored after `fn` returns\n * (even on error). Useful for side-effect reads that should not trigger\n * derivation invalidation.\n *\n * @param fn - The function to execute without tracking.\n * @returns The return value of `fn`.\n *\n * @internal\n */\nexport function withoutTracking<T>(fn: () => T): T {\n const saved = depStack.splice(0, depStack.length);\n\n try {\n return fn();\n } finally {\n for (const ctx of saved) {\n depStack.push(ctx);\n }\n }\n}\n\n/**\n * Track a specific key in the current context.\n *\n * @remarks\n * No-op if no tracking context is active.\n *\n * @param key - The fact key to record as a dependency.\n *\n * @internal\n */\nexport function trackAccess(key: string): void {\n const len = depStack.length;\n if (len === 0) {\n return;\n }\n depStack[len - 1]!.add(key);\n}\n\n/**\n * Prototype pollution guard — shared across all proxy handlers.\n *\n * @remarks\n * Contains `__proto__`, `constructor`, and `prototype`. Every proxy `get`\n * and `has` trap checks this set and returns `undefined` / `false` for\n * matching keys, preventing prototype pollution via proxy-based objects.\n *\n * @internal\n */\nexport const BLOCKED_PROPS: ReadonlySet<string> = Object.freeze(\n new Set([\"__proto__\", \"constructor\", \"prototype\"]),\n);\n\n// ============================================================================\n// Non-JSON value-type detection (MIGRATION_FEEDBACK item 20)\n// ============================================================================\n\n/**\n * Detect whether `value` is a non-JSON-roundtrippable type whose mutations\n * the facts proxy cannot track for reactivity.\n *\n * Returns the kind label (`\"Date\"`, `\"Set\"`, `\"Map\"`, `\"File\"`, or\n * `\"ClassInstance\"`) when one is detected, or `null` for plain objects,\n * arrays, primitives, and `null`/`undefined`.\n *\n * The `File` check is SSR-safe: if the runtime has no `File` global the\n * branch is skipped without throwing.\n *\n * The `ClassInstance` check fires for any object whose prototype is not\n * `Object.prototype` and which is not an array — e.g. instances of user\n * classes whose mutations bypass reactivity.\n *\n * @internal\n */\nexport function detectNonJsonValueType(value: unknown): string | null {\n if (value === null || typeof value !== \"object\") {\n return null;\n }\n if (value instanceof Date) {\n return \"Date\";\n }\n if (value instanceof Set) {\n return \"Set\";\n }\n if (value instanceof Map) {\n return \"Map\";\n }\n if (typeof File !== \"undefined\" && value instanceof File) {\n return \"File\";\n }\n // Plain objects and arrays are JSON-friendly.\n if (Array.isArray(value)) {\n return null;\n }\n // Class instances: prototype is not Object.prototype.\n // Plain `{}` literals have prototype `Object.prototype`; objects created\n // via `Object.create(null)` have a `null` prototype which we treat as\n // \"plain\" (it's still JSON-roundtrippable).\n const proto = Object.getPrototypeOf(value);\n if (proto !== null && proto !== Object.prototype) {\n return \"ClassInstance\";\n }\n\n return null;\n}\n\n/**\n * Per-(path, valueType) dedupe cache — once a warning fires for a given\n * combo we never re-emit. Keeps the dev console quiet under loops that\n * assign the same Date 100 times in a row.\n *\n * @internal\n */\nconst nonJsonWarningCache = new Set<string>();\n\nconst nonJsonHints: Record<string, string> = {\n Date: \".getTime() for timestamps\",\n Set: \"[...set] for arrays\",\n Map: \"Object.fromEntries(map) for plain objects\",\n File: \"{ name, size, type, lastModified } for metadata\",\n ClassInstance: \"a plain-object snapshot\",\n};\n\n/**\n * Emit a one-time dev-mode warning when a non-JSON value is assigned to a\n * fact. Called from the proxy `set` traps in both `createFactsProxy`\n * (single-module / standalone facts) and `createModuleFactsProxy`\n * (system-namespaced facts). No-ops in production builds — the call sites\n * are gated on `isDevelopment` so this entire helper is tree-shakable.\n *\n * @param factPath - Display path for the warning (e.g. `auth.token` or\n * bare `token` for non-namespaced stores).\n * @param valueType - The label returned from {@link detectNonJsonValueType}.\n *\n * @internal\n */\nexport function warnNonJsonFactAssignment(\n factPath: string,\n valueType: string,\n): void {\n const cacheKey = `${factPath}|${valueType}`;\n if (nonJsonWarningCache.has(cacheKey)) {\n return;\n }\n nonJsonWarningCache.add(cacheKey);\n\n const hint = nonJsonHints[valueType] ?? \"a JSON-roundtrippable value\";\n console.warn(\n `[Directive] Fact \"${factPath}\" assigned a ${valueType} instance.\\n` +\n `Facts must be JSON-roundtrippable for reactivity to work correctly.\\n` +\n `${valueType} mutations are not tracked.\\n` +\n `Use ${hint} instead.\\n` +\n `See: https://directive.run/docs/facts#json-rule`,\n );\n}\n\n/**\n * Reset the warning dedupe cache. Test-only — exported via internals for\n * vitest spec setup. Not part of the public API.\n *\n * @internal\n */\nexport function _resetNonJsonWarningCache(): void {\n nonJsonWarningCache.clear();\n}\n"]}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

import { a8 as Schema, a as Facts, F as FactPredicate, aS as InferSchema, y as FactTemplate, D as DefinitionMeta, q as Requirement, b9 as RequirementOutput, a7 as RetryPolicy, B as BatchConfig, b0 as ResolverContext, a6 as PredicateOp, $ as PatchSpec, C as ClauseResult } from './plugins-BIzXaYbg.cjs';
/**
* Derivation Types - Type definitions for derivations
*/
/** Derivation definition function signature. */
interface DerivationDef<S extends Schema, T, D extends DerivationsDef<S>> {
(facts: Facts<S>, derived: DerivedValues<S, D>): T;
}
/**
* Derivation definition with metadata (object form).
* Use this when you want to attach debugging metadata to a derivation.
*
* @example
* ```typescript
* derive: {
* displayName: {
* compute: (facts) => `${facts.firstName} ${facts.lastName}`,
* meta: { label: "Display Name", description: "Full name for UI" },
* },
* },
* ```
*/
interface DerivationDefWithMeta<S extends Schema, T, D extends DerivationsDef<S>> {
/**
* The derivation body. Either:
* - a function `(facts, derived) => T` (original form), or
* - a {@link FactPredicate} data spec — boolean derivations only, or
* - a {@link FactTemplate} `{ $template: "..." }` — string derivations only.
*
* Data forms are normalized to a wrapper function at registration; the
* wrapper reads through the facts proxy so existing auto-tracking
* captures dependencies.
*/
compute: DerivationDef<S, T, D> | ([T] extends [boolean] ? FactPredicate<InferSchema<S>> : never) | ([T] extends [string] ? FactTemplate : never);
meta?: DefinitionMeta;
}
/** Map of derivation definitions (internal — always bare functions after unwrap). */
type DerivationsDef<S extends Schema> = Record<string, DerivationDef<S, unknown, DerivationsDef<S>>>;
/** Computed derived values. */
type DerivedValues<S extends Schema, D extends DerivationsDef<S>> = {
readonly [K in keyof D]: ReturnType<D[K]>;
};
/** Internal derivation state */
interface DerivationState<T> {
id: string;
compute: () => T;
cachedValue: T | undefined;
dependencies: Set<string>;
isStale: boolean;
isComputing: boolean;
/** Consecutive runs producing the same deps (auto-tracked only) */
stableRunCount: number;
/** Once true, skip withTracking() overhead until a tracked fact mutates */
depsStable: boolean;
}
/**
* Type Helpers - External typed constraint and resolver definitions
*
* These types enable defining constraints and resolvers with full type safety
* outside of module definitions, while maintaining proper type inference.
*/
/**
* External constraint definition with full typing.
* Use this when defining constraints outside of createModule().
*
* @typeParam S - The schema type
* @typeParam R - The requirement type (defaults to Requirement)
*
* @example
* ```typescript
* // Define a typed constraint factory
* const createMaxCountConstraint = <S extends Schema>(
* maxCount: number
* ): TypedConstraint<S, { type: "RESET_COUNT" }> => ({
* priority: 10,
* when: (facts) => (facts as { count: number }).count > maxCount,
* require: { type: "RESET_COUNT" },
* });
*
* // Use in module
* const module = createModule("counter", {
* schema: { count: t.number() },
* constraints: {
* maxCount: createMaxCountConstraint(100),
* },
* });
* ```
*/
interface TypedConstraint<S extends Schema, R extends Requirement = Requirement> {
/** Priority for ordering (higher runs first) */
priority?: number;
/** Mark this constraint as async (avoids runtime detection) */
async?: boolean;
/** Condition function (sync or async) */
when: (facts: Facts<S>) => boolean | Promise<boolean>;
/**
* Requirement(s) to produce when condition is met.
*/
require: RequirementOutput<R> | ((facts: Facts<S>) => RequirementOutput<R>);
/** Timeout for async constraints (ms) */
timeout?: number;
/**
* Constraint IDs whose resolvers must complete before this constraint is evaluated.
* - If dependency's `when()` returns false, this constraint proceeds (nothing to wait for)
* - If dependency's resolver fails, this constraint remains blocked until it succeeds
* - Cross-module: use the constraint ID as it appears in the merged system
*/
after?: string[];
}
/**
* External resolver definition with full typing.
* Use this when defining resolvers outside of createModule().
*
* @typeParam S - The schema type
* @typeParam R - The requirement type (defaults to Requirement)
*
* @example
* ```typescript
* // Define a typed resolver factory
* interface FetchUserReq extends Requirement {
* type: "FETCH_USER";
* userId: string;
* }
*
* const createFetchUserResolver = <S extends Schema>(
* fetchFn: (userId: string) => Promise<User>
* ): TypedResolver<S, FetchUserReq> => ({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* key: (req) => `fetch-user-${req.userId}`,
* retry: { attempts: 3, backoff: "exponential" },
* resolve: async (req, ctx) => {
* const user = await fetchFn(req.userId);
* (ctx.facts as { user: User }).user = user;
* },
* });
* ```
*/
interface TypedResolver<S extends Schema, R extends Requirement = Requirement> {
/**
* Requirement type to handle.
* - String: matches `req.type` directly (e.g., `requirement: "FETCH_USER"`)
* - Function: type guard predicate (e.g., `requirement: (req) => req.type === "FETCH_USER"`)
*/
requirement: R["type"] | ((req: Requirement) => req is R);
/** Custom key function for deduplication */
key?: (req: R) => string;
/** Retry policy */
retry?: RetryPolicy;
/** Timeout for resolver execution (ms) */
timeout?: number;
/** Batch configuration */
batch?: BatchConfig;
/** Resolve function for single requirement */
resolve?: (req: R, ctx: ResolverContext<S>) => Promise<void>;
/** Resolve function for batched requirements */
resolveBatch?: (reqs: R[], ctx: ResolverContext<S>) => Promise<void>;
}
/**
* Create a typed constraint factory for a specific schema.
* This enables creating reusable constraint definitions with proper typing.
*
* @example
* ```typescript
* const schema = { count: t.number(), threshold: t.number() };
* const factory = createConstraintFactory<typeof schema>();
*
* const maxCountConstraint = factory.create({
* when: (facts) => facts.count > facts.threshold,
* require: { type: "RESET" },
* });
* ```
*/
declare function createConstraintFactory<S extends Schema>(): {
/**
* Create a typed constraint
*/
create<R extends Requirement = Requirement>(constraint: TypedConstraint<S, R>): TypedConstraint<S, R>;
};
/**
* Create a typed resolver factory for a specific schema.
* This enables creating reusable resolver definitions with proper typing.
*
* @example
* ```typescript
* const schema = { user: t.object<User>() };
* const factory = createResolverFactory<typeof schema>();
*
* const fetchUserResolver = factory.create<FetchUserReq>({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* resolve: async (req, ctx) => {
* ctx.facts.user = await fetchUser(req.userId);
* },
* });
* ```
*/
declare function createResolverFactory<S extends Schema>(): {
/**
* Create a typed resolver
*/
create<R extends Requirement = Requirement>(resolver: TypedResolver<S, R>): TypedResolver<S, R>;
};
/**
* Type-safe constraint creator.
* Simpler alternative to createConstraintFactory when you don't need a factory pattern.
*
* @example
* ```typescript
* const constraint = typedConstraint<typeof schema, { type: "RESET" }>({
* when: (facts) => facts.count > 100,
* require: { type: "RESET" },
* });
* ```
*/
declare function typedConstraint<S extends Schema, R extends Requirement = Requirement>(constraint: TypedConstraint<S, R>): TypedConstraint<S, R>;
/**
* Type-safe resolver creator.
* Simpler alternative to createResolverFactory when you don't need a factory pattern.
*
* @example
* ```typescript
* const resolver = typedResolver<typeof schema, FetchUserReq>({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* resolve: async (req, ctx) => {
* ctx.facts.user = await fetchUser(req.userId);
* },
* });
* ```
*/
declare function typedResolver<S extends Schema, R extends Requirement = Requirement>(resolver: TypedResolver<S, R>): TypedResolver<S, R>;
/**
* Schema Introspection
*
* A runtime discriminant for every `t.*()` builder result, so downstream
* consumers (`predicateFromIntent`, `doctor`, future `predicateToZod`)
* can ask "what kind is this fact?" without grepping the source.
*
* The discriminant lives at `_kind?: SchemaKindNode` on `ExtendedSchemaType`.
* Base builders set it; chain mutators (`.nullable()`, `.brand()`, etc.)
* preserve / decorate it. When `_kind` is absent (legacy or third-party
* builder), the parser falls back to reading the freeform `_typeName`
* string. When even that fails: `{ kind: "unknown" }` — graceful close.
*
* This module has zero hot-path cost; it is only invoked when an
* introspecting caller asks for it.
*/
/**
* The closed set of kinds a Directive schema field can be.
*
* Drives operator availability via {@link getOperatorsForKind}: e.g.
* `"number"` gets the orderable operators (`$gte`, `$lte`); `"boolean"`
* does not.
*/
type SchemaKind = "number" | "string" | "boolean" | "bigint" | "date" | "array" | "object" | "record" | "tuple" | "enum" | "literal" | "union" | "branded" | "unknown";
/**
* A tree-shaped discriminator for a schema field. Composite kinds
* (array, object, tuple, etc.) carry their element / shape information
* so an LLM-prompt builder can show "cartTotal is a number" AND
* "items is an array of { sku: string, qty: number }".
*
* `nullable` / `hasDefault` flags appear on the inner node (NOT a
* wrapping kind) so operator-lookup on `t.number().nullable()` returns
* the number's operators unchanged — `$gte` works on the non-null arm.
*/
type SchemaKindNode = ({
kind: "number" | "string" | "boolean" | "bigint" | "date" | "unknown";
} | {
kind: "literal";
value: string | number | boolean | null;
primitive: "string" | "number" | "boolean" | "null";
} | {
kind: "enum";
values: readonly (string | number)[];
primitive: "string" | "number";
} | {
kind: "array";
element: SchemaKindNode;
} | {
kind: "tuple";
elements: readonly SchemaKindNode[];
} | {
kind: "object";
shape: Record<string, SchemaKindNode>;
} | {
kind: "record";
value: SchemaKindNode;
} | {
kind: "union";
members: readonly SchemaKindNode[];
} | {
kind: "branded";
inner: SchemaKindNode;
}) & {
/** True if the schema accepts `null` (from `.nullable()` / `.optional()`). */
nullable?: boolean;
/** True if the schema has a `.default()`. */
hasDefault?: boolean;
};
/**
* Return the {@link SchemaKindNode} for a schema field. Prefers the
* explicit `_kind` discriminant set by the builder; falls back to
* parsing the freeform `_typeName` string for legacy / third-party
* builders that don't set `_kind`.
*
* Hostile-getter safe: `_kind` / `_typeName` reads are wrapped — a builder
* that throws on property access returns `{ kind: "unknown" }` instead of
* propagating the throw to introspecting callers.
*
* In dev mode, a function input (`typeof schema === "function"`) emits a
* warning — common foot-gun where the caller forgot to invoke a builder
* factory (e.g. wrote `t.number` instead of `t.number()`).
*
* @example
* ```ts
* getKind(t.number()) // → { kind: "number" }
* getKind(t.string().nullable()) // → { kind: "string", nullable: true }
* getKind(t.array(t.number())) // → { kind: "array", element: { kind: "number" } }
* ```
*/
declare function getKind(schema: unknown): SchemaKindNode;
/**
* Walk the `facts` block of a module schema and emit a flat map from
* dotted path → kind node. Nested `t.object()` shapes flatten using
* `.` as the separator, matching the convention used by
* `OperatorObject<V>`'s nested-path support.
*
* Passing a top-level schema directly (without the `facts:` wrapper)
* also works — anything iterable as `Record<string, ExtendedSchemaType>`
* is acceptable.
*
* Hostile-getter safe: a builder whose `_kind` / `_typeName` throws is
* silently skipped (treated as `{ kind: "unknown" }` for that field)
* rather than aborting the whole walk.
*
* In dev mode, a top-level schema that yields an empty map (no
* introspectable keys) emits a warning — common foot-gun where the
* caller passed `myModule` instead of `myModule.schema`.
*/
declare function getSchemaFieldKinds(schema: unknown): Map<string, SchemaKindNode>;
/**
* Return the set of `PredicateOp` strings that are valid against a
* given {@link SchemaKindNode}.
*
* Mirrors the type-level matrix encoded in `OperatorObject<V>` in
* `types/predicate.ts` — drift between the two is enforced by the
* compile-time conformance test
* (`schema-introspection-conformance.test-d.ts`).
*
* - **Common to all kinds:** `$eq`, `$ne`, `$in`, `$nin`, `$exists`
* - **Orderable (`number`/`string`/`bigint`/`date`):** + `$gt`, `$gte`,
* `$lt`, `$lte`, `$between`
* - **String-specific:** + `$matches`, `$startsWith`, `$endsWith`, `$contains`
* - **Array:** + `$contains` (over the element type)
* - **Union:** *intersection* across members (the operand must be valid
* for every branch).
* - **Branded:** delegates to the inner kind.
* - **Literal / Enum:** operators of the primitive, with `$eq` / `$in`
* operand restricted at the LLM-prompt layer (not enforced here).
*
* `nullable` does not change operator availability — `$gte` on a
* nullable number is fine on the non-null arm; `$exists` handles null.
*/
declare function getOperatorsForKind(node: SchemaKindNode): readonly PredicateOp[];
/**
* Return all known predicate operators — convenience for prompt builders
* that need to show the LLM the full set.
*/
declare function listAllPredicateOperators(): readonly PredicateOp[];
/**
* Runtime for data-configuration predicates and templates.
*
* Pure module — imports only its own types. Reads facts through whatever
* object it is handed (the reactive `Facts` proxy in production, a plain
* snapshot in tests), so it never depends on the engine, store, or tracking.
*/
/** A readable scope — the `Facts` proxy and a plain snapshot both satisfy it. */
type Scope = Record<string, unknown>;
/**
* True when `v` is a data-form spec (predicate object/array) rather than a
* function. Excludes class instances (Date, RegExp, Map, Set, Promise, etc.)
* — only plain `{}` literals and arrays of plain clause shapes qualify.
*
* @example
* ```ts
* isPredicate({ phase: "red" }); // true
* isPredicate((f) => f.phase === "red"); // false
* isPredicate([{ fact: "phase", op: "$eq", value: "red" }]); // true
* ```
*/
declare function isPredicate(v: unknown): boolean;
/**
* True when `v` is a {@link FactTemplate} (`{ $template: string }`).
*
* @example
* ```ts
* isTemplate({ $template: "Hi ${name}" }); // true
* isTemplate({ $set: { name: "x" } }); // false
* ```
*/
declare function isTemplate(v: unknown): v is FactTemplate;
/**
* Throw when a predicate spec contains an operand that cannot survive a
* JSON round-trip — i.e. that would silently mis-evaluate if the spec was
* loaded from `JSON.parse`.
*
* Three failure classes are detected:
*
* - **Lost `RegExp` operand.** A `$matches` operand that is not a
* `RegExp` instance. `JSON.parse` reconstructs a serialized regex as
* `{}`, so a `$matches` clause with an empty-object operand is the
* signature of a regex that did not survive serialization. Reify it
* with `new RegExp(pattern, flags)` before installing the predicate.
* - **`bigint` operand.** `JSON.stringify` throws on `bigint`, so a
* `bigint` operand cannot have been produced by a JSON pipeline and
* cannot be persisted by one either.
* - **`Set` / `Map` operand.** Both serialize to `{}` and lose all
* members; a predicate carrying one is not JSON-safe.
*
* This is an opt-in helper — the engine does not call it automatically.
* Users who load predicates from JSON should call it after `JSON.parse`
* to fail loud rather than silently mis-evaluate. See the
* "Serialization" section of RFC-0004.
*
* @example
* ```ts
* validatePredicate({ phase: { $matches: {} } });
* // throws — empty object where a RegExp is required
*
* validatePredicate({ phase: "red", elapsed: { $gte: 30 } });
* // ok — JSON-clean operands
* ```
*/
declare function validatePredicate(spec: unknown, path?: string): void;
interface SchemaValidationError {
/** Dotted path to the failing clause (e.g. `cartTotal`, `auth.token.$gte`). */
readonly path: string;
/** The operator that failed (or the literal-equality marker `$eq`). */
readonly op: string;
/** The kind of the fact at this path, or `undefined` when the fact wasn't in the kind map. */
readonly kind?: SchemaKindNode;
/** The operators that ARE allowed for this fact's kind. */
readonly allowedOps?: readonly string[];
/** Human-readable failure reason (suitable for feeding back to an LLM). */
readonly reason: string;
}
interface SchemaValidationOptions {
/** Reject predicates with more than this many operator clauses (DoS guard). Default unbounded. */
readonly maxOperatorCount?: number;
/**
* Reject `$in` / `$nin` operands that contain more than this many elements
* (query-planner DoS guard). Default unbounded. A typical safe cap is 1000
* — beyond that, a downstream query compiler may degrade quadratically.
*/
readonly maxArrayOperandLength?: number;
}
/**
* Heuristic: flag a regex source string that has obvious nested quantifiers
* (e.g. `(.+)+`, `(.*)*`, `(\w+)+`, `(a|a)+`) — the classic ReDoS shapes.
* Not a full ReDoS prover; intentionally conservative so a string-rehydrated
* `$matches` operand can be rejected before it ever reaches `RegExp.test`.
*
* Callers MUST NOT treat a `false` result as "safe" — a determined adversary
* can craft patterns this heuristic misses. The right answer for untrusted
* regex is "don't accept untrusted regex"; this helper exists to catch the
* obvious foot-guns.
*
* @example
* ```ts
* dangerousRegex("(a+)+"); // → true
* dangerousRegex("(.*)*"); // → true
* dangerousRegex("(\\w+)+"); // → true
* dangerousRegex("^[a-z]+$"); // → false
* ```
*/
declare function dangerousRegex(source: string): boolean;
type SchemaValidationResult = {
ok: true;
operatorCount: number;
} | {
ok: false;
errors: readonly SchemaValidationError[];
operatorCount: number;
};
/**
* Cross-check an LLM-emitted (or otherwise externally-sourced) predicate
* against a schema's runtime kind map. Catches errors that
* {@link validatePredicate} cannot — operator-on-wrong-kind (`$gte` on a
* boolean fact), unknown fact paths, and (optionally) operator-count
* exhaustion DoS attempts.
*
* Pair with {@link validatePredicate} (structural / JSON safety) for full
* coverage. Use {@link getSchemaFieldKinds} to derive `kindMap` from a
* module schema.
*
* Designed for the LLM-emit retry loop: returns a list of errors with
* structured `{path, op, kind, allowedOps, reason}` rather than throwing,
* so the caller can feed the errors back to the model.
*
* @example
* ```ts
* const kindMap = getSchemaFieldKinds({ facts: { cartTotal: t.number(), active: t.boolean() } });
* const result = validatePredicateAgainstSchema(
* { cartTotal: { $gte: 50 }, active: { $gte: true } },
* kindMap,
* );
* // → { ok: false, errors: [{ path: "active", op: "$gte", reason: "..." }], operatorCount: 2 }
* ```
*/
declare function validatePredicateAgainstSchema(spec: unknown, kindMap: Map<string, SchemaKindNode>, opts?: SchemaValidationOptions): SchemaValidationResult;
/**
* Evaluate a {@link FactPredicate} against a fact scope. `prev` (a previous
* snapshot) is consulted only by the `$changed` operator.
*
* @example
* ```ts
* evaluatePredicate({ phase: "red", elapsed: { $gte: 30 } }, { phase: "red", elapsed: 45 });
* // → true
* evaluatePredicate({ $any: [{ phase: "red" }, { phase: "yellow" }] }, { phase: "green" });
* // → false
* ```
*/
declare function evaluatePredicate(spec: unknown, facts: Scope, prev?: Scope, depth?: number): boolean;
/**
* Evaluate a predicate and return a per-clause breakdown — the data feed for
* devtools, `system.explain()`, and `directive explain`.
*
* @example
* ```ts
* evaluatePredicateExplained(
* { phase: "red", elapsed: { $gte: 30 } },
* { phase: "red", elapsed: 20 },
* );
* // → [
* // { path: "phase", op: "$eq", expected: "red", actual: "red", pass: true },
* // { path: "elapsed", op: "$gte", expected: 30, actual: 20, pass: false },
* // ]
* ```
*/
declare function evaluatePredicateExplained(spec: unknown, facts: Scope, prev?: Scope, pathPrefix?: string): ClauseResult[];
/**
* Memoize a predicate as a reusable evaluation closure.
*
* The returned function accepts any `facts` scope (the reactive proxy in
* production, a plain object in tests) plus an optional `prev` snapshot for
* `$changed`. The closure is cached **by predicate identity** in a
* `WeakMap`, so passing the same `predicate` reference repeatedly is
* allocation-free; cleanup is automatic once the predicate is no longer
* reachable.
*
* Note: no actual compilation happens — the returned closure re-walks the
* spec on every call via `evaluatePredicate`. The name reflects what the
* function does (closure memoization keyed by predicate identity), not a
* bytecode/AST compile step.
*
* Intended for advanced users who want a stable function reference per
* predicate (custom devtools, batched analyses). Regular module code does
* not need to call this — the engine wraps data-form `when` / `on` specs
* automatically at registration.
*
* @example
* ```ts
* const predicate = { phase: "red", elapsed: { $gte: 30 } };
* const check = memoizePredicate(predicate);
* check({ phase: "red", elapsed: 45 }); // → true
* check({ phase: "red", elapsed: 5 }); // → false
* ```
*/
declare function memoizePredicate(predicate: object): (facts: Scope, prev?: Scope) => boolean;
/**
* Collect the fact keys a predicate references. Used for static analysis,
* devtools, and effect `on` dependency wiring. Nested predicates contribute
* dotted keys (`auth.token`).
*
* @example
* ```ts
* extractDeps({ phase: "red", elapsed: { $gte: 30 } });
* // → Set { "phase", "elapsed" }
* extractDeps({ self: { phase: "red" }, auth: { token: { $exists: true } } });
* // → Set { "self.phase", "auth.token" }
* ```
*/
declare function extractDeps(spec: unknown, prefix?: string): Set<string>;
/**
* Interpolate a {@link FactTemplate} against a scope. Single-pass character
* scanner: `${ident}` interpolates `scope[ident]`; `$${` emits a literal
* `${`; unknown keys dev-warn and yield an empty string.
*
* @example
* ```ts
* evaluateTemplate({ $template: "Hi ${name}!" }, { name: "Ada" });
* // → "Hi Ada!"
* evaluateTemplate({ $template: "$${price}" }, {});
* // → "${price}"
* ```
*/
declare function evaluateTemplate(spec: FactTemplate, scope: Scope): string;
/**
* Collect the placeholder keys referenced by a template. The static-analysis
* counterpart to {@link extractDeps} — useful for devtools, codegen, and
* "which facts does this template read" inspections. Only valid identifier
* placeholders are collected; malformed ones are ignored.
*
* @example
* ```ts
* extractTemplateKeys({ $template: "${firstName} ${lastName}" });
* // → Set { "firstName", "lastName" }
* extractTemplateKeys({ $template: "$${literal}" });
* // → Set {} (escaped — not a placeholder)
* ```
*/
declare function extractTemplateKeys(spec: FactTemplate): Set<string>;
/**
* Build a stable dedup key by selecting fields from a requirement payload.
* Order-as-declared; values are stable-stringified (keys sorted recursively)
* so two payloads with the same fields in different orders dedupe to the
* same key.
*
* @example
* ```ts
* evaluateKeySelector(["url", "method"], { url: "/a", method: "GET" });
* // → '"/a"|"GET"'
* evaluateKeySelector(["id"], { id: 42 });
* // → '42'
* ```
*/
declare function evaluateKeySelector(selector: readonly string[], source: Record<string, unknown>): string;
/**
* Apply a {@link PatchSpec} — assign facts from literals, payload copies
* (`$ref`), or interpolated strings (`$template`). Mutates through the passed
* `facts` proxy so change-tracking and downstream invalidation fire.
*
* @example
* ```ts
* const spec = {
* $set: {
* active: true,
* userId: { $ref: "id" },
* label: { $template: "user ${name}" },
* },
* };
* applyPatch(spec, facts, { id: "u_1", name: "Ada" });
* // facts.active = true; facts.userId = "u_1"; facts.label = "user Ada"
* ```
*/
declare function applyPatch(spec: PatchSpec<Record<string, unknown>, Record<string, unknown>>, facts: Record<string, unknown>, payload: Record<string, unknown>): void;
export { createConstraintFactory as A, createResolverFactory as B, dangerousRegex as C, type DerivationDefWithMeta as D, type SchemaKindNode as S, type TypedConstraint as T, type SchemaKind as a, type SchemaValidationError as b, type SchemaValidationOptions as c, type SchemaValidationResult as d, applyPatch as e, evaluateKeySelector as f, evaluatePredicate as g, evaluatePredicateExplained as h, evaluateTemplate as i, extractDeps as j, extractTemplateKeys as k, getKind as l, getOperatorsForKind as m, getSchemaFieldKinds as n, isPredicate as o, isTemplate as p, listAllPredicateOperators as q, memoizePredicate as r, typedResolver as s, typedConstraint as t, validatePredicateAgainstSchema as u, validatePredicate as v, type DerivationsDef as w, type DerivedValues as x, type DerivationState as y, type TypedResolver as z };
import { a8 as Schema, a as Facts, F as FactPredicate, aS as InferSchema, y as FactTemplate, D as DefinitionMeta, q as Requirement, b9 as RequirementOutput, a7 as RetryPolicy, B as BatchConfig, b0 as ResolverContext, a6 as PredicateOp, $ as PatchSpec, C as ClauseResult } from './plugins-BIzXaYbg.js';
/**
* Derivation Types - Type definitions for derivations
*/
/** Derivation definition function signature. */
interface DerivationDef<S extends Schema, T, D extends DerivationsDef<S>> {
(facts: Facts<S>, derived: DerivedValues<S, D>): T;
}
/**
* Derivation definition with metadata (object form).
* Use this when you want to attach debugging metadata to a derivation.
*
* @example
* ```typescript
* derive: {
* displayName: {
* compute: (facts) => `${facts.firstName} ${facts.lastName}`,
* meta: { label: "Display Name", description: "Full name for UI" },
* },
* },
* ```
*/
interface DerivationDefWithMeta<S extends Schema, T, D extends DerivationsDef<S>> {
/**
* The derivation body. Either:
* - a function `(facts, derived) => T` (original form), or
* - a {@link FactPredicate} data spec — boolean derivations only, or
* - a {@link FactTemplate} `{ $template: "..." }` — string derivations only.
*
* Data forms are normalized to a wrapper function at registration; the
* wrapper reads through the facts proxy so existing auto-tracking
* captures dependencies.
*/
compute: DerivationDef<S, T, D> | ([T] extends [boolean] ? FactPredicate<InferSchema<S>> : never) | ([T] extends [string] ? FactTemplate : never);
meta?: DefinitionMeta;
}
/** Map of derivation definitions (internal — always bare functions after unwrap). */
type DerivationsDef<S extends Schema> = Record<string, DerivationDef<S, unknown, DerivationsDef<S>>>;
/** Computed derived values. */
type DerivedValues<S extends Schema, D extends DerivationsDef<S>> = {
readonly [K in keyof D]: ReturnType<D[K]>;
};
/** Internal derivation state */
interface DerivationState<T> {
id: string;
compute: () => T;
cachedValue: T | undefined;
dependencies: Set<string>;
isStale: boolean;
isComputing: boolean;
/** Consecutive runs producing the same deps (auto-tracked only) */
stableRunCount: number;
/** Once true, skip withTracking() overhead until a tracked fact mutates */
depsStable: boolean;
}
/**
* Type Helpers - External typed constraint and resolver definitions
*
* These types enable defining constraints and resolvers with full type safety
* outside of module definitions, while maintaining proper type inference.
*/
/**
* External constraint definition with full typing.
* Use this when defining constraints outside of createModule().
*
* @typeParam S - The schema type
* @typeParam R - The requirement type (defaults to Requirement)
*
* @example
* ```typescript
* // Define a typed constraint factory
* const createMaxCountConstraint = <S extends Schema>(
* maxCount: number
* ): TypedConstraint<S, { type: "RESET_COUNT" }> => ({
* priority: 10,
* when: (facts) => (facts as { count: number }).count > maxCount,
* require: { type: "RESET_COUNT" },
* });
*
* // Use in module
* const module = createModule("counter", {
* schema: { count: t.number() },
* constraints: {
* maxCount: createMaxCountConstraint(100),
* },
* });
* ```
*/
interface TypedConstraint<S extends Schema, R extends Requirement = Requirement> {
/** Priority for ordering (higher runs first) */
priority?: number;
/** Mark this constraint as async (avoids runtime detection) */
async?: boolean;
/** Condition function (sync or async) */
when: (facts: Facts<S>) => boolean | Promise<boolean>;
/**
* Requirement(s) to produce when condition is met.
*/
require: RequirementOutput<R> | ((facts: Facts<S>) => RequirementOutput<R>);
/** Timeout for async constraints (ms) */
timeout?: number;
/**
* Constraint IDs whose resolvers must complete before this constraint is evaluated.
* - If dependency's `when()` returns false, this constraint proceeds (nothing to wait for)
* - If dependency's resolver fails, this constraint remains blocked until it succeeds
* - Cross-module: use the constraint ID as it appears in the merged system
*/
after?: string[];
}
/**
* External resolver definition with full typing.
* Use this when defining resolvers outside of createModule().
*
* @typeParam S - The schema type
* @typeParam R - The requirement type (defaults to Requirement)
*
* @example
* ```typescript
* // Define a typed resolver factory
* interface FetchUserReq extends Requirement {
* type: "FETCH_USER";
* userId: string;
* }
*
* const createFetchUserResolver = <S extends Schema>(
* fetchFn: (userId: string) => Promise<User>
* ): TypedResolver<S, FetchUserReq> => ({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* key: (req) => `fetch-user-${req.userId}`,
* retry: { attempts: 3, backoff: "exponential" },
* resolve: async (req, ctx) => {
* const user = await fetchFn(req.userId);
* (ctx.facts as { user: User }).user = user;
* },
* });
* ```
*/
interface TypedResolver<S extends Schema, R extends Requirement = Requirement> {
/**
* Requirement type to handle.
* - String: matches `req.type` directly (e.g., `requirement: "FETCH_USER"`)
* - Function: type guard predicate (e.g., `requirement: (req) => req.type === "FETCH_USER"`)
*/
requirement: R["type"] | ((req: Requirement) => req is R);
/** Custom key function for deduplication */
key?: (req: R) => string;
/** Retry policy */
retry?: RetryPolicy;
/** Timeout for resolver execution (ms) */
timeout?: number;
/** Batch configuration */
batch?: BatchConfig;
/** Resolve function for single requirement */
resolve?: (req: R, ctx: ResolverContext<S>) => Promise<void>;
/** Resolve function for batched requirements */
resolveBatch?: (reqs: R[], ctx: ResolverContext<S>) => Promise<void>;
}
/**
* Create a typed constraint factory for a specific schema.
* This enables creating reusable constraint definitions with proper typing.
*
* @example
* ```typescript
* const schema = { count: t.number(), threshold: t.number() };
* const factory = createConstraintFactory<typeof schema>();
*
* const maxCountConstraint = factory.create({
* when: (facts) => facts.count > facts.threshold,
* require: { type: "RESET" },
* });
* ```
*/
declare function createConstraintFactory<S extends Schema>(): {
/**
* Create a typed constraint
*/
create<R extends Requirement = Requirement>(constraint: TypedConstraint<S, R>): TypedConstraint<S, R>;
};
/**
* Create a typed resolver factory for a specific schema.
* This enables creating reusable resolver definitions with proper typing.
*
* @example
* ```typescript
* const schema = { user: t.object<User>() };
* const factory = createResolverFactory<typeof schema>();
*
* const fetchUserResolver = factory.create<FetchUserReq>({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* resolve: async (req, ctx) => {
* ctx.facts.user = await fetchUser(req.userId);
* },
* });
* ```
*/
declare function createResolverFactory<S extends Schema>(): {
/**
* Create a typed resolver
*/
create<R extends Requirement = Requirement>(resolver: TypedResolver<S, R>): TypedResolver<S, R>;
};
/**
* Type-safe constraint creator.
* Simpler alternative to createConstraintFactory when you don't need a factory pattern.
*
* @example
* ```typescript
* const constraint = typedConstraint<typeof schema, { type: "RESET" }>({
* when: (facts) => facts.count > 100,
* require: { type: "RESET" },
* });
* ```
*/
declare function typedConstraint<S extends Schema, R extends Requirement = Requirement>(constraint: TypedConstraint<S, R>): TypedConstraint<S, R>;
/**
* Type-safe resolver creator.
* Simpler alternative to createResolverFactory when you don't need a factory pattern.
*
* @example
* ```typescript
* const resolver = typedResolver<typeof schema, FetchUserReq>({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* resolve: async (req, ctx) => {
* ctx.facts.user = await fetchUser(req.userId);
* },
* });
* ```
*/
declare function typedResolver<S extends Schema, R extends Requirement = Requirement>(resolver: TypedResolver<S, R>): TypedResolver<S, R>;
/**
* Schema Introspection
*
* A runtime discriminant for every `t.*()` builder result, so downstream
* consumers (`predicateFromIntent`, `doctor`, future `predicateToZod`)
* can ask "what kind is this fact?" without grepping the source.
*
* The discriminant lives at `_kind?: SchemaKindNode` on `ExtendedSchemaType`.
* Base builders set it; chain mutators (`.nullable()`, `.brand()`, etc.)
* preserve / decorate it. When `_kind` is absent (legacy or third-party
* builder), the parser falls back to reading the freeform `_typeName`
* string. When even that fails: `{ kind: "unknown" }` — graceful close.
*
* This module has zero hot-path cost; it is only invoked when an
* introspecting caller asks for it.
*/
/**
* The closed set of kinds a Directive schema field can be.
*
* Drives operator availability via {@link getOperatorsForKind}: e.g.
* `"number"` gets the orderable operators (`$gte`, `$lte`); `"boolean"`
* does not.
*/
type SchemaKind = "number" | "string" | "boolean" | "bigint" | "date" | "array" | "object" | "record" | "tuple" | "enum" | "literal" | "union" | "branded" | "unknown";
/**
* A tree-shaped discriminator for a schema field. Composite kinds
* (array, object, tuple, etc.) carry their element / shape information
* so an LLM-prompt builder can show "cartTotal is a number" AND
* "items is an array of { sku: string, qty: number }".
*
* `nullable` / `hasDefault` flags appear on the inner node (NOT a
* wrapping kind) so operator-lookup on `t.number().nullable()` returns
* the number's operators unchanged — `$gte` works on the non-null arm.
*/
type SchemaKindNode = ({
kind: "number" | "string" | "boolean" | "bigint" | "date" | "unknown";
} | {
kind: "literal";
value: string | number | boolean | null;
primitive: "string" | "number" | "boolean" | "null";
} | {
kind: "enum";
values: readonly (string | number)[];
primitive: "string" | "number";
} | {
kind: "array";
element: SchemaKindNode;
} | {
kind: "tuple";
elements: readonly SchemaKindNode[];
} | {
kind: "object";
shape: Record<string, SchemaKindNode>;
} | {
kind: "record";
value: SchemaKindNode;
} | {
kind: "union";
members: readonly SchemaKindNode[];
} | {
kind: "branded";
inner: SchemaKindNode;
}) & {
/** True if the schema accepts `null` (from `.nullable()` / `.optional()`). */
nullable?: boolean;
/** True if the schema has a `.default()`. */
hasDefault?: boolean;
};
/**
* Return the {@link SchemaKindNode} for a schema field. Prefers the
* explicit `_kind` discriminant set by the builder; falls back to
* parsing the freeform `_typeName` string for legacy / third-party
* builders that don't set `_kind`.
*
* Hostile-getter safe: `_kind` / `_typeName` reads are wrapped — a builder
* that throws on property access returns `{ kind: "unknown" }` instead of
* propagating the throw to introspecting callers.
*
* In dev mode, a function input (`typeof schema === "function"`) emits a
* warning — common foot-gun where the caller forgot to invoke a builder
* factory (e.g. wrote `t.number` instead of `t.number()`).
*
* @example
* ```ts
* getKind(t.number()) // → { kind: "number" }
* getKind(t.string().nullable()) // → { kind: "string", nullable: true }
* getKind(t.array(t.number())) // → { kind: "array", element: { kind: "number" } }
* ```
*/
declare function getKind(schema: unknown): SchemaKindNode;
/**
* Walk the `facts` block of a module schema and emit a flat map from
* dotted path → kind node. Nested `t.object()` shapes flatten using
* `.` as the separator, matching the convention used by
* `OperatorObject<V>`'s nested-path support.
*
* Passing a top-level schema directly (without the `facts:` wrapper)
* also works — anything iterable as `Record<string, ExtendedSchemaType>`
* is acceptable.
*
* Hostile-getter safe: a builder whose `_kind` / `_typeName` throws is
* silently skipped (treated as `{ kind: "unknown" }` for that field)
* rather than aborting the whole walk.
*
* In dev mode, a top-level schema that yields an empty map (no
* introspectable keys) emits a warning — common foot-gun where the
* caller passed `myModule` instead of `myModule.schema`.
*/
declare function getSchemaFieldKinds(schema: unknown): Map<string, SchemaKindNode>;
/**
* Return the set of `PredicateOp` strings that are valid against a
* given {@link SchemaKindNode}.
*
* Mirrors the type-level matrix encoded in `OperatorObject<V>` in
* `types/predicate.ts` — drift between the two is enforced by the
* compile-time conformance test
* (`schema-introspection-conformance.test-d.ts`).
*
* - **Common to all kinds:** `$eq`, `$ne`, `$in`, `$nin`, `$exists`
* - **Orderable (`number`/`string`/`bigint`/`date`):** + `$gt`, `$gte`,
* `$lt`, `$lte`, `$between`
* - **String-specific:** + `$matches`, `$startsWith`, `$endsWith`, `$contains`
* - **Array:** + `$contains` (over the element type)
* - **Union:** *intersection* across members (the operand must be valid
* for every branch).
* - **Branded:** delegates to the inner kind.
* - **Literal / Enum:** operators of the primitive, with `$eq` / `$in`
* operand restricted at the LLM-prompt layer (not enforced here).
*
* `nullable` does not change operator availability — `$gte` on a
* nullable number is fine on the non-null arm; `$exists` handles null.
*/
declare function getOperatorsForKind(node: SchemaKindNode): readonly PredicateOp[];
/**
* Return all known predicate operators — convenience for prompt builders
* that need to show the LLM the full set.
*/
declare function listAllPredicateOperators(): readonly PredicateOp[];
/**
* Runtime for data-configuration predicates and templates.
*
* Pure module — imports only its own types. Reads facts through whatever
* object it is handed (the reactive `Facts` proxy in production, a plain
* snapshot in tests), so it never depends on the engine, store, or tracking.
*/
/** A readable scope — the `Facts` proxy and a plain snapshot both satisfy it. */
type Scope = Record<string, unknown>;
/**
* True when `v` is a data-form spec (predicate object/array) rather than a
* function. Excludes class instances (Date, RegExp, Map, Set, Promise, etc.)
* — only plain `{}` literals and arrays of plain clause shapes qualify.
*
* @example
* ```ts
* isPredicate({ phase: "red" }); // true
* isPredicate((f) => f.phase === "red"); // false
* isPredicate([{ fact: "phase", op: "$eq", value: "red" }]); // true
* ```
*/
declare function isPredicate(v: unknown): boolean;
/**
* True when `v` is a {@link FactTemplate} (`{ $template: string }`).
*
* @example
* ```ts
* isTemplate({ $template: "Hi ${name}" }); // true
* isTemplate({ $set: { name: "x" } }); // false
* ```
*/
declare function isTemplate(v: unknown): v is FactTemplate;
/**
* Throw when a predicate spec contains an operand that cannot survive a
* JSON round-trip — i.e. that would silently mis-evaluate if the spec was
* loaded from `JSON.parse`.
*
* Three failure classes are detected:
*
* - **Lost `RegExp` operand.** A `$matches` operand that is not a
* `RegExp` instance. `JSON.parse` reconstructs a serialized regex as
* `{}`, so a `$matches` clause with an empty-object operand is the
* signature of a regex that did not survive serialization. Reify it
* with `new RegExp(pattern, flags)` before installing the predicate.
* - **`bigint` operand.** `JSON.stringify` throws on `bigint`, so a
* `bigint` operand cannot have been produced by a JSON pipeline and
* cannot be persisted by one either.
* - **`Set` / `Map` operand.** Both serialize to `{}` and lose all
* members; a predicate carrying one is not JSON-safe.
*
* This is an opt-in helper — the engine does not call it automatically.
* Users who load predicates from JSON should call it after `JSON.parse`
* to fail loud rather than silently mis-evaluate. See the
* "Serialization" section of RFC-0004.
*
* @example
* ```ts
* validatePredicate({ phase: { $matches: {} } });
* // throws — empty object where a RegExp is required
*
* validatePredicate({ phase: "red", elapsed: { $gte: 30 } });
* // ok — JSON-clean operands
* ```
*/
declare function validatePredicate(spec: unknown, path?: string): void;
interface SchemaValidationError {
/** Dotted path to the failing clause (e.g. `cartTotal`, `auth.token.$gte`). */
readonly path: string;
/** The operator that failed (or the literal-equality marker `$eq`). */
readonly op: string;
/** The kind of the fact at this path, or `undefined` when the fact wasn't in the kind map. */
readonly kind?: SchemaKindNode;
/** The operators that ARE allowed for this fact's kind. */
readonly allowedOps?: readonly string[];
/** Human-readable failure reason (suitable for feeding back to an LLM). */
readonly reason: string;
}
interface SchemaValidationOptions {
/** Reject predicates with more than this many operator clauses (DoS guard). Default unbounded. */
readonly maxOperatorCount?: number;
/**
* Reject `$in` / `$nin` operands that contain more than this many elements
* (query-planner DoS guard). Default unbounded. A typical safe cap is 1000
* — beyond that, a downstream query compiler may degrade quadratically.
*/
readonly maxArrayOperandLength?: number;
}
/**
* Heuristic: flag a regex source string that has obvious nested quantifiers
* (e.g. `(.+)+`, `(.*)*`, `(\w+)+`, `(a|a)+`) — the classic ReDoS shapes.
* Not a full ReDoS prover; intentionally conservative so a string-rehydrated
* `$matches` operand can be rejected before it ever reaches `RegExp.test`.
*
* Callers MUST NOT treat a `false` result as "safe" — a determined adversary
* can craft patterns this heuristic misses. The right answer for untrusted
* regex is "don't accept untrusted regex"; this helper exists to catch the
* obvious foot-guns.
*
* @example
* ```ts
* dangerousRegex("(a+)+"); // → true
* dangerousRegex("(.*)*"); // → true
* dangerousRegex("(\\w+)+"); // → true
* dangerousRegex("^[a-z]+$"); // → false
* ```
*/
declare function dangerousRegex(source: string): boolean;
type SchemaValidationResult = {
ok: true;
operatorCount: number;
} | {
ok: false;
errors: readonly SchemaValidationError[];
operatorCount: number;
};
/**
* Cross-check an LLM-emitted (or otherwise externally-sourced) predicate
* against a schema's runtime kind map. Catches errors that
* {@link validatePredicate} cannot — operator-on-wrong-kind (`$gte` on a
* boolean fact), unknown fact paths, and (optionally) operator-count
* exhaustion DoS attempts.
*
* Pair with {@link validatePredicate} (structural / JSON safety) for full
* coverage. Use {@link getSchemaFieldKinds} to derive `kindMap` from a
* module schema.
*
* Designed for the LLM-emit retry loop: returns a list of errors with
* structured `{path, op, kind, allowedOps, reason}` rather than throwing,
* so the caller can feed the errors back to the model.
*
* @example
* ```ts
* const kindMap = getSchemaFieldKinds({ facts: { cartTotal: t.number(), active: t.boolean() } });
* const result = validatePredicateAgainstSchema(
* { cartTotal: { $gte: 50 }, active: { $gte: true } },
* kindMap,
* );
* // → { ok: false, errors: [{ path: "active", op: "$gte", reason: "..." }], operatorCount: 2 }
* ```
*/
declare function validatePredicateAgainstSchema(spec: unknown, kindMap: Map<string, SchemaKindNode>, opts?: SchemaValidationOptions): SchemaValidationResult;
/**
* Evaluate a {@link FactPredicate} against a fact scope. `prev` (a previous
* snapshot) is consulted only by the `$changed` operator.
*
* @example
* ```ts
* evaluatePredicate({ phase: "red", elapsed: { $gte: 30 } }, { phase: "red", elapsed: 45 });
* // → true
* evaluatePredicate({ $any: [{ phase: "red" }, { phase: "yellow" }] }, { phase: "green" });
* // → false
* ```
*/
declare function evaluatePredicate(spec: unknown, facts: Scope, prev?: Scope, depth?: number): boolean;
/**
* Evaluate a predicate and return a per-clause breakdown — the data feed for
* devtools, `system.explain()`, and `directive explain`.
*
* @example
* ```ts
* evaluatePredicateExplained(
* { phase: "red", elapsed: { $gte: 30 } },
* { phase: "red", elapsed: 20 },
* );
* // → [
* // { path: "phase", op: "$eq", expected: "red", actual: "red", pass: true },
* // { path: "elapsed", op: "$gte", expected: 30, actual: 20, pass: false },
* // ]
* ```
*/
declare function evaluatePredicateExplained(spec: unknown, facts: Scope, prev?: Scope, pathPrefix?: string): ClauseResult[];
/**
* Memoize a predicate as a reusable evaluation closure.
*
* The returned function accepts any `facts` scope (the reactive proxy in
* production, a plain object in tests) plus an optional `prev` snapshot for
* `$changed`. The closure is cached **by predicate identity** in a
* `WeakMap`, so passing the same `predicate` reference repeatedly is
* allocation-free; cleanup is automatic once the predicate is no longer
* reachable.
*
* Note: no actual compilation happens — the returned closure re-walks the
* spec on every call via `evaluatePredicate`. The name reflects what the
* function does (closure memoization keyed by predicate identity), not a
* bytecode/AST compile step.
*
* Intended for advanced users who want a stable function reference per
* predicate (custom devtools, batched analyses). Regular module code does
* not need to call this — the engine wraps data-form `when` / `on` specs
* automatically at registration.
*
* @example
* ```ts
* const predicate = { phase: "red", elapsed: { $gte: 30 } };
* const check = memoizePredicate(predicate);
* check({ phase: "red", elapsed: 45 }); // → true
* check({ phase: "red", elapsed: 5 }); // → false
* ```
*/
declare function memoizePredicate(predicate: object): (facts: Scope, prev?: Scope) => boolean;
/**
* Collect the fact keys a predicate references. Used for static analysis,
* devtools, and effect `on` dependency wiring. Nested predicates contribute
* dotted keys (`auth.token`).
*
* @example
* ```ts
* extractDeps({ phase: "red", elapsed: { $gte: 30 } });
* // → Set { "phase", "elapsed" }
* extractDeps({ self: { phase: "red" }, auth: { token: { $exists: true } } });
* // → Set { "self.phase", "auth.token" }
* ```
*/
declare function extractDeps(spec: unknown, prefix?: string): Set<string>;
/**
* Interpolate a {@link FactTemplate} against a scope. Single-pass character
* scanner: `${ident}` interpolates `scope[ident]`; `$${` emits a literal
* `${`; unknown keys dev-warn and yield an empty string.
*
* @example
* ```ts
* evaluateTemplate({ $template: "Hi ${name}!" }, { name: "Ada" });
* // → "Hi Ada!"
* evaluateTemplate({ $template: "$${price}" }, {});
* // → "${price}"
* ```
*/
declare function evaluateTemplate(spec: FactTemplate, scope: Scope): string;
/**
* Collect the placeholder keys referenced by a template. The static-analysis
* counterpart to {@link extractDeps} — useful for devtools, codegen, and
* "which facts does this template read" inspections. Only valid identifier
* placeholders are collected; malformed ones are ignored.
*
* @example
* ```ts
* extractTemplateKeys({ $template: "${firstName} ${lastName}" });
* // → Set { "firstName", "lastName" }
* extractTemplateKeys({ $template: "$${literal}" });
* // → Set {} (escaped — not a placeholder)
* ```
*/
declare function extractTemplateKeys(spec: FactTemplate): Set<string>;
/**
* Build a stable dedup key by selecting fields from a requirement payload.
* Order-as-declared; values are stable-stringified (keys sorted recursively)
* so two payloads with the same fields in different orders dedupe to the
* same key.
*
* @example
* ```ts
* evaluateKeySelector(["url", "method"], { url: "/a", method: "GET" });
* // → '"/a"|"GET"'
* evaluateKeySelector(["id"], { id: 42 });
* // → '42'
* ```
*/
declare function evaluateKeySelector(selector: readonly string[], source: Record<string, unknown>): string;
/**
* Apply a {@link PatchSpec} — assign facts from literals, payload copies
* (`$ref`), or interpolated strings (`$template`). Mutates through the passed
* `facts` proxy so change-tracking and downstream invalidation fire.
*
* @example
* ```ts
* const spec = {
* $set: {
* active: true,
* userId: { $ref: "id" },
* label: { $template: "user ${name}" },
* },
* };
* applyPatch(spec, facts, { id: "u_1", name: "Ada" });
* // facts.active = true; facts.userId = "u_1"; facts.label = "user Ada"
* ```
*/
declare function applyPatch(spec: PatchSpec<Record<string, unknown>, Record<string, unknown>>, facts: Record<string, unknown>, payload: Record<string, unknown>): void;
export { createConstraintFactory as A, createResolverFactory as B, dangerousRegex as C, type DerivationDefWithMeta as D, type SchemaKindNode as S, type TypedConstraint as T, type SchemaKind as a, type SchemaValidationError as b, type SchemaValidationOptions as c, type SchemaValidationResult as d, applyPatch as e, evaluateKeySelector as f, evaluatePredicate as g, evaluatePredicateExplained as h, evaluateTemplate as i, extractDeps as j, extractTemplateKeys as k, getKind as l, getOperatorsForKind as m, getSchemaFieldKinds as n, isPredicate as o, isTemplate as p, listAllPredicateOperators as q, memoizePredicate as r, typedResolver as s, typedConstraint as t, validatePredicateAgainstSchema as u, validatePredicate as v, type DerivationsDef as w, type DerivedValues as x, type DerivationState as y, type TypedResolver as z };
export{a as createSystem}from'./chunk-644QZVTT.js';import'./chunk-R2GHSCTR.js';import'./chunk-2FF6QGOA.js';import'./chunk-I722BZA5.js';import'./chunk-PXRV64PA.js';//# sourceMappingURL=system-A6VYKLVF.js.map
//# sourceMappingURL=system-A6VYKLVF.js.map
{"version":3,"sources":[],"names":[],"mappings":"","file":"system-A6VYKLVF.js"}
'use strict';var chunkNPX5EKPP_cjs=require('./chunk-NPX5EKPP.cjs');require('./chunk-ENZEHIL7.cjs'),require('./chunk-T4TRJEJN.cjs'),require('./chunk-X7G7UBXU.cjs'),require('./chunk-4MNQDXH7.cjs');Object.defineProperty(exports,"createSystem",{enumerable:true,get:function(){return chunkNPX5EKPP_cjs.a}});//# sourceMappingURL=system-CDJMD5O5.cjs.map
//# sourceMappingURL=system-CDJMD5O5.cjs.map
{"version":3,"sources":[],"names":[],"mappings":"","file":"system-CDJMD5O5.cjs"}
/**
* Create a stable JSON string with sorted keys.
* Handles circular references and deeply nested objects safely.
*
* @param value - The value to stringify
* @param maxDepth - Maximum nesting depth (default: 50)
* @returns A stable JSON string
*/
declare function stableStringify(value: unknown, maxDepth?: number): string;
/**
* Shallow equality comparison for objects.
* Used by React hooks to avoid unnecessary re-renders.
*
* @param a - First object
* @param b - Second object
* @returns True if objects are shallowly equal
*/
declare function shallowEqual<T extends Record<string, unknown>>(a: T, b: T): boolean;
/**
* Generate a simple hash string from an object.
* Uses djb2 algorithm on the stable stringified value.
*
* **Limitations:**
* - 32-bit hash output means collision probability increases with data set size
* (birthday paradox: ~50% collision chance at ~77,000 distinct values)
* - Suitable for: cache invalidation, change detection, deduplication of small sets
* - NOT suitable for: cryptographic use, security-sensitive operations, large-scale deduplication
*
* For security-sensitive use cases requiring stronger collision resistance,
* consider using a cryptographic hash like SHA-256.
*
* @param value - The value to hash
* @returns A hex hash string (8 characters, 32 bits)
*/
declare function hashObject(value: unknown): string;
/**
* Distributable snapshot type for type-safe helper functions.
*/
interface DistributableSnapshotLike<T = Record<string, unknown>> {
data: T;
createdAt: number;
expiresAt?: number;
version?: string;
metadata?: Record<string, unknown>;
}
/**
* Check if a distributable snapshot has expired.
* Returns false if the snapshot has no expiresAt field.
*
* @example
* ```typescript
* const snapshot = system.getDistributableSnapshot({ ttlSeconds: 3600 });
* // ... later ...
* if (isSnapshotExpired(snapshot)) {
* // Refresh the snapshot
* }
* ```
*
* @param snapshot - The snapshot to check
* @param now - Optional current timestamp (defaults to Date.now())
* @returns True if the snapshot has expired, false otherwise
*/
declare function isSnapshotExpired<T>(snapshot: DistributableSnapshotLike<T>, now?: number): boolean;
/**
* Validate a distributable snapshot and return its data.
* Throws if the snapshot is malformed or has expired.
*
* @example
* ```typescript
* const cached = JSON.parse(await redis.get(`entitlements:${userId}`));
* try {
* const data = validateSnapshot(cached);
* // Use data.canUseFeature, etc.
* } catch (e) {
* // Snapshot invalid or expired, refresh it
* }
* ```
*
* @example Using custom timestamp for testing
* ```typescript
* const snapshot = { data: { test: true }, createdAt: 1000, expiresAt: 2000 };
* validateSnapshot(snapshot, 1500); // Returns { test: true }
* validateSnapshot(snapshot, 2500); // Throws: Snapshot expired
* ```
*
* @param snapshot - The snapshot to validate
* @param now - Optional current timestamp (defaults to Date.now())
* @returns The snapshot data if valid
* @throws Error if the snapshot is malformed or has expired
*/
declare function validateSnapshot<T>(snapshot: DistributableSnapshotLike<T>, now?: number): T;
/**
* Diff result for a single changed value.
*/
interface SnapshotDiffEntry {
/** The key path that changed (e.g., "canUseApi" or "limits.apiCalls") */
path: string;
/** The value in the old snapshot */
oldValue: unknown;
/** The value in the new snapshot */
newValue: unknown;
/** Type of change: "added", "removed", or "changed" */
type: "added" | "removed" | "changed";
}
/**
* Result of diffing two snapshots.
*/
interface SnapshotDiff {
/** Whether the snapshots are identical */
identical: boolean;
/** List of changes between snapshots */
changes: SnapshotDiffEntry[];
/** Whether the version changed (if both have versions) */
versionChanged: boolean;
/** Old version (if available) */
oldVersion?: string;
/** New version (if available) */
newVersion?: string;
}
/**
* Compare two distributable snapshots and return the differences.
* Useful for debugging, audit logs, and webhook payloads.
*
* @example
* ```typescript
* const oldSnapshot = system.getDistributableSnapshot({ includeVersion: true });
* system.dispatch({ type: "upgradePlan", plan: "pro" });
* const newSnapshot = system.getDistributableSnapshot({ includeVersion: true });
*
* const diff = diffSnapshots(oldSnapshot, newSnapshot);
* if (!diff.identical) {
* console.log("Changes:", diff.changes);
* // [{ path: "canUseApi", oldValue: false, newValue: true, type: "changed" }]
* }
* ```
*
* @param oldSnapshot - The previous snapshot
* @param newSnapshot - The new snapshot
* @returns A diff result with all changes
*/
declare function diffSnapshots<T = Record<string, unknown>>(oldSnapshot: DistributableSnapshotLike<T>, newSnapshot: DistributableSnapshotLike<T>): SnapshotDiff;
/**
* A signed distributable snapshot.
* Contains the original snapshot plus a cryptographic signature.
*/
interface SignedSnapshot<T = Record<string, unknown>> extends DistributableSnapshotLike<T> {
/** HMAC-SHA256 signature in hex format */
signature: string;
/** Signing algorithm used */
algorithm: "hmac-sha256";
}
/**
* Check if a snapshot is signed.
*
* @param snapshot - The snapshot to check
* @returns True if the snapshot has a signature
*/
declare function isSignedSnapshot<T>(snapshot: DistributableSnapshotLike<T> | SignedSnapshot<T>): snapshot is SignedSnapshot<T>;
/**
* Sign a distributable snapshot using HMAC-SHA256.
* Creates a tamper-proof signature that can be verified later.
*
* **Security Notes:**
* - Use a cryptographically random secret of at least 32 bytes
* - Store the secret securely (environment variable, secrets manager)
* - Never expose the secret to clients
* - The signature covers all snapshot fields for integrity
*
* @example
* ```typescript
* const snapshot = system.getDistributableSnapshot({
* includeDerivations: ['canUseFeature', 'limits'],
* ttlSeconds: 3600,
* });
*
* // Sign the snapshot (server-side only)
* const signed = await signSnapshot(snapshot, process.env.SNAPSHOT_SECRET);
*
* // Store in JWT, Redis, or send to client
* const jwt = createJWT({ snapshot: signed });
*
* // Later, verify the signature
* const isValid = await verifySnapshotSignature(signed, process.env.SNAPSHOT_SECRET);
* if (!isValid) {
* throw new Error('Snapshot has been tampered with');
* }
* ```
*
* @param snapshot - The snapshot to sign
* @param secret - The HMAC secret (string or Uint8Array)
* @returns A signed snapshot with the signature attached
*/
declare function signSnapshot<T>(snapshot: DistributableSnapshotLike<T>, secret: string | Uint8Array): Promise<SignedSnapshot<T>>;
/**
* Verify the signature of a signed snapshot.
* Returns true if the signature is valid, false otherwise.
*
* **Important:** Always verify signatures before trusting snapshot data,
* especially if the snapshot was received from an untrusted source (client, cache).
*
* @example
* ```typescript
* // Receive signed snapshot from client or cache
* const snapshot = JSON.parse(cachedData);
*
* // Verify before using
* const isValid = await verifySnapshotSignature(snapshot, process.env.SNAPSHOT_SECRET);
* if (!isValid) {
* throw new Error('Invalid snapshot signature - possible tampering');
* }
*
* // Now safe to use snapshot.data
* if (snapshot.data.canUseFeature.api) {
* // Grant access
* }
* ```
*
* @param signedSnapshot - The signed snapshot to verify
* @param secret - The HMAC secret (must match the signing secret)
* @returns True if signature is valid, false otherwise
*/
declare function verifySnapshotSignature<T>(signedSnapshot: SignedSnapshot<T>, secret: string | Uint8Array): Promise<boolean>;
/**
* Safely stringify any value for display. Handles circular references,
* BigInt, throwing toJSON, and optional truncation.
*
* This is the canonical implementation – all packages should import this
* instead of maintaining local copies.
*/
declare function safeStringify(data: unknown, maxLen?: number): string;
export { type DistributableSnapshotLike as D, type SignedSnapshot as S, type SnapshotDiff as a, type SnapshotDiffEntry as b, isSnapshotExpired as c, diffSnapshots as d, signSnapshot as e, verifySnapshotSignature as f, safeStringify as g, hashObject as h, isSignedSnapshot as i, stableStringify as j, shallowEqual as s, validateSnapshot as v };
/**
* Create a stable JSON string with sorted keys.
* Handles circular references and deeply nested objects safely.
*
* @param value - The value to stringify
* @param maxDepth - Maximum nesting depth (default: 50)
* @returns A stable JSON string
*/
declare function stableStringify(value: unknown, maxDepth?: number): string;
/**
* Shallow equality comparison for objects.
* Used by React hooks to avoid unnecessary re-renders.
*
* @param a - First object
* @param b - Second object
* @returns True if objects are shallowly equal
*/
declare function shallowEqual<T extends Record<string, unknown>>(a: T, b: T): boolean;
/**
* Generate a simple hash string from an object.
* Uses djb2 algorithm on the stable stringified value.
*
* **Limitations:**
* - 32-bit hash output means collision probability increases with data set size
* (birthday paradox: ~50% collision chance at ~77,000 distinct values)
* - Suitable for: cache invalidation, change detection, deduplication of small sets
* - NOT suitable for: cryptographic use, security-sensitive operations, large-scale deduplication
*
* For security-sensitive use cases requiring stronger collision resistance,
* consider using a cryptographic hash like SHA-256.
*
* @param value - The value to hash
* @returns A hex hash string (8 characters, 32 bits)
*/
declare function hashObject(value: unknown): string;
/**
* Distributable snapshot type for type-safe helper functions.
*/
interface DistributableSnapshotLike<T = Record<string, unknown>> {
data: T;
createdAt: number;
expiresAt?: number;
version?: string;
metadata?: Record<string, unknown>;
}
/**
* Check if a distributable snapshot has expired.
* Returns false if the snapshot has no expiresAt field.
*
* @example
* ```typescript
* const snapshot = system.getDistributableSnapshot({ ttlSeconds: 3600 });
* // ... later ...
* if (isSnapshotExpired(snapshot)) {
* // Refresh the snapshot
* }
* ```
*
* @param snapshot - The snapshot to check
* @param now - Optional current timestamp (defaults to Date.now())
* @returns True if the snapshot has expired, false otherwise
*/
declare function isSnapshotExpired<T>(snapshot: DistributableSnapshotLike<T>, now?: number): boolean;
/**
* Validate a distributable snapshot and return its data.
* Throws if the snapshot is malformed or has expired.
*
* @example
* ```typescript
* const cached = JSON.parse(await redis.get(`entitlements:${userId}`));
* try {
* const data = validateSnapshot(cached);
* // Use data.canUseFeature, etc.
* } catch (e) {
* // Snapshot invalid or expired, refresh it
* }
* ```
*
* @example Using custom timestamp for testing
* ```typescript
* const snapshot = { data: { test: true }, createdAt: 1000, expiresAt: 2000 };
* validateSnapshot(snapshot, 1500); // Returns { test: true }
* validateSnapshot(snapshot, 2500); // Throws: Snapshot expired
* ```
*
* @param snapshot - The snapshot to validate
* @param now - Optional current timestamp (defaults to Date.now())
* @returns The snapshot data if valid
* @throws Error if the snapshot is malformed or has expired
*/
declare function validateSnapshot<T>(snapshot: DistributableSnapshotLike<T>, now?: number): T;
/**
* Diff result for a single changed value.
*/
interface SnapshotDiffEntry {
/** The key path that changed (e.g., "canUseApi" or "limits.apiCalls") */
path: string;
/** The value in the old snapshot */
oldValue: unknown;
/** The value in the new snapshot */
newValue: unknown;
/** Type of change: "added", "removed", or "changed" */
type: "added" | "removed" | "changed";
}
/**
* Result of diffing two snapshots.
*/
interface SnapshotDiff {
/** Whether the snapshots are identical */
identical: boolean;
/** List of changes between snapshots */
changes: SnapshotDiffEntry[];
/** Whether the version changed (if both have versions) */
versionChanged: boolean;
/** Old version (if available) */
oldVersion?: string;
/** New version (if available) */
newVersion?: string;
}
/**
* Compare two distributable snapshots and return the differences.
* Useful for debugging, audit logs, and webhook payloads.
*
* @example
* ```typescript
* const oldSnapshot = system.getDistributableSnapshot({ includeVersion: true });
* system.dispatch({ type: "upgradePlan", plan: "pro" });
* const newSnapshot = system.getDistributableSnapshot({ includeVersion: true });
*
* const diff = diffSnapshots(oldSnapshot, newSnapshot);
* if (!diff.identical) {
* console.log("Changes:", diff.changes);
* // [{ path: "canUseApi", oldValue: false, newValue: true, type: "changed" }]
* }
* ```
*
* @param oldSnapshot - The previous snapshot
* @param newSnapshot - The new snapshot
* @returns A diff result with all changes
*/
declare function diffSnapshots<T = Record<string, unknown>>(oldSnapshot: DistributableSnapshotLike<T>, newSnapshot: DistributableSnapshotLike<T>): SnapshotDiff;
/**
* A signed distributable snapshot.
* Contains the original snapshot plus a cryptographic signature.
*/
interface SignedSnapshot<T = Record<string, unknown>> extends DistributableSnapshotLike<T> {
/** HMAC-SHA256 signature in hex format */
signature: string;
/** Signing algorithm used */
algorithm: "hmac-sha256";
}
/**
* Check if a snapshot is signed.
*
* @param snapshot - The snapshot to check
* @returns True if the snapshot has a signature
*/
declare function isSignedSnapshot<T>(snapshot: DistributableSnapshotLike<T> | SignedSnapshot<T>): snapshot is SignedSnapshot<T>;
/**
* Sign a distributable snapshot using HMAC-SHA256.
* Creates a tamper-proof signature that can be verified later.
*
* **Security Notes:**
* - Use a cryptographically random secret of at least 32 bytes
* - Store the secret securely (environment variable, secrets manager)
* - Never expose the secret to clients
* - The signature covers all snapshot fields for integrity
*
* @example
* ```typescript
* const snapshot = system.getDistributableSnapshot({
* includeDerivations: ['canUseFeature', 'limits'],
* ttlSeconds: 3600,
* });
*
* // Sign the snapshot (server-side only)
* const signed = await signSnapshot(snapshot, process.env.SNAPSHOT_SECRET);
*
* // Store in JWT, Redis, or send to client
* const jwt = createJWT({ snapshot: signed });
*
* // Later, verify the signature
* const isValid = await verifySnapshotSignature(signed, process.env.SNAPSHOT_SECRET);
* if (!isValid) {
* throw new Error('Snapshot has been tampered with');
* }
* ```
*
* @param snapshot - The snapshot to sign
* @param secret - The HMAC secret (string or Uint8Array)
* @returns A signed snapshot with the signature attached
*/
declare function signSnapshot<T>(snapshot: DistributableSnapshotLike<T>, secret: string | Uint8Array): Promise<SignedSnapshot<T>>;
/**
* Verify the signature of a signed snapshot.
* Returns true if the signature is valid, false otherwise.
*
* **Important:** Always verify signatures before trusting snapshot data,
* especially if the snapshot was received from an untrusted source (client, cache).
*
* @example
* ```typescript
* // Receive signed snapshot from client or cache
* const snapshot = JSON.parse(cachedData);
*
* // Verify before using
* const isValid = await verifySnapshotSignature(snapshot, process.env.SNAPSHOT_SECRET);
* if (!isValid) {
* throw new Error('Invalid snapshot signature - possible tampering');
* }
*
* // Now safe to use snapshot.data
* if (snapshot.data.canUseFeature.api) {
* // Grant access
* }
* ```
*
* @param signedSnapshot - The signed snapshot to verify
* @param secret - The HMAC secret (must match the signing secret)
* @returns True if signature is valid, false otherwise
*/
declare function verifySnapshotSignature<T>(signedSnapshot: SignedSnapshot<T>, secret: string | Uint8Array): Promise<boolean>;
/**
* Safely stringify any value for display. Handles circular references,
* BigInt, throwing toJSON, and optional truncation.
*
* This is the canonical implementation – all packages should import this
* instead of maintaining local copies.
*/
declare function safeStringify(data: unknown, maxLen?: number): string;
export { type DistributableSnapshotLike as D, type SignedSnapshot as S, type SnapshotDiff as a, type SnapshotDiffEntry as b, isSnapshotExpired as c, diffSnapshots as d, signSnapshot as e, verifySnapshotSignature as f, safeStringify as g, hashObject as h, isSignedSnapshot as i, stableStringify as j, shallowEqual as s, validateSnapshot as v };
+1
-1

@@ -1,2 +0,2 @@

'use strict';var chunkN4KTCKOI_cjs=require('./chunk-N4KTCKOI.cjs'),chunkEOLY64E6_cjs=require('./chunk-EOLY64E6.cjs');function w(n){let e=n.inspect();return {isSettled:n.isSettled,unmet:e.unmet,inflight:e.inflight,isWorking:e.unmet.length>0||e.inflight.length>0,hasUnmet:e.unmet.length>0,hasInflight:e.inflight.length>0}}function S(n,e){let r=null,t=null,s=0;return {throttled:((...i)=>{let o=Date.now(),l=o-s;l>=e?(s=o,n(...i)):(t=i,r||(r=setTimeout(()=>{r=null,s=Date.now(),t&&(n(...t),t=null);},e-l)));}),cleanup:()=>{r&&(clearTimeout(r),r=null),t=null;}}}function x(n,e){if(chunkN4KTCKOI_cjs.a&&e==null)throw new Error(`[Directive] ${n}() requires a system instance as the first argument. Received ${e}.`)}function R(n,e){return Object.is(n,e)}function T(n){let e=n.history;if(!e)return null;let r=e.snapshots.map(t=>({id:t.id,timestamp:t.timestamp,trigger:t.trigger}));return {canGoBack:e.currentIndex>0,canGoForward:e.currentIndex<e.snapshots.length-1,currentIndex:e.currentIndex,totalSnapshots:e.snapshots.length,snapshots:r,getSnapshotFacts:t=>{let s=e.snapshots.find(a=>a.id===t);return s?s.facts:null},goTo:t=>e.goTo(t),goBack:t=>e.goBack(t),goForward:t=>e.goForward(t),replay:()=>e.replay(),exportSession:()=>e.export(),importSession:t=>e.import(t),beginChangeset:t=>e.beginChangeset(t),endChangeset:()=>e.endChangeset(),isPaused:e.isPaused,pause:()=>e.pause(),resume:()=>e.resume()}}function I(n,e){let r={};for(let t of e)r[t]=n.facts.$store.get(t);return r}function C(n,e,r){let t=[],s=new Proxy({},{get(i,o){if(typeof o=="string")return e.has(o)?(t.push(o),n.read(o)):n.facts.$store.get(o)},has(i,o){return typeof o!="string"?false:e.has(o)||n.facts.$store.has(o)},ownKeys(){let i=Object.keys(n.facts.$store.toObject()),o=new Set(i);for(let l of e)o.add(l);return [...o]},getOwnPropertyDescriptor(){return {configurable:true,enumerable:true,writable:true}}}),{value:a,deps:u}=chunkN4KTCKOI_cjs.i(()=>r(s));return {value:a,factKeys:Array.from(u),deriveKeys:t}}function P(n,e,r,t){let s=e.length!==n.length||e.some((u,i)=>u!==n[i]),a=t.length!==r.length||t.some((u,i)=>u!==r[i]);return s||a}function q(n,e){if(!n)return {...e};let r="data"in n&&typeof n.data=="object"&&n.data!==null?n.data:n;return {...e,...r}}Object.defineProperty(exports,"createCallbackPlugin",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.d}});Object.defineProperty(exports,"getBridgeFact",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.c}});Object.defineProperty(exports,"requirementGuard",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.e}});Object.defineProperty(exports,"requirementGuardMultiple",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.f}});Object.defineProperty(exports,"setBridgeFact",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.b}});Object.defineProperty(exports,"shallowEqual",{enumerable:true,get:function(){return chunkEOLY64E6_cjs.f}});exports.assertSystem=x;exports.buildHistoryState=T;exports.computeInspectState=w;exports.createThrottle=S;exports.defaultEquality=R;exports.depsChanged=P;exports.mergeHydrationFacts=q;exports.pickFacts=I;exports.runTrackedSelector=C;//# sourceMappingURL=adapter-utils.cjs.map
'use strict';var chunkX7G7UBXU_cjs=require('./chunk-X7G7UBXU.cjs'),chunk4MNQDXH7_cjs=require('./chunk-4MNQDXH7.cjs');function w(n){let e=n.inspect();return {isSettled:n.isSettled,unmet:e.unmet,inflight:e.inflight,isWorking:e.unmet.length>0||e.inflight.length>0,hasUnmet:e.unmet.length>0,hasInflight:e.inflight.length>0}}function S(n,e){let r=null,t=null,s=0;return {throttled:((...i)=>{let o=Date.now(),l=o-s;l>=e?(s=o,n(...i)):(t=i,r||(r=setTimeout(()=>{r=null,s=Date.now(),t&&(n(...t),t=null);},e-l)));}),cleanup:()=>{r&&(clearTimeout(r),r=null),t=null;}}}function x(n,e){if(chunk4MNQDXH7_cjs.a&&e==null)throw new Error(`[Directive] ${n}() requires a system instance as the first argument. Received ${e}.`)}function R(n,e){return Object.is(n,e)}function T(n){let e=n.history;if(!e)return null;let r=e.snapshots.map(t=>({id:t.id,timestamp:t.timestamp,trigger:t.trigger}));return {canGoBack:e.currentIndex>0,canGoForward:e.currentIndex<e.snapshots.length-1,currentIndex:e.currentIndex,totalSnapshots:e.snapshots.length,snapshots:r,getSnapshotFacts:t=>{let s=e.snapshots.find(a=>a.id===t);return s?s.facts:null},goTo:t=>e.goTo(t),goBack:t=>e.goBack(t),goForward:t=>e.goForward(t),replay:()=>e.replay(),exportSession:()=>e.export(),importSession:t=>e.import(t),beginChangeset:t=>e.beginChangeset(t),endChangeset:()=>e.endChangeset(),isPaused:e.isPaused,pause:()=>e.pause(),resume:()=>e.resume()}}function I(n,e){let r={};for(let t of e)r[t]=n.facts.$store.get(t);return r}function C(n,e,r){let t=[],s=new Proxy({},{get(i,o){if(typeof o=="string")return e.has(o)?(t.push(o),n.read(o)):n.facts.$store.get(o)},has(i,o){return typeof o!="string"?false:e.has(o)||n.facts.$store.has(o)},ownKeys(){let i=Object.keys(n.facts.$store.toObject()),o=new Set(i);for(let l of e)o.add(l);return [...o]},getOwnPropertyDescriptor(){return {configurable:true,enumerable:true,writable:true}}}),{value:a,deps:u}=chunkX7G7UBXU_cjs.h(()=>r(s));return {value:a,factKeys:Array.from(u),deriveKeys:t}}function P(n,e,r,t){let s=e.length!==n.length||e.some((u,i)=>u!==n[i]),a=t.length!==r.length||t.some((u,i)=>u!==r[i]);return s||a}function q(n,e){if(!n)return {...e};let r="data"in n&&typeof n.data=="object"&&n.data!==null?n.data:n;return {...e,...r}}Object.defineProperty(exports,"createCallbackPlugin",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.c}});Object.defineProperty(exports,"getBridgeFact",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.b}});Object.defineProperty(exports,"requirementGuard",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.d}});Object.defineProperty(exports,"requirementGuardMultiple",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.e}});Object.defineProperty(exports,"setBridgeFact",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.a}});Object.defineProperty(exports,"shallowEqual",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.g}});exports.assertSystem=x;exports.buildHistoryState=T;exports.computeInspectState=w;exports.createThrottle=S;exports.defaultEquality=R;exports.depsChanged=P;exports.mergeHydrationFacts=q;exports.pickFacts=I;exports.runTrackedSelector=C;//# sourceMappingURL=adapter-utils.cjs.map
//# sourceMappingURL=adapter-utils.cjs.map

@@ -1,3 +0,3 @@

import { t as Requirement, q as Plugin, c as Facts, a8 as Schema, I as HistoryAPI, ac as SystemInspection, K as HistoryState } from './plugins-Ykl_sAPE.cjs';
export { s as shallowEqual } from './utils-BnQajqPu.cjs';
import { q as Requirement, P as Plugin, a as Facts, a8 as Schema, H as HistoryAPI, ac as SystemInspection, I as HistoryState } from './plugins-BIzXaYbg.cjs';
export { s as shallowEqual } from './utils-Mg55IerF.cjs';

@@ -4,0 +4,0 @@ /**

@@ -1,3 +0,3 @@

import { t as Requirement, q as Plugin, c as Facts, a8 as Schema, I as HistoryAPI, ac as SystemInspection, K as HistoryState } from './plugins-Ykl_sAPE.js';
export { s as shallowEqual } from './utils-BnQajqPu.js';
import { q as Requirement, P as Plugin, a as Facts, a8 as Schema, H as HistoryAPI, ac as SystemInspection, I as HistoryState } from './plugins-BIzXaYbg.js';
export { s as shallowEqual } from './utils-Mg55IerF.js';

@@ -4,0 +4,0 @@ /**

@@ -1,2 +0,2 @@

import {a,i}from'./chunk-TZHC4E6S.js';export{d as createCallbackPlugin,c as getBridgeFact,e as requirementGuard,f as requirementGuardMultiple,b as setBridgeFact}from'./chunk-TZHC4E6S.js';export{f as shallowEqual}from'./chunk-T6IJUWYR.js';function w(n){let e=n.inspect();return {isSettled:n.isSettled,unmet:e.unmet,inflight:e.inflight,isWorking:e.unmet.length>0||e.inflight.length>0,hasUnmet:e.unmet.length>0,hasInflight:e.inflight.length>0}}function S(n,e){let r=null,t=null,s=0;return {throttled:((...i)=>{let o=Date.now(),l=o-s;l>=e?(s=o,n(...i)):(t=i,r||(r=setTimeout(()=>{r=null,s=Date.now(),t&&(n(...t),t=null);},e-l)));}),cleanup:()=>{r&&(clearTimeout(r),r=null),t=null;}}}function x(n,e){if(a&&e==null)throw new Error(`[Directive] ${n}() requires a system instance as the first argument. Received ${e}.`)}function R(n,e){return Object.is(n,e)}function T(n){let e=n.history;if(!e)return null;let r=e.snapshots.map(t=>({id:t.id,timestamp:t.timestamp,trigger:t.trigger}));return {canGoBack:e.currentIndex>0,canGoForward:e.currentIndex<e.snapshots.length-1,currentIndex:e.currentIndex,totalSnapshots:e.snapshots.length,snapshots:r,getSnapshotFacts:t=>{let s=e.snapshots.find(a=>a.id===t);return s?s.facts:null},goTo:t=>e.goTo(t),goBack:t=>e.goBack(t),goForward:t=>e.goForward(t),replay:()=>e.replay(),exportSession:()=>e.export(),importSession:t=>e.import(t),beginChangeset:t=>e.beginChangeset(t),endChangeset:()=>e.endChangeset(),isPaused:e.isPaused,pause:()=>e.pause(),resume:()=>e.resume()}}function I(n,e){let r={};for(let t of e)r[t]=n.facts.$store.get(t);return r}function C(n,e,r){let t=[],s=new Proxy({},{get(i,o){if(typeof o=="string")return e.has(o)?(t.push(o),n.read(o)):n.facts.$store.get(o)},has(i,o){return typeof o!="string"?false:e.has(o)||n.facts.$store.has(o)},ownKeys(){let i=Object.keys(n.facts.$store.toObject()),o=new Set(i);for(let l of e)o.add(l);return [...o]},getOwnPropertyDescriptor(){return {configurable:true,enumerable:true,writable:true}}}),{value:a,deps:u}=i(()=>r(s));return {value:a,factKeys:Array.from(u),deriveKeys:t}}function P(n,e,r,t){let s=e.length!==n.length||e.some((u,i)=>u!==n[i]),a=t.length!==r.length||t.some((u,i)=>u!==r[i]);return s||a}function q(n,e){if(!n)return {...e};let r="data"in n&&typeof n.data=="object"&&n.data!==null?n.data:n;return {...e,...r}}export{x as assertSystem,T as buildHistoryState,w as computeInspectState,S as createThrottle,R as defaultEquality,P as depsChanged,q as mergeHydrationFacts,I as pickFacts,C as runTrackedSelector};//# sourceMappingURL=adapter-utils.js.map
import {h}from'./chunk-I722BZA5.js';export{c as createCallbackPlugin,b as getBridgeFact,d as requirementGuard,e as requirementGuardMultiple,a as setBridgeFact}from'./chunk-I722BZA5.js';import {a}from'./chunk-PXRV64PA.js';export{g as shallowEqual}from'./chunk-PXRV64PA.js';function w(n){let e=n.inspect();return {isSettled:n.isSettled,unmet:e.unmet,inflight:e.inflight,isWorking:e.unmet.length>0||e.inflight.length>0,hasUnmet:e.unmet.length>0,hasInflight:e.inflight.length>0}}function S(n,e){let r=null,t=null,s=0;return {throttled:((...i)=>{let o=Date.now(),l=o-s;l>=e?(s=o,n(...i)):(t=i,r||(r=setTimeout(()=>{r=null,s=Date.now(),t&&(n(...t),t=null);},e-l)));}),cleanup:()=>{r&&(clearTimeout(r),r=null),t=null;}}}function x(n,e){if(a&&e==null)throw new Error(`[Directive] ${n}() requires a system instance as the first argument. Received ${e}.`)}function R(n,e){return Object.is(n,e)}function T(n){let e=n.history;if(!e)return null;let r=e.snapshots.map(t=>({id:t.id,timestamp:t.timestamp,trigger:t.trigger}));return {canGoBack:e.currentIndex>0,canGoForward:e.currentIndex<e.snapshots.length-1,currentIndex:e.currentIndex,totalSnapshots:e.snapshots.length,snapshots:r,getSnapshotFacts:t=>{let s=e.snapshots.find(a=>a.id===t);return s?s.facts:null},goTo:t=>e.goTo(t),goBack:t=>e.goBack(t),goForward:t=>e.goForward(t),replay:()=>e.replay(),exportSession:()=>e.export(),importSession:t=>e.import(t),beginChangeset:t=>e.beginChangeset(t),endChangeset:()=>e.endChangeset(),isPaused:e.isPaused,pause:()=>e.pause(),resume:()=>e.resume()}}function I(n,e){let r={};for(let t of e)r[t]=n.facts.$store.get(t);return r}function C(n,e,r){let t=[],s=new Proxy({},{get(i,o){if(typeof o=="string")return e.has(o)?(t.push(o),n.read(o)):n.facts.$store.get(o)},has(i,o){return typeof o!="string"?false:e.has(o)||n.facts.$store.has(o)},ownKeys(){let i=Object.keys(n.facts.$store.toObject()),o=new Set(i);for(let l of e)o.add(l);return [...o]},getOwnPropertyDescriptor(){return {configurable:true,enumerable:true,writable:true}}}),{value:a,deps:u}=h(()=>r(s));return {value:a,factKeys:Array.from(u),deriveKeys:t}}function P(n,e,r,t){let s=e.length!==n.length||e.some((u,i)=>u!==n[i]),a=t.length!==r.length||t.some((u,i)=>u!==r[i]);return s||a}function q(n,e){if(!n)return {...e};let r="data"in n&&typeof n.data=="object"&&n.data!==null?n.data:n;return {...e,...r}}export{x as assertSystem,T as buildHistoryState,w as computeInspectState,S as createThrottle,R as defaultEquality,P as depsChanged,q as mergeHydrationFacts,I as pickFacts,C as runTrackedSelector};//# sourceMappingURL=adapter-utils.js.map
//# sourceMappingURL=adapter-utils.js.map

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/adapter-utils.ts"],"names":["computeInspectState","system","inspection","createThrottle","callback","ms","timeoutId","lastArgs","lastCallTime","args","now","timeSinceLastCall","assertSystem","hookName","dev_true_default","defaultEquality","a","b","buildHistoryState","debug","snapshots","s","id","snap","snapshotId","steps","json","label","pickFacts","keys","result","key","runTrackedSelector","deriveKeySet","selector","accessedDeriveKeys","stateProxy","_","prop","factKeys","combined","k","value","deps","withTracking","depsChanged","prevFacts","newFacts","prevDerived","newDerived","factsChanged","derivedChanged","mergeHydrationFacts","snapshot","initialFacts","data"],"mappings":"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","file":"adapter-utils.js","sourcesContent":["/**\n * Shared Adapter Utilities\n *\n * Common types and helper functions used across all framework adapters.\n * @internal\n */\n\nimport isDevelopment from \"#is-development\";\nimport { withTracking } from \"./core/tracking.js\";\nimport type {\n HistoryAPI,\n HistoryState,\n SnapshotMeta,\n SystemInspection,\n} from \"./core/types.js\";\n\n// ============================================================================\n// SystemLike — structural type satisfied by both System and SingleModuleSystem\n// ============================================================================\n\n/**\n * Minimal structural type for shared adapter helpers.\n * Both `System<any>` and `SingleModuleSystem<any>` satisfy this interface,\n * eliminating the need for `as unknown as System<any>` casts in adapters.\n * @internal\n */\nexport interface SystemLike {\n readonly isSettled: boolean;\n readonly history: HistoryAPI | null;\n readonly facts: {\n $store: {\n get(key: string): unknown;\n has(key: string): boolean;\n toObject(): Record<string, unknown>;\n };\n };\n readonly derive?: Record<string, unknown>;\n read(key: string): unknown;\n inspect(): SystemInspection;\n}\n\n// ============================================================================\n// Requirements State\n// ============================================================================\n\n/**\n * Requirements state returned by useRequirements hooks.\n * Provides a focused view of just requirements without full inspection overhead.\n */\nexport interface RequirementsState {\n /** Array of unmet requirements waiting to be resolved */\n unmet: Array<{\n id: string;\n requirement: { type: string; [key: string]: unknown };\n fromConstraint: string;\n }>;\n /** Array of requirements currently being resolved */\n inflight: Array<{ id: string; resolverId: string; startedAt: number }>;\n /** Whether there are any unmet requirements */\n hasUnmet: boolean;\n /** Whether there are any inflight requirements */\n hasInflight: boolean;\n /** Whether the system is actively working (has unmet or inflight requirements) */\n isWorking: boolean;\n}\n\n// ============================================================================\n// Inspect State (shared across all adapters)\n// ============================================================================\n\n/**\n * Consolidated inspection state returned by useInspect hooks.\n * Identical shape across React, Vue, Svelte, Solid, and Lit adapters.\n */\nexport interface InspectState {\n /** Whether the system has settled (no pending operations) */\n isSettled: boolean;\n /** Array of unmet requirements */\n unmet: RequirementsState[\"unmet\"];\n /** Array of inflight requirements */\n inflight: RequirementsState[\"inflight\"];\n /** Whether the system is actively working */\n isWorking: boolean;\n /** Whether there are any unmet requirements */\n hasUnmet: boolean;\n /** Whether there are any inflight requirements */\n hasInflight: boolean;\n}\n\n/**\n * Information about a single constraint.\n */\nexport interface ConstraintInfo {\n id: string;\n active: boolean;\n priority: number;\n}\n\n/**\n * Compute InspectState from a system instance.\n * Centralizes the logic currently duplicated across adapters.\n * @internal\n */\nexport function computeInspectState(system: SystemLike): InspectState {\n const inspection = system.inspect();\n return {\n isSettled: system.isSettled,\n unmet: inspection.unmet,\n inflight: inspection.inflight,\n isWorking: inspection.unmet.length > 0 || inspection.inflight.length > 0,\n hasUnmet: inspection.unmet.length > 0,\n hasInflight: inspection.inflight.length > 0,\n };\n}\n\n// ============================================================================\n// Throttled Hook Options\n// ============================================================================\n\n/**\n * Options for throttled hooks.\n * Used by useInspectThrottled, useRequirementsThrottled, etc.\n */\nexport interface ThrottledHookOptions {\n /**\n * Minimum time between updates in milliseconds.\n * @default 100\n */\n throttleMs?: number;\n}\n\n// ============================================================================\n// Throttle Utility\n// ============================================================================\n\n/**\n * Create a throttled version of a callback function.\n * Uses trailing-edge throttling: the callback will be called at most once per interval,\n * with the latest arguments from the most recent call.\n *\n * @param callback - The function to throttle\n * @param ms - The minimum time between calls in milliseconds\n * @returns A throttled version of the callback and a cleanup function\n * @internal\n */\nexport function createThrottle<T extends (...args: unknown[]) => void>(\n callback: T,\n ms: number,\n): { throttled: T; cleanup: () => void } {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let lastArgs: Parameters<T> | null = null;\n let lastCallTime = 0;\n\n const throttled = ((...args: Parameters<T>) => {\n const now = Date.now();\n const timeSinceLastCall = now - lastCallTime;\n\n if (timeSinceLastCall >= ms) {\n // Enough time has passed, call immediately\n lastCallTime = now;\n callback(...args);\n } else {\n // Schedule for later, keeping latest args\n lastArgs = args;\n if (!timeoutId) {\n timeoutId = setTimeout(() => {\n timeoutId = null;\n lastCallTime = Date.now();\n if (lastArgs) {\n callback(...lastArgs);\n lastArgs = null;\n }\n }, ms - timeSinceLastCall);\n }\n }\n }) as T;\n\n const cleanup = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n lastArgs = null;\n };\n\n return { throttled, cleanup };\n}\n\n// ============================================================================\n// Shared Adapter Helpers\n// ============================================================================\n\n/**\n * Dev-mode assertion that the system parameter is non-null.\n * Tree-shaken in production builds.\n * @internal\n */\nexport function assertSystem(hookName: string, system: unknown): void {\n if (isDevelopment && system == null) {\n throw new Error(\n `[Directive] ${hookName}() requires a system instance as the first argument. Received ${system}.`,\n );\n }\n}\n\n/** Default equality function using Object.is */\nexport function defaultEquality<T>(a: T, b: T): boolean {\n return Object.is(a, b);\n}\n\n/**\n * Build a HistoryState object from a system's history instance.\n * Returns null when history is disabled.\n * @internal\n */\nexport function buildHistoryState(system: SystemLike): HistoryState | null {\n const debug = system.history;\n if (!debug) return null;\n\n // Build lightweight metadata array (no facts data)\n const snapshots: SnapshotMeta[] = debug.snapshots.map((s) => ({\n id: s.id,\n timestamp: s.timestamp,\n trigger: s.trigger,\n }));\n\n return {\n // Navigation state\n canGoBack: debug.currentIndex > 0,\n canGoForward: debug.currentIndex < debug.snapshots.length - 1,\n currentIndex: debug.currentIndex,\n totalSnapshots: debug.snapshots.length,\n\n // Snapshot access\n snapshots,\n getSnapshotFacts: (id: number): Record<string, unknown> | null => {\n const snap = debug.snapshots.find((s) => s.id === id);\n return snap ? snap.facts : null;\n },\n\n // Navigation\n goTo: (snapshotId: number) => debug.goTo(snapshotId),\n goBack: (steps?: number) => debug.goBack(steps),\n goForward: (steps?: number) => debug.goForward(steps),\n replay: () => debug.replay(),\n\n // Session persistence\n exportSession: () => debug.export(),\n importSession: (json: string) => debug.import(json),\n\n // Changesets\n beginChangeset: (label: string) => debug.beginChangeset(label),\n endChangeset: () => debug.endChangeset(),\n\n // Recording control\n isPaused: debug.isPaused,\n pause: () => debug.pause(),\n resume: () => debug.resume(),\n };\n}\n\n/**\n * Pick specific fact values from a system's store.\n * @internal\n */\nexport function pickFacts(\n system: SystemLike,\n keys: string[],\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const key of keys) {\n result[key] = system.facts.$store.get(key);\n }\n return result;\n}\n\n// ============================================================================\n// Tracked Selector\n// ============================================================================\n\n/** Result of running a selector with tracking. @internal */\nexport interface TrackedSelectorResult<R> {\n value: R;\n factKeys: string[];\n deriveKeys: string[];\n}\n\n/**\n * Run a selector against a system with automatic dependency tracking.\n * Creates a Proxy that intercepts property access to distinguish between\n * fact reads (tracked via withTracking) and derivation reads (tracked manually).\n *\n * Used by useSelector in all framework adapters.\n * @internal\n */\nexport function runTrackedSelector<R>(\n system: SystemLike,\n deriveKeySet: Set<string>,\n selector: (state: Record<string, unknown>) => R,\n): TrackedSelectorResult<R> {\n const accessedDeriveKeys: string[] = [];\n\n const stateProxy = new Proxy(\n {},\n {\n get(_, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n if (deriveKeySet.has(prop)) {\n accessedDeriveKeys.push(prop);\n return system.read(prop);\n }\n return system.facts.$store.get(prop);\n },\n has(_, prop: string | symbol) {\n if (typeof prop !== \"string\") return false;\n return deriveKeySet.has(prop) || system.facts.$store.has(prop);\n },\n ownKeys() {\n const factKeys = Object.keys(system.facts.$store.toObject());\n const combined = new Set(factKeys);\n for (const k of deriveKeySet) combined.add(k);\n return [...combined];\n },\n getOwnPropertyDescriptor() {\n return { configurable: true, enumerable: true, writable: true };\n },\n },\n );\n\n const { value, deps } = withTracking(() =>\n selector(stateProxy as Record<string, unknown>),\n );\n return {\n value,\n factKeys: Array.from(deps) as string[],\n deriveKeys: accessedDeriveKeys,\n };\n}\n\n/**\n * Check if tracked dependency keys have changed.\n * @internal\n */\nexport function depsChanged(\n prevFacts: string[],\n newFacts: string[],\n prevDerived: string[],\n newDerived: string[],\n): boolean {\n const factsChanged =\n newFacts.length !== prevFacts.length ||\n newFacts.some((k, i) => k !== prevFacts[i]);\n const derivedChanged =\n newDerived.length !== prevDerived.length ||\n newDerived.some((k, i) => k !== prevDerived[i]);\n return factsChanged || derivedChanged;\n}\n\n// ============================================================================\n// Re-exports from core/types/adapter-utils and utils/utils\n// ============================================================================\n\nexport {\n setBridgeFact,\n getBridgeFact,\n createCallbackPlugin,\n requirementGuard,\n requirementGuardMultiple,\n} from \"./core/types/adapter-utils.js\";\n\nexport { shallowEqual } from \"./utils/utils.js\";\n\n/**\n * Merge a DistributableSnapshot's data into initialFacts for SSR hydration.\n * Used by all framework adapters' hydration hooks/controllers.\n *\n * Accepts both shapes:\n * - DistributableSnapshot (`{ data: Record<string, unknown> }`) — used by React's DirectiveHydrator\n * - Plain `Record<string, unknown>` — used by Lit/Vue/Svelte/Solid adapters\n */\nexport function mergeHydrationFacts(\n snapshot:\n | { data?: Record<string, unknown> }\n | Record<string, unknown>\n | undefined\n | null,\n initialFacts?: Record<string, unknown>,\n): Record<string, unknown> {\n if (!snapshot) {\n return { ...initialFacts };\n }\n\n // If snapshot has a .data property that is a non-null object, treat as DistributableSnapshot\n const data =\n \"data\" in snapshot &&\n typeof snapshot.data === \"object\" &&\n snapshot.data !== null\n ? (snapshot.data as Record<string, unknown>)\n : (snapshot as Record<string, unknown>);\n\n return { ...initialFacts, ...data };\n}\n"]}
{"version":3,"sources":["../src/adapter-utils.ts"],"names":["computeInspectState","system","inspection","createThrottle","callback","ms","timeoutId","lastArgs","lastCallTime","args","now","timeSinceLastCall","assertSystem","hookName","dev_true_default","defaultEquality","a","b","buildHistoryState","debug","snapshots","s","id","snap","snapshotId","steps","json","label","pickFacts","keys","result","key","runTrackedSelector","deriveKeySet","selector","accessedDeriveKeys","stateProxy","_","prop","factKeys","combined","k","value","deps","withTracking","depsChanged","prevFacts","newFacts","prevDerived","newDerived","factsChanged","derivedChanged","mergeHydrationFacts","snapshot","initialFacts","data"],"mappings":"gRAuGO,SAASA,CAAAA,CAAoBC,CAAAA,CAAkC,CACpE,IAAMC,CAAAA,CAAaD,CAAAA,CAAO,OAAA,EAAQ,CAClC,OAAO,CACL,SAAA,CAAWA,CAAAA,CAAO,SAAA,CAClB,KAAA,CAAOC,CAAAA,CAAW,KAAA,CAClB,QAAA,CAAUA,CAAAA,CAAW,QAAA,CACrB,SAAA,CAAWA,CAAAA,CAAW,KAAA,CAAM,MAAA,CAAS,CAAA,EAAKA,CAAAA,CAAW,QAAA,CAAS,MAAA,CAAS,CAAA,CACvE,QAAA,CAAUA,CAAAA,CAAW,KAAA,CAAM,MAAA,CAAS,CAAA,CACpC,WAAA,CAAaA,CAAAA,CAAW,QAAA,CAAS,MAAA,CAAS,CAC5C,CACF,CAgCO,SAASC,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACuC,CACvC,IAAIC,CAAAA,CAAkD,IAAA,CAClDC,CAAAA,CAAiC,IAAA,CACjCC,CAAAA,CAAe,CAAA,CAkCnB,OAAO,CAAE,SAAA,EAhCU,CAAA,GAAIC,CAAAA,GAAwB,CAC7C,IAAMC,CAAAA,CAAM,IAAA,CAAK,GAAA,EAAI,CACfC,CAAAA,CAAoBD,CAAAA,CAAMF,CAAAA,CAE5BG,CAAAA,EAAqBN,CAAAA,EAEvBG,CAAAA,CAAeE,CAAAA,CACfN,CAAAA,CAAS,GAAGK,CAAI,CAAA,GAGhBF,CAAAA,CAAWE,CAAAA,CACNH,CAAAA,GACHA,CAAAA,CAAY,UAAA,CAAW,IAAM,CAC3BA,CAAAA,CAAY,IAAA,CACZE,CAAAA,CAAe,IAAA,CAAK,GAAA,EAAI,CACpBD,CAAAA,GACFH,CAAAA,CAAS,GAAGG,CAAQ,CAAA,CACpBA,CAAAA,CAAW,IAAA,EAEf,CAAA,CAAGF,CAAAA,CAAKM,CAAiB,CAAA,CAAA,EAG/B,CAAA,CAAA,CAUoB,OAAA,CARJ,IAAM,CAChBL,CAAAA,GACF,YAAA,CAAaA,CAAS,CAAA,CACtBA,CAAAA,CAAY,IAAA,CAAA,CAEdC,CAAAA,CAAW,KACb,CAE4B,CAC9B,CAWO,SAASK,CAAAA,CAAaC,CAAAA,CAAkBZ,CAAAA,CAAuB,CACpE,GAAIa,CAAAA,EAAiBb,CAAAA,EAAU,IAAA,CAC7B,MAAM,IAAI,KAAA,CACR,CAAA,YAAA,EAAeY,CAAQ,CAAA,8DAAA,EAAiEZ,CAAM,CAAA,CAAA,CAChG,CAEJ,CAGO,SAASc,CAAAA,CAAmBC,CAAAA,CAAMC,CAAAA,CAAe,CACtD,OAAO,MAAA,CAAO,EAAA,CAAGD,CAAAA,CAAGC,CAAC,CACvB,CAOO,SAASC,CAAAA,CAAkBjB,CAAAA,CAAyC,CACzE,IAAMkB,CAAAA,CAAQlB,CAAAA,CAAO,OAAA,CACrB,GAAI,CAACkB,CAAAA,CAAO,OAAO,IAAA,CAGnB,IAAMC,CAAAA,CAA4BD,CAAAA,CAAM,SAAA,CAAU,GAAA,CAAKE,CAAAA,GAAO,CAC5D,EAAA,CAAIA,CAAAA,CAAE,EAAA,CACN,SAAA,CAAWA,CAAAA,CAAE,SAAA,CACb,OAAA,CAASA,CAAAA,CAAE,OACb,CAAA,CAAE,CAAA,CAEF,OAAO,CAEL,SAAA,CAAWF,CAAAA,CAAM,YAAA,CAAe,CAAA,CAChC,YAAA,CAAcA,CAAAA,CAAM,YAAA,CAAeA,CAAAA,CAAM,SAAA,CAAU,MAAA,CAAS,CAAA,CAC5D,YAAA,CAAcA,CAAAA,CAAM,YAAA,CACpB,cAAA,CAAgBA,CAAAA,CAAM,SAAA,CAAU,MAAA,CAGhC,SAAA,CAAAC,CAAAA,CACA,gBAAA,CAAmBE,CAAAA,EAA+C,CAChE,IAAMC,CAAAA,CAAOJ,CAAAA,CAAM,SAAA,CAAU,IAAA,CAAME,CAAAA,EAAMA,CAAAA,CAAE,EAAA,GAAOC,CAAE,CAAA,CACpD,OAAOC,CAAAA,CAAOA,CAAAA,CAAK,KAAA,CAAQ,IAC7B,CAAA,CAGA,IAAA,CAAOC,CAAAA,EAAuBL,CAAAA,CAAM,IAAA,CAAKK,CAAU,CAAA,CACnD,MAAA,CAASC,CAAAA,EAAmBN,CAAAA,CAAM,MAAA,CAAOM,CAAK,CAAA,CAC9C,SAAA,CAAYA,CAAAA,EAAmBN,CAAAA,CAAM,SAAA,CAAUM,CAAK,CAAA,CACpD,MAAA,CAAQ,IAAMN,CAAAA,CAAM,MAAA,EAAO,CAG3B,aAAA,CAAe,IAAMA,CAAAA,CAAM,MAAA,EAAO,CAClC,aAAA,CAAgBO,CAAAA,EAAiBP,CAAAA,CAAM,MAAA,CAAOO,CAAI,CAAA,CAGlD,cAAA,CAAiBC,CAAAA,EAAkBR,CAAAA,CAAM,cAAA,CAAeQ,CAAK,CAAA,CAC7D,YAAA,CAAc,IAAMR,CAAAA,CAAM,YAAA,EAAa,CAGvC,QAAA,CAAUA,CAAAA,CAAM,QAAA,CAChB,KAAA,CAAO,IAAMA,CAAAA,CAAM,KAAA,EAAM,CACzB,MAAA,CAAQ,IAAMA,CAAAA,CAAM,MAAA,EACtB,CACF,CAMO,SAASS,CAAAA,CACd3B,CAAAA,CACA4B,CAAAA,CACyB,CACzB,IAAMC,CAAAA,CAAkC,EAAC,CACzC,IAAA,IAAWC,CAAAA,IAAOF,CAAAA,CAChBC,CAAAA,CAAOC,CAAG,CAAA,CAAI9B,CAAAA,CAAO,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI8B,CAAG,CAAA,CAE3C,OAAOD,CACT,CAqBO,SAASE,CAAAA,CACd/B,CAAAA,CACAgC,CAAAA,CACAC,CAAAA,CAC0B,CAC1B,IAAMC,CAAAA,CAA+B,EAAC,CAEhCC,CAAAA,CAAa,IAAI,KAAA,CACrB,EAAC,CACD,CACE,GAAA,CAAIC,CAAAA,CAAGC,CAAAA,CAAuB,CAC5B,GAAI,OAAOA,CAAAA,EAAS,QAAA,CACpB,OAAIL,CAAAA,CAAa,GAAA,CAAIK,CAAI,CAAA,EACvBH,CAAAA,CAAmB,IAAA,CAAKG,CAAI,CAAA,CACrBrC,CAAAA,CAAO,IAAA,CAAKqC,CAAI,CAAA,EAElBrC,CAAAA,CAAO,KAAA,CAAM,MAAA,CAAO,GAAA,CAAIqC,CAAI,CACrC,CAAA,CACA,GAAA,CAAID,CAAAA,CAAGC,CAAAA,CAAuB,CAC5B,OAAI,OAAOA,CAAAA,EAAS,QAAA,CAAiB,KAAA,CAC9BL,CAAAA,CAAa,GAAA,CAAIK,CAAI,CAAA,EAAKrC,CAAAA,CAAO,KAAA,CAAM,MAAA,CAAO,GAAA,CAAIqC,CAAI,CAC/D,CAAA,CACA,OAAA,EAAU,CACR,IAAMC,CAAAA,CAAW,MAAA,CAAO,IAAA,CAAKtC,CAAAA,CAAO,KAAA,CAAM,MAAA,CAAO,QAAA,EAAU,CAAA,CACrDuC,CAAAA,CAAW,IAAI,GAAA,CAAID,CAAQ,CAAA,CACjC,IAAA,IAAWE,CAAAA,IAAKR,CAAAA,CAAcO,CAAAA,CAAS,GAAA,CAAIC,CAAC,CAAA,CAC5C,OAAO,CAAC,GAAGD,CAAQ,CACrB,CAAA,CACA,wBAAA,EAA2B,CACzB,OAAO,CAAE,YAAA,CAAc,IAAA,CAAM,UAAA,CAAY,IAAA,CAAM,QAAA,CAAU,IAAK,CAChE,CACF,CACF,CAAA,CAEM,CAAE,KAAA,CAAAE,CAAAA,CAAO,IAAA,CAAAC,CAAK,CAAA,CAAIC,CAAAA,CAAa,IACnCV,CAAAA,CAASE,CAAqC,CAChD,CAAA,CACA,OAAO,CACL,KAAA,CAAAM,CAAAA,CACA,QAAA,CAAU,KAAA,CAAM,IAAA,CAAKC,CAAI,CAAA,CACzB,UAAA,CAAYR,CACd,CACF,CAMO,SAASU,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACS,CACT,IAAMC,CAAAA,CACJH,CAAAA,CAAS,MAAA,GAAWD,CAAAA,CAAU,MAAA,EAC9BC,CAAAA,CAAS,IAAA,CAAK,CAACN,CAAAA,CAAG,CAAA,GAAMA,CAAAA,GAAMK,CAAAA,CAAU,CAAC,CAAC,CAAA,CACtCK,CAAAA,CACJF,CAAAA,CAAW,MAAA,GAAWD,CAAAA,CAAY,MAAA,EAClCC,CAAAA,CAAW,IAAA,CAAK,CAACR,CAAAA,CAAG,CAAA,GAAMA,CAAAA,GAAMO,CAAAA,CAAY,CAAC,CAAC,CAAA,CAChD,OAAOE,CAAAA,EAAgBC,CACzB,CAwBO,SAASC,CAAAA,CACdC,CAAAA,CAKAC,CAAAA,CACyB,CACzB,GAAI,CAACD,CAAAA,CACH,OAAO,CAAE,GAAGC,CAAa,CAAA,CAI3B,IAAMC,CAAAA,CACJ,MAAA,GAAUF,CAAAA,EACV,OAAOA,CAAAA,CAAS,IAAA,EAAS,QAAA,EACzBA,CAAAA,CAAS,IAAA,GAAS,IAAA,CACbA,CAAAA,CAAS,IAAA,CACTA,CAAAA,CAEP,OAAO,CAAE,GAAGC,CAAAA,CAAc,GAAGC,CAAK,CACpC","file":"adapter-utils.js","sourcesContent":["/**\n * Shared Adapter Utilities\n *\n * Common types and helper functions used across all framework adapters.\n * @internal\n */\n\nimport isDevelopment from \"#is-development\";\nimport { withTracking } from \"./core/tracking.js\";\nimport type {\n HistoryAPI,\n HistoryState,\n SnapshotMeta,\n SystemInspection,\n} from \"./core/types.js\";\n\n// ============================================================================\n// SystemLike — structural type satisfied by both System and SingleModuleSystem\n// ============================================================================\n\n/**\n * Minimal structural type for shared adapter helpers.\n * Both `System<any>` and `SingleModuleSystem<any>` satisfy this interface,\n * eliminating the need for `as unknown as System<any>` casts in adapters.\n * @internal\n */\nexport interface SystemLike {\n readonly isSettled: boolean;\n readonly history: HistoryAPI | null;\n readonly facts: {\n $store: {\n get(key: string): unknown;\n has(key: string): boolean;\n toObject(): Record<string, unknown>;\n };\n };\n readonly derive?: Record<string, unknown>;\n read(key: string): unknown;\n inspect(): SystemInspection;\n}\n\n// ============================================================================\n// Requirements State\n// ============================================================================\n\n/**\n * Requirements state returned by useRequirements hooks.\n * Provides a focused view of just requirements without full inspection overhead.\n */\nexport interface RequirementsState {\n /** Array of unmet requirements waiting to be resolved */\n unmet: Array<{\n id: string;\n requirement: { type: string; [key: string]: unknown };\n fromConstraint: string;\n }>;\n /** Array of requirements currently being resolved */\n inflight: Array<{ id: string; resolverId: string; startedAt: number }>;\n /** Whether there are any unmet requirements */\n hasUnmet: boolean;\n /** Whether there are any inflight requirements */\n hasInflight: boolean;\n /** Whether the system is actively working (has unmet or inflight requirements) */\n isWorking: boolean;\n}\n\n// ============================================================================\n// Inspect State (shared across all adapters)\n// ============================================================================\n\n/**\n * Consolidated inspection state returned by useInspect hooks.\n * Identical shape across React, Vue, Svelte, Solid, and Lit adapters.\n */\nexport interface InspectState {\n /** Whether the system has settled (no pending operations) */\n isSettled: boolean;\n /** Array of unmet requirements */\n unmet: RequirementsState[\"unmet\"];\n /** Array of inflight requirements */\n inflight: RequirementsState[\"inflight\"];\n /** Whether the system is actively working */\n isWorking: boolean;\n /** Whether there are any unmet requirements */\n hasUnmet: boolean;\n /** Whether there are any inflight requirements */\n hasInflight: boolean;\n}\n\n/**\n * Information about a single constraint.\n */\nexport interface ConstraintInfo {\n id: string;\n active: boolean;\n priority: number;\n}\n\n/**\n * Compute InspectState from a system instance.\n * Centralizes the logic currently duplicated across adapters.\n * @internal\n */\nexport function computeInspectState(system: SystemLike): InspectState {\n const inspection = system.inspect();\n return {\n isSettled: system.isSettled,\n unmet: inspection.unmet,\n inflight: inspection.inflight,\n isWorking: inspection.unmet.length > 0 || inspection.inflight.length > 0,\n hasUnmet: inspection.unmet.length > 0,\n hasInflight: inspection.inflight.length > 0,\n };\n}\n\n// ============================================================================\n// Throttled Hook Options\n// ============================================================================\n\n/**\n * Options for throttled hooks.\n * Used by useInspectThrottled, useRequirementsThrottled, etc.\n */\nexport interface ThrottledHookOptions {\n /**\n * Minimum time between updates in milliseconds.\n * @default 100\n */\n throttleMs?: number;\n}\n\n// ============================================================================\n// Throttle Utility\n// ============================================================================\n\n/**\n * Create a throttled version of a callback function.\n * Uses trailing-edge throttling: the callback will be called at most once per interval,\n * with the latest arguments from the most recent call.\n *\n * @param callback - The function to throttle\n * @param ms - The minimum time between calls in milliseconds\n * @returns A throttled version of the callback and a cleanup function\n * @internal\n */\nexport function createThrottle<T extends (...args: unknown[]) => void>(\n callback: T,\n ms: number,\n): { throttled: T; cleanup: () => void } {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n let lastArgs: Parameters<T> | null = null;\n let lastCallTime = 0;\n\n const throttled = ((...args: Parameters<T>) => {\n const now = Date.now();\n const timeSinceLastCall = now - lastCallTime;\n\n if (timeSinceLastCall >= ms) {\n // Enough time has passed, call immediately\n lastCallTime = now;\n callback(...args);\n } else {\n // Schedule for later, keeping latest args\n lastArgs = args;\n if (!timeoutId) {\n timeoutId = setTimeout(() => {\n timeoutId = null;\n lastCallTime = Date.now();\n if (lastArgs) {\n callback(...lastArgs);\n lastArgs = null;\n }\n }, ms - timeSinceLastCall);\n }\n }\n }) as T;\n\n const cleanup = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n lastArgs = null;\n };\n\n return { throttled, cleanup };\n}\n\n// ============================================================================\n// Shared Adapter Helpers\n// ============================================================================\n\n/**\n * Dev-mode assertion that the system parameter is non-null.\n * Tree-shaken in production builds.\n * @internal\n */\nexport function assertSystem(hookName: string, system: unknown): void {\n if (isDevelopment && system == null) {\n throw new Error(\n `[Directive] ${hookName}() requires a system instance as the first argument. Received ${system}.`,\n );\n }\n}\n\n/** Default equality function using Object.is */\nexport function defaultEquality<T>(a: T, b: T): boolean {\n return Object.is(a, b);\n}\n\n/**\n * Build a HistoryState object from a system's history instance.\n * Returns null when history is disabled.\n * @internal\n */\nexport function buildHistoryState(system: SystemLike): HistoryState | null {\n const debug = system.history;\n if (!debug) return null;\n\n // Build lightweight metadata array (no facts data)\n const snapshots: SnapshotMeta[] = debug.snapshots.map((s) => ({\n id: s.id,\n timestamp: s.timestamp,\n trigger: s.trigger,\n }));\n\n return {\n // Navigation state\n canGoBack: debug.currentIndex > 0,\n canGoForward: debug.currentIndex < debug.snapshots.length - 1,\n currentIndex: debug.currentIndex,\n totalSnapshots: debug.snapshots.length,\n\n // Snapshot access\n snapshots,\n getSnapshotFacts: (id: number): Record<string, unknown> | null => {\n const snap = debug.snapshots.find((s) => s.id === id);\n return snap ? snap.facts : null;\n },\n\n // Navigation\n goTo: (snapshotId: number) => debug.goTo(snapshotId),\n goBack: (steps?: number) => debug.goBack(steps),\n goForward: (steps?: number) => debug.goForward(steps),\n replay: () => debug.replay(),\n\n // Session persistence\n exportSession: () => debug.export(),\n importSession: (json: string) => debug.import(json),\n\n // Changesets\n beginChangeset: (label: string) => debug.beginChangeset(label),\n endChangeset: () => debug.endChangeset(),\n\n // Recording control\n isPaused: debug.isPaused,\n pause: () => debug.pause(),\n resume: () => debug.resume(),\n };\n}\n\n/**\n * Pick specific fact values from a system's store.\n * @internal\n */\nexport function pickFacts(\n system: SystemLike,\n keys: string[],\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const key of keys) {\n result[key] = system.facts.$store.get(key);\n }\n return result;\n}\n\n// ============================================================================\n// Tracked Selector\n// ============================================================================\n\n/** Result of running a selector with tracking. @internal */\nexport interface TrackedSelectorResult<R> {\n value: R;\n factKeys: string[];\n deriveKeys: string[];\n}\n\n/**\n * Run a selector against a system with automatic dependency tracking.\n * Creates a Proxy that intercepts property access to distinguish between\n * fact reads (tracked via withTracking) and derivation reads (tracked manually).\n *\n * Used by useSelector in all framework adapters.\n * @internal\n */\nexport function runTrackedSelector<R>(\n system: SystemLike,\n deriveKeySet: Set<string>,\n selector: (state: Record<string, unknown>) => R,\n): TrackedSelectorResult<R> {\n const accessedDeriveKeys: string[] = [];\n\n const stateProxy = new Proxy(\n {},\n {\n get(_, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n if (deriveKeySet.has(prop)) {\n accessedDeriveKeys.push(prop);\n return system.read(prop);\n }\n return system.facts.$store.get(prop);\n },\n has(_, prop: string | symbol) {\n if (typeof prop !== \"string\") return false;\n return deriveKeySet.has(prop) || system.facts.$store.has(prop);\n },\n ownKeys() {\n const factKeys = Object.keys(system.facts.$store.toObject());\n const combined = new Set(factKeys);\n for (const k of deriveKeySet) combined.add(k);\n return [...combined];\n },\n getOwnPropertyDescriptor() {\n return { configurable: true, enumerable: true, writable: true };\n },\n },\n );\n\n const { value, deps } = withTracking(() =>\n selector(stateProxy as Record<string, unknown>),\n );\n return {\n value,\n factKeys: Array.from(deps) as string[],\n deriveKeys: accessedDeriveKeys,\n };\n}\n\n/**\n * Check if tracked dependency keys have changed.\n * @internal\n */\nexport function depsChanged(\n prevFacts: string[],\n newFacts: string[],\n prevDerived: string[],\n newDerived: string[],\n): boolean {\n const factsChanged =\n newFacts.length !== prevFacts.length ||\n newFacts.some((k, i) => k !== prevFacts[i]);\n const derivedChanged =\n newDerived.length !== prevDerived.length ||\n newDerived.some((k, i) => k !== prevDerived[i]);\n return factsChanged || derivedChanged;\n}\n\n// ============================================================================\n// Re-exports from core/types/adapter-utils and utils/utils\n// ============================================================================\n\nexport {\n setBridgeFact,\n getBridgeFact,\n createCallbackPlugin,\n requirementGuard,\n requirementGuardMultiple,\n} from \"./core/types/adapter-utils.js\";\n\nexport { shallowEqual } from \"./utils/utils.js\";\n\n/**\n * Merge a DistributableSnapshot's data into initialFacts for SSR hydration.\n * Used by all framework adapters' hydration hooks/controllers.\n *\n * Accepts both shapes:\n * - DistributableSnapshot (`{ data: Record<string, unknown> }`) — used by React's DirectiveHydrator\n * - Plain `Record<string, unknown>` — used by Lit/Vue/Svelte/Solid adapters\n */\nexport function mergeHydrationFacts(\n snapshot:\n | { data?: Record<string, unknown> }\n | Record<string, unknown>\n | undefined\n | null,\n initialFacts?: Record<string, unknown>,\n): Record<string, unknown> {\n if (!snapshot) {\n return { ...initialFacts };\n }\n\n // If snapshot has a .data property that is a non-null object, treat as DistributableSnapshot\n const data =\n \"data\" in snapshot &&\n typeof snapshot.data === \"object\" &&\n snapshot.data !== null\n ? (snapshot.data as Record<string, unknown>)\n : (snapshot as Record<string, unknown>);\n\n return { ...initialFacts, ...data };\n}\n"]}

@@ -1,5 +0,5 @@

'use strict';var chunk4VZOZWXM_cjs=require('./chunk-4VZOZWXM.cjs'),chunkEX3XG667_cjs=require('./chunk-EX3XG667.cjs'),chunk7NMXRATK_cjs=require('./chunk-7NMXRATK.cjs'),chunkN4KTCKOI_cjs=require('./chunk-N4KTCKOI.cjs'),chunkEOLY64E6_cjs=require('./chunk-EOLY64E6.cjs');var R=1e6;function ye(e,t){try{chunk7NMXRATK_cjs.k(e);}catch(r){let i=r instanceof Error?r.message:String(r);throw new Error(`[Directive] replayUnder: the ${t} predicate is invalid \u2014 ${i}`)}if(!chunk7NMXRATK_cjs.h(e)){let r=e===null||typeof e!="object"?`${typeof e} \u2014 ${JSON.stringify(e)}`:JSON.stringify(e).slice(0,80);throw new Error(`[Directive] replayUnder: the ${t} predicate is not a valid FactPredicate (got ${r})`)}let n;if(chunk7NMXRATK_cjs.i(e,{operator(r,i){n===void 0&&i.startsWith("$")&&!chunk7NMXRATK_cjs.a.has(i)&&(n=i);},strayOperatorKey(r){n===void 0&&!chunk7NMXRATK_cjs.a.has(r)&&!chunk7NMXRATK_cjs.b.has(r)&&(n=r);}}),n!==void 0)throw new Error(`[Directive] replayUnder: the ${t} predicate uses an unknown operator "${n}" \u2014 known operators: ${[...chunk7NMXRATK_cjs.a].join(", ")}`)}function we(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return $e(e);let t=Array.isArray(e)?e:e&&typeof e=="object"&&Array.isArray(e.frames)?e.frames:null;if(!t)throw new Error("[Directive] toReplayFrames: history must be a JSON array of frames, an object with a `frames` array, or a history export with a `snapshots` array");if(t.length>R)throw new Error(`[Directive] toReplayFrames: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${R}) \u2014 split or down-sample the history`);return t.map((n,r)=>{if(n&&typeof n=="object"&&"facts"in n){let i=n,s={id:i.id??`#${r}`,facts:i.facts??{}};return typeof i.timestamp=="number"&&(s.timestamp=i.timestamp),s}return {id:`#${r}`,facts:n??{}}})}function $e(e){let t=typeof e=="string"?JSON.parse(e):e;if(Array.isArray(t))return X(t);if(!t||typeof t!="object")throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");let n=t;if(n.version!==void 0&&n.version!==1)throw new Error(`[Directive] framesFromHistory: unsupported history export version ${JSON.stringify(n.version)} \u2014 expected 1`);if(!Array.isArray(n.snapshots))throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");return X(n.snapshots)}function X(e){if(!Array.isArray(e))throw new Error("[Directive] framesFromSnapshots: expected an array of fact-state snapshots");if(e.length>R)throw new Error(`[Directive] framesFromSnapshots: history has ${e.length} snapshots, exceeds the MAX_REPLAY_FRAMES limit (${R}) \u2014 split or down-sample the history`);for(let t=0;t<e.length;t++){let n=e[t];if(!n||typeof n!="object"||!("facts"in n))throw new Error(`[Directive] framesFromSnapshots: snapshot at index ${t} is not a { facts, ... } object`)}return we(e)}function L(e){let{frames:t,original:n,proposed:r,entityKey:i}=e,s=e.maxSamples??20,o=s>0?s:0;if(t.length>R)throw new Error(`[Directive] replayUnder: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${R}) \u2014 split or down-sample the history`);ye(n,"original"),ye(r,"proposed");let c=0,a=0,u=0,l=0,d=0,f=[],g=[],m=i?new Set:void 0,h=i?new Set:void 0,k;for(let P of t){let $=P.facts,v=chunk7NMXRATK_cjs.m(n,$,k),M=chunk7NMXRATK_cjs.m(r,$,k);v&&(c++,m?.add($[i])),M&&(a++,h?.add($[i])),v===M?d++:!v&&M?(u++,f.length<o&&f.push(me(P,n,r,k))):(l++,g.length<o&&g.push(me(P,n,r,k))),k=$;}let E={framesEvaluated:t.length,original:{matched:c},proposed:{matched:a},delta:a-c,newMatchCount:u,lostMatchCount:l,unchanged:d,newMatches:f,lostMatches:g};return m&&h&&(E.original.matchedEntities=m.size,E.proposed.matchedEntities=h.size),E}function me(e,t,n,r){let i=e.facts,s={frameId:e.id,facts:i,originalExplain:chunk7NMXRATK_cjs.n(t,i,r),proposedExplain:chunk7NMXRATK_cjs.n(n,i,r)};return e.timestamp!==void 0&&(s.timestamp=e.timestamp),s}var Y=1e4,be=5e7;function vt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===1&&typeof e.$hole=="string"}function G(e,t,n=new Set,r=0){if(r>chunk7NMXRATK_cjs.g)throw new Error(`[Directive] sweepUnder: template exceeds MAX_PREDICATE_DEPTH (${chunk7NMXRATK_cjs.g}) \u2014 flatten the template or split the sweep`);if(vt(e)){let i=e.$hole;if(!(i in t))throw new Error(`[Directive] sweepUnder: template references hole "${i}" but sweep has no values for it`);return t[i]}if(e===null||typeof e!="object")return e;if(n.has(e))throw new Error("[Directive] sweepUnder: template contains a cycle \u2014 predicate templates must be a tree");n.add(e);try{if(Array.isArray(e))return e.map(s=>G(s,t,n,r+1));let i={};for(let[s,o]of Object.entries(e))i[s]=G(o,t,n,r+1);return i}finally{n.delete(e);}}function*Te(e,t){if(e.length===0){yield {};return}let n=e[0],r=e.slice(1),i=t[n]??[];for(let s of i)for(let o of Te(r,t))yield {[n]:s,...o};}function kt(e){let t=1;for(let n of Object.values(e))t*=n.length;return t}function Mt(e){let{frames:t,original:n,template:r,sweep:i,objective:s=$=>$.proposed.matched,entityKey:o,maxSamples:c=0}=e,a=Object.keys(i);if(a.length===0)throw new Error("[Directive] sweepUnder: `sweep` must contain at least one hole name");let u=kt(i);if(u>Y)throw new Error(`[Directive] sweepUnder: grid has ${u} points, exceeds the MAX_SWEEP_POINTS limit (${Y}) \u2014 narrow the sweep ranges or split the run`);if(u===0)throw new Error("[Directive] sweepUnder: at least one hole has zero candidate values");let l=u*t.length;if(l>be)throw new Error(`[Directive] sweepUnder: ${u} points \xD7 ${t.length} frames = ${l} per-frame evaluations, exceeds the MAX_SWEEP_EVALUATIONS limit (${be}) \u2014 narrow the sweep, down-sample the history, or split the run`);let d=false,f=$=>{let v;try{v=s($);}catch(M){return d||(d=true,console.warn(`[Directive] sweepUnder: objective threw \u2014 point will not rank (${M.message})`)),Number.NEGATIVE_INFINITY}return typeof v!="number"||!Number.isFinite(v)?(d||(d=true,console.warn(`[Directive] sweepUnder: objective returned a non-finite number (${String(v)}) \u2014 point will not rank`)),Number.NEGATIVE_INFINITY):v},g=L({frames:t,original:n,proposed:n,entityKey:o,maxSamples:c}),m={values:{},report:g,score:f(g)},h=[],k=0,E=Number.NEGATIVE_INFINITY;for(let $ of Te(a,i)){let v=G(r,$),M=L({frames:t,original:n,proposed:v,entityKey:o,maxSamples:c}),H=f(M);H>E&&(E=H,k=h.length),h.push({values:$,report:M,score:H});}let P=h[k];return {points:h,bestIndex:k,best:P,baseline:m}}function V(e){let t=e&&typeof e=="object"&&!Array.isArray(e)&&"constraints"in e?e.constraints:e;if(Array.isArray(t)){let n={};for(let r of t){if(!r||typeof r!="object"||!("id"in r))throw new Error("[Directive] diffRules: array entries must be `{ id, whenSpec }` objects");let i=r;if(typeof i.id!="string")throw new Error("[Directive] diffRules: constraint `id` must be a string");n[i.id]=i.whenSpec;}return n}if(t&&typeof t=="object")return t;throw new Error("[Directive] diffRules: expected a `{ id: whenSpec }` map, an array of `{ id, whenSpec }`, or `{ constraints: ... }`")}var Dt=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),Rt=new Set(["$all","$any","$not"]);function Se(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Et(e){if(!Se(e))return false;let t=Object.keys(e);if(t.length===0)return false;let n=false;for(let r of t){if(!r.startsWith("$"))return false;Dt.has(r)&&(n=true);}return n}function T(e,t="",n=[]){if(e===null||typeof e!="object")return n;if(Array.isArray(e)){for(let r of e)if(r&&typeof r=="object"&&"fact"in r&&"op"in r){let i=r;n.push({path:t?`${t}.${String(i.fact)}`:String(i.fact),op:String(i.op),value:i.value});}return n}if("$all"in e&&Array.isArray(e.$all))return e.$all.forEach((i,s)=>{T(i,`${t}$all[${s}]`,n);}),n;if("$any"in e&&Array.isArray(e.$any))return e.$any.forEach((i,s)=>{T(i,`${t}$any[${s}]`,n);}),n;if("$not"in e)return T(e.$not,`${t}$not`,n),n;for(let[r,i]of Object.entries(e)){let s=t?`${t}.${r}`:r;if(Et(i))for(let[o,c]of Object.entries(i))n.push({path:s,op:o,value:c});else Se(i)&&!Rt.has(r)?T(i,s,n):n.push({path:s,op:"$eq",value:i});}return n}function D(e){return typeof e=="number"&&Number.isFinite(e)}function xt(e,t,n){switch(e){case "$gte":case "$gt":if(D(t)&&D(n)){if(n<t)return "relaxed";if(n>t)return "tightened"}return null;case "$lte":case "$lt":if(D(t)&&D(n)){if(n>t)return "relaxed";if(n<t)return "tightened"}return null;case "$between":{if(Array.isArray(t)&&Array.isArray(n)&&t.length===2&&n.length===2&&D(t[0])&&D(t[1])&&D(n[0])&&D(n[1])){let r=t[1]-t[0],i=n[1]-n[0];if(i>r)return "relaxed";if(i<r)return "tightened"}return null}case "$in":case "$nin":{if(Array.isArray(t)&&Array.isArray(n))if(e==="$in"){if(n.length>t.length)return "relaxed";if(n.length<t.length)return "tightened"}else {if(n.length>t.length)return "tightened";if(n.length<t.length)return "relaxed"}return null}case "$contains":{if(Array.isArray(t)&&Array.isArray(n)){if(n.length>t.length)return "relaxed";if(n.length<t.length)return "tightened"}return null}default:return null}}function At(e){let t=V(e.before),n=V(e.after),i=[...new Set([...Object.keys(t),...Object.keys(n)])].sort(),s=[],o={added:0,removed:0,changed:0,unchanged:0,totalClauseChanges:0};for(let c of i){let a=t[c],u=n[c],l=c in t,d=c in n;if(l&&!d){let g=T(a),m=g.length===0?[{path:"(function-form predicate)",kind:"removed"}]:g.map(h=>({path:h.path,kind:"removed",before:{op:h.op,value:h.value}}));ee(m),s.push({id:c,status:"removed",changes:m}),o.removed++,o.totalClauseChanges+=m.length;continue}if(!l&&d){let g=T(u),m=g.length===0?[{path:"(function-form predicate)",kind:"added"}]:g.map(h=>({path:h.path,kind:"added",after:{op:h.op,value:h.value}}));ee(m),s.push({id:c,status:"added",changes:m}),o.added++,o.totalClauseChanges+=m.length;continue}let f=ve(a,u);f.length===0?(s.push({id:c,status:"unchanged",changes:[]}),o.unchanged++):(s.push({id:c,status:"changed",changes:f}),o.changed++,o.totalClauseChanges+=f.length);}return {constraints:s,summary:o}}function ve(e,t){if(e!==void 0&&t!==void 0&&(e===null||t===null||typeof e!="object"||typeof t!="object"))return chunkEOLY64E6_cjs.d(e)===chunkEOLY64E6_cjs.d(t)?[]:[{path:"",kind:"changed",before:{op:"$eq",value:e},after:{op:"$eq",value:t}}];let n=e===void 0?[]:T(e),r=t===void 0?[]:T(t),i=u=>`${u.path}::${u.op}`,s=new Map(n.map(u=>[i(u),u])),o=new Map(r.map(u=>[i(u),u])),c=new Set([...s.keys(),...o.keys()]),a=[];for(let u of c){let l=s.get(u),d=o.get(u);if(l&&!d){a.push({path:l.path,kind:"removed",before:{op:l.op,value:l.value}});continue}if(!l&&d){a.push({path:d.path,kind:"added",after:{op:d.op,value:d.value}});continue}if(l&&d){if(chunkEOLY64E6_cjs.d(l.value)===chunkEOLY64E6_cjs.d(d.value))continue;let f=xt(l.op,l.value,d.value);a.push({path:l.path,kind:f??"changed",before:{op:l.op,value:l.value},after:{op:d.op,value:d.value}});}}return ee(a),a}function ee(e){e.sort((t,n)=>{let r=t.path.localeCompare(n.path);if(r!==0)return r;let i=t.before?.op??t.after?.op??"",s=n.before?.op??n.after?.op??"";return i.localeCompare(s)});}function B(e){return e===null?"null":e===void 0?"undefined":e instanceof Date?e.toISOString():typeof e=="string"||typeof e=="object"?JSON.stringify(e):String(e)}function Ct(e){let t=e.path,n=B(e.expected),r=B(e.actual);switch(e.op){case "$eq":return `set ${t} to ${n} (currently ${r})`;case "$ne":return `change ${t} to anything other than ${n} (currently ${r})`;case "$gt":return `set ${t} above ${n} (currently ${r})`;case "$gte":return `set ${t} to at least ${n} (currently ${r})`;case "$lt":return `set ${t} below ${n} (currently ${r})`;case "$lte":return `set ${t} to at most ${n} (currently ${r})`;case "$in":return `set ${t} to one of ${n} (currently ${r})`;case "$nin":return `set ${t} to something other than ${n} (currently ${r})`;case "$exists":return e.expected===true?`set ${t} to a non-null value (currently null/missing)`:`unset ${t} (currently ${r})`;case "$between":return Array.isArray(e.expected)&&e.expected.length===2?`set ${t} between ${B(e.expected[0])} and ${B(e.expected[1])} (currently ${r})`:`set ${t} within range ${n} (currently ${r})`;case "$startsWith":return `set ${t} to start with ${n} (currently ${r})`;case "$endsWith":return `set ${t} to end with ${n} (currently ${r})`;case "$contains":return `set ${t} to contain ${n} (currently ${r})`;case "$matches":return `set ${t} to match the pattern ${n} (currently ${r})`;case "$changed":return `the previous-vs-current change of ${t} is required to differ (currently they match: ${r})`;case "$all":case "$any":case "$not":return `the ${e.op} group at "${t}" did not pass \u2014 see its child clauses`;default:return `clause at ${t} (${e.op}) failed: expected ${n}, got ${r}`}}function ke(e,t){for(let n of e)if(!n.pass){if((n.op==="$all"||n.op==="$any"||n.op==="$not")&&n.children){ke(n.children,t);continue}t.push({path:n.path,op:n.op,expected:n.expected,actual:n.actual,suggestion:Ct(n)});}}function Pt(e,t,n){let r=chunk7NMXRATK_cjs.n(e,t,n),i=r.every(o=>o.pass),s=[];return i||ke(r,s),{wouldFire:i,whenExplain:r,missingChanges:s,predicate:e}}var Me=new Set(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$nin"]);function W(e,t){if(e===t)return 0;if(typeof e=="number"&&typeof t=="number"||typeof e=="bigint"&&typeof t=="bigint")return e<t?-1:e>t?1:0;if(e instanceof Date&&t instanceof Date){let n=e.getTime(),r=t.getTime();return n<r?-1:n>r?1:0}return typeof e=="string"&&typeof t=="string"?e<t?-1:e>t?1:0:Number.NaN}function F(e,t){if(e===t)return true;if(typeof e!=typeof t||e===null||t===null||typeof e!="object"||Array.isArray(e)!==Array.isArray(t))return false;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return false;for(let i=0;i<e.length;i++)if(!F(e[i],t[i]))return false;return true}let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return false;for(let i of n)if(!F(e[i],t[i]))return false;return true}function jt(e,t){if(!Me.has(e.op)||!Me.has(t.op))return {type:"overlap",reason:`Both rules touch "${e.path}".`};if(e.op==="$eq"&&t.op==="$eq")return F(e.value,t.value)?{type:"subset",reason:`Both rules require ${e.path} = ${JSON.stringify(e.value)} \u2014 candidate is redundant.`}:{type:"direct",reason:`Candidate requires ${e.path} = ${JSON.stringify(e.value)} but an existing rule requires ${e.path} = ${JSON.stringify(t.value)} \u2014 they cannot both fire.`};if(e.op==="$eq"&&t.op==="$ne")return F(e.value,t.value)?{type:"direct",reason:`Candidate requires ${e.path} = ${JSON.stringify(e.value)} but an existing rule excludes that value.`}:null;if(e.op==="$ne"&&t.op==="$eq")return F(e.value,t.value)?{type:"direct",reason:`Candidate excludes ${e.path} = ${JSON.stringify(e.value)} but an existing rule requires that exact value.`}:null;if(e.op==="$in"&&t.op==="$in"){let o=new Set(Array.isArray(e.value)?e.value:[]),c=new Set(Array.isArray(t.value)?t.value:[]),a=[...o].filter(u=>c.has(u));return a.length===0?{type:"direct",reason:`Candidate $in set for ${e.path} (${JSON.stringify([...o])}) and existing $in set (${JSON.stringify([...c])}) have no values in common \u2014 the candidate can never fire while the existing rule holds.`}:a.length===o.size&&a.length<c.size?{type:"subset",reason:`Candidate $in set for ${e.path} is a strict subset of the existing rule's $in set.`}:null}let n=e.op==="$gt"||e.op==="$gte"?e.value:void 0,r=e.op==="$lt"||e.op==="$lte"?e.value:void 0,i=t.op==="$gt"||t.op==="$gte"?t.value:void 0,s=t.op==="$lt"||t.op==="$lte"?t.value:void 0;if(n!==void 0&&s!==void 0){let o=W(n,s);if(!Number.isNaN(o)&&(o>0||o===0&&(e.op==="$gt"||t.op==="$lt")))return {type:"direct",reason:`Candidate requires ${e.path} ${e.op==="$gt"?">":"\u2265"} ${JSON.stringify(n)} but an existing rule caps it at ${t.op==="$lt"?"<":"\u2264"} ${JSON.stringify(s)}.`}}if(i!==void 0&&r!==void 0){let o=W(i,r);if(!Number.isNaN(o)&&(o>0||o===0&&(t.op==="$gt"||e.op==="$lt")))return {type:"direct",reason:`Candidate caps ${e.path} at ${e.op==="$lt"?"<":"\u2264"} ${JSON.stringify(r)} but an existing rule requires it ${t.op==="$gt"?">":"\u2265"} ${JSON.stringify(i)}.`}}if(n!==void 0&&i!==void 0){let o=W(n,i);if(!Number.isNaN(o)&&o>0)return {type:"subset",reason:`Candidate's lower bound on ${e.path} (${JSON.stringify(n)}) is stricter than the existing rule's lower bound (${JSON.stringify(i)}) \u2014 candidate is a subset.`}}if(r!==void 0&&s!==void 0){let o=W(r,s);if(!Number.isNaN(o)&&o<0)return {type:"subset",reason:`Candidate's upper bound on ${e.path} (${JSON.stringify(r)}) is stricter than the existing rule's upper bound (${JSON.stringify(s)}) \u2014 candidate is a subset.`}}return {type:"overlap",reason:`Both rules constrain "${e.path}".`}}function Ot(e){return typeof e=="object"&&e!==null&&typeof e.id=="string"}var Ft={checkAgainst(e,t){let n=Array.isArray(t)?t:"constraints"in t&&Array.isArray(t.constraints)?t.constraints:[],r=T(e);if(r.length===0)return {contradictions:[],warnings:[]};let i=new Map;for(let c of r){let a=i.get(c.path)??[];a.push(c),i.set(c.path,a);}let s=[],o=[];for(let c of n){if(!Ot(c)||c.whenSpec===void 0)continue;let a=T(c.whenSpec);for(let u of a){let l=i.get(u.path);if(l)for(let d of l){let f=jt(d,u);if(!f)continue;let g={constraintId:c.id,type:f.type,reason:f.reason,candidatePath:d.path,candidate:{op:d.op,value:d.value},existing:{op:u.op,value:u.value}};f.type==="overlap"?o.push(g):s.push(g);}}}return {contradictions:s,warnings:o}}};var _t=/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)?$/;function N(e,t){if(typeof e!="string"||!_t.test(e))throw new Error(`[Directive] predicateToSQL: invalid ${t} identifier "${e}" \u2014 must match /^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)?$/`)}function De(e,t){if(t&&!t.includes(e))throw new Error(`[Directive] predicateToSQL: column "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function Nt(e){if(Array.isArray(e)){if(e.length===0)throw new Error("[Directive] predicateToSQL: select must not be empty");for(let n of e)N(n,"column");return e.join(", ")}let t=e;return t==="*"?"*":(N(t,"column"),t)}function w(e,t){return e.params.push(t),e.placeholder(e.params.length)}function te(e,t,n,r){switch(t){case "$eq":return `${e} = ${w(r,n)}`;case "$ne":return `${e} <> ${w(r,n)}`;case "$gt":return `${e} > ${w(r,n)}`;case "$gte":return `${e} >= ${w(r,n)}`;case "$lt":return `${e} < ${w(r,n)}`;case "$lte":return `${e} <= ${w(r,n)}`;case "$in":if(!Array.isArray(n))throw new Error("[Directive] predicateToSQL: $in operand must be an array");return `${e} = ANY(${w(r,n)})`;case "$nin":if(!Array.isArray(n))throw new Error("[Directive] predicateToSQL: $nin operand must be an array");return `NOT (${e} = ANY(${w(r,n)}))`;case "$exists":return n===true?`${e} IS NOT NULL`:`${e} IS NULL`;case "$between":{if(!Array.isArray(n)||n.length!==2)throw new Error("[Directive] predicateToSQL: $between operand must be a [low, high] tuple");return `${e} BETWEEN ${w(r,n[0])} AND ${w(r,n[1])}`}case "$startsWith":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $startsWith operand must be a string");return `${e} LIKE ${w(r,ne(n))} || '%' ESCAPE '\\'`;case "$endsWith":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $endsWith operand must be a string");return `${e} LIKE '%' || ${w(r,ne(n))} ESCAPE '\\'`;case "$contains":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $contains only supports string operands \u2014 array containment requires a JOIN, not a predicate");return `${e} LIKE '%' || ${w(r,ne(n))} || '%' ESCAPE '\\'`;case "$matches":{if(!(n instanceof RegExp))throw new Error("[Directive] predicateToSQL: $matches operand must be a RegExp");let i=n.flags.includes("i")?"~*":"~";return `${e} ${i} ${w(r,n.source)}`}case "$changed":throw new Error('[Directive] predicateToSQL: $changed is an effects-only operator \u2014 no server-side translation (a database row has no "prev" snapshot)');default:throw new Error(`[Directive] predicateToSQL: unknown operator "${t}" \u2014 known: ${[...chunk7NMXRATK_cjs.a].join(", ")}`)}}function ne(e){return e.replace(/[\\%_]/g,"\\$&")}function Re(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function qt(e){if(!Re(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function re(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToSQL: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function _(e,t,n){if(n>chunk7NMXRATK_cjs.g)throw new Error(`[Directive] predicateToSQL: predicate depth limit (${chunk7NMXRATK_cjs.g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error(`[Directive] predicateToSQL: predicate must be an object or array, got ${typeof e}`);if(Array.isArray(e)){if(e.length===0)return "TRUE";let i=e.map(s=>{if(!s||typeof s!="object"||!("fact"in s)||!("op"in s))throw new Error("[Directive] predicateToSQL: array-form clause must be { fact, op, value }");let o=s;return N(o.fact,"column"),De(o.fact,t.allowed),te(o.fact,o.op,o.value,t)});return i.length===1?i[0]:`(${i.join(" AND ")})`}if("$all"in e){re(e,"$all");let i=e.$all;if(!Array.isArray(i))throw new Error("[Directive] predicateToSQL: $all must be an array");if(i.length===0)return "TRUE";let s=i.map(o=>_(o,t,n+1));return s.length===1?s[0]:`(${s.join(" AND ")})`}if("$any"in e){re(e,"$any");let i=e.$any;if(!Array.isArray(i))throw new Error("[Directive] predicateToSQL: $any must be an array");if(i.length===0)return "FALSE";let s=i.map(o=>_(o,t,n+1));return s.length===1?s[0]:`(${s.join(" OR ")})`}if("$not"in e){re(e,"$not");let i=e.$not;return `NOT (${_(i,t,n+1)})`}let r=[];for(let[i,s]of Object.entries(e))if(N(i,"column"),De(i,t.allowed),qt(s))for(let[o,c]of Object.entries(s)){if(!chunk7NMXRATK_cjs.a.has(o))throw new Error(`[Directive] predicateToSQL: unknown operator "${o}" on column "${i}" \u2014 known: ${[...chunk7NMXRATK_cjs.a].join(", ")}`);r.push(te(i,o,c,t));}else {if(Re(s))throw new Error(`[Directive] predicateToSQL: nested predicate at "${i}" \u2014 cross-module / partial-match predicates have no SQL equivalent (single-table queries only in v1; pass a flat predicate or build JOIN by hand with predicateToWhere)`);r.push(te(i,"$eq",s,t));}return r.length===0?"TRUE":r.length===1?r[0]:`(${r.join(" AND ")})`}var Ee=e=>`$${e}`;function It(e,t){let{table:n,allowedKeys:r}=t,i=t.placeholder??Ee,s=t.select??"*";N(n,"table");let o=Nt(s),c={params:[],placeholder:i,allowed:r},a=_(e,c,0);return {sql:`SELECT ${o} FROM ${n} WHERE ${a}`,where:a,params:c.params}}function Lt(e,t={}){let n=t.placeholder??Ee,r={params:[],placeholder:n,allowed:t.allowedKeys};return {where:_(e,r,0),params:r.params}}function ie(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function se(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Bt(e){if(!se(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}var Wt=/^[A-Za-z_][A-Za-z0-9_]*$/,Kt=/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;function xe(e,t){if(typeof e!="string"||e.length===0)throw new Error(`[Directive] predicateToMongo: field name must be a non-empty string, got ${typeof e}`);if(e.startsWith("$"))throw new Error(`[Directive] predicateToMongo: field name "${e}" starts with "$" \u2014 reserved for Mongo operators (a top-level $where would be an injection vector)`);if(!(t.allowDottedPaths?Kt:Wt).test(e))throw new Error(`[Directive] predicateToMongo: invalid field name "${e}"${t.allowDottedPaths?"":' \u2014 pass options.allowDottedPaths=true to permit sub-document paths like "user.role"'}`)}function Ae(e,t){if(t&&!t.includes(e))throw new Error(`[Directive] predicateToMongo: field "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function oe(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToMongo: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function Ce(e,t){switch(e){case "$eq":case "$ne":case "$gt":case "$gte":case "$lt":case "$lte":case "$in":case "$nin":case "$exists":return {[e]:t};case "$between":{if(!Array.isArray(t)||t.length!==2)throw new Error("[Directive] predicateToMongo: $between operand must be a [low, high] tuple");return {$gte:t[0],$lte:t[1]}}case "$startsWith":if(typeof t!="string")throw new Error("[Directive] predicateToMongo: $startsWith operand must be a string");return {$regex:`^${ie(t)}`};case "$endsWith":if(typeof t!="string")throw new Error("[Directive] predicateToMongo: $endsWith operand must be a string");return {$regex:`${ie(t)}$`};case "$contains":if(typeof t=="string")return {$regex:ie(t)};throw new Error("[Directive] predicateToMongo: $contains in Mongo expects a string operand \u2014 for array element membership use $elemMatch or $in directly");case "$matches":{if(t instanceof RegExp)return t.flags?{$regex:t.source,$options:t.flags}:{$regex:t.source};if(typeof t=="string")return {$regex:t};throw new Error("[Directive] predicateToMongo: $matches operand must be a RegExp or string")}case "$changed":throw new Error("[Directive] predicateToMongo: $changed is an effects-only operator \u2014 no MongoDB query equivalent");default:throw new Error(`[Directive] predicateToMongo: unknown operator "${e}" \u2014 known: ${[...chunk7NMXRATK_cjs.a].join(", ")}`)}}function A(e,t,n){if(n>chunk7NMXRATK_cjs.g)throw new Error(`[Directive] predicateToMongo: predicate depth limit (${chunk7NMXRATK_cjs.g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error(`[Directive] predicateToMongo: predicate must be an object or array, got ${typeof e}`);if(Array.isArray(e)){if(e.length===0)return {};let i={},s=[];for(let o of e){if(!o||typeof o!="object"||!("fact"in o)||!("op"in o))throw new Error("[Directive] predicateToMongo: array-form clause must be { fact, op, value }");let c=o;xe(c.fact,t),Ae(c.fact,t.allowedKeys);let a=Ce(c.op,c.value);if(c.fact in i&&se(i[c.fact])){let u=i[c.fact];Object.keys(a).some(d=>d in u)?s.push({[c.fact]:a}):i[c.fact]={...u,...a};}else c.fact in i?s.push({[c.fact]:a}):i[c.fact]=a;}if(s.length>0){let o=[];for(let[c,a]of Object.entries(i))o.push({[c]:a});return o.push(...s),{$and:o}}return i}if("$all"in e){oe(e,"$all");let i=e.$all;if(!Array.isArray(i))throw new Error("[Directive] predicateToMongo: $all must be an array");return i.length===0?{}:i.length===1?A(i[0],t,n+1):{$and:i.map(s=>A(s,t,n+1))}}if("$any"in e){oe(e,"$any");let i=e.$any;if(!Array.isArray(i))throw new Error("[Directive] predicateToMongo: $any must be an array");return i.length===0?{$expr:{$eq:[1,0]}}:i.length===1?A(i[0],t,n+1):{$or:i.map(s=>A(s,t,n+1))}}if("$not"in e){oe(e,"$not");let i=e.$not;return {$nor:[A(i,t,n+1)]}}let r={};for(let[i,s]of Object.entries(e))if(xe(i,t),Ae(i,t.allowedKeys),Bt(s)){let o={};for(let[c,a]of Object.entries(s)){if(!chunk7NMXRATK_cjs.a.has(c))throw new Error(`[Directive] predicateToMongo: unknown operator "${c}" on field "${i}" \u2014 known: ${[...chunk7NMXRATK_cjs.a].join(", ")}`);Object.assign(o,Ce(c,a));}r[i]=o;}else r[i]=s;return r}function Ut(e,t={}){return A(e,t,0)}var zt=/^[A-Za-z_][A-Za-z0-9_]*$/;function Pe(e,t){if(typeof e!="string"||!zt.test(e))throw new Error(`[Directive] predicateToPostgrest: invalid column identifier "${e}"`);if(t&&!t.includes(e))throw new Error(`[Directive] predicateToPostgrest: column "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function ae(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToPostgrest: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function S(e){if(e==null)return "null";if(typeof e=="boolean")return e?"true":"false";if(typeof e=="number"||typeof e=="bigint")return String(e);if(e instanceof Date)return e.toISOString();if(typeof e=="string")return /[,.():"\\\s]/.test(e)?`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:e;throw new Error(`[Directive] predicateToPostgrest: cannot encode value of type ${typeof e}`)}function je(e){return `(${e.map(S).join(",")})`}function ue(e){return e.replace(/[\\%_*]/g,"\\$&")}function C(e,t){switch(e){case "$eq":return `eq.${S(t)}`;case "$ne":return `neq.${S(t)}`;case "$gt":return `gt.${S(t)}`;case "$gte":return `gte.${S(t)}`;case "$lt":return `lt.${S(t)}`;case "$lte":return `lte.${S(t)}`;case "$in":if(!Array.isArray(t))throw new Error("[Directive] predicateToPostgrest: $in operand must be an array");return `in.${je(t)}`;case "$nin":if(!Array.isArray(t))throw new Error("[Directive] predicateToPostgrest: $nin operand must be an array");return `not.in.${je(t)}`;case "$exists":return t===true?"not.is.null":"is.null";case "$startsWith":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $startsWith operand must be a string");return `like.${S(ue(t)+"*")}`;case "$endsWith":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $endsWith operand must be a string");return `like.${S("*"+ue(t))}`;case "$contains":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $contains expects a string operand (array containment is the cs operator with a different shape \u2014 out of scope for v1)");return `like.${S("*"+ue(t)+"*")}`;case "$matches":if(t instanceof RegExp)return `${t.flags.includes("i")?"imatch":"match"}.${S(t.source)}`;if(typeof t=="string")return `match.${S(t)}`;throw new Error("[Directive] predicateToPostgrest: $matches operand must be a RegExp or string");case "$changed":throw new Error("[Directive] predicateToPostgrest: $changed is an effects-only operator \u2014 no server query equivalent");default:throw new Error(`[Directive] predicateToPostgrest: unknown operator "${e}" \u2014 known: ${[...chunk7NMXRATK_cjs.a].join(", ")}`)}}function Oe(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Ht(e){if(!Oe(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function ce(e,t){return `${e}=${t}`}function K(e,t){return `${e}=(${t.join(",")})`}function le(e,t,n,r){if(t==="$between"){if(!Array.isArray(n)||n.length!==2)throw new Error("[Directive] predicateToPostgrest: $between operand must be a [low, high] tuple");let i=r?ce(e,C("$gte",n[0])):`${e}.${C("$gte",n[0])}`,s=r?ce(e,C("$lte",n[1])):`${e}.${C("$lte",n[1])}`;return [i,s]}return [r?ce(e,C(t,n)):`${e}.${C(t,n)}`]}function q(e,t,n,r){if(r>chunk7NMXRATK_cjs.g)throw new Error(`[Directive] predicateToPostgrest: predicate depth limit (${chunk7NMXRATK_cjs.g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error("[Directive] predicateToPostgrest: predicate must be an object or array");if(Array.isArray(e)){let s=[];for(let o of e){if(!o||typeof o!="object"||!("fact"in o)||!("op"in o))throw new Error("[Directive] predicateToPostgrest: array-form clause must be { fact, op, value }");let c=o;Pe(c.fact,t),s.push(...le(c.fact,c.op,c.value,n));}return s}if("$all"in e){ae(e,"$all");let s=e.$all;if(!Array.isArray(s))throw new Error("[Directive] predicateToPostgrest: $all must be an array");if(n){let c=[];for(let a of s)c.push(...q(a,t,true,r+1));return c}let o=[];for(let c of s)o.push(...q(c,t,false,r+1));return [K("and",o)]}if("$any"in e){ae(e,"$any");let s=e.$any;if(!Array.isArray(s))throw new Error("[Directive] predicateToPostgrest: $any must be an array");if(s.length===0)return n?["id=is.null","id=not.is.null"]:[K("and",["id.is.null","id.not.is.null"])];let o=[];for(let c of s)o.push(...q(c,t,false,r+1));return [K("or",o)]}if("$not"in e){ae(e,"$not");let s=e.$not,o=q(s,t,false,r+1);return [K("not.and",o)]}let i=[];for(let[s,o]of Object.entries(e))if(Pe(s,t),Ht(o))for(let[c,a]of Object.entries(o)){if(!chunk7NMXRATK_cjs.a.has(c))throw new Error(`[Directive] predicateToPostgrest: unknown operator "${c}" on column "${s}" \u2014 known: ${[...chunk7NMXRATK_cjs.a].join(", ")}`);i.push(...le(s,c,a,n));}else {if(Oe(o))throw new Error(`[Directive] predicateToPostgrest: nested predicate at "${s}" \u2014 single-table queries only`);i.push(...le(s,"$eq",o,n));}return i}function Qt(e){let t=e.indexOf("=");if(t<0)return encodeURIComponent(e);let n=e.slice(0,t),r=e.slice(t+1);return `${n}=${encodeURIComponent(r)}`}function Jt(e,t={}){let n=t.mode??"querystring",r=q(e,t.allowedKeys,true,0);return r.length===0?"":n==="raw"?r.join("&"):r.map(Qt).join("&")}function U(e=[],t,n,r,i,s,o){return {_type:void 0,_validators:e,_typeName:t,_default:n,_transform:r,_description:i,_refinements:s,_meta:o,validate(c){return U([...e,c],t,n,r,i,s,o)}}}function p(e,t,n,r,i,s,o){return {...U(e,t,n,r,i,s,o),default(a){return p(e,t,a,r,i,s,o)},transform(a){return p([],t,void 0,l=>{let d=r?r(l):l;return a(d)},i,void 0,o)},brand(){return p(e,`Branded<${t}>`,n,r,i,s,o)},describe(a){return p(e,t,n,r,a,s,o)},refine(a,u){let l=[...s??[],{predicate:a,message:u}];return p([...e,a],t,n,r,i,l,o)},nullable(){return p([a=>a===null||e.every(u=>u(a))],`${t} | null`,n,r,i,void 0,o)},optional(){return p([a=>a===void 0||e.every(u=>u(a))],`${t} | undefined`,n,r,i,void 0,o)},meta(a){return p(e,t,n,r,i,s,a)}}}var Zt=((...e)=>{if(e.length===0)return p([],"union");let t=e.map(n=>n._typeName??"unknown");return p([n=>e.some(r=>r._validators.every(i=>i(n)))],t.join(" | "))}),Xt={string(){let e=(t,n,r,i,s,o)=>({...p(t,"string",n,r,i,s,o),minLength(a){return e([...t,u=>u.length>=a],n,r,i,s,o)},maxLength(a){return e([...t,u=>u.length<=a],n,r,i,s,o)},pattern(a){return e([...t,u=>a.test(u)],n,r,i,s,o)},default(a){return e(t,a,r,i,s,o)},describe(a){return e(t,n,r,a,s,o)},refine(a,u){let l=[...s??[],{predicate:a,message:u}];return e([...t,a],n,r,i,l,o)},meta(a){return e(t,n,r,i,s,a)}});return e([t=>typeof t=="string"])},number(){let e=(t,n,r,i,s,o)=>({...p(t,"number",n,r,i,s,o),min(a){return e([...t,u=>u>=a],n,r,i,s,o)},max(a){return e([...t,u=>u<=a],n,r,i,s,o)},default(a){return e(t,a,r,i,s,o)},describe(a){return e(t,n,r,a,s,o)},refine(a,u){let l=[...s??[],{predicate:a,message:u}];return e([...t,a],n,r,i,l,o)},meta(a){return e(t,n,r,i,s,a)}});return e([t=>typeof t=="number"])},boolean(){return p([e=>typeof e=="boolean"],"boolean")},array(){let e=(t,n,r,i,s,o)=>{let c=p(t,"array",r,void 0,i,void 0,o),a=s??{value:-1};return {...c,get _lastFailedIndex(){return a.value},set _lastFailedIndex(l){a.value=l;},of(l){let d={value:-1};return e([...t,f=>{for(let g=0;g<f.length;g++)if(!l._validators.every(m=>m(f[g])))return d.value=g,false;return true}],l,r,i,d,o)},nonEmpty(){return e([...t,l=>l.length>0],n,r,i,a,o)},maxLength(l){return e([...t,d=>d.length<=l],n,r,i,a,o)},minLength(l){return e([...t,d=>d.length>=l],n,r,i,a,o)},default(l){return e(t,n,l,i,a,o)},describe(l){return e(t,n,r,l,a,o)},meta(l){return e(t,n,r,i,a,l)}}};return e([t=>Array.isArray(t)])},object(){let e=(t,n,r,i)=>({...p(t,"object",n,void 0,r,void 0,i),shape(o){return e([...t,c=>{for(let[a,u]of Object.entries(o)){let l=c[a],d=u;if(d&&!d._validators.every(f=>f(l)))return false}return true}],n,r,i)},nonNull(){return e([...t,o=>o!=null],n,r,i)},hasKeys(...o){return e([...t,c=>o.every(a=>a in c)],n,r,i)},default(o){return e(t,o,r,i)},describe(o){return e(t,n,o,i)},meta(o){return e(t,n,r,o)}});return e([t=>typeof t=="object"&&t!==null&&!Array.isArray(t)])},enum(...e){chunkN4KTCKOI_cjs.a&&e.length===0&&console.warn("[Directive] t.enum() called with no values - this will reject all strings");let t=new Set(e);return p([n=>typeof n=="string"&&t.has(n)],`enum(${e.join("|")})`)},literal(e){return p([t=>t===e],`literal(${String(e)})`)},nullable(e){let t=e._typeName??"unknown";return U([n=>n===null?true:e._validators.every(r=>r(n))],`${t} | null`)},optional(e){let t=e._typeName??"unknown";return U([n=>n===void 0?true:e._validators.every(r=>r(n))],`${t} | undefined`)},union:Zt,record(e){let t=e._typeName??"unknown";return p([n=>typeof n!="object"||n===null||Array.isArray(n)?false:Object.values(n).every(r=>e._validators.every(i=>i(r)))],`Record<string, ${t}>`)},tuple(...e){chunkN4KTCKOI_cjs.a&&e.length===0&&console.warn("[Directive] t.tuple() called with no types - this will only accept empty arrays");let t=e.map(n=>n._typeName??"unknown");return p([n=>!Array.isArray(n)||n.length!==e.length?false:e.every((r,i)=>r._validators.every(s=>s(n[i])))],`[${t.join(", ")}]`)},date(){return p([e=>e instanceof Date&&!Number.isNaN(e.getTime())],"Date")},uuid(){let e=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;return p([t=>typeof t=="string"&&e.test(t)],"uuid")},email(){let e=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;return p([t=>typeof t=="string"&&e.test(t)],"email")},url(){return p([e=>{if(typeof e!="string")return false;try{return new URL(e),!0}catch{return false}}],"url")},bigint(){return p([e=>typeof e=="bigint"],"bigint")},any(){return p([],"any")},unknown(){return p([],"unknown")}};function Yt(e){if(!e||typeof e!="string"){console.warn("[Directive] Module ID must be a non-empty string");return}/^(__[a-z][a-z0-9_-]*|[a-z][a-z0-9-]*)$/i.test(e)||console.warn(`[Directive] Module ID "${e}" should follow kebab-case convention (e.g., "my-module")`);}function Fe(e,t,n,r,i){for(let s of e)t.has(s)||console.warn(`[Directive] ${n} "${s}" not declared in ${r}`);for(let s of t)e.has(s)||console.warn(`[Directive] ${r}["${s}"] ${i}`);}function Gt(e,t){e.length===0&&console.warn("[Directive] history.snapshotEvents is an empty array \u2014 no events will create history snapshots. Omit history.snapshotEvents entirely to snapshot all events, or list specific events.");let n=new Set(Object.keys(t));for(let r of e)n.has(r)||console.warn(`[Directive] history.snapshotEvents entry "${r}" not declared in schema.events. Available events: ${[...n].join(", ")||"(none)"}`);}function Vt(e,t){let n=new Set(Object.keys(t));for(let[r,i]of Object.entries(e)){let s=i;typeof s.requirement=="string"&&!n.has(s.requirement)&&console.warn(`[Directive] Resolver "${r}" references unknown requirement type "${s.requirement}". Available types: ${[...n].join(", ")||"(none)"}`);}}function en(e,t){let n=t.schema?.facts??{},r=Object.keys(n);if(r.length===0)return;let i=new Set(["self","prev","current"]),s="crossModuleDeps"in t&&t.crossModuleDeps?Object.keys(t.crossModuleDeps):[];for(let o of s)i.add(o);for(let o of r)if(i.has(o))throw new Error(`[Directive] module '${e}': fact key '${o}' conflicts with a reserved namespace pivot or evaluation alias (self / prev / current / a crossModuleDep namespace). Three fixes:
'use strict';var chunkIXRS4LM4_cjs=require('./chunk-IXRS4LM4.cjs'),chunkNPX5EKPP_cjs=require('./chunk-NPX5EKPP.cjs'),chunkENZEHIL7_cjs=require('./chunk-ENZEHIL7.cjs'),chunkT4TRJEJN_cjs=require('./chunk-T4TRJEJN.cjs'),chunkX7G7UBXU_cjs=require('./chunk-X7G7UBXU.cjs'),chunk4MNQDXH7_cjs=require('./chunk-4MNQDXH7.cjs');var C=1e6;function Me(e,t){try{chunkT4TRJEJN_cjs.l(e);}catch(r){let i=r instanceof Error?r.message:String(r);throw new Error(`[Directive] replayUnder: the ${t} predicate is invalid \u2014 ${i}`)}if(!chunkT4TRJEJN_cjs.h(e)){let r=e===null||typeof e!="object"?`${typeof e} \u2014 ${JSON.stringify(e)}`:JSON.stringify(e).slice(0,80);throw new Error(`[Directive] replayUnder: the ${t} predicate is not a valid FactPredicate (got ${r})`)}let n;if(chunkT4TRJEJN_cjs.i(e,{operator(r,i){n===void 0&&i.startsWith("$")&&!chunkT4TRJEJN_cjs.a.has(i)&&(n=i);},strayOperatorKey(r){n===void 0&&!chunkT4TRJEJN_cjs.a.has(r)&&!chunkT4TRJEJN_cjs.b.has(r)&&(n=r);}}),n!==void 0)throw new Error(`[Directive] replayUnder: the ${t} predicate uses an unknown operator "${n}" \u2014 known operators: ${[...chunkT4TRJEJN_cjs.a].join(", ")}`)}function Ae(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return De(e);let t=Array.isArray(e)?e:e&&typeof e=="object"&&Array.isArray(e.frames)?e.frames:null;if(!t)throw new Error("[Directive] toReplayFrames: history must be a JSON array of frames, an object with a `frames` array, or a history export with a `snapshots` array");if(t.length>C)throw new Error(`[Directive] toReplayFrames: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${C}) \u2014 split or down-sample the history`);return t.map((n,r)=>{if(n&&typeof n=="object"&&"facts"in n){let i=n,s={id:i.id??`#${r}`,facts:i.facts??{}};return typeof i.timestamp=="number"&&(s.timestamp=i.timestamp),s}return {id:`#${r}`,facts:n??{}}})}function De(e){let t=typeof e=="string"?JSON.parse(e):e;if(Array.isArray(t))return se(t);if(!t||typeof t!="object")throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");let n=t;if(n.version!==void 0&&n.version!==1)throw new Error(`[Directive] framesFromHistory: unsupported history export version ${JSON.stringify(n.version)} \u2014 expected 1`);if(!Array.isArray(n.snapshots))throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");return se(n.snapshots)}function se(e){if(!Array.isArray(e))throw new Error("[Directive] framesFromSnapshots: expected an array of fact-state snapshots");if(e.length>C)throw new Error(`[Directive] framesFromSnapshots: history has ${e.length} snapshots, exceeds the MAX_REPLAY_FRAMES limit (${C}) \u2014 split or down-sample the history`);for(let t=0;t<e.length;t++){let n=e[t];if(!n||typeof n!="object"||!("facts"in n))throw new Error(`[Directive] framesFromSnapshots: snapshot at index ${t} is not a { facts, ... } object`)}return Ae(e)}function H(e){let{frames:t,original:n,proposed:r,entityKey:i}=e,s=e.maxSamples??20,o=s>0?s:0;if(t.length>C)throw new Error(`[Directive] replayUnder: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${C}) \u2014 split or down-sample the history`);Me(n,"original"),Me(r,"proposed");let u=0,a=0,c=0,l=0,d=0,g=[],y=[],$=i?new Set:void 0,m=i?new Set:void 0,M;for(let F of t){let T=F.facts,v=chunkT4TRJEJN_cjs.o(n,T,M),A=chunkT4TRJEJN_cjs.o(r,T,M);v&&(u++,$?.add(T[i])),A&&(a++,m?.add(T[i])),v===A?d++:!v&&A?(c++,g.length<o&&g.push(Re(F,n,r,M))):(l++,y.length<o&&y.push(Re(F,n,r,M))),M=T;}let E={framesEvaluated:t.length,original:{matched:u},proposed:{matched:a},delta:a-u,newMatchCount:c,lostMatchCount:l,unchanged:d,newMatches:g,lostMatches:y};return $&&m&&(E.original.matchedEntities=$.size,E.proposed.matchedEntities=m.size),E}function Re(e,t,n,r){let i=e.facts,s={frameId:e.id,facts:i,originalExplain:chunkT4TRJEJN_cjs.p(t,i,r),proposedExplain:chunkT4TRJEJN_cjs.p(n,i,r)};return e.timestamp!==void 0&&(s.timestamp=e.timestamp),s}var ae=1e4,Ce=5e7;function It(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===1&&typeof e.$hole=="string"}function ue(e,t,n=new Set,r=0){if(r>chunkT4TRJEJN_cjs.g)throw new Error(`[Directive] sweepUnder: template exceeds MAX_PREDICATE_DEPTH (${chunkT4TRJEJN_cjs.g}) \u2014 flatten the template or split the sweep`);if(It(e)){let i=e.$hole;if(!(i in t))throw new Error(`[Directive] sweepUnder: template references hole "${i}" but sweep has no values for it`);return t[i]}if(e===null||typeof e!="object")return e;if(n.has(e))throw new Error("[Directive] sweepUnder: template contains a cycle \u2014 predicate templates must be a tree");n.add(e);try{if(Array.isArray(e))return e.map(s=>ue(s,t,n,r+1));let i={};for(let[s,o]of Object.entries(e))i[s]=ue(o,t,n,r+1);return i}finally{n.delete(e);}}function*Ee(e,t){if(e.length===0){yield {};return}let n=e[0],r=e.slice(1),i=t[n]??[];for(let s of i)for(let o of Ee(r,t))yield {[n]:s,...o};}function Lt(e){let t=1;for(let n of Object.values(e))t*=n.length;return t}function qt(e){let{frames:t,original:n,template:r,sweep:i,objective:s=T=>T.proposed.matched,entityKey:o,maxSamples:u=0}=e,a=Object.keys(i);if(a.length===0)throw new Error("[Directive] sweepUnder: `sweep` must contain at least one hole name");let c=Lt(i);if(c>ae)throw new Error(`[Directive] sweepUnder: grid has ${c} points, exceeds the MAX_SWEEP_POINTS limit (${ae}) \u2014 narrow the sweep ranges or split the run`);if(c===0)throw new Error("[Directive] sweepUnder: at least one hole has zero candidate values");let l=c*t.length;if(l>Ce)throw new Error(`[Directive] sweepUnder: ${c} points \xD7 ${t.length} frames = ${l} per-frame evaluations, exceeds the MAX_SWEEP_EVALUATIONS limit (${Ce}) \u2014 narrow the sweep, down-sample the history, or split the run`);let d=false,g=T=>{let v;try{v=s(T);}catch(A){return d||(d=true,console.warn(`[Directive] sweepUnder: objective threw \u2014 point will not rank (${A.message})`)),Number.NEGATIVE_INFINITY}return typeof v!="number"||!Number.isFinite(v)?(d||(d=true,console.warn(`[Directive] sweepUnder: objective returned a non-finite number (${String(v)}) \u2014 point will not rank`)),Number.NEGATIVE_INFINITY):v},y=H({frames:t,original:n,proposed:n,entityKey:o,maxSamples:u}),$={values:{},report:y,score:g(y)},m=[],M=0,E=Number.NEGATIVE_INFINITY;for(let T of Ee(a,i)){let v=ue(r,T),A=H({frames:t,original:n,proposed:v,entityKey:o,maxSamples:u}),te=g(A);te>E&&(E=te,M=m.length),m.push({values:T,report:A,score:te});}let F=m[M];return {points:m,bestIndex:M,best:F,baseline:$}}function ce(e){let t=e&&typeof e=="object"&&!Array.isArray(e)&&"constraints"in e?e.constraints:e;if(Array.isArray(t)){let n={};for(let r of t){if(!r||typeof r!="object"||!("id"in r))throw new Error("[Directive] diffRules: array entries must be `{ id, whenSpec }` objects");let i=r;if(typeof i.id!="string")throw new Error("[Directive] diffRules: constraint `id` must be a string");n[i.id]=i.whenSpec;}return n}if(t&&typeof t=="object")return t;throw new Error("[Directive] diffRules: expected a `{ id: whenSpec }` map, an array of `{ id, whenSpec }`, or `{ constraints: ... }`")}var Bt=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),Wt=new Set(["$all","$any","$not"]);function xe(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Ut(e){if(!xe(e))return false;let t=Object.keys(e);if(t.length===0)return false;let n=false;for(let r of t){if(!r.startsWith("$"))return false;Bt.has(r)&&(n=true);}return n}function S(e,t="",n=[]){if(e===null||typeof e!="object")return n;if(Array.isArray(e)){for(let r of e)if(r&&typeof r=="object"&&"fact"in r&&"op"in r){let i=r;n.push({path:t?`${t}.${String(i.fact)}`:String(i.fact),op:String(i.op),value:i.value});}return n}if("$all"in e&&Array.isArray(e.$all))return e.$all.forEach((i,s)=>{S(i,`${t}$all[${s}]`,n);}),n;if("$any"in e&&Array.isArray(e.$any))return e.$any.forEach((i,s)=>{S(i,`${t}$any[${s}]`,n);}),n;if("$not"in e)return S(e.$not,`${t}$not`,n),n;for(let[r,i]of Object.entries(e)){let s=t?`${t}.${r}`:r;if(Ut(i))for(let[o,u]of Object.entries(i))n.push({path:s,op:o,value:u});else xe(i)&&!Wt.has(r)?S(i,s,n):n.push({path:s,op:"$eq",value:i});}return n}function D(e){return typeof e=="number"&&Number.isFinite(e)}function Kt(e,t,n){switch(e){case "$gte":case "$gt":if(D(t)&&D(n)){if(n<t)return "relaxed";if(n>t)return "tightened"}return null;case "$lte":case "$lt":if(D(t)&&D(n)){if(n>t)return "relaxed";if(n<t)return "tightened"}return null;case "$between":{if(Array.isArray(t)&&Array.isArray(n)&&t.length===2&&n.length===2&&D(t[0])&&D(t[1])&&D(n[0])&&D(n[1])){let r=t[1]-t[0],i=n[1]-n[0];if(i>r)return "relaxed";if(i<r)return "tightened"}return null}case "$in":case "$nin":{if(Array.isArray(t)&&Array.isArray(n))if(e==="$in"){if(n.length>t.length)return "relaxed";if(n.length<t.length)return "tightened"}else {if(n.length>t.length)return "tightened";if(n.length<t.length)return "relaxed"}return null}case "$contains":{if(Array.isArray(t)&&Array.isArray(n)){if(n.length>t.length)return "relaxed";if(n.length<t.length)return "tightened"}return null}default:return null}}function zt(e){let t=ce(e.before),n=ce(e.after),i=[...new Set([...Object.keys(t),...Object.keys(n)])].sort(),s=[],o={added:0,removed:0,changed:0,unchanged:0,totalClauseChanges:0};for(let u of i){let a=t[u],c=n[u],l=u in t,d=u in n;if(l&&!d){let y=S(a),$=y.length===0?[{path:"(function-form predicate)",kind:"removed"}]:y.map(m=>({path:m.path,kind:"removed",before:{op:m.op,value:m.value}}));le($),s.push({id:u,status:"removed",changes:$}),o.removed++,o.totalClauseChanges+=$.length;continue}if(!l&&d){let y=S(c),$=y.length===0?[{path:"(function-form predicate)",kind:"added"}]:y.map(m=>({path:m.path,kind:"added",after:{op:m.op,value:m.value}}));le($),s.push({id:u,status:"added",changes:$}),o.added++,o.totalClauseChanges+=$.length;continue}let g=Oe(a,c);g.length===0?(s.push({id:u,status:"unchanged",changes:[]}),o.unchanged++):(s.push({id:u,status:"changed",changes:g}),o.changed++,o.totalClauseChanges+=g.length);}return {constraints:s,summary:o}}function Oe(e,t){if(e!==void 0&&t!==void 0&&(e===null||t===null||typeof e!="object"||typeof t!="object"))return chunk4MNQDXH7_cjs.e(e)===chunk4MNQDXH7_cjs.e(t)?[]:[{path:"",kind:"changed",before:{op:"$eq",value:e},after:{op:"$eq",value:t}}];let n=e===void 0?[]:S(e),r=t===void 0?[]:S(t),i=c=>`${c.path}::${c.op}`,s=new Map(n.map(c=>[i(c),c])),o=new Map(r.map(c=>[i(c),c])),u=new Set([...s.keys(),...o.keys()]),a=[];for(let c of u){let l=s.get(c),d=o.get(c);if(l&&!d){a.push({path:l.path,kind:"removed",before:{op:l.op,value:l.value}});continue}if(!l&&d){a.push({path:d.path,kind:"added",after:{op:d.op,value:d.value}});continue}if(l&&d){if(chunk4MNQDXH7_cjs.e(l.value)===chunk4MNQDXH7_cjs.e(d.value))continue;let g=Kt(l.op,l.value,d.value);a.push({path:l.path,kind:g??"changed",before:{op:l.op,value:l.value},after:{op:d.op,value:d.value}});}}return le(a),a}function le(e){e.sort((t,n)=>{let r=t.path.localeCompare(n.path);if(r!==0)return r;let i=t.before?.op??t.after?.op??"",s=n.before?.op??n.after?.op??"";return i.localeCompare(s)});}function Ht(e){return chunk4MNQDXH7_cjs.h(e)}function J(e){return e===null?"null":e===void 0?"undefined":e instanceof Date?e.toISOString():typeof e=="string"||typeof e=="object"?JSON.stringify(e):String(e)}function Jt(e){let t=e.path,n=J(e.expected),r=J(e.actual);switch(e.op){case "$eq":return `set ${t} to ${n} (currently ${r})`;case "$ne":return `change ${t} to anything other than ${n} (currently ${r})`;case "$gt":return `set ${t} above ${n} (currently ${r})`;case "$gte":return `set ${t} to at least ${n} (currently ${r})`;case "$lt":return `set ${t} below ${n} (currently ${r})`;case "$lte":return `set ${t} to at most ${n} (currently ${r})`;case "$in":return `set ${t} to one of ${n} (currently ${r})`;case "$nin":return `set ${t} to something other than ${n} (currently ${r})`;case "$exists":return e.expected===true?`set ${t} to a non-null value (currently null/missing)`:`unset ${t} (currently ${r})`;case "$between":return Array.isArray(e.expected)&&e.expected.length===2?`set ${t} between ${J(e.expected[0])} and ${J(e.expected[1])} (currently ${r})`:`set ${t} within range ${n} (currently ${r})`;case "$startsWith":return `set ${t} to start with ${n} (currently ${r})`;case "$endsWith":return `set ${t} to end with ${n} (currently ${r})`;case "$contains":return `set ${t} to contain ${n} (currently ${r})`;case "$matches":return `set ${t} to match the pattern ${n} (currently ${r})`;case "$changed":return `the previous-vs-current change of ${t} is required to differ (currently they match: ${r})`;case "$all":case "$any":case "$not":return `the ${e.op} group at "${t}" did not pass \u2014 see its child clauses`;default:return `clause at ${t} (${e.op}) failed: expected ${n}, got ${r}`}}function je(e,t){for(let n of e)if(!n.pass){if((n.op==="$all"||n.op==="$any"||n.op==="$not")&&n.children){je(n.children,t);continue}t.push({path:n.path,op:n.op,expected:n.expected,actual:n.actual,suggestion:Jt(n)});}}function Qt(e,t,n){let r=chunkT4TRJEJN_cjs.p(e,t,n),i=r.every(o=>o.pass),s=[];if(i||je(r,s),!i&&n===void 0){let o=[];chunkT4TRJEJN_cjs.i(e,{operator(u,a){a==="$changed"&&o.push(u);}});for(let u of o)s.push({path:u,op:"$changed",expected:true,actual:void 0,suggestion:`$changed clause at "${u}" cannot be evaluated without a \`prev\` snapshot \u2014 pass predict(predicate, facts, prev).`});}return {wouldFire:i,whenExplain:r,missingChanges:s}}var Pe=new Set(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$nin"]);function Q(e,t){if(e===t)return 0;if(typeof e=="number"&&typeof t=="number"||typeof e=="bigint"&&typeof t=="bigint")return e<t?-1:e>t?1:0;if(e instanceof Date&&t instanceof Date){let n=e.getTime(),r=t.getTime();return n<r?-1:n>r?1:0}return typeof e=="string"&&typeof t=="string"?e<t?-1:e>t?1:0:Number.NaN}function _(e,t){if(e===t)return true;if(typeof e!=typeof t||e===null||t===null||typeof e!="object"||Array.isArray(e)!==Array.isArray(t))return false;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return false;for(let i=0;i<e.length;i++)if(!_(e[i],t[i]))return false;return true}let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return false;for(let i of n)if(!_(e[i],t[i]))return false;return true}function Xt(e,t){if(!Pe.has(e.op)||!Pe.has(t.op))return {type:"overlap",reason:`Both rules touch "${e.path}".`};if(e.op==="$eq"&&t.op==="$eq")return _(e.value,t.value)?{type:"subset",reason:`Both rules require ${e.path} = ${JSON.stringify(e.value)} \u2014 candidate is redundant.`}:{type:"direct",reason:`Candidate requires ${e.path} = ${JSON.stringify(e.value)} but an existing rule requires ${e.path} = ${JSON.stringify(t.value)} \u2014 they cannot both fire.`};if(e.op==="$eq"&&t.op==="$ne")return _(e.value,t.value)?{type:"direct",reason:`Candidate requires ${e.path} = ${JSON.stringify(e.value)} but an existing rule excludes that value.`}:null;if(e.op==="$ne"&&t.op==="$eq")return _(e.value,t.value)?{type:"direct",reason:`Candidate excludes ${e.path} = ${JSON.stringify(e.value)} but an existing rule requires that exact value.`}:null;if(e.op==="$in"&&t.op==="$in"){let o=new Set(Array.isArray(e.value)?e.value:[]),u=new Set(Array.isArray(t.value)?t.value:[]),a=[...o].filter(c=>u.has(c));return a.length===0?{type:"direct",reason:`Candidate $in set for ${e.path} (${JSON.stringify([...o])}) and existing $in set (${JSON.stringify([...u])}) have no values in common \u2014 the candidate can never fire while the existing rule holds.`}:a.length===o.size&&a.length<u.size?{type:"subset",reason:`Candidate $in set for ${e.path} is a strict subset of the existing rule's $in set.`}:null}let n=e.op==="$gt"||e.op==="$gte"?e.value:void 0,r=e.op==="$lt"||e.op==="$lte"?e.value:void 0,i=t.op==="$gt"||t.op==="$gte"?t.value:void 0,s=t.op==="$lt"||t.op==="$lte"?t.value:void 0;if(n!==void 0&&s!==void 0){let o=Q(n,s);if(!Number.isNaN(o)&&(o>0||o===0&&(e.op==="$gt"||t.op==="$lt")))return {type:"direct",reason:`Candidate requires ${e.path} ${e.op==="$gt"?">":"\u2265"} ${JSON.stringify(n)} but an existing rule caps it at ${t.op==="$lt"?"<":"\u2264"} ${JSON.stringify(s)}.`}}if(i!==void 0&&r!==void 0){let o=Q(i,r);if(!Number.isNaN(o)&&(o>0||o===0&&(t.op==="$gt"||e.op==="$lt")))return {type:"direct",reason:`Candidate caps ${e.path} at ${e.op==="$lt"?"<":"\u2264"} ${JSON.stringify(r)} but an existing rule requires it ${t.op==="$gt"?">":"\u2265"} ${JSON.stringify(i)}.`}}if(n!==void 0&&i!==void 0){let o=Q(n,i);if(!Number.isNaN(o)&&o>0)return {type:"subset",reason:`Candidate's lower bound on ${e.path} (${JSON.stringify(n)}) is stricter than the existing rule's lower bound (${JSON.stringify(i)}) \u2014 candidate is a subset.`}}if(r!==void 0&&s!==void 0){let o=Q(r,s);if(!Number.isNaN(o)&&o<0)return {type:"subset",reason:`Candidate's upper bound on ${e.path} (${JSON.stringify(r)}) is stricter than the existing rule's upper bound (${JSON.stringify(s)}) \u2014 candidate is a subset.`}}return {type:"overlap",reason:`Both rules constrain "${e.path}".`}}function Fe(e){return typeof e=="object"&&e!==null&&typeof e.id=="string"}var Zt={checkAgainst(e,t){let n=Array.isArray(t)?t:"constraints"in t&&Array.isArray(t.constraints)?t.constraints:[],r=S(e);if(r.length===0)return {contradictions:[],warnings:[]};let i=new Map;for(let u of r){let a=i.get(u.path)??[];a.push(u),i.set(u.path,a);}let s=[],o=[];for(let u of n){if(!Fe(u)||u.whenSpec===void 0)continue;let a=S(u.whenSpec);for(let c of a){let l=i.get(c.path);if(l)for(let d of l){let g=Xt(d,c);if(!g)continue;let y={constraintId:u.id,type:g.type,reason:g.reason,candidatePath:d.path,candidate:{op:d.op,value:d.value},existing:{op:c.op,value:c.value}};g.type==="overlap"||g.type==="subset"?o.push(y):s.push(y);}}}return {contradictions:s,warnings:o}},checkOwns(e,t){let n=Array.isArray(t)?t:"constraints"in t&&Array.isArray(t.constraints)?t.constraints:[],r=S(e);if(r.length===0)return {warnings:[]};let i=new Set(r.map(o=>o.path)),s=[];for(let o of n){if(!Fe(o))continue;let u=Array.isArray(o.owns)?o.owns:[],a=Array.isArray(o.bind)?o.bind:[];for(let c of u)i.has(c)&&s.push({constraintId:o.id,candidatePath:c,source:"owns",reason:`Constraint "${o.id}" already owns "${c}" \u2014 candidate would race or shadow its writes.`,severity:"warning"});for(let c of a)i.has(c)&&s.push({constraintId:o.id,candidatePath:c,source:"bind",reason:`Constraint "${o.id}" binds "${c}" \u2014 candidate would write to a bound field.`,severity:"warning"});}return {warnings:s}}};var I=new Map,Yt=50;function Gt(e){let t=I.get(e);if(!t){try{t=new Intl.NumberFormat(e);}catch{t=new Intl.NumberFormat("en-US");}if(I.size>=Yt){let n=I.keys().next().value;n!==void 0&&I.delete(n);}I.set(e,t);}return t}function Vt(e,t={}){let n=t.style??"natural",r=t.parenthesize??true,i=t.locale??"en-US",s=t.factName??(a=>a);if(e===null||typeof e!="object")return "<invalid predicate>";let o={style:n,parenthesize:r,locale:i,factName:s,seen:new WeakSet,cycle:false},u=X(e,o,0);return o.cycle?"<invalid predicate: cycle>":u}var Ie=" AND ",en=" OR ",tn="NOT",Le=" \u2227 ",nn=" \u2228 ",rn="\xAC";function q(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function on(e){if(!q(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function X(e,t,n){if(n>chunkT4TRJEJN_cjs.g)return chunk4MNQDXH7_cjs.a&&console.warn(`[Directive] describePredicate: depth limit (${chunkT4TRJEJN_cjs.g}) exceeded \u2014 bailing.`),t.style==="formal"?"\u22A5":"always true";if(Array.isArray(e))return sn(e,t);if(!q(e))return f(e,t);if(t.seen.has(e))return t.cycle=true,"<invalid predicate: cycle>";t.seen.add(e);let r=e,i=Object.keys(r);for(let o of ["$all","$any","$not"])if(o in r)return an(o,r[o],t,n);let s=[];for(let o of i)o.startsWith("$")||s.push(qe(o,r[o],t,n));return Z(s,t)}function sn(e,t,n){let r=[];for(let i of e){if(!q(i))continue;let s=i;typeof s.fact!="string"||typeof s.op!="string"||r.push(L(s.fact,s.op,s.value,t));}return r.length===0?t.style==="formal"?"\u22A4":"always true":Z(r,t)}function an(e,t,n,r){if(e==="$not"){if(q(t)&&Object.keys(t).length===0)return n.style==="formal"?"\u22A5":"never";let o=X(t,n,r+1);return o==="always true"?"never":o==="\u22A4"?"\u22A5":`${n.style==="formal"?rn:`${tn} `}(${o})`}if(!Array.isArray(t))return n.style==="formal"?"\u22A5":"<invalid predicate>";if(t.length===0)return e==="$all"?n.style==="formal"?"\u22A4":"always true":n.style==="formal"?"\u22A5":"never";let i=[];for(let o of t){let u=X(o,n,r+1);i.push(u);}if(i.length===1)return i[0];let s=n.parenthesize?i.map(o=>`(${o})`):i;return e==="$all"?s.join(n.style==="formal"?Le:Ie):s.join(n.style==="formal"?nn:en)}function qe(e,t,n,r){if(on(t)){let i=t,s=Object.keys(i);if(s.length===1)return L(e,s[0],i[s[0]],n);let o=s.map(u=>L(e,u,i[u],n));return Z(o,n)}if(q(t)){let i=t;if("$all"in i||"$any"in i||"$not"in i)return X(t,n,r+1);let o=[];for(let u of Object.keys(i))u.startsWith("$")||o.push(qe(`${e}.${u}`,i[u],n,r+1));return o.length===0?L(e,"$eq",t,n):Z(o,n)}return L(e,"$eq",t,n)}function L(e,t,n,r){let i=r.style==="formal"?e:r.factName(e);return r.style==="formal"?cn(i,t,n,r):un(i,t,n,r)}function un(e,t,n,r){switch(t){case "$eq":return n===null?`${e} is null`:`${e} is ${f(n,r)}`;case "$ne":return n===null?`${e} is not null`:`${e} is not ${f(n,r)}`;case "$gt":return `${e} is more than ${f(n,r)}`;case "$gte":return `${e} is at least ${f(n,r)}`;case "$lt":return `${e} is less than ${f(n,r)}`;case "$lte":return `${e} is at most ${f(n,r)}`;case "$in":return `${e} is one of ${Ne(n,r)}`;case "$nin":return `${e} is not one of ${Ne(n,r)}`;case "$exists":return n===true?`${e} is set`:`${e} is not set`;case "$between":return Array.isArray(n)&&n.length===2?`${e} is between ${f(n[0],r)} and ${f(n[1],r)}`:`${e} is between ${f(n,r)}`;case "$startsWith":return `${e} starts with ${O(n,r,true)}`;case "$endsWith":return `${e} ends with ${O(n,r,true)}`;case "$contains":return `${e} contains ${O(n,r,true)}`;case "$matches":return n instanceof RegExp?`${e} matches ${n.toString()}`:`${e} matches ${f(n,r)}`;case "$changed":return `${e} changed`;default:return chunk4MNQDXH7_cjs.a&&!chunkT4TRJEJN_cjs.a.has(t)&&console.warn(`[Directive] describePredicate: unknown operator "${t}" \u2014 falling through to generic rendering.`),`${e} ${t} ${f(n,r)}`}}function cn(e,t,n,r){switch(t){case "$eq":return `${e} = ${f(n,r)}`;case "$ne":return `${e} \u2260 ${f(n,r)}`;case "$gt":return `${e} > ${f(n,r)}`;case "$gte":return `${e} \u2265 ${f(n,r)}`;case "$lt":return `${e} < ${f(n,r)}`;case "$lte":return `${e} \u2264 ${f(n,r)}`;case "$in":return `${e} \u2208 {${_e(n,r)}}`;case "$nin":return `${e} \u2209 {${_e(n,r)}}`;case "$exists":return n===true?`\u2203 ${e}`:`\u2204 ${e}`;case "$between":return Array.isArray(n)&&n.length===2?`${f(n[0],r)} \u2264 ${e} \u2264 ${f(n[1],r)}`:`${e} \u2208 [${f(n,r)}]`;case "$startsWith":return `${e} ^= ${O(n,r,true)}`;case "$endsWith":return `${e} $= ${O(n,r,true)}`;case "$contains":return `${e} \u2287 ${O(n,r,true)}`;case "$matches":return n instanceof RegExp?`${e} ~ ${n.toString()}`:`${e} ~ ${f(n,r)}`;case "$changed":return `\u0394${e}`;default:return chunk4MNQDXH7_cjs.a&&!chunkT4TRJEJN_cjs.a.has(t)&&console.warn(`[Directive] describePredicate: unknown operator "${t}" \u2014 falling through to generic rendering.`),`${e} ${t} ${f(n,r)}`}}function Y(e){return e.length===0?true:/[\s,"']/.test(e)}function O(e,t,n){return typeof e!="string"||n||Y(e)?JSON.stringify(e):e}function f(e,t){if(e===null)return "null";if(e===void 0)return "undefined";if(typeof e=="boolean")return e?"true":"false";if(typeof e=="number"){if(!Number.isFinite(e))return String(e);try{return Gt(t.locale).format(e)}catch{return String(e)}}if(typeof e=="bigint")return t.style==="formal"?`${e.toString()}n`:e.toString();if(typeof e=="string")return t.style==="formal"||Y(e)?JSON.stringify(e):e;if(e instanceof Date)return e.toISOString();if(e instanceof RegExp)return e.toString();if(Array.isArray(e))return `[${e.map(n=>f(n,t)).join(", ")}]`;if(typeof e=="object")try{return JSON.stringify(e)}catch{return "[object]"}return String(e)}function Ne(e,t){return Array.isArray(e)?e.map(n=>typeof n=="string"?Y(n)?JSON.stringify(n):n:f(n,t)).join(", "):f(e,t)}function _e(e,t){return Array.isArray(e)?e.map(n=>typeof n=="string"?Y(n)?JSON.stringify(n):n:f(n,t)).join(", "):f(e,t)}function Z(e,t){if(e.length===0)return t.style==="formal"?"\u22A4":"always true";if(e.length===1)return e[0];let n=t.style==="formal"?Le:Ie;return t.parenthesize,e.join(n)}var ln=/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)?$/;function W(e,t){if(typeof e!="string"||!ln.test(e))throw new Error(`[Directive] predicateToSQL: invalid ${t} identifier "${e}" \u2014 must match /^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)?$/`)}function Be(e,t){if(t&&!t.includes(e))throw new Error(`[Directive] predicateToSQL: column "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function dn(e){if(Array.isArray(e)){if(e.length===0)throw new Error("[Directive] predicateToSQL: select must not be empty");for(let n of e)W(n,"column");return e.join(", ")}let t=e;return t==="*"?"*":(W(t,"column"),t)}function b(e,t){return e.params.push(t),e.placeholder(e.params.length)}function de(e,t,n,r){switch(t){case "$eq":return `${e} = ${b(r,n)}`;case "$ne":return `${e} <> ${b(r,n)}`;case "$gt":return `${e} > ${b(r,n)}`;case "$gte":return `${e} >= ${b(r,n)}`;case "$lt":return `${e} < ${b(r,n)}`;case "$lte":return `${e} <= ${b(r,n)}`;case "$in":if(!Array.isArray(n))throw new Error("[Directive] predicateToSQL: $in operand must be an array");return `${e} = ANY(${b(r,n)})`;case "$nin":if(!Array.isArray(n))throw new Error("[Directive] predicateToSQL: $nin operand must be an array");return `NOT (${e} = ANY(${b(r,n)}))`;case "$exists":return n===true?`${e} IS NOT NULL`:`${e} IS NULL`;case "$between":{if(!Array.isArray(n)||n.length!==2)throw new Error("[Directive] predicateToSQL: $between operand must be a [low, high] tuple");return `${e} BETWEEN ${b(r,n[0])} AND ${b(r,n[1])}`}case "$startsWith":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $startsWith operand must be a string");return `${e} LIKE ${b(r,fe(n))} || '%' ESCAPE '\\'`;case "$endsWith":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $endsWith operand must be a string");return `${e} LIKE '%' || ${b(r,fe(n))} ESCAPE '\\'`;case "$contains":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $contains only supports string operands \u2014 array containment requires a JOIN, not a predicate");return `${e} LIKE '%' || ${b(r,fe(n))} || '%' ESCAPE '\\'`;case "$matches":{if(!(n instanceof RegExp))throw new Error("[Directive] predicateToSQL: $matches operand must be a RegExp");let i=n.flags.includes("i")?"~*":"~";return `${e} ${i} ${b(r,n.source)}`}case "$changed":throw new Error('[Directive] predicateToSQL: $changed is an effects-only operator \u2014 no server-side translation (a database row has no "prev" snapshot)');default:throw new Error(`[Directive] predicateToSQL: unknown operator "${t}" \u2014 known: ${[...chunkT4TRJEJN_cjs.a].join(", ")}`)}}function fe(e){return e.replace(/[\\%_]/g,"\\$&")}function We(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function fn(e){if(!We(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function pe(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToSQL: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function B(e,t,n){if(n>chunkT4TRJEJN_cjs.g)throw new Error(`[Directive] predicateToSQL: predicate depth limit (${chunkT4TRJEJN_cjs.g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error(`[Directive] predicateToSQL: predicate must be an object or array, got ${typeof e}`);if(Array.isArray(e)){if(e.length===0)return "TRUE";let i=e.map(s=>{if(!s||typeof s!="object"||!("fact"in s)||!("op"in s))throw new Error("[Directive] predicateToSQL: array-form clause must be { fact, op, value }");let o=s;return W(o.fact,"column"),Be(o.fact,t.allowed),de(o.fact,o.op,o.value,t)});return i.length===1?i[0]:`(${i.join(" AND ")})`}if("$all"in e){pe(e,"$all");let i=e.$all;if(!Array.isArray(i))throw new Error("[Directive] predicateToSQL: $all must be an array");if(i.length===0)return "TRUE";let s=i.map(o=>B(o,t,n+1));return s.length===1?s[0]:`(${s.join(" AND ")})`}if("$any"in e){pe(e,"$any");let i=e.$any;if(!Array.isArray(i))throw new Error("[Directive] predicateToSQL: $any must be an array");if(i.length===0)return "FALSE";let s=i.map(o=>B(o,t,n+1));return s.length===1?s[0]:`(${s.join(" OR ")})`}if("$not"in e){pe(e,"$not");let i=e.$not;return `NOT (${B(i,t,n+1)})`}let r=[];for(let[i,s]of Object.entries(e))if(W(i,"column"),Be(i,t.allowed),fn(s))for(let[o,u]of Object.entries(s)){if(!chunkT4TRJEJN_cjs.a.has(o))throw new Error(`[Directive] predicateToSQL: unknown operator "${o}" on column "${i}" \u2014 known: ${[...chunkT4TRJEJN_cjs.a].join(", ")}`);r.push(de(i,o,u,t));}else {if(We(s))throw new Error(`[Directive] predicateToSQL: nested predicate at "${i}" \u2014 cross-module / partial-match predicates have no SQL equivalent (single-table queries only in v1; pass a flat predicate or build JOIN by hand with predicateToWhere)`);r.push(de(i,"$eq",s,t));}return r.length===0?"TRUE":r.length===1?r[0]:`(${r.join(" AND ")})`}var Ue=e=>`$${e}`;function pn(e,t){let{table:n,allowedKeys:r}=t,i=t.placeholder??Ue,s=t.select??"*";W(n,"table");let o=dn(s),u={params:[],placeholder:i,allowed:r},a=B(e,u,0);return {sql:`SELECT ${o} FROM ${n} WHERE ${a}`,where:a,params:u.params}}function gn(e,t={}){let n=t.placeholder??Ue,r={params:[],placeholder:n,allowed:t.allowedKeys};return {where:B(e,r,0),params:r.params}}function ge(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function he(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function yn(e){if(!he(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}var hn=/^[A-Za-z_][A-Za-z0-9_]*$/,mn=/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;function Ke(e,t){if(typeof e!="string"||e.length===0)throw new Error(`[Directive] predicateToMongo: field name must be a non-empty string, got ${typeof e}`);if(e.startsWith("$"))throw new Error(`[Directive] predicateToMongo: field name "${e}" starts with "$" \u2014 reserved for Mongo operators (a top-level $where would be an injection vector)`);if(!(t.allowDottedPaths?mn:hn).test(e))throw new Error(`[Directive] predicateToMongo: invalid field name "${e}"${t.allowDottedPaths?"":' \u2014 pass options.allowDottedPaths=true to permit sub-document paths like "user.role"'}`)}function ze(e,t){if(t&&!t.includes(e))throw new Error(`[Directive] predicateToMongo: field "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function ye(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToMongo: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function He(e,t){switch(e){case "$eq":case "$ne":case "$gt":case "$gte":case "$lt":case "$lte":case "$in":case "$nin":case "$exists":return {[e]:t};case "$between":{if(!Array.isArray(t)||t.length!==2)throw new Error("[Directive] predicateToMongo: $between operand must be a [low, high] tuple");return {$gte:t[0],$lte:t[1]}}case "$startsWith":if(typeof t!="string")throw new Error("[Directive] predicateToMongo: $startsWith operand must be a string");return {$regex:`^${ge(t)}`};case "$endsWith":if(typeof t!="string")throw new Error("[Directive] predicateToMongo: $endsWith operand must be a string");return {$regex:`${ge(t)}$`};case "$contains":if(typeof t=="string")return {$regex:ge(t)};throw new Error("[Directive] predicateToMongo: $contains in Mongo expects a string operand \u2014 for array element membership use $elemMatch or $in directly");case "$matches":{if(t instanceof RegExp)return t.flags?{$regex:t.source,$options:t.flags}:{$regex:t.source};if(typeof t=="string")return {$regex:t};throw new Error("[Directive] predicateToMongo: $matches operand must be a RegExp or string")}case "$changed":throw new Error("[Directive] predicateToMongo: $changed is an effects-only operator \u2014 no MongoDB query equivalent");default:throw new Error(`[Directive] predicateToMongo: unknown operator "${e}" \u2014 known: ${[...chunkT4TRJEJN_cjs.a].join(", ")}`)}}function j(e,t,n){if(n>chunkT4TRJEJN_cjs.g)throw new Error(`[Directive] predicateToMongo: predicate depth limit (${chunkT4TRJEJN_cjs.g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error(`[Directive] predicateToMongo: predicate must be an object or array, got ${typeof e}`);if(Array.isArray(e)){if(e.length===0)return {};let i={},s=[];for(let o of e){if(!o||typeof o!="object"||!("fact"in o)||!("op"in o))throw new Error("[Directive] predicateToMongo: array-form clause must be { fact, op, value }");let u=o;Ke(u.fact,t),ze(u.fact,t.allowedKeys);let a=He(u.op,u.value);if(u.fact in i&&he(i[u.fact])){let c=i[u.fact];Object.keys(a).some(d=>d in c)?s.push({[u.fact]:a}):i[u.fact]={...c,...a};}else u.fact in i?s.push({[u.fact]:a}):i[u.fact]=a;}if(s.length>0){let o=[];for(let[u,a]of Object.entries(i))o.push({[u]:a});return o.push(...s),{$and:o}}return i}if("$all"in e){ye(e,"$all");let i=e.$all;if(!Array.isArray(i))throw new Error("[Directive] predicateToMongo: $all must be an array");return i.length===0?{}:i.length===1?j(i[0],t,n+1):{$and:i.map(s=>j(s,t,n+1))}}if("$any"in e){ye(e,"$any");let i=e.$any;if(!Array.isArray(i))throw new Error("[Directive] predicateToMongo: $any must be an array");return i.length===0?{$expr:{$eq:[1,0]}}:i.length===1?j(i[0],t,n+1):{$or:i.map(s=>j(s,t,n+1))}}if("$not"in e){ye(e,"$not");let i=e.$not;return {$nor:[j(i,t,n+1)]}}let r={};for(let[i,s]of Object.entries(e))if(Ke(i,t),ze(i,t.allowedKeys),yn(s)){let o={};for(let[u,a]of Object.entries(s)){if(!chunkT4TRJEJN_cjs.a.has(u))throw new Error(`[Directive] predicateToMongo: unknown operator "${u}" on field "${i}" \u2014 known: ${[...chunkT4TRJEJN_cjs.a].join(", ")}`);Object.assign(o,He(u,a));}r[i]=o;}else r[i]=s;return r}function $n(e,t={}){return j(e,t,0)}var wn=/^[A-Za-z_][A-Za-z0-9_]*$/;function Je(e,t){if(typeof e!="string"||!wn.test(e))throw new Error(`[Directive] predicateToPostgrest: invalid column identifier "${e}"`);if(t&&!t.includes(e))throw new Error(`[Directive] predicateToPostgrest: column "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function me(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToPostgrest: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function k(e){if(e==null)return "null";if(typeof e=="boolean")return e?"true":"false";if(typeof e=="number"||typeof e=="bigint")return String(e);if(e instanceof Date)return e.toISOString();if(typeof e=="string")return /[,.():"\\\s]/.test(e)?`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:e;throw new Error(`[Directive] predicateToPostgrest: cannot encode value of type ${typeof e}`)}function Qe(e){return `(${e.map(k).join(",")})`}function $e(e){return e.replace(/[\\%_*]/g,"\\$&")}function P(e,t){switch(e){case "$eq":return `eq.${k(t)}`;case "$ne":return `neq.${k(t)}`;case "$gt":return `gt.${k(t)}`;case "$gte":return `gte.${k(t)}`;case "$lt":return `lt.${k(t)}`;case "$lte":return `lte.${k(t)}`;case "$in":if(!Array.isArray(t))throw new Error("[Directive] predicateToPostgrest: $in operand must be an array");return `in.${Qe(t)}`;case "$nin":if(!Array.isArray(t))throw new Error("[Directive] predicateToPostgrest: $nin operand must be an array");return `not.in.${Qe(t)}`;case "$exists":return t===true?"not.is.null":"is.null";case "$startsWith":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $startsWith operand must be a string");return `like.${k($e(t)+"*")}`;case "$endsWith":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $endsWith operand must be a string");return `like.${k("*"+$e(t))}`;case "$contains":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $contains expects a string operand (array containment is the cs operator with a different shape \u2014 out of scope for v1)");return `like.${k("*"+$e(t)+"*")}`;case "$matches":if(t instanceof RegExp)return `${t.flags.includes("i")?"imatch":"match"}.${k(t.source)}`;if(typeof t=="string")return `match.${k(t)}`;throw new Error("[Directive] predicateToPostgrest: $matches operand must be a RegExp or string");case "$changed":throw new Error("[Directive] predicateToPostgrest: $changed is an effects-only operator \u2014 no server query equivalent");default:throw new Error(`[Directive] predicateToPostgrest: unknown operator "${e}" \u2014 known: ${[...chunkT4TRJEJN_cjs.a].join(", ")}`)}}function Xe(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function bn(e){if(!Xe(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function we(e,t){return `${e}=${t}`}function G(e,t){return `${e}=(${t.join(",")})`}function be(e,t,n,r){if(t==="$between"){if(!Array.isArray(n)||n.length!==2)throw new Error("[Directive] predicateToPostgrest: $between operand must be a [low, high] tuple");let i=r?we(e,P("$gte",n[0])):`${e}.${P("$gte",n[0])}`,s=r?we(e,P("$lte",n[1])):`${e}.${P("$lte",n[1])}`;return [i,s]}return [r?we(e,P(t,n)):`${e}.${P(t,n)}`]}function U(e,t,n,r){if(r>chunkT4TRJEJN_cjs.g)throw new Error(`[Directive] predicateToPostgrest: predicate depth limit (${chunkT4TRJEJN_cjs.g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error("[Directive] predicateToPostgrest: predicate must be an object or array");if(Array.isArray(e)){let s=[];for(let o of e){if(!o||typeof o!="object"||!("fact"in o)||!("op"in o))throw new Error("[Directive] predicateToPostgrest: array-form clause must be { fact, op, value }");let u=o;Je(u.fact,t),s.push(...be(u.fact,u.op,u.value,n));}return s}if("$all"in e){me(e,"$all");let s=e.$all;if(!Array.isArray(s))throw new Error("[Directive] predicateToPostgrest: $all must be an array");if(n){let u=[];for(let a of s)u.push(...U(a,t,true,r+1));return u}let o=[];for(let u of s)o.push(...U(u,t,false,r+1));return [G("and",o)]}if("$any"in e){me(e,"$any");let s=e.$any;if(!Array.isArray(s))throw new Error("[Directive] predicateToPostgrest: $any must be an array");if(s.length===0)return n?["id=is.null","id=not.is.null"]:[G("and",["id.is.null","id.not.is.null"])];let o=[];for(let u of s)o.push(...U(u,t,false,r+1));return [G("or",o)]}if("$not"in e){me(e,"$not");let s=e.$not,o=U(s,t,false,r+1);return [G("not.and",o)]}let i=[];for(let[s,o]of Object.entries(e))if(Je(s,t),bn(o))for(let[u,a]of Object.entries(o)){if(!chunkT4TRJEJN_cjs.a.has(u))throw new Error(`[Directive] predicateToPostgrest: unknown operator "${u}" on column "${s}" \u2014 known: ${[...chunkT4TRJEJN_cjs.a].join(", ")}`);i.push(...be(s,u,a,n));}else {if(Xe(o))throw new Error(`[Directive] predicateToPostgrest: nested predicate at "${s}" \u2014 single-table queries only`);i.push(...be(s,"$eq",o,n));}return i}function Sn(e){let t=e.indexOf("=");if(t<0)return encodeURIComponent(e);let n=e.slice(0,t),r=e.slice(t+1);return `${n}=${encodeURIComponent(r)}`}function Tn(e,t={}){let n=t.mode??"querystring",r=U(e,t.allowedKeys,true,0);return r.length===0?"":n==="raw"?r.join("&"):r.map(Sn).join("&")}function V(e=[],t,n,r,i,s,o){return {_type:void 0,_validators:e,_typeName:t,_default:n,_transform:r,_description:i,_refinements:s,_meta:o,validate(u){return V([...e,u],t,n,r,i,s,o)}}}function p(e,t,n,r,i,s,o){return {...V(e,t,n,r,i,s,o),default(a){return p(e,t,a,r,i,s,o)},transform(a){return p([],t,void 0,l=>{let d=r?r(l):l;return a(d)},i,void 0,o)},brand(){return p(e,`Branded<${t}>`,n,r,i,s,o)},describe(a){return p(e,t,n,r,a,s,o)},refine(a,c){let l=[...s??[],{predicate:a,message:c}];return p([...e,a],t,n,r,i,l,o)},nullable(){return p([a=>a===null||e.every(c=>c(a))],`${t} | null`,n,r,i,void 0,o)},optional(){return p([a=>a===void 0||e.every(c=>c(a))],`${t} | undefined`,n,r,i,void 0,o)},meta(a){return p(e,t,n,r,i,s,a)}}}var kn=((...e)=>{if(e.length===0)return p([],"union");let t=e.map(n=>n._typeName??"unknown");return p([n=>e.some(r=>r._validators.every(i=>i(n)))],t.join(" | "))}),vn={string(){let e=(t,n,r,i,s,o)=>({...p(t,"string",n,r,i,s,o),minLength(a){return e([...t,c=>c.length>=a],n,r,i,s,o)},maxLength(a){return e([...t,c=>c.length<=a],n,r,i,s,o)},pattern(a){return e([...t,c=>a.test(c)],n,r,i,s,o)},default(a){return e(t,a,r,i,s,o)},describe(a){return e(t,n,r,a,s,o)},refine(a,c){let l=[...s??[],{predicate:a,message:c}];return e([...t,a],n,r,i,l,o)},meta(a){return e(t,n,r,i,s,a)}});return e([t=>typeof t=="string"])},number(){let e=(t,n,r,i,s,o)=>({...p(t,"number",n,r,i,s,o),min(a){return e([...t,c=>c>=a],n,r,i,s,o)},max(a){return e([...t,c=>c<=a],n,r,i,s,o)},default(a){return e(t,a,r,i,s,o)},describe(a){return e(t,n,r,a,s,o)},refine(a,c){let l=[...s??[],{predicate:a,message:c}];return e([...t,a],n,r,i,l,o)},meta(a){return e(t,n,r,i,s,a)}});return e([t=>typeof t=="number"])},boolean(){return p([e=>typeof e=="boolean"],"boolean")},array(){let e=(t,n,r,i,s,o)=>{let u=p(t,"array",r,void 0,i,void 0,o),a=s??{value:-1};return {...u,get _lastFailedIndex(){return a.value},set _lastFailedIndex(l){a.value=l;},of(l){let d={value:-1};return e([...t,g=>{for(let y=0;y<g.length;y++)if(!l._validators.every($=>$(g[y])))return d.value=y,false;return true}],l,r,i,d,o)},nonEmpty(){return e([...t,l=>l.length>0],n,r,i,a,o)},maxLength(l){return e([...t,d=>d.length<=l],n,r,i,a,o)},minLength(l){return e([...t,d=>d.length>=l],n,r,i,a,o)},default(l){return e(t,n,l,i,a,o)},describe(l){return e(t,n,r,l,a,o)},meta(l){return e(t,n,r,i,a,l)}}};return e([t=>Array.isArray(t)])},object(){let e=(t,n,r,i)=>({...p(t,"object",n,void 0,r,void 0,i),shape(o){return e([...t,u=>{for(let[a,c]of Object.entries(o)){let l=u[a],d=c;if(d&&!d._validators.every(g=>g(l)))return false}return true}],n,r,i)},nonNull(){return e([...t,o=>o!=null],n,r,i)},hasKeys(...o){return e([...t,u=>o.every(a=>a in u)],n,r,i)},default(o){return e(t,o,r,i)},describe(o){return e(t,n,o,i)},meta(o){return e(t,n,r,o)}});return e([t=>typeof t=="object"&&t!==null&&!Array.isArray(t)])},enum(...e){chunk4MNQDXH7_cjs.a&&e.length===0&&console.warn("[Directive] t.enum() called with no values - this will reject all strings");let t=new Set(e);return p([n=>typeof n=="string"&&t.has(n)],`enum(${e.join("|")})`)},literal(e){return p([t=>t===e],`literal(${String(e)})`)},nullable(e){let t=e._typeName??"unknown";return V([n=>n===null?true:e._validators.every(r=>r(n))],`${t} | null`)},optional(e){let t=e._typeName??"unknown";return V([n=>n===void 0?true:e._validators.every(r=>r(n))],`${t} | undefined`)},union:kn,record(e){let t=e._typeName??"unknown";return p([n=>typeof n!="object"||n===null||Array.isArray(n)?false:Object.values(n).every(r=>e._validators.every(i=>i(r)))],`Record<string, ${t}>`)},tuple(...e){chunk4MNQDXH7_cjs.a&&e.length===0&&console.warn("[Directive] t.tuple() called with no types - this will only accept empty arrays");let t=e.map(n=>n._typeName??"unknown");return p([n=>!Array.isArray(n)||n.length!==e.length?false:e.every((r,i)=>r._validators.every(s=>s(n[i])))],`[${t.join(", ")}]`)},date(){return p([e=>e instanceof Date&&!Number.isNaN(e.getTime())],"Date")},uuid(){let e=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;return p([t=>typeof t=="string"&&e.test(t)],"uuid")},email(){let e=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;return p([t=>typeof t=="string"&&e.test(t)],"email")},url(){return p([e=>{if(typeof e!="string")return false;try{return new URL(e),!0}catch{return false}}],"url")},bigint(){return p([e=>typeof e=="bigint"],"bigint")},any(){return p([],"any")},unknown(){return p([],"unknown")}};function Mn(e){if(!e||typeof e!="string"){console.warn("[Directive] Module ID must be a non-empty string");return}/^(__[a-z][a-z0-9_-]*|[a-z][a-z0-9-]*)$/i.test(e)||console.warn(`[Directive] Module ID "${e}" should follow kebab-case convention (e.g., "my-module")`);}function Ze(e,t,n,r,i){for(let s of e)t.has(s)||console.warn(`[Directive] ${n} "${s}" not declared in ${r}`);for(let s of t)e.has(s)||console.warn(`[Directive] ${r}["${s}"] ${i}`);}function Rn(e,t){e.length===0&&console.warn("[Directive] history.snapshotEvents is an empty array \u2014 no events will create history snapshots. Omit history.snapshotEvents entirely to snapshot all events, or list specific events.");let n=new Set(Object.keys(t));for(let r of e)n.has(r)||console.warn(`[Directive] history.snapshotEvents entry "${r}" not declared in schema.events. Available events: ${[...n].join(", ")||"(none)"}`);}function An(e,t){let n=new Set(Object.keys(t));for(let[r,i]of Object.entries(e)){let s=i;typeof s.requirement=="string"&&!n.has(s.requirement)&&console.warn(`[Directive] Resolver "${r}" references unknown requirement type "${s.requirement}". Available types: ${[...n].join(", ")||"(none)"}`);}}function Dn(e,t){let n=t.schema?.facts??{},r=Object.keys(n);if(r.length===0)return;let i=new Set(["self","prev","current"]),s="crossModuleDeps"in t&&t.crossModuleDeps?Object.keys(t.crossModuleDeps):[];for(let o of s)i.add(o);for(let o of r)if(i.has(o))throw new Error(`[Directive] module '${e}': fact key '${o}' conflicts with a reserved namespace pivot or evaluation alias (self / prev / current / a crossModuleDep namespace). Three fixes:
1. Rename the fact (e.g. ${o}_)
2. Remove '${o}' from this module's crossModuleDeps if it's not actually needed
3. Move the fact under a wrapping namespace (t.object({ inner: ... }))`)}function tn(e,t){let n=t.constraints;if(n)for(let[r,i]of Object.entries(n)){let s=i?.owns;if(s){for(let o of s)if(chunkN4KTCKOI_cjs.l.has(o)||o.startsWith("$"))throw new Error(`[Directive] module '${e}' constraint '${r}': owns key '${o}' is reserved (BLOCKED_PROPS or $-prefixed)`)}}}function nn(e,t){Yt(e),t.schema?t.schema.facts||console.warn("[Directive] Module schema.facts is required"):console.warn("[Directive] Module schema is required"),Fe(new Set(Object.keys(t.derive??{})),new Set(Object.keys(t.schema?.derivations??{})),"Derivation","schema.derivations","has no matching implementation in derive"),Fe(new Set(Object.keys(t.events??{})),new Set(Object.keys(t.schema?.events??{})),"Event","schema.events","has no matching handler in events"),t.history?.snapshotEvents&&Gt(t.history.snapshotEvents,t.schema?.events??{}),t.resolvers&&t.schema?.requirements&&Vt(t.resolvers,t.schema.requirements);}function _e(e,t){en(e,t),tn(e,t),chunkN4KTCKOI_cjs.a&&nn(e,t);let n="crossModuleDeps"in t?t.crossModuleDeps:void 0;return {id:e,schema:t.schema,init:t.init,derive:t.derive??{},events:t.events??{},effects:t.effects,constraints:t.constraints,resolvers:t.resolvers,hooks:t.hooks,meta:t.meta,history:t.history,crossModuleDeps:n}}function rn(e){return t=>_e(t,e)}function de(){let e={pending:new Map,inflight:new Map,failed:new Map,errors:new Map,listeners:new Set};function t(){for(let a of e.listeners)a();}function n(a,u){let l=a.get(u);return l||(l=new Set,a.set(u,l)),l}function r(a){let u=e.pending.get(a)??new Set,l=e.inflight.get(a)??new Set,d=e.failed.get(a)??new Set,f=e.errors.get(a)??null;return {pending:u.size,inflight:l.size,failed:d.size,isLoading:u.size>0||l.size>0,hasError:d.size>0,lastError:f}}function i(){let a=new Set([...e.pending.keys(),...e.inflight.keys(),...e.failed.keys()]),u=new Map;for(let l of a)u.set(l,r(l));return u}function s(a){return e.listeners.add(a),()=>e.listeners.delete(a)}function o(){e.pending.clear(),e.inflight.clear(),e.failed.clear(),e.errors.clear(),t();}return {plugin:{name:"requirement-status",onRequirementCreated(a){let u=a.requirement.type;n(e.pending,u).add(a.id),e.failed.get(u)?.delete(a.id),t();},onResolverStart(a,u){let l=u.requirement.type;e.pending.get(l)?.delete(u.id),n(e.inflight,l).add(u.id),t();},onResolverComplete(a,u){let l=u.requirement.type;e.inflight.get(l)?.delete(u.id),e.pending.get(l)?.delete(u.id),t();},onResolverError(a,u,l){let d=u.requirement.type;e.inflight.get(d)?.delete(u.id),n(e.failed,d).add(u.id),e.errors.set(d,l instanceof Error?l:new Error(String(l))),t();},onResolverCancel(a,u){let l=u.requirement.type;e.pending.get(l)?.delete(u.id),e.inflight.get(l)?.delete(u.id),t();},onRequirementMet(a){let u=a.requirement.type;e.pending.get(u)?.delete(a.id),e.inflight.get(u)?.delete(a.id),t();}},getStatus:r,getAllStatus:i,subscribe:s,reset:o}}function on(e){return t=>e.getStatus(t)}function sn(e){let t=de(),r=[...e.plugins??[],t.plugin];return {system:chunkEX3XG667_cjs.a({module:e.module,plugins:r,trace:e.trace,errorBoundary:e.errorBoundary,tickMs:e.tickMs,zeroConfig:e.zeroConfig,initialFacts:e.initialFacts}),statusPlugin:t}}function Ne(){return {now:()=>Date.now(),setTimeout:(e,t)=>{let n=globalThis.setTimeout(e,t);return ()=>globalThis.clearTimeout(n)}}}function an(e=0){let t=e,n=0,r=[];return {now:()=>t,setTimeout:(i,s)=>{let o={id:n++,deadlineMs:t+s,cb:i,canceled:false};return r.push(o),()=>{o.canceled=true;}},advanceBy:i=>{let s=t+i;for(;;){let o=r.filter(a=>!a.canceled&&a.deadlineMs<=s).sort((a,u)=>a.deadlineMs!==u.deadlineMs?a.deadlineMs-u.deadlineMs:a.id-u.id);if(o.length===0)break;let c=o[0];t=Math.max(t,c.deadlineMs),c.canceled=true,c.cb();}t=Math.max(t,s);}}}function un(){return Ne()}function pe(){return {startedAtMs:null,pausedDurationMs:0,pausedAtMs:null,status:"idle",repeats:0}}function z(e,t){return e.startedAtMs===null?0:e.status==="paused"&&e.pausedAtMs!==null?Math.max(0,e.pausedAtMs-e.startedAtMs-e.pausedDurationMs):Math.max(0,t-e.startedAtMs-e.pausedDurationMs)}function qe(e,t,n){return Math.max(0,n-z(e,t))}function Ie(e,t){return e.status==="running"||e.status==="paused"?e:{...e,startedAtMs:t,pausedDurationMs:0,pausedAtMs:null,status:"running",repeats:0}}function Le(e,t){return e.status!=="running"?e:{...e,pausedAtMs:t,status:"paused"}}function Be(e,t){if(e.status!=="paused"||e.pausedAtMs===null)return e;let n=Math.max(0,t-e.pausedAtMs);return {...e,pausedDurationMs:e.pausedDurationMs+n,pausedAtMs:null,status:"running"}}function We(){return pe()}function Ke(e){return {...e,status:"completed"}}function Ue(e,t){return e.startedAtMs===null||e.status==="paused"?e:{...e,startedAtMs:e.startedAtMs+t,pausedDurationMs:0,pausedAtMs:null,repeats:e.repeats+1}}function ze(e,t,n){if(e.status!=="running")return {kind:"no-op"};let r=z(e,t);return n.mode==="up"?{kind:"no-op"}:n.mode==="repeat"?r>=n.ms?{kind:"repeat"}:{kind:"no-op"}:r>=n.ms?{kind:"complete"}:{kind:"no-op"}}function cn(e){return {initial:pe,start:Ie,pause:Le,resume:Be,reset:We,complete:Ke,registerRepeat:t=>Ue(t,e.ms),tick:(t,n)=>ze(t,n,e),elapsedMs:z,remainingMs:(t,n)=>qe(t,n,e.ms)}}var Wn={None:"none",Linear:"linear",Exponential:"exponential"};Object.defineProperty(exports,"createAuditLedger",{enumerable:true,get:function(){return chunk4VZOZWXM_cjs.b}});Object.defineProperty(exports,"memorySink",{enumerable:true,get:function(){return chunk4VZOZWXM_cjs.a}});Object.defineProperty(exports,"createSystem",{enumerable:true,get:function(){return chunkEX3XG667_cjs.a}});Object.defineProperty(exports,"DirectiveError",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.v}});Object.defineProperty(exports,"RequirementSet",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.I}});Object.defineProperty(exports,"applyPatch",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.t}});Object.defineProperty(exports,"evaluateKeySelector",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.s}});Object.defineProperty(exports,"evaluatePredicate",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.m}});Object.defineProperty(exports,"evaluatePredicateExplained",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.n}});Object.defineProperty(exports,"evaluateTemplate",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.q}});Object.defineProperty(exports,"extractDeps",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.p}});Object.defineProperty(exports,"extractTemplateKeys",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.r}});Object.defineProperty(exports,"forType",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.H}});Object.defineProperty(exports,"generateRequirementId",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.E}});Object.defineProperty(exports,"getKind",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.c}});Object.defineProperty(exports,"getOperatorsForKind",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.e}});Object.defineProperty(exports,"getSchemaFieldKinds",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.d}});Object.defineProperty(exports,"isNamespacedSystem",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.B}});Object.defineProperty(exports,"isPredicate",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.h}});Object.defineProperty(exports,"isRequirementType",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.G}});Object.defineProperty(exports,"isSingleModuleSystem",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.A}});Object.defineProperty(exports,"isTemplate",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.j}});Object.defineProperty(exports,"listAllPredicateOperators",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.f}});Object.defineProperty(exports,"memoizePredicate",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.o}});Object.defineProperty(exports,"req",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.F}});Object.defineProperty(exports,"typedConstraint",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.y}});Object.defineProperty(exports,"typedResolver",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.z}});Object.defineProperty(exports,"validatePredicate",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.k}});Object.defineProperty(exports,"validatePredicateAgainstSchema",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.l}});Object.defineProperty(exports,"diffSnapshots",{enumerable:true,get:function(){return chunkEOLY64E6_cjs.j}});Object.defineProperty(exports,"isSignedSnapshot",{enumerable:true,get:function(){return chunkEOLY64E6_cjs.k}});Object.defineProperty(exports,"isSnapshotExpired",{enumerable:true,get:function(){return chunkEOLY64E6_cjs.h}});Object.defineProperty(exports,"shallowEqual",{enumerable:true,get:function(){return chunkEOLY64E6_cjs.f}});Object.defineProperty(exports,"signSnapshot",{enumerable:true,get:function(){return chunkEOLY64E6_cjs.l}});Object.defineProperty(exports,"validateSnapshot",{enumerable:true,get:function(){return chunkEOLY64E6_cjs.i}});Object.defineProperty(exports,"verifySnapshotSignature",{enumerable:true,get:function(){return chunkEOLY64E6_cjs.m}});exports.Backoff=Wn;exports.MAX_REPLAY_FRAMES=R;exports.MAX_SWEEP_POINTS=Y;exports.completeTimer=Ke;exports.createModule=_e;exports.createModuleFactory=rn;exports.createRequirementStatusPlugin=de;exports.createStatusHook=on;exports.createSystemWithStatus=sn;exports.defaultClock=un;exports.diffClauses=ve;exports.diffRules=At;exports.doctor=Ft;exports.elapsedMs=z;exports.flattenPredicate=T;exports.framesFromHistory=$e;exports.framesFromSnapshots=X;exports.initialTimerState=pe;exports.pauseTimer=Le;exports.predicateToMongo=Ut;exports.predicateToPostgrest=Jt;exports.predicateToSQL=It;exports.predicateToWhere=Lt;exports.predict=Pt;exports.realClock=Ne;exports.registerRepeat=Ue;exports.remainingMs=qe;exports.replayUnder=L;exports.resetTimer=We;exports.resumeTimer=Be;exports.startTimer=Ie;exports.sweepUnder=Mt;exports.t=Xt;exports.tickTimer=ze;exports.timerOps=cn;exports.toReplayFrames=we;exports.toRulesMap=V;exports.virtualClock=an;//# sourceMappingURL=index.cjs.map
3. Move the fact under a wrapping namespace (t.object({ inner: ... }))`)}function Cn(e,t){let n=t.constraints;if(n)for(let[r,i]of Object.entries(n)){let s=i?.owns;if(s){for(let o of s)if(chunkX7G7UBXU_cjs.k.has(o)||o.startsWith("$"))throw new Error(`[Directive] module '${e}' constraint '${r}': owns key '${o}' is reserved (BLOCKED_PROPS or $-prefixed)`)}}}function En(e,t){Mn(e),t.schema?t.schema.facts||console.warn("[Directive] Module schema.facts is required"):console.warn("[Directive] Module schema is required"),Ze(new Set(Object.keys(t.derive??{})),new Set(Object.keys(t.schema?.derivations??{})),"Derivation","schema.derivations","has no matching implementation in derive"),Ze(new Set(Object.keys(t.events??{})),new Set(Object.keys(t.schema?.events??{})),"Event","schema.events","has no matching handler in events"),t.history?.snapshotEvents&&Rn(t.history.snapshotEvents,t.schema?.events??{}),t.resolvers&&t.schema?.requirements&&An(t.resolvers,t.schema.requirements);}function Ye(e,t){Dn(e,t),Cn(e,t),chunk4MNQDXH7_cjs.a&&En(e,t);let n="crossModuleDeps"in t?t.crossModuleDeps:void 0;return {id:e,schema:t.schema,init:t.init,derive:t.derive??{},events:t.events??{},effects:t.effects,constraints:t.constraints,resolvers:t.resolvers,hooks:t.hooks,meta:t.meta,history:t.history,crossModuleDeps:n}}function xn(e){return t=>Ye(t,e)}function Se(){let e={pending:new Map,inflight:new Map,failed:new Map,errors:new Map,listeners:new Set};function t(){for(let a of e.listeners)a();}function n(a,c){let l=a.get(c);return l||(l=new Set,a.set(c,l)),l}function r(a){let c=e.pending.get(a)??new Set,l=e.inflight.get(a)??new Set,d=e.failed.get(a)??new Set,g=e.errors.get(a)??null;return {pending:c.size,inflight:l.size,failed:d.size,isLoading:c.size>0||l.size>0,hasError:d.size>0,lastError:g}}function i(){let a=new Set([...e.pending.keys(),...e.inflight.keys(),...e.failed.keys()]),c=new Map;for(let l of a)c.set(l,r(l));return c}function s(a){return e.listeners.add(a),()=>e.listeners.delete(a)}function o(){e.pending.clear(),e.inflight.clear(),e.failed.clear(),e.errors.clear(),t();}return {plugin:{name:"requirement-status",onRequirementCreated(a){let c=a.requirement.type;n(e.pending,c).add(a.id),e.failed.get(c)?.delete(a.id),t();},onResolverStart(a,c){let l=c.requirement.type;e.pending.get(l)?.delete(c.id),n(e.inflight,l).add(c.id),t();},onResolverComplete(a,c){let l=c.requirement.type;e.inflight.get(l)?.delete(c.id),e.pending.get(l)?.delete(c.id),t();},onResolverError(a,c,l){let d=c.requirement.type;e.inflight.get(d)?.delete(c.id),n(e.failed,d).add(c.id),e.errors.set(d,l instanceof Error?l:new Error(String(l))),t();},onResolverCancel(a,c){let l=c.requirement.type;e.pending.get(l)?.delete(c.id),e.inflight.get(l)?.delete(c.id),t();},onRequirementMet(a){let c=a.requirement.type;e.pending.get(c)?.delete(a.id),e.inflight.get(c)?.delete(a.id),t();}},getStatus:r,getAllStatus:i,subscribe:s,reset:o}}function On(e){return t=>e.getStatus(t)}function jn(e){let t=Se(),r=[...e.plugins??[],t.plugin];return {system:chunkNPX5EKPP_cjs.a({module:e.module,plugins:r,trace:e.trace,errorBoundary:e.errorBoundary,tickMs:e.tickMs,zeroConfig:e.zeroConfig,initialFacts:e.initialFacts}),statusPlugin:t}}function Ge(){return {now:()=>Date.now(),setTimeout:(e,t)=>{let n=globalThis.setTimeout(e,t);return ()=>globalThis.clearTimeout(n)}}}function Pn(e=0){let t=e,n=0,r=[];return {now:()=>t,setTimeout:(i,s)=>{let o={id:n++,deadlineMs:t+s,cb:i,canceled:false};return r.push(o),()=>{o.canceled=true;}},advanceBy:i=>{let s=t+i;for(;;){let o=r.filter(a=>!a.canceled&&a.deadlineMs<=s).sort((a,c)=>a.deadlineMs!==c.deadlineMs?a.deadlineMs-c.deadlineMs:a.id-c.id);if(o.length===0)break;let u=o[0];t=Math.max(t,u.deadlineMs),u.canceled=true,u.cb();}t=Math.max(t,s);}}}function Fn(){return Ge()}function Te(){return {startedAtMs:null,pausedDurationMs:0,pausedAtMs:null,status:"idle",repeats:0}}function ee(e,t){return e.startedAtMs===null?0:e.status==="paused"&&e.pausedAtMs!==null?Math.max(0,e.pausedAtMs-e.startedAtMs-e.pausedDurationMs):Math.max(0,t-e.startedAtMs-e.pausedDurationMs)}function Ve(e,t,n){return Math.max(0,n-ee(e,t))}function et(e,t){return e.status==="running"||e.status==="paused"?e:{...e,startedAtMs:t,pausedDurationMs:0,pausedAtMs:null,status:"running",repeats:0}}function tt(e,t){return e.status!=="running"?e:{...e,pausedAtMs:t,status:"paused"}}function nt(e,t){if(e.status!=="paused"||e.pausedAtMs===null)return e;let n=Math.max(0,t-e.pausedAtMs);return {...e,pausedDurationMs:e.pausedDurationMs+n,pausedAtMs:null,status:"running"}}function rt(){return Te()}function it(e){return {...e,status:"completed"}}function ot(e,t){return e.startedAtMs===null||e.status==="paused"?e:{...e,startedAtMs:e.startedAtMs+t,pausedDurationMs:0,pausedAtMs:null,repeats:e.repeats+1}}function st(e,t,n){if(e.status!=="running")return {kind:"no-op"};let r=ee(e,t);return n.mode==="up"?{kind:"no-op"}:n.mode==="repeat"?r>=n.ms?{kind:"repeat"}:{kind:"no-op"}:r>=n.ms?{kind:"complete"}:{kind:"no-op"}}function Nn(e){return {initial:Te,start:et,pause:tt,resume:nt,reset:rt,complete:it,registerRepeat:t=>ot(t,e.ms),tick:(t,n)=>st(t,n,e),elapsedMs:ee,remainingMs:(t,n)=>Ve(t,n,e.ms)}}var Sr={None:"none",Linear:"linear",Exponential:"exponential"};Object.defineProperty(exports,"createAuditLedger",{enumerable:true,get:function(){return chunkIXRS4LM4_cjs.b}});Object.defineProperty(exports,"memorySink",{enumerable:true,get:function(){return chunkIXRS4LM4_cjs.a}});Object.defineProperty(exports,"createSystem",{enumerable:true,get:function(){return chunkNPX5EKPP_cjs.a}});Object.defineProperty(exports,"DirectiveError",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.b}});Object.defineProperty(exports,"RequirementSet",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.o}});Object.defineProperty(exports,"forType",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.n}});Object.defineProperty(exports,"generateRequirementId",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.k}});Object.defineProperty(exports,"isNamespacedSystem",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.h}});Object.defineProperty(exports,"isRequirementType",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.m}});Object.defineProperty(exports,"isSingleModuleSystem",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.g}});Object.defineProperty(exports,"req",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.l}});Object.defineProperty(exports,"typedConstraint",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.e}});Object.defineProperty(exports,"typedResolver",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.f}});Object.defineProperty(exports,"applyPatch",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.v}});Object.defineProperty(exports,"evaluateKeySelector",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.u}});Object.defineProperty(exports,"evaluatePredicate",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.o}});Object.defineProperty(exports,"evaluatePredicateExplained",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.p}});Object.defineProperty(exports,"evaluateTemplate",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.s}});Object.defineProperty(exports,"extractDeps",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.r}});Object.defineProperty(exports,"extractTemplateKeys",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.t}});Object.defineProperty(exports,"getKind",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.c}});Object.defineProperty(exports,"getOperatorsForKind",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.e}});Object.defineProperty(exports,"getSchemaFieldKinds",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.d}});Object.defineProperty(exports,"isPredicate",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.h}});Object.defineProperty(exports,"isTemplate",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.k}});Object.defineProperty(exports,"listAllPredicateOperators",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.f}});Object.defineProperty(exports,"memoizePredicate",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.q}});Object.defineProperty(exports,"validatePredicate",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.l}});Object.defineProperty(exports,"validatePredicateAgainstSchema",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.n}});Object.defineProperty(exports,"diffSnapshots",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.k}});Object.defineProperty(exports,"isSignedSnapshot",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.l}});Object.defineProperty(exports,"isSnapshotExpired",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.i}});Object.defineProperty(exports,"shallowEqual",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.g}});Object.defineProperty(exports,"signSnapshot",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.m}});Object.defineProperty(exports,"validateSnapshot",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.j}});Object.defineProperty(exports,"verifySnapshotSignature",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.n}});exports.Backoff=Sr;exports.MAX_REPLAY_FRAMES=C;exports.MAX_SWEEP_POINTS=ae;exports.completeTimer=it;exports.createModule=Ye;exports.createModuleFactory=xn;exports.createRequirementStatusPlugin=Se;exports.createStatusHook=On;exports.createSystemWithStatus=jn;exports.defaultClock=Fn;exports.describePredicate=Vt;exports.diffClauses=Oe;exports.diffRules=zt;exports.doctor=Zt;exports.elapsedMs=ee;exports.flattenPredicate=S;exports.framesFromHistory=De;exports.framesFromSnapshots=se;exports.initialTimerState=Te;exports.pauseTimer=tt;exports.predicateHash=Ht;exports.predicateToMongo=$n;exports.predicateToPostgrest=Tn;exports.predicateToSQL=pn;exports.predicateToWhere=gn;exports.predict=Qt;exports.realClock=Ge;exports.registerRepeat=ot;exports.remainingMs=Ve;exports.replayUnder=H;exports.resetTimer=rt;exports.resumeTimer=nt;exports.startTimer=et;exports.sweepUnder=qt;exports.t=vn;exports.tickTimer=st;exports.timerOps=Nn;exports.toReplayFrames=Ae;exports.toRulesMap=ce;exports.virtualClock=Pn;//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map

@@ -1,5 +0,5 @@

export{b as createAuditLedger,a as memorySink}from'./chunk-7TSYQEN3.js';import {a as a$1}from'./chunk-26Z5VNPZ.js';export{a as createSystem}from'./chunk-26Z5VNPZ.js';import {m,n,k,h,i,a as a$2,b,g}from'./chunk-TPOKS4RY.js';export{v as DirectiveError,I as RequirementSet,t as applyPatch,s as evaluateKeySelector,m as evaluatePredicate,n as evaluatePredicateExplained,q as evaluateTemplate,p as extractDeps,r as extractTemplateKeys,H as forType,E as generateRequirementId,c as getKind,e as getOperatorsForKind,d as getSchemaFieldKinds,B as isNamespacedSystem,h as isPredicate,G as isRequirementType,A as isSingleModuleSystem,j as isTemplate,f as listAllPredicateOperators,o as memoizePredicate,F as req,y as typedConstraint,z as typedResolver,k as validatePredicate,l as validatePredicateAgainstSchema}from'./chunk-TPOKS4RY.js';import {a,l}from'./chunk-TZHC4E6S.js';import {d}from'./chunk-T6IJUWYR.js';export{j as diffSnapshots,k as isSignedSnapshot,h as isSnapshotExpired,f as shallowEqual,l as signSnapshot,i as validateSnapshot,m as verifySnapshotSignature}from'./chunk-T6IJUWYR.js';var R=1e6;function ye(e,t){try{k(e);}catch(r){let i=r instanceof Error?r.message:String(r);throw new Error(`[Directive] replayUnder: the ${t} predicate is invalid \u2014 ${i}`)}if(!h(e)){let r=e===null||typeof e!="object"?`${typeof e} \u2014 ${JSON.stringify(e)}`:JSON.stringify(e).slice(0,80);throw new Error(`[Directive] replayUnder: the ${t} predicate is not a valid FactPredicate (got ${r})`)}let n;if(i(e,{operator(r,i){n===void 0&&i.startsWith("$")&&!a$2.has(i)&&(n=i);},strayOperatorKey(r){n===void 0&&!a$2.has(r)&&!b.has(r)&&(n=r);}}),n!==void 0)throw new Error(`[Directive] replayUnder: the ${t} predicate uses an unknown operator "${n}" \u2014 known operators: ${[...a$2].join(", ")}`)}function we(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return $e(e);let t=Array.isArray(e)?e:e&&typeof e=="object"&&Array.isArray(e.frames)?e.frames:null;if(!t)throw new Error("[Directive] toReplayFrames: history must be a JSON array of frames, an object with a `frames` array, or a history export with a `snapshots` array");if(t.length>R)throw new Error(`[Directive] toReplayFrames: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${R}) \u2014 split or down-sample the history`);return t.map((n,r)=>{if(n&&typeof n=="object"&&"facts"in n){let i=n,s={id:i.id??`#${r}`,facts:i.facts??{}};return typeof i.timestamp=="number"&&(s.timestamp=i.timestamp),s}return {id:`#${r}`,facts:n??{}}})}function $e(e){let t=typeof e=="string"?JSON.parse(e):e;if(Array.isArray(t))return X(t);if(!t||typeof t!="object")throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");let n=t;if(n.version!==void 0&&n.version!==1)throw new Error(`[Directive] framesFromHistory: unsupported history export version ${JSON.stringify(n.version)} \u2014 expected 1`);if(!Array.isArray(n.snapshots))throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");return X(n.snapshots)}function X(e){if(!Array.isArray(e))throw new Error("[Directive] framesFromSnapshots: expected an array of fact-state snapshots");if(e.length>R)throw new Error(`[Directive] framesFromSnapshots: history has ${e.length} snapshots, exceeds the MAX_REPLAY_FRAMES limit (${R}) \u2014 split or down-sample the history`);for(let t=0;t<e.length;t++){let n=e[t];if(!n||typeof n!="object"||!("facts"in n))throw new Error(`[Directive] framesFromSnapshots: snapshot at index ${t} is not a { facts, ... } object`)}return we(e)}function L(e){let{frames:t,original:n,proposed:r,entityKey:i}=e,s=e.maxSamples??20,o=s>0?s:0;if(t.length>R)throw new Error(`[Directive] replayUnder: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${R}) \u2014 split or down-sample the history`);ye(n,"original"),ye(r,"proposed");let c=0,a=0,u=0,l=0,d=0,f=[],g=[],m$1=i?new Set:void 0,h=i?new Set:void 0,k;for(let P of t){let $=P.facts,v=m(n,$,k),M=m(r,$,k);v&&(c++,m$1?.add($[i])),M&&(a++,h?.add($[i])),v===M?d++:!v&&M?(u++,f.length<o&&f.push(me(P,n,r,k))):(l++,g.length<o&&g.push(me(P,n,r,k))),k=$;}let E={framesEvaluated:t.length,original:{matched:c},proposed:{matched:a},delta:a-c,newMatchCount:u,lostMatchCount:l,unchanged:d,newMatches:f,lostMatches:g};return m$1&&h&&(E.original.matchedEntities=m$1.size,E.proposed.matchedEntities=h.size),E}function me(e,t,n$1,r){let i=e.facts,s={frameId:e.id,facts:i,originalExplain:n(t,i,r),proposedExplain:n(n$1,i,r)};return e.timestamp!==void 0&&(s.timestamp=e.timestamp),s}var Y=1e4,be=5e7;function vt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===1&&typeof e.$hole=="string"}function G(e,t,n=new Set,r=0){if(r>g)throw new Error(`[Directive] sweepUnder: template exceeds MAX_PREDICATE_DEPTH (${g}) \u2014 flatten the template or split the sweep`);if(vt(e)){let i=e.$hole;if(!(i in t))throw new Error(`[Directive] sweepUnder: template references hole "${i}" but sweep has no values for it`);return t[i]}if(e===null||typeof e!="object")return e;if(n.has(e))throw new Error("[Directive] sweepUnder: template contains a cycle \u2014 predicate templates must be a tree");n.add(e);try{if(Array.isArray(e))return e.map(s=>G(s,t,n,r+1));let i={};for(let[s,o]of Object.entries(e))i[s]=G(o,t,n,r+1);return i}finally{n.delete(e);}}function*Te(e,t){if(e.length===0){yield {};return}let n=e[0],r=e.slice(1),i=t[n]??[];for(let s of i)for(let o of Te(r,t))yield {[n]:s,...o};}function kt(e){let t=1;for(let n of Object.values(e))t*=n.length;return t}function Mt(e){let{frames:t,original:n,template:r,sweep:i,objective:s=$=>$.proposed.matched,entityKey:o,maxSamples:c=0}=e,a=Object.keys(i);if(a.length===0)throw new Error("[Directive] sweepUnder: `sweep` must contain at least one hole name");let u=kt(i);if(u>Y)throw new Error(`[Directive] sweepUnder: grid has ${u} points, exceeds the MAX_SWEEP_POINTS limit (${Y}) \u2014 narrow the sweep ranges or split the run`);if(u===0)throw new Error("[Directive] sweepUnder: at least one hole has zero candidate values");let l=u*t.length;if(l>be)throw new Error(`[Directive] sweepUnder: ${u} points \xD7 ${t.length} frames = ${l} per-frame evaluations, exceeds the MAX_SWEEP_EVALUATIONS limit (${be}) \u2014 narrow the sweep, down-sample the history, or split the run`);let d=false,f=$=>{let v;try{v=s($);}catch(M){return d||(d=true,console.warn(`[Directive] sweepUnder: objective threw \u2014 point will not rank (${M.message})`)),Number.NEGATIVE_INFINITY}return typeof v!="number"||!Number.isFinite(v)?(d||(d=true,console.warn(`[Directive] sweepUnder: objective returned a non-finite number (${String(v)}) \u2014 point will not rank`)),Number.NEGATIVE_INFINITY):v},g=L({frames:t,original:n,proposed:n,entityKey:o,maxSamples:c}),m={values:{},report:g,score:f(g)},h=[],k=0,E=Number.NEGATIVE_INFINITY;for(let $ of Te(a,i)){let v=G(r,$),M=L({frames:t,original:n,proposed:v,entityKey:o,maxSamples:c}),H=f(M);H>E&&(E=H,k=h.length),h.push({values:$,report:M,score:H});}let P=h[k];return {points:h,bestIndex:k,best:P,baseline:m}}function V(e){let t=e&&typeof e=="object"&&!Array.isArray(e)&&"constraints"in e?e.constraints:e;if(Array.isArray(t)){let n={};for(let r of t){if(!r||typeof r!="object"||!("id"in r))throw new Error("[Directive] diffRules: array entries must be `{ id, whenSpec }` objects");let i=r;if(typeof i.id!="string")throw new Error("[Directive] diffRules: constraint `id` must be a string");n[i.id]=i.whenSpec;}return n}if(t&&typeof t=="object")return t;throw new Error("[Directive] diffRules: expected a `{ id: whenSpec }` map, an array of `{ id, whenSpec }`, or `{ constraints: ... }`")}var Dt=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),Rt=new Set(["$all","$any","$not"]);function Se(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Et(e){if(!Se(e))return false;let t=Object.keys(e);if(t.length===0)return false;let n=false;for(let r of t){if(!r.startsWith("$"))return false;Dt.has(r)&&(n=true);}return n}function T(e,t="",n=[]){if(e===null||typeof e!="object")return n;if(Array.isArray(e)){for(let r of e)if(r&&typeof r=="object"&&"fact"in r&&"op"in r){let i=r;n.push({path:t?`${t}.${String(i.fact)}`:String(i.fact),op:String(i.op),value:i.value});}return n}if("$all"in e&&Array.isArray(e.$all))return e.$all.forEach((i,s)=>{T(i,`${t}$all[${s}]`,n);}),n;if("$any"in e&&Array.isArray(e.$any))return e.$any.forEach((i,s)=>{T(i,`${t}$any[${s}]`,n);}),n;if("$not"in e)return T(e.$not,`${t}$not`,n),n;for(let[r,i]of Object.entries(e)){let s=t?`${t}.${r}`:r;if(Et(i))for(let[o,c]of Object.entries(i))n.push({path:s,op:o,value:c});else Se(i)&&!Rt.has(r)?T(i,s,n):n.push({path:s,op:"$eq",value:i});}return n}function D(e){return typeof e=="number"&&Number.isFinite(e)}function xt(e,t,n){switch(e){case "$gte":case "$gt":if(D(t)&&D(n)){if(n<t)return "relaxed";if(n>t)return "tightened"}return null;case "$lte":case "$lt":if(D(t)&&D(n)){if(n>t)return "relaxed";if(n<t)return "tightened"}return null;case "$between":{if(Array.isArray(t)&&Array.isArray(n)&&t.length===2&&n.length===2&&D(t[0])&&D(t[1])&&D(n[0])&&D(n[1])){let r=t[1]-t[0],i=n[1]-n[0];if(i>r)return "relaxed";if(i<r)return "tightened"}return null}case "$in":case "$nin":{if(Array.isArray(t)&&Array.isArray(n))if(e==="$in"){if(n.length>t.length)return "relaxed";if(n.length<t.length)return "tightened"}else {if(n.length>t.length)return "tightened";if(n.length<t.length)return "relaxed"}return null}case "$contains":{if(Array.isArray(t)&&Array.isArray(n)){if(n.length>t.length)return "relaxed";if(n.length<t.length)return "tightened"}return null}default:return null}}function At(e){let t=V(e.before),n=V(e.after),i=[...new Set([...Object.keys(t),...Object.keys(n)])].sort(),s=[],o={added:0,removed:0,changed:0,unchanged:0,totalClauseChanges:0};for(let c of i){let a=t[c],u=n[c],l=c in t,d=c in n;if(l&&!d){let g=T(a),m=g.length===0?[{path:"(function-form predicate)",kind:"removed"}]:g.map(h=>({path:h.path,kind:"removed",before:{op:h.op,value:h.value}}));ee(m),s.push({id:c,status:"removed",changes:m}),o.removed++,o.totalClauseChanges+=m.length;continue}if(!l&&d){let g=T(u),m=g.length===0?[{path:"(function-form predicate)",kind:"added"}]:g.map(h=>({path:h.path,kind:"added",after:{op:h.op,value:h.value}}));ee(m),s.push({id:c,status:"added",changes:m}),o.added++,o.totalClauseChanges+=m.length;continue}let f=ve(a,u);f.length===0?(s.push({id:c,status:"unchanged",changes:[]}),o.unchanged++):(s.push({id:c,status:"changed",changes:f}),o.changed++,o.totalClauseChanges+=f.length);}return {constraints:s,summary:o}}function ve(e,t){if(e!==void 0&&t!==void 0&&(e===null||t===null||typeof e!="object"||typeof t!="object"))return d(e)===d(t)?[]:[{path:"",kind:"changed",before:{op:"$eq",value:e},after:{op:"$eq",value:t}}];let n=e===void 0?[]:T(e),r=t===void 0?[]:T(t),i=u=>`${u.path}::${u.op}`,s=new Map(n.map(u=>[i(u),u])),o=new Map(r.map(u=>[i(u),u])),c=new Set([...s.keys(),...o.keys()]),a=[];for(let u of c){let l=s.get(u),d$1=o.get(u);if(l&&!d$1){a.push({path:l.path,kind:"removed",before:{op:l.op,value:l.value}});continue}if(!l&&d$1){a.push({path:d$1.path,kind:"added",after:{op:d$1.op,value:d$1.value}});continue}if(l&&d$1){if(d(l.value)===d(d$1.value))continue;let f=xt(l.op,l.value,d$1.value);a.push({path:l.path,kind:f??"changed",before:{op:l.op,value:l.value},after:{op:d$1.op,value:d$1.value}});}}return ee(a),a}function ee(e){e.sort((t,n)=>{let r=t.path.localeCompare(n.path);if(r!==0)return r;let i=t.before?.op??t.after?.op??"",s=n.before?.op??n.after?.op??"";return i.localeCompare(s)});}function B(e){return e===null?"null":e===void 0?"undefined":e instanceof Date?e.toISOString():typeof e=="string"||typeof e=="object"?JSON.stringify(e):String(e)}function Ct(e){let t=e.path,n=B(e.expected),r=B(e.actual);switch(e.op){case "$eq":return `set ${t} to ${n} (currently ${r})`;case "$ne":return `change ${t} to anything other than ${n} (currently ${r})`;case "$gt":return `set ${t} above ${n} (currently ${r})`;case "$gte":return `set ${t} to at least ${n} (currently ${r})`;case "$lt":return `set ${t} below ${n} (currently ${r})`;case "$lte":return `set ${t} to at most ${n} (currently ${r})`;case "$in":return `set ${t} to one of ${n} (currently ${r})`;case "$nin":return `set ${t} to something other than ${n} (currently ${r})`;case "$exists":return e.expected===true?`set ${t} to a non-null value (currently null/missing)`:`unset ${t} (currently ${r})`;case "$between":return Array.isArray(e.expected)&&e.expected.length===2?`set ${t} between ${B(e.expected[0])} and ${B(e.expected[1])} (currently ${r})`:`set ${t} within range ${n} (currently ${r})`;case "$startsWith":return `set ${t} to start with ${n} (currently ${r})`;case "$endsWith":return `set ${t} to end with ${n} (currently ${r})`;case "$contains":return `set ${t} to contain ${n} (currently ${r})`;case "$matches":return `set ${t} to match the pattern ${n} (currently ${r})`;case "$changed":return `the previous-vs-current change of ${t} is required to differ (currently they match: ${r})`;case "$all":case "$any":case "$not":return `the ${e.op} group at "${t}" did not pass \u2014 see its child clauses`;default:return `clause at ${t} (${e.op}) failed: expected ${n}, got ${r}`}}function ke(e,t){for(let n of e)if(!n.pass){if((n.op==="$all"||n.op==="$any"||n.op==="$not")&&n.children){ke(n.children,t);continue}t.push({path:n.path,op:n.op,expected:n.expected,actual:n.actual,suggestion:Ct(n)});}}function Pt(e,t,n$1){let r=n(e,t,n$1),i=r.every(o=>o.pass),s=[];return i||ke(r,s),{wouldFire:i,whenExplain:r,missingChanges:s,predicate:e}}var Me=new Set(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$nin"]);function W(e,t){if(e===t)return 0;if(typeof e=="number"&&typeof t=="number"||typeof e=="bigint"&&typeof t=="bigint")return e<t?-1:e>t?1:0;if(e instanceof Date&&t instanceof Date){let n=e.getTime(),r=t.getTime();return n<r?-1:n>r?1:0}return typeof e=="string"&&typeof t=="string"?e<t?-1:e>t?1:0:Number.NaN}function F(e,t){if(e===t)return true;if(typeof e!=typeof t||e===null||t===null||typeof e!="object"||Array.isArray(e)!==Array.isArray(t))return false;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return false;for(let i=0;i<e.length;i++)if(!F(e[i],t[i]))return false;return true}let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return false;for(let i of n)if(!F(e[i],t[i]))return false;return true}function jt(e,t){if(!Me.has(e.op)||!Me.has(t.op))return {type:"overlap",reason:`Both rules touch "${e.path}".`};if(e.op==="$eq"&&t.op==="$eq")return F(e.value,t.value)?{type:"subset",reason:`Both rules require ${e.path} = ${JSON.stringify(e.value)} \u2014 candidate is redundant.`}:{type:"direct",reason:`Candidate requires ${e.path} = ${JSON.stringify(e.value)} but an existing rule requires ${e.path} = ${JSON.stringify(t.value)} \u2014 they cannot both fire.`};if(e.op==="$eq"&&t.op==="$ne")return F(e.value,t.value)?{type:"direct",reason:`Candidate requires ${e.path} = ${JSON.stringify(e.value)} but an existing rule excludes that value.`}:null;if(e.op==="$ne"&&t.op==="$eq")return F(e.value,t.value)?{type:"direct",reason:`Candidate excludes ${e.path} = ${JSON.stringify(e.value)} but an existing rule requires that exact value.`}:null;if(e.op==="$in"&&t.op==="$in"){let o=new Set(Array.isArray(e.value)?e.value:[]),c=new Set(Array.isArray(t.value)?t.value:[]),a=[...o].filter(u=>c.has(u));return a.length===0?{type:"direct",reason:`Candidate $in set for ${e.path} (${JSON.stringify([...o])}) and existing $in set (${JSON.stringify([...c])}) have no values in common \u2014 the candidate can never fire while the existing rule holds.`}:a.length===o.size&&a.length<c.size?{type:"subset",reason:`Candidate $in set for ${e.path} is a strict subset of the existing rule's $in set.`}:null}let n=e.op==="$gt"||e.op==="$gte"?e.value:void 0,r=e.op==="$lt"||e.op==="$lte"?e.value:void 0,i=t.op==="$gt"||t.op==="$gte"?t.value:void 0,s=t.op==="$lt"||t.op==="$lte"?t.value:void 0;if(n!==void 0&&s!==void 0){let o=W(n,s);if(!Number.isNaN(o)&&(o>0||o===0&&(e.op==="$gt"||t.op==="$lt")))return {type:"direct",reason:`Candidate requires ${e.path} ${e.op==="$gt"?">":"\u2265"} ${JSON.stringify(n)} but an existing rule caps it at ${t.op==="$lt"?"<":"\u2264"} ${JSON.stringify(s)}.`}}if(i!==void 0&&r!==void 0){let o=W(i,r);if(!Number.isNaN(o)&&(o>0||o===0&&(t.op==="$gt"||e.op==="$lt")))return {type:"direct",reason:`Candidate caps ${e.path} at ${e.op==="$lt"?"<":"\u2264"} ${JSON.stringify(r)} but an existing rule requires it ${t.op==="$gt"?">":"\u2265"} ${JSON.stringify(i)}.`}}if(n!==void 0&&i!==void 0){let o=W(n,i);if(!Number.isNaN(o)&&o>0)return {type:"subset",reason:`Candidate's lower bound on ${e.path} (${JSON.stringify(n)}) is stricter than the existing rule's lower bound (${JSON.stringify(i)}) \u2014 candidate is a subset.`}}if(r!==void 0&&s!==void 0){let o=W(r,s);if(!Number.isNaN(o)&&o<0)return {type:"subset",reason:`Candidate's upper bound on ${e.path} (${JSON.stringify(r)}) is stricter than the existing rule's upper bound (${JSON.stringify(s)}) \u2014 candidate is a subset.`}}return {type:"overlap",reason:`Both rules constrain "${e.path}".`}}function Ot(e){return typeof e=="object"&&e!==null&&typeof e.id=="string"}var Ft={checkAgainst(e,t){let n=Array.isArray(t)?t:"constraints"in t&&Array.isArray(t.constraints)?t.constraints:[],r=T(e);if(r.length===0)return {contradictions:[],warnings:[]};let i=new Map;for(let c of r){let a=i.get(c.path)??[];a.push(c),i.set(c.path,a);}let s=[],o=[];for(let c of n){if(!Ot(c)||c.whenSpec===void 0)continue;let a=T(c.whenSpec);for(let u of a){let l=i.get(u.path);if(l)for(let d of l){let f=jt(d,u);if(!f)continue;let g={constraintId:c.id,type:f.type,reason:f.reason,candidatePath:d.path,candidate:{op:d.op,value:d.value},existing:{op:u.op,value:u.value}};f.type==="overlap"?o.push(g):s.push(g);}}}return {contradictions:s,warnings:o}}};var _t=/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)?$/;function N(e,t){if(typeof e!="string"||!_t.test(e))throw new Error(`[Directive] predicateToSQL: invalid ${t} identifier "${e}" \u2014 must match /^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)?$/`)}function De(e,t){if(t&&!t.includes(e))throw new Error(`[Directive] predicateToSQL: column "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function Nt(e){if(Array.isArray(e)){if(e.length===0)throw new Error("[Directive] predicateToSQL: select must not be empty");for(let n of e)N(n,"column");return e.join(", ")}let t=e;return t==="*"?"*":(N(t,"column"),t)}function w(e,t){return e.params.push(t),e.placeholder(e.params.length)}function te(e,t,n,r){switch(t){case "$eq":return `${e} = ${w(r,n)}`;case "$ne":return `${e} <> ${w(r,n)}`;case "$gt":return `${e} > ${w(r,n)}`;case "$gte":return `${e} >= ${w(r,n)}`;case "$lt":return `${e} < ${w(r,n)}`;case "$lte":return `${e} <= ${w(r,n)}`;case "$in":if(!Array.isArray(n))throw new Error("[Directive] predicateToSQL: $in operand must be an array");return `${e} = ANY(${w(r,n)})`;case "$nin":if(!Array.isArray(n))throw new Error("[Directive] predicateToSQL: $nin operand must be an array");return `NOT (${e} = ANY(${w(r,n)}))`;case "$exists":return n===true?`${e} IS NOT NULL`:`${e} IS NULL`;case "$between":{if(!Array.isArray(n)||n.length!==2)throw new Error("[Directive] predicateToSQL: $between operand must be a [low, high] tuple");return `${e} BETWEEN ${w(r,n[0])} AND ${w(r,n[1])}`}case "$startsWith":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $startsWith operand must be a string");return `${e} LIKE ${w(r,ne(n))} || '%' ESCAPE '\\'`;case "$endsWith":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $endsWith operand must be a string");return `${e} LIKE '%' || ${w(r,ne(n))} ESCAPE '\\'`;case "$contains":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $contains only supports string operands \u2014 array containment requires a JOIN, not a predicate");return `${e} LIKE '%' || ${w(r,ne(n))} || '%' ESCAPE '\\'`;case "$matches":{if(!(n instanceof RegExp))throw new Error("[Directive] predicateToSQL: $matches operand must be a RegExp");let i=n.flags.includes("i")?"~*":"~";return `${e} ${i} ${w(r,n.source)}`}case "$changed":throw new Error('[Directive] predicateToSQL: $changed is an effects-only operator \u2014 no server-side translation (a database row has no "prev" snapshot)');default:throw new Error(`[Directive] predicateToSQL: unknown operator "${t}" \u2014 known: ${[...a$2].join(", ")}`)}}function ne(e){return e.replace(/[\\%_]/g,"\\$&")}function Re(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function qt(e){if(!Re(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function re(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToSQL: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function _(e,t,n){if(n>g)throw new Error(`[Directive] predicateToSQL: predicate depth limit (${g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error(`[Directive] predicateToSQL: predicate must be an object or array, got ${typeof e}`);if(Array.isArray(e)){if(e.length===0)return "TRUE";let i=e.map(s=>{if(!s||typeof s!="object"||!("fact"in s)||!("op"in s))throw new Error("[Directive] predicateToSQL: array-form clause must be { fact, op, value }");let o=s;return N(o.fact,"column"),De(o.fact,t.allowed),te(o.fact,o.op,o.value,t)});return i.length===1?i[0]:`(${i.join(" AND ")})`}if("$all"in e){re(e,"$all");let i=e.$all;if(!Array.isArray(i))throw new Error("[Directive] predicateToSQL: $all must be an array");if(i.length===0)return "TRUE";let s=i.map(o=>_(o,t,n+1));return s.length===1?s[0]:`(${s.join(" AND ")})`}if("$any"in e){re(e,"$any");let i=e.$any;if(!Array.isArray(i))throw new Error("[Directive] predicateToSQL: $any must be an array");if(i.length===0)return "FALSE";let s=i.map(o=>_(o,t,n+1));return s.length===1?s[0]:`(${s.join(" OR ")})`}if("$not"in e){re(e,"$not");let i=e.$not;return `NOT (${_(i,t,n+1)})`}let r=[];for(let[i,s]of Object.entries(e))if(N(i,"column"),De(i,t.allowed),qt(s))for(let[o,c]of Object.entries(s)){if(!a$2.has(o))throw new Error(`[Directive] predicateToSQL: unknown operator "${o}" on column "${i}" \u2014 known: ${[...a$2].join(", ")}`);r.push(te(i,o,c,t));}else {if(Re(s))throw new Error(`[Directive] predicateToSQL: nested predicate at "${i}" \u2014 cross-module / partial-match predicates have no SQL equivalent (single-table queries only in v1; pass a flat predicate or build JOIN by hand with predicateToWhere)`);r.push(te(i,"$eq",s,t));}return r.length===0?"TRUE":r.length===1?r[0]:`(${r.join(" AND ")})`}var Ee=e=>`$${e}`;function It(e,t){let{table:n,allowedKeys:r}=t,i=t.placeholder??Ee,s=t.select??"*";N(n,"table");let o=Nt(s),c={params:[],placeholder:i,allowed:r},a=_(e,c,0);return {sql:`SELECT ${o} FROM ${n} WHERE ${a}`,where:a,params:c.params}}function Lt(e,t={}){let n=t.placeholder??Ee,r={params:[],placeholder:n,allowed:t.allowedKeys};return {where:_(e,r,0),params:r.params}}function ie(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function se(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Bt(e){if(!se(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}var Wt=/^[A-Za-z_][A-Za-z0-9_]*$/,Kt=/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;function xe(e,t){if(typeof e!="string"||e.length===0)throw new Error(`[Directive] predicateToMongo: field name must be a non-empty string, got ${typeof e}`);if(e.startsWith("$"))throw new Error(`[Directive] predicateToMongo: field name "${e}" starts with "$" \u2014 reserved for Mongo operators (a top-level $where would be an injection vector)`);if(!(t.allowDottedPaths?Kt:Wt).test(e))throw new Error(`[Directive] predicateToMongo: invalid field name "${e}"${t.allowDottedPaths?"":' \u2014 pass options.allowDottedPaths=true to permit sub-document paths like "user.role"'}`)}function Ae(e,t){if(t&&!t.includes(e))throw new Error(`[Directive] predicateToMongo: field "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function oe(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToMongo: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function Ce(e,t){switch(e){case "$eq":case "$ne":case "$gt":case "$gte":case "$lt":case "$lte":case "$in":case "$nin":case "$exists":return {[e]:t};case "$between":{if(!Array.isArray(t)||t.length!==2)throw new Error("[Directive] predicateToMongo: $between operand must be a [low, high] tuple");return {$gte:t[0],$lte:t[1]}}case "$startsWith":if(typeof t!="string")throw new Error("[Directive] predicateToMongo: $startsWith operand must be a string");return {$regex:`^${ie(t)}`};case "$endsWith":if(typeof t!="string")throw new Error("[Directive] predicateToMongo: $endsWith operand must be a string");return {$regex:`${ie(t)}$`};case "$contains":if(typeof t=="string")return {$regex:ie(t)};throw new Error("[Directive] predicateToMongo: $contains in Mongo expects a string operand \u2014 for array element membership use $elemMatch or $in directly");case "$matches":{if(t instanceof RegExp)return t.flags?{$regex:t.source,$options:t.flags}:{$regex:t.source};if(typeof t=="string")return {$regex:t};throw new Error("[Directive] predicateToMongo: $matches operand must be a RegExp or string")}case "$changed":throw new Error("[Directive] predicateToMongo: $changed is an effects-only operator \u2014 no MongoDB query equivalent");default:throw new Error(`[Directive] predicateToMongo: unknown operator "${e}" \u2014 known: ${[...a$2].join(", ")}`)}}function A(e,t,n){if(n>g)throw new Error(`[Directive] predicateToMongo: predicate depth limit (${g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error(`[Directive] predicateToMongo: predicate must be an object or array, got ${typeof e}`);if(Array.isArray(e)){if(e.length===0)return {};let i={},s=[];for(let o of e){if(!o||typeof o!="object"||!("fact"in o)||!("op"in o))throw new Error("[Directive] predicateToMongo: array-form clause must be { fact, op, value }");let c=o;xe(c.fact,t),Ae(c.fact,t.allowedKeys);let a=Ce(c.op,c.value);if(c.fact in i&&se(i[c.fact])){let u=i[c.fact];Object.keys(a).some(d=>d in u)?s.push({[c.fact]:a}):i[c.fact]={...u,...a};}else c.fact in i?s.push({[c.fact]:a}):i[c.fact]=a;}if(s.length>0){let o=[];for(let[c,a]of Object.entries(i))o.push({[c]:a});return o.push(...s),{$and:o}}return i}if("$all"in e){oe(e,"$all");let i=e.$all;if(!Array.isArray(i))throw new Error("[Directive] predicateToMongo: $all must be an array");return i.length===0?{}:i.length===1?A(i[0],t,n+1):{$and:i.map(s=>A(s,t,n+1))}}if("$any"in e){oe(e,"$any");let i=e.$any;if(!Array.isArray(i))throw new Error("[Directive] predicateToMongo: $any must be an array");return i.length===0?{$expr:{$eq:[1,0]}}:i.length===1?A(i[0],t,n+1):{$or:i.map(s=>A(s,t,n+1))}}if("$not"in e){oe(e,"$not");let i=e.$not;return {$nor:[A(i,t,n+1)]}}let r={};for(let[i,s]of Object.entries(e))if(xe(i,t),Ae(i,t.allowedKeys),Bt(s)){let o={};for(let[c,a]of Object.entries(s)){if(!a$2.has(c))throw new Error(`[Directive] predicateToMongo: unknown operator "${c}" on field "${i}" \u2014 known: ${[...a$2].join(", ")}`);Object.assign(o,Ce(c,a));}r[i]=o;}else r[i]=s;return r}function Ut(e,t={}){return A(e,t,0)}var zt=/^[A-Za-z_][A-Za-z0-9_]*$/;function Pe(e,t){if(typeof e!="string"||!zt.test(e))throw new Error(`[Directive] predicateToPostgrest: invalid column identifier "${e}"`);if(t&&!t.includes(e))throw new Error(`[Directive] predicateToPostgrest: column "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function ae(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToPostgrest: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function S(e){if(e==null)return "null";if(typeof e=="boolean")return e?"true":"false";if(typeof e=="number"||typeof e=="bigint")return String(e);if(e instanceof Date)return e.toISOString();if(typeof e=="string")return /[,.():"\\\s]/.test(e)?`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:e;throw new Error(`[Directive] predicateToPostgrest: cannot encode value of type ${typeof e}`)}function je(e){return `(${e.map(S).join(",")})`}function ue(e){return e.replace(/[\\%_*]/g,"\\$&")}function C(e,t){switch(e){case "$eq":return `eq.${S(t)}`;case "$ne":return `neq.${S(t)}`;case "$gt":return `gt.${S(t)}`;case "$gte":return `gte.${S(t)}`;case "$lt":return `lt.${S(t)}`;case "$lte":return `lte.${S(t)}`;case "$in":if(!Array.isArray(t))throw new Error("[Directive] predicateToPostgrest: $in operand must be an array");return `in.${je(t)}`;case "$nin":if(!Array.isArray(t))throw new Error("[Directive] predicateToPostgrest: $nin operand must be an array");return `not.in.${je(t)}`;case "$exists":return t===true?"not.is.null":"is.null";case "$startsWith":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $startsWith operand must be a string");return `like.${S(ue(t)+"*")}`;case "$endsWith":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $endsWith operand must be a string");return `like.${S("*"+ue(t))}`;case "$contains":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $contains expects a string operand (array containment is the cs operator with a different shape \u2014 out of scope for v1)");return `like.${S("*"+ue(t)+"*")}`;case "$matches":if(t instanceof RegExp)return `${t.flags.includes("i")?"imatch":"match"}.${S(t.source)}`;if(typeof t=="string")return `match.${S(t)}`;throw new Error("[Directive] predicateToPostgrest: $matches operand must be a RegExp or string");case "$changed":throw new Error("[Directive] predicateToPostgrest: $changed is an effects-only operator \u2014 no server query equivalent");default:throw new Error(`[Directive] predicateToPostgrest: unknown operator "${e}" \u2014 known: ${[...a$2].join(", ")}`)}}function Oe(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Ht(e){if(!Oe(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function ce(e,t){return `${e}=${t}`}function K(e,t){return `${e}=(${t.join(",")})`}function le(e,t,n,r){if(t==="$between"){if(!Array.isArray(n)||n.length!==2)throw new Error("[Directive] predicateToPostgrest: $between operand must be a [low, high] tuple");let i=r?ce(e,C("$gte",n[0])):`${e}.${C("$gte",n[0])}`,s=r?ce(e,C("$lte",n[1])):`${e}.${C("$lte",n[1])}`;return [i,s]}return [r?ce(e,C(t,n)):`${e}.${C(t,n)}`]}function q(e,t,n,r){if(r>g)throw new Error(`[Directive] predicateToPostgrest: predicate depth limit (${g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error("[Directive] predicateToPostgrest: predicate must be an object or array");if(Array.isArray(e)){let s=[];for(let o of e){if(!o||typeof o!="object"||!("fact"in o)||!("op"in o))throw new Error("[Directive] predicateToPostgrest: array-form clause must be { fact, op, value }");let c=o;Pe(c.fact,t),s.push(...le(c.fact,c.op,c.value,n));}return s}if("$all"in e){ae(e,"$all");let s=e.$all;if(!Array.isArray(s))throw new Error("[Directive] predicateToPostgrest: $all must be an array");if(n){let c=[];for(let a of s)c.push(...q(a,t,true,r+1));return c}let o=[];for(let c of s)o.push(...q(c,t,false,r+1));return [K("and",o)]}if("$any"in e){ae(e,"$any");let s=e.$any;if(!Array.isArray(s))throw new Error("[Directive] predicateToPostgrest: $any must be an array");if(s.length===0)return n?["id=is.null","id=not.is.null"]:[K("and",["id.is.null","id.not.is.null"])];let o=[];for(let c of s)o.push(...q(c,t,false,r+1));return [K("or",o)]}if("$not"in e){ae(e,"$not");let s=e.$not,o=q(s,t,false,r+1);return [K("not.and",o)]}let i=[];for(let[s,o]of Object.entries(e))if(Pe(s,t),Ht(o))for(let[c,a]of Object.entries(o)){if(!a$2.has(c))throw new Error(`[Directive] predicateToPostgrest: unknown operator "${c}" on column "${s}" \u2014 known: ${[...a$2].join(", ")}`);i.push(...le(s,c,a,n));}else {if(Oe(o))throw new Error(`[Directive] predicateToPostgrest: nested predicate at "${s}" \u2014 single-table queries only`);i.push(...le(s,"$eq",o,n));}return i}function Qt(e){let t=e.indexOf("=");if(t<0)return encodeURIComponent(e);let n=e.slice(0,t),r=e.slice(t+1);return `${n}=${encodeURIComponent(r)}`}function Jt(e,t={}){let n=t.mode??"querystring",r=q(e,t.allowedKeys,true,0);return r.length===0?"":n==="raw"?r.join("&"):r.map(Qt).join("&")}function U(e=[],t,n,r,i,s,o){return {_type:void 0,_validators:e,_typeName:t,_default:n,_transform:r,_description:i,_refinements:s,_meta:o,validate(c){return U([...e,c],t,n,r,i,s,o)}}}function p(e,t,n,r,i,s,o){return {...U(e,t,n,r,i,s,o),default(a){return p(e,t,a,r,i,s,o)},transform(a){return p([],t,void 0,l=>{let d=r?r(l):l;return a(d)},i,void 0,o)},brand(){return p(e,`Branded<${t}>`,n,r,i,s,o)},describe(a){return p(e,t,n,r,a,s,o)},refine(a,u){let l=[...s??[],{predicate:a,message:u}];return p([...e,a],t,n,r,i,l,o)},nullable(){return p([a=>a===null||e.every(u=>u(a))],`${t} | null`,n,r,i,void 0,o)},optional(){return p([a=>a===void 0||e.every(u=>u(a))],`${t} | undefined`,n,r,i,void 0,o)},meta(a){return p(e,t,n,r,i,s,a)}}}var Zt=((...e)=>{if(e.length===0)return p([],"union");let t=e.map(n=>n._typeName??"unknown");return p([n=>e.some(r=>r._validators.every(i=>i(n)))],t.join(" | "))}),Xt={string(){let e=(t,n,r,i,s,o)=>({...p(t,"string",n,r,i,s,o),minLength(a){return e([...t,u=>u.length>=a],n,r,i,s,o)},maxLength(a){return e([...t,u=>u.length<=a],n,r,i,s,o)},pattern(a){return e([...t,u=>a.test(u)],n,r,i,s,o)},default(a){return e(t,a,r,i,s,o)},describe(a){return e(t,n,r,a,s,o)},refine(a,u){let l=[...s??[],{predicate:a,message:u}];return e([...t,a],n,r,i,l,o)},meta(a){return e(t,n,r,i,s,a)}});return e([t=>typeof t=="string"])},number(){let e=(t,n,r,i,s,o)=>({...p(t,"number",n,r,i,s,o),min(a){return e([...t,u=>u>=a],n,r,i,s,o)},max(a){return e([...t,u=>u<=a],n,r,i,s,o)},default(a){return e(t,a,r,i,s,o)},describe(a){return e(t,n,r,a,s,o)},refine(a,u){let l=[...s??[],{predicate:a,message:u}];return e([...t,a],n,r,i,l,o)},meta(a){return e(t,n,r,i,s,a)}});return e([t=>typeof t=="number"])},boolean(){return p([e=>typeof e=="boolean"],"boolean")},array(){let e=(t,n,r,i,s,o)=>{let c=p(t,"array",r,void 0,i,void 0,o),a=s??{value:-1};return {...c,get _lastFailedIndex(){return a.value},set _lastFailedIndex(l){a.value=l;},of(l){let d={value:-1};return e([...t,f=>{for(let g=0;g<f.length;g++)if(!l._validators.every(m=>m(f[g])))return d.value=g,false;return true}],l,r,i,d,o)},nonEmpty(){return e([...t,l=>l.length>0],n,r,i,a,o)},maxLength(l){return e([...t,d=>d.length<=l],n,r,i,a,o)},minLength(l){return e([...t,d=>d.length>=l],n,r,i,a,o)},default(l){return e(t,n,l,i,a,o)},describe(l){return e(t,n,r,l,a,o)},meta(l){return e(t,n,r,i,a,l)}}};return e([t=>Array.isArray(t)])},object(){let e=(t,n,r,i)=>({...p(t,"object",n,void 0,r,void 0,i),shape(o){return e([...t,c=>{for(let[a,u]of Object.entries(o)){let l=c[a],d=u;if(d&&!d._validators.every(f=>f(l)))return false}return true}],n,r,i)},nonNull(){return e([...t,o=>o!=null],n,r,i)},hasKeys(...o){return e([...t,c=>o.every(a=>a in c)],n,r,i)},default(o){return e(t,o,r,i)},describe(o){return e(t,n,o,i)},meta(o){return e(t,n,r,o)}});return e([t=>typeof t=="object"&&t!==null&&!Array.isArray(t)])},enum(...e){a&&e.length===0&&console.warn("[Directive] t.enum() called with no values - this will reject all strings");let t=new Set(e);return p([n=>typeof n=="string"&&t.has(n)],`enum(${e.join("|")})`)},literal(e){return p([t=>t===e],`literal(${String(e)})`)},nullable(e){let t=e._typeName??"unknown";return U([n=>n===null?true:e._validators.every(r=>r(n))],`${t} | null`)},optional(e){let t=e._typeName??"unknown";return U([n=>n===void 0?true:e._validators.every(r=>r(n))],`${t} | undefined`)},union:Zt,record(e){let t=e._typeName??"unknown";return p([n=>typeof n!="object"||n===null||Array.isArray(n)?false:Object.values(n).every(r=>e._validators.every(i=>i(r)))],`Record<string, ${t}>`)},tuple(...e){a&&e.length===0&&console.warn("[Directive] t.tuple() called with no types - this will only accept empty arrays");let t=e.map(n=>n._typeName??"unknown");return p([n=>!Array.isArray(n)||n.length!==e.length?false:e.every((r,i)=>r._validators.every(s=>s(n[i])))],`[${t.join(", ")}]`)},date(){return p([e=>e instanceof Date&&!Number.isNaN(e.getTime())],"Date")},uuid(){let e=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;return p([t=>typeof t=="string"&&e.test(t)],"uuid")},email(){let e=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;return p([t=>typeof t=="string"&&e.test(t)],"email")},url(){return p([e=>{if(typeof e!="string")return false;try{return new URL(e),!0}catch{return false}}],"url")},bigint(){return p([e=>typeof e=="bigint"],"bigint")},any(){return p([],"any")},unknown(){return p([],"unknown")}};function Yt(e){if(!e||typeof e!="string"){console.warn("[Directive] Module ID must be a non-empty string");return}/^(__[a-z][a-z0-9_-]*|[a-z][a-z0-9-]*)$/i.test(e)||console.warn(`[Directive] Module ID "${e}" should follow kebab-case convention (e.g., "my-module")`);}function Fe(e,t,n,r,i){for(let s of e)t.has(s)||console.warn(`[Directive] ${n} "${s}" not declared in ${r}`);for(let s of t)e.has(s)||console.warn(`[Directive] ${r}["${s}"] ${i}`);}function Gt(e,t){e.length===0&&console.warn("[Directive] history.snapshotEvents is an empty array \u2014 no events will create history snapshots. Omit history.snapshotEvents entirely to snapshot all events, or list specific events.");let n=new Set(Object.keys(t));for(let r of e)n.has(r)||console.warn(`[Directive] history.snapshotEvents entry "${r}" not declared in schema.events. Available events: ${[...n].join(", ")||"(none)"}`);}function Vt(e,t){let n=new Set(Object.keys(t));for(let[r,i]of Object.entries(e)){let s=i;typeof s.requirement=="string"&&!n.has(s.requirement)&&console.warn(`[Directive] Resolver "${r}" references unknown requirement type "${s.requirement}". Available types: ${[...n].join(", ")||"(none)"}`);}}function en(e,t){let n=t.schema?.facts??{},r=Object.keys(n);if(r.length===0)return;let i=new Set(["self","prev","current"]),s="crossModuleDeps"in t&&t.crossModuleDeps?Object.keys(t.crossModuleDeps):[];for(let o of s)i.add(o);for(let o of r)if(i.has(o))throw new Error(`[Directive] module '${e}': fact key '${o}' conflicts with a reserved namespace pivot or evaluation alias (self / prev / current / a crossModuleDep namespace). Three fixes:
export{b as createAuditLedger,a as memorySink}from'./chunk-PA6VC32N.js';import {a as a$2}from'./chunk-644QZVTT.js';export{a as createSystem}from'./chunk-644QZVTT.js';export{b as DirectiveError,o as RequirementSet,n as forType,k as generateRequirementId,h as isNamespacedSystem,m as isRequirementType,g as isSingleModuleSystem,l as req,e as typedConstraint,f as typedResolver}from'./chunk-R2GHSCTR.js';import {o,p as p$1,i,g,a as a$1,l,h as h$1,b as b$1}from'./chunk-2FF6QGOA.js';export{v as applyPatch,u as evaluateKeySelector,o as evaluatePredicate,p as evaluatePredicateExplained,s as evaluateTemplate,r as extractDeps,t as extractTemplateKeys,c as getKind,e as getOperatorsForKind,d as getSchemaFieldKinds,h as isPredicate,k as isTemplate,f as listAllPredicateOperators,q as memoizePredicate,l as validatePredicate,n as validatePredicateAgainstSchema}from'./chunk-2FF6QGOA.js';import {k as k$1}from'./chunk-I722BZA5.js';import {e,h,a}from'./chunk-PXRV64PA.js';export{k as diffSnapshots,l as isSignedSnapshot,i as isSnapshotExpired,g as shallowEqual,m as signSnapshot,j as validateSnapshot,n as verifySnapshotSignature}from'./chunk-PXRV64PA.js';var C=1e6;function Me(e,t){try{l(e);}catch(r){let i=r instanceof Error?r.message:String(r);throw new Error(`[Directive] replayUnder: the ${t} predicate is invalid \u2014 ${i}`)}if(!h$1(e)){let r=e===null||typeof e!="object"?`${typeof e} \u2014 ${JSON.stringify(e)}`:JSON.stringify(e).slice(0,80);throw new Error(`[Directive] replayUnder: the ${t} predicate is not a valid FactPredicate (got ${r})`)}let n;if(i(e,{operator(r,i){n===void 0&&i.startsWith("$")&&!a$1.has(i)&&(n=i);},strayOperatorKey(r){n===void 0&&!a$1.has(r)&&!b$1.has(r)&&(n=r);}}),n!==void 0)throw new Error(`[Directive] replayUnder: the ${t} predicate uses an unknown operator "${n}" \u2014 known operators: ${[...a$1].join(", ")}`)}function Ae(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&Array.isArray(e.snapshots))return De(e);let t=Array.isArray(e)?e:e&&typeof e=="object"&&Array.isArray(e.frames)?e.frames:null;if(!t)throw new Error("[Directive] toReplayFrames: history must be a JSON array of frames, an object with a `frames` array, or a history export with a `snapshots` array");if(t.length>C)throw new Error(`[Directive] toReplayFrames: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${C}) \u2014 split or down-sample the history`);return t.map((n,r)=>{if(n&&typeof n=="object"&&"facts"in n){let i=n,s={id:i.id??`#${r}`,facts:i.facts??{}};return typeof i.timestamp=="number"&&(s.timestamp=i.timestamp),s}return {id:`#${r}`,facts:n??{}}})}function De(e){let t=typeof e=="string"?JSON.parse(e):e;if(Array.isArray(t))return se(t);if(!t||typeof t!="object")throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");let n=t;if(n.version!==void 0&&n.version!==1)throw new Error(`[Directive] framesFromHistory: unsupported history export version ${JSON.stringify(n.version)} \u2014 expected 1`);if(!Array.isArray(n.snapshots))throw new Error("[Directive] framesFromHistory: expected a history export object with a `snapshots` array (from system.history.export())");return se(n.snapshots)}function se(e){if(!Array.isArray(e))throw new Error("[Directive] framesFromSnapshots: expected an array of fact-state snapshots");if(e.length>C)throw new Error(`[Directive] framesFromSnapshots: history has ${e.length} snapshots, exceeds the MAX_REPLAY_FRAMES limit (${C}) \u2014 split or down-sample the history`);for(let t=0;t<e.length;t++){let n=e[t];if(!n||typeof n!="object"||!("facts"in n))throw new Error(`[Directive] framesFromSnapshots: snapshot at index ${t} is not a { facts, ... } object`)}return Ae(e)}function H(e){let{frames:t,original:n,proposed:r,entityKey:i}=e,s=e.maxSamples??20,o$1=s>0?s:0;if(t.length>C)throw new Error(`[Directive] replayUnder: history has ${t.length} frames, exceeds the MAX_REPLAY_FRAMES limit (${C}) \u2014 split or down-sample the history`);Me(n,"original"),Me(r,"proposed");let u=0,a=0,c=0,l=0,d=0,g=[],y=[],$=i?new Set:void 0,m=i?new Set:void 0,M;for(let F of t){let T=F.facts,v=o(n,T,M),A=o(r,T,M);v&&(u++,$?.add(T[i])),A&&(a++,m?.add(T[i])),v===A?d++:!v&&A?(c++,g.length<o$1&&g.push(Re(F,n,r,M))):(l++,y.length<o$1&&y.push(Re(F,n,r,M))),M=T;}let E={framesEvaluated:t.length,original:{matched:u},proposed:{matched:a},delta:a-u,newMatchCount:c,lostMatchCount:l,unchanged:d,newMatches:g,lostMatches:y};return $&&m&&(E.original.matchedEntities=$.size,E.proposed.matchedEntities=m.size),E}function Re(e,t,n,r){let i=e.facts,s={frameId:e.id,facts:i,originalExplain:p$1(t,i,r),proposedExplain:p$1(n,i,r)};return e.timestamp!==void 0&&(s.timestamp=e.timestamp),s}var ae=1e4,Ce=5e7;function It(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===1&&typeof e.$hole=="string"}function ue(e,t,n=new Set,r=0){if(r>g)throw new Error(`[Directive] sweepUnder: template exceeds MAX_PREDICATE_DEPTH (${g}) \u2014 flatten the template or split the sweep`);if(It(e)){let i=e.$hole;if(!(i in t))throw new Error(`[Directive] sweepUnder: template references hole "${i}" but sweep has no values for it`);return t[i]}if(e===null||typeof e!="object")return e;if(n.has(e))throw new Error("[Directive] sweepUnder: template contains a cycle \u2014 predicate templates must be a tree");n.add(e);try{if(Array.isArray(e))return e.map(s=>ue(s,t,n,r+1));let i={};for(let[s,o]of Object.entries(e))i[s]=ue(o,t,n,r+1);return i}finally{n.delete(e);}}function*Ee(e,t){if(e.length===0){yield {};return}let n=e[0],r=e.slice(1),i=t[n]??[];for(let s of i)for(let o of Ee(r,t))yield {[n]:s,...o};}function Lt(e){let t=1;for(let n of Object.values(e))t*=n.length;return t}function qt(e){let{frames:t,original:n,template:r,sweep:i,objective:s=T=>T.proposed.matched,entityKey:o,maxSamples:u=0}=e,a=Object.keys(i);if(a.length===0)throw new Error("[Directive] sweepUnder: `sweep` must contain at least one hole name");let c=Lt(i);if(c>ae)throw new Error(`[Directive] sweepUnder: grid has ${c} points, exceeds the MAX_SWEEP_POINTS limit (${ae}) \u2014 narrow the sweep ranges or split the run`);if(c===0)throw new Error("[Directive] sweepUnder: at least one hole has zero candidate values");let l=c*t.length;if(l>Ce)throw new Error(`[Directive] sweepUnder: ${c} points \xD7 ${t.length} frames = ${l} per-frame evaluations, exceeds the MAX_SWEEP_EVALUATIONS limit (${Ce}) \u2014 narrow the sweep, down-sample the history, or split the run`);let d=false,g=T=>{let v;try{v=s(T);}catch(A){return d||(d=true,console.warn(`[Directive] sweepUnder: objective threw \u2014 point will not rank (${A.message})`)),Number.NEGATIVE_INFINITY}return typeof v!="number"||!Number.isFinite(v)?(d||(d=true,console.warn(`[Directive] sweepUnder: objective returned a non-finite number (${String(v)}) \u2014 point will not rank`)),Number.NEGATIVE_INFINITY):v},y=H({frames:t,original:n,proposed:n,entityKey:o,maxSamples:u}),$={values:{},report:y,score:g(y)},m=[],M=0,E=Number.NEGATIVE_INFINITY;for(let T of Ee(a,i)){let v=ue(r,T),A=H({frames:t,original:n,proposed:v,entityKey:o,maxSamples:u}),te=g(A);te>E&&(E=te,M=m.length),m.push({values:T,report:A,score:te});}let F=m[M];return {points:m,bestIndex:M,best:F,baseline:$}}function ce(e){let t=e&&typeof e=="object"&&!Array.isArray(e)&&"constraints"in e?e.constraints:e;if(Array.isArray(t)){let n={};for(let r of t){if(!r||typeof r!="object"||!("id"in r))throw new Error("[Directive] diffRules: array entries must be `{ id, whenSpec }` objects");let i=r;if(typeof i.id!="string")throw new Error("[Directive] diffRules: constraint `id` must be a string");n[i.id]=i.whenSpec;}return n}if(t&&typeof t=="object")return t;throw new Error("[Directive] diffRules: expected a `{ id: whenSpec }` map, an array of `{ id, whenSpec }`, or `{ constraints: ... }`")}var Bt=new Set(["$eq","$ne","$in","$nin","$exists","$gt","$gte","$lt","$lte","$between","$matches","$startsWith","$endsWith","$contains","$changed"]),Wt=new Set(["$all","$any","$not"]);function xe(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Ut(e){if(!xe(e))return false;let t=Object.keys(e);if(t.length===0)return false;let n=false;for(let r of t){if(!r.startsWith("$"))return false;Bt.has(r)&&(n=true);}return n}function S(e,t="",n=[]){if(e===null||typeof e!="object")return n;if(Array.isArray(e)){for(let r of e)if(r&&typeof r=="object"&&"fact"in r&&"op"in r){let i=r;n.push({path:t?`${t}.${String(i.fact)}`:String(i.fact),op:String(i.op),value:i.value});}return n}if("$all"in e&&Array.isArray(e.$all))return e.$all.forEach((i,s)=>{S(i,`${t}$all[${s}]`,n);}),n;if("$any"in e&&Array.isArray(e.$any))return e.$any.forEach((i,s)=>{S(i,`${t}$any[${s}]`,n);}),n;if("$not"in e)return S(e.$not,`${t}$not`,n),n;for(let[r,i]of Object.entries(e)){let s=t?`${t}.${r}`:r;if(Ut(i))for(let[o,u]of Object.entries(i))n.push({path:s,op:o,value:u});else xe(i)&&!Wt.has(r)?S(i,s,n):n.push({path:s,op:"$eq",value:i});}return n}function D(e){return typeof e=="number"&&Number.isFinite(e)}function Kt(e,t,n){switch(e){case "$gte":case "$gt":if(D(t)&&D(n)){if(n<t)return "relaxed";if(n>t)return "tightened"}return null;case "$lte":case "$lt":if(D(t)&&D(n)){if(n>t)return "relaxed";if(n<t)return "tightened"}return null;case "$between":{if(Array.isArray(t)&&Array.isArray(n)&&t.length===2&&n.length===2&&D(t[0])&&D(t[1])&&D(n[0])&&D(n[1])){let r=t[1]-t[0],i=n[1]-n[0];if(i>r)return "relaxed";if(i<r)return "tightened"}return null}case "$in":case "$nin":{if(Array.isArray(t)&&Array.isArray(n))if(e==="$in"){if(n.length>t.length)return "relaxed";if(n.length<t.length)return "tightened"}else {if(n.length>t.length)return "tightened";if(n.length<t.length)return "relaxed"}return null}case "$contains":{if(Array.isArray(t)&&Array.isArray(n)){if(n.length>t.length)return "relaxed";if(n.length<t.length)return "tightened"}return null}default:return null}}function zt(e){let t=ce(e.before),n=ce(e.after),i=[...new Set([...Object.keys(t),...Object.keys(n)])].sort(),s=[],o={added:0,removed:0,changed:0,unchanged:0,totalClauseChanges:0};for(let u of i){let a=t[u],c=n[u],l=u in t,d=u in n;if(l&&!d){let y=S(a),$=y.length===0?[{path:"(function-form predicate)",kind:"removed"}]:y.map(m=>({path:m.path,kind:"removed",before:{op:m.op,value:m.value}}));le($),s.push({id:u,status:"removed",changes:$}),o.removed++,o.totalClauseChanges+=$.length;continue}if(!l&&d){let y=S(c),$=y.length===0?[{path:"(function-form predicate)",kind:"added"}]:y.map(m=>({path:m.path,kind:"added",after:{op:m.op,value:m.value}}));le($),s.push({id:u,status:"added",changes:$}),o.added++,o.totalClauseChanges+=$.length;continue}let g=Oe(a,c);g.length===0?(s.push({id:u,status:"unchanged",changes:[]}),o.unchanged++):(s.push({id:u,status:"changed",changes:g}),o.changed++,o.totalClauseChanges+=g.length);}return {constraints:s,summary:o}}function Oe(e$1,t){if(e$1!==void 0&&t!==void 0&&(e$1===null||t===null||typeof e$1!="object"||typeof t!="object"))return e(e$1)===e(t)?[]:[{path:"",kind:"changed",before:{op:"$eq",value:e$1},after:{op:"$eq",value:t}}];let n=e$1===void 0?[]:S(e$1),r=t===void 0?[]:S(t),i=c=>`${c.path}::${c.op}`,s=new Map(n.map(c=>[i(c),c])),o=new Map(r.map(c=>[i(c),c])),u=new Set([...s.keys(),...o.keys()]),a=[];for(let c of u){let l=s.get(c),d=o.get(c);if(l&&!d){a.push({path:l.path,kind:"removed",before:{op:l.op,value:l.value}});continue}if(!l&&d){a.push({path:d.path,kind:"added",after:{op:d.op,value:d.value}});continue}if(l&&d){if(e(l.value)===e(d.value))continue;let g=Kt(l.op,l.value,d.value);a.push({path:l.path,kind:g??"changed",before:{op:l.op,value:l.value},after:{op:d.op,value:d.value}});}}return le(a),a}function le(e){e.sort((t,n)=>{let r=t.path.localeCompare(n.path);if(r!==0)return r;let i=t.before?.op??t.after?.op??"",s=n.before?.op??n.after?.op??"";return i.localeCompare(s)});}function Ht(e){return h(e)}function J(e){return e===null?"null":e===void 0?"undefined":e instanceof Date?e.toISOString():typeof e=="string"||typeof e=="object"?JSON.stringify(e):String(e)}function Jt(e){let t=e.path,n=J(e.expected),r=J(e.actual);switch(e.op){case "$eq":return `set ${t} to ${n} (currently ${r})`;case "$ne":return `change ${t} to anything other than ${n} (currently ${r})`;case "$gt":return `set ${t} above ${n} (currently ${r})`;case "$gte":return `set ${t} to at least ${n} (currently ${r})`;case "$lt":return `set ${t} below ${n} (currently ${r})`;case "$lte":return `set ${t} to at most ${n} (currently ${r})`;case "$in":return `set ${t} to one of ${n} (currently ${r})`;case "$nin":return `set ${t} to something other than ${n} (currently ${r})`;case "$exists":return e.expected===true?`set ${t} to a non-null value (currently null/missing)`:`unset ${t} (currently ${r})`;case "$between":return Array.isArray(e.expected)&&e.expected.length===2?`set ${t} between ${J(e.expected[0])} and ${J(e.expected[1])} (currently ${r})`:`set ${t} within range ${n} (currently ${r})`;case "$startsWith":return `set ${t} to start with ${n} (currently ${r})`;case "$endsWith":return `set ${t} to end with ${n} (currently ${r})`;case "$contains":return `set ${t} to contain ${n} (currently ${r})`;case "$matches":return `set ${t} to match the pattern ${n} (currently ${r})`;case "$changed":return `the previous-vs-current change of ${t} is required to differ (currently they match: ${r})`;case "$all":case "$any":case "$not":return `the ${e.op} group at "${t}" did not pass \u2014 see its child clauses`;default:return `clause at ${t} (${e.op}) failed: expected ${n}, got ${r}`}}function je(e,t){for(let n of e)if(!n.pass){if((n.op==="$all"||n.op==="$any"||n.op==="$not")&&n.children){je(n.children,t);continue}t.push({path:n.path,op:n.op,expected:n.expected,actual:n.actual,suggestion:Jt(n)});}}function Qt(e,t,n){let r=p$1(e,t,n),i$1=r.every(o=>o.pass),s=[];if(i$1||je(r,s),!i$1&&n===void 0){let o=[];i(e,{operator(u,a){a==="$changed"&&o.push(u);}});for(let u of o)s.push({path:u,op:"$changed",expected:true,actual:void 0,suggestion:`$changed clause at "${u}" cannot be evaluated without a \`prev\` snapshot \u2014 pass predict(predicate, facts, prev).`});}return {wouldFire:i$1,whenExplain:r,missingChanges:s}}var Pe=new Set(["$eq","$ne","$gt","$gte","$lt","$lte","$in","$nin"]);function Q(e,t){if(e===t)return 0;if(typeof e=="number"&&typeof t=="number"||typeof e=="bigint"&&typeof t=="bigint")return e<t?-1:e>t?1:0;if(e instanceof Date&&t instanceof Date){let n=e.getTime(),r=t.getTime();return n<r?-1:n>r?1:0}return typeof e=="string"&&typeof t=="string"?e<t?-1:e>t?1:0:Number.NaN}function _(e,t){if(e===t)return true;if(typeof e!=typeof t||e===null||t===null||typeof e!="object"||Array.isArray(e)!==Array.isArray(t))return false;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return false;for(let i=0;i<e.length;i++)if(!_(e[i],t[i]))return false;return true}let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return false;for(let i of n)if(!_(e[i],t[i]))return false;return true}function Xt(e,t){if(!Pe.has(e.op)||!Pe.has(t.op))return {type:"overlap",reason:`Both rules touch "${e.path}".`};if(e.op==="$eq"&&t.op==="$eq")return _(e.value,t.value)?{type:"subset",reason:`Both rules require ${e.path} = ${JSON.stringify(e.value)} \u2014 candidate is redundant.`}:{type:"direct",reason:`Candidate requires ${e.path} = ${JSON.stringify(e.value)} but an existing rule requires ${e.path} = ${JSON.stringify(t.value)} \u2014 they cannot both fire.`};if(e.op==="$eq"&&t.op==="$ne")return _(e.value,t.value)?{type:"direct",reason:`Candidate requires ${e.path} = ${JSON.stringify(e.value)} but an existing rule excludes that value.`}:null;if(e.op==="$ne"&&t.op==="$eq")return _(e.value,t.value)?{type:"direct",reason:`Candidate excludes ${e.path} = ${JSON.stringify(e.value)} but an existing rule requires that exact value.`}:null;if(e.op==="$in"&&t.op==="$in"){let o=new Set(Array.isArray(e.value)?e.value:[]),u=new Set(Array.isArray(t.value)?t.value:[]),a=[...o].filter(c=>u.has(c));return a.length===0?{type:"direct",reason:`Candidate $in set for ${e.path} (${JSON.stringify([...o])}) and existing $in set (${JSON.stringify([...u])}) have no values in common \u2014 the candidate can never fire while the existing rule holds.`}:a.length===o.size&&a.length<u.size?{type:"subset",reason:`Candidate $in set for ${e.path} is a strict subset of the existing rule's $in set.`}:null}let n=e.op==="$gt"||e.op==="$gte"?e.value:void 0,r=e.op==="$lt"||e.op==="$lte"?e.value:void 0,i=t.op==="$gt"||t.op==="$gte"?t.value:void 0,s=t.op==="$lt"||t.op==="$lte"?t.value:void 0;if(n!==void 0&&s!==void 0){let o=Q(n,s);if(!Number.isNaN(o)&&(o>0||o===0&&(e.op==="$gt"||t.op==="$lt")))return {type:"direct",reason:`Candidate requires ${e.path} ${e.op==="$gt"?">":"\u2265"} ${JSON.stringify(n)} but an existing rule caps it at ${t.op==="$lt"?"<":"\u2264"} ${JSON.stringify(s)}.`}}if(i!==void 0&&r!==void 0){let o=Q(i,r);if(!Number.isNaN(o)&&(o>0||o===0&&(t.op==="$gt"||e.op==="$lt")))return {type:"direct",reason:`Candidate caps ${e.path} at ${e.op==="$lt"?"<":"\u2264"} ${JSON.stringify(r)} but an existing rule requires it ${t.op==="$gt"?">":"\u2265"} ${JSON.stringify(i)}.`}}if(n!==void 0&&i!==void 0){let o=Q(n,i);if(!Number.isNaN(o)&&o>0)return {type:"subset",reason:`Candidate's lower bound on ${e.path} (${JSON.stringify(n)}) is stricter than the existing rule's lower bound (${JSON.stringify(i)}) \u2014 candidate is a subset.`}}if(r!==void 0&&s!==void 0){let o=Q(r,s);if(!Number.isNaN(o)&&o<0)return {type:"subset",reason:`Candidate's upper bound on ${e.path} (${JSON.stringify(r)}) is stricter than the existing rule's upper bound (${JSON.stringify(s)}) \u2014 candidate is a subset.`}}return {type:"overlap",reason:`Both rules constrain "${e.path}".`}}function Fe(e){return typeof e=="object"&&e!==null&&typeof e.id=="string"}var Zt={checkAgainst(e,t){let n=Array.isArray(t)?t:"constraints"in t&&Array.isArray(t.constraints)?t.constraints:[],r=S(e);if(r.length===0)return {contradictions:[],warnings:[]};let i=new Map;for(let u of r){let a=i.get(u.path)??[];a.push(u),i.set(u.path,a);}let s=[],o=[];for(let u of n){if(!Fe(u)||u.whenSpec===void 0)continue;let a=S(u.whenSpec);for(let c of a){let l=i.get(c.path);if(l)for(let d of l){let g=Xt(d,c);if(!g)continue;let y={constraintId:u.id,type:g.type,reason:g.reason,candidatePath:d.path,candidate:{op:d.op,value:d.value},existing:{op:c.op,value:c.value}};g.type==="overlap"||g.type==="subset"?o.push(y):s.push(y);}}}return {contradictions:s,warnings:o}},checkOwns(e,t){let n=Array.isArray(t)?t:"constraints"in t&&Array.isArray(t.constraints)?t.constraints:[],r=S(e);if(r.length===0)return {warnings:[]};let i=new Set(r.map(o=>o.path)),s=[];for(let o of n){if(!Fe(o))continue;let u=Array.isArray(o.owns)?o.owns:[],a=Array.isArray(o.bind)?o.bind:[];for(let c of u)i.has(c)&&s.push({constraintId:o.id,candidatePath:c,source:"owns",reason:`Constraint "${o.id}" already owns "${c}" \u2014 candidate would race or shadow its writes.`,severity:"warning"});for(let c of a)i.has(c)&&s.push({constraintId:o.id,candidatePath:c,source:"bind",reason:`Constraint "${o.id}" binds "${c}" \u2014 candidate would write to a bound field.`,severity:"warning"});}return {warnings:s}}};var I=new Map,Yt=50;function Gt(e){let t=I.get(e);if(!t){try{t=new Intl.NumberFormat(e);}catch{t=new Intl.NumberFormat("en-US");}if(I.size>=Yt){let n=I.keys().next().value;n!==void 0&&I.delete(n);}I.set(e,t);}return t}function Vt(e,t={}){let n=t.style??"natural",r=t.parenthesize??true,i=t.locale??"en-US",s=t.factName??(a=>a);if(e===null||typeof e!="object")return "<invalid predicate>";let o={style:n,parenthesize:r,locale:i,factName:s,seen:new WeakSet,cycle:false},u=X(e,o,0);return o.cycle?"<invalid predicate: cycle>":u}var Ie=" AND ",en=" OR ",tn="NOT",Le=" \u2227 ",nn=" \u2228 ",rn="\xAC";function q(e){return typeof e!="object"||e===null||Array.isArray(e)?false:!(e instanceof Date)&&!(e instanceof RegExp)}function on(e){if(!q(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function X(e,t,n){if(n>g)return a&&console.warn(`[Directive] describePredicate: depth limit (${g}) exceeded \u2014 bailing.`),t.style==="formal"?"\u22A5":"always true";if(Array.isArray(e))return sn(e,t);if(!q(e))return f(e,t);if(t.seen.has(e))return t.cycle=true,"<invalid predicate: cycle>";t.seen.add(e);let r=e,i=Object.keys(r);for(let o of ["$all","$any","$not"])if(o in r)return an(o,r[o],t,n);let s=[];for(let o of i)o.startsWith("$")||s.push(qe(o,r[o],t,n));return Z(s,t)}function sn(e,t,n){let r=[];for(let i of e){if(!q(i))continue;let s=i;typeof s.fact!="string"||typeof s.op!="string"||r.push(L(s.fact,s.op,s.value,t));}return r.length===0?t.style==="formal"?"\u22A4":"always true":Z(r,t)}function an(e,t,n,r){if(e==="$not"){if(q(t)&&Object.keys(t).length===0)return n.style==="formal"?"\u22A5":"never";let o=X(t,n,r+1);return o==="always true"?"never":o==="\u22A4"?"\u22A5":`${n.style==="formal"?rn:`${tn} `}(${o})`}if(!Array.isArray(t))return n.style==="formal"?"\u22A5":"<invalid predicate>";if(t.length===0)return e==="$all"?n.style==="formal"?"\u22A4":"always true":n.style==="formal"?"\u22A5":"never";let i=[];for(let o of t){let u=X(o,n,r+1);i.push(u);}if(i.length===1)return i[0];let s=n.parenthesize?i.map(o=>`(${o})`):i;return e==="$all"?s.join(n.style==="formal"?Le:Ie):s.join(n.style==="formal"?nn:en)}function qe(e,t,n,r){if(on(t)){let i=t,s=Object.keys(i);if(s.length===1)return L(e,s[0],i[s[0]],n);let o=s.map(u=>L(e,u,i[u],n));return Z(o,n)}if(q(t)){let i=t;if("$all"in i||"$any"in i||"$not"in i)return X(t,n,r+1);let o=[];for(let u of Object.keys(i))u.startsWith("$")||o.push(qe(`${e}.${u}`,i[u],n,r+1));return o.length===0?L(e,"$eq",t,n):Z(o,n)}return L(e,"$eq",t,n)}function L(e,t,n,r){let i=r.style==="formal"?e:r.factName(e);return r.style==="formal"?cn(i,t,n,r):un(i,t,n,r)}function un(e,t,n,r){switch(t){case "$eq":return n===null?`${e} is null`:`${e} is ${f(n,r)}`;case "$ne":return n===null?`${e} is not null`:`${e} is not ${f(n,r)}`;case "$gt":return `${e} is more than ${f(n,r)}`;case "$gte":return `${e} is at least ${f(n,r)}`;case "$lt":return `${e} is less than ${f(n,r)}`;case "$lte":return `${e} is at most ${f(n,r)}`;case "$in":return `${e} is one of ${Ne(n,r)}`;case "$nin":return `${e} is not one of ${Ne(n,r)}`;case "$exists":return n===true?`${e} is set`:`${e} is not set`;case "$between":return Array.isArray(n)&&n.length===2?`${e} is between ${f(n[0],r)} and ${f(n[1],r)}`:`${e} is between ${f(n,r)}`;case "$startsWith":return `${e} starts with ${O(n,r,true)}`;case "$endsWith":return `${e} ends with ${O(n,r,true)}`;case "$contains":return `${e} contains ${O(n,r,true)}`;case "$matches":return n instanceof RegExp?`${e} matches ${n.toString()}`:`${e} matches ${f(n,r)}`;case "$changed":return `${e} changed`;default:return a&&!a$1.has(t)&&console.warn(`[Directive] describePredicate: unknown operator "${t}" \u2014 falling through to generic rendering.`),`${e} ${t} ${f(n,r)}`}}function cn(e,t,n,r){switch(t){case "$eq":return `${e} = ${f(n,r)}`;case "$ne":return `${e} \u2260 ${f(n,r)}`;case "$gt":return `${e} > ${f(n,r)}`;case "$gte":return `${e} \u2265 ${f(n,r)}`;case "$lt":return `${e} < ${f(n,r)}`;case "$lte":return `${e} \u2264 ${f(n,r)}`;case "$in":return `${e} \u2208 {${_e(n,r)}}`;case "$nin":return `${e} \u2209 {${_e(n,r)}}`;case "$exists":return n===true?`\u2203 ${e}`:`\u2204 ${e}`;case "$between":return Array.isArray(n)&&n.length===2?`${f(n[0],r)} \u2264 ${e} \u2264 ${f(n[1],r)}`:`${e} \u2208 [${f(n,r)}]`;case "$startsWith":return `${e} ^= ${O(n,r,true)}`;case "$endsWith":return `${e} $= ${O(n,r,true)}`;case "$contains":return `${e} \u2287 ${O(n,r,true)}`;case "$matches":return n instanceof RegExp?`${e} ~ ${n.toString()}`:`${e} ~ ${f(n,r)}`;case "$changed":return `\u0394${e}`;default:return a&&!a$1.has(t)&&console.warn(`[Directive] describePredicate: unknown operator "${t}" \u2014 falling through to generic rendering.`),`${e} ${t} ${f(n,r)}`}}function Y(e){return e.length===0?true:/[\s,"']/.test(e)}function O(e,t,n){return typeof e!="string"||n||Y(e)?JSON.stringify(e):e}function f(e,t){if(e===null)return "null";if(e===void 0)return "undefined";if(typeof e=="boolean")return e?"true":"false";if(typeof e=="number"){if(!Number.isFinite(e))return String(e);try{return Gt(t.locale).format(e)}catch{return String(e)}}if(typeof e=="bigint")return t.style==="formal"?`${e.toString()}n`:e.toString();if(typeof e=="string")return t.style==="formal"||Y(e)?JSON.stringify(e):e;if(e instanceof Date)return e.toISOString();if(e instanceof RegExp)return e.toString();if(Array.isArray(e))return `[${e.map(n=>f(n,t)).join(", ")}]`;if(typeof e=="object")try{return JSON.stringify(e)}catch{return "[object]"}return String(e)}function Ne(e,t){return Array.isArray(e)?e.map(n=>typeof n=="string"?Y(n)?JSON.stringify(n):n:f(n,t)).join(", "):f(e,t)}function _e(e,t){return Array.isArray(e)?e.map(n=>typeof n=="string"?Y(n)?JSON.stringify(n):n:f(n,t)).join(", "):f(e,t)}function Z(e,t){if(e.length===0)return t.style==="formal"?"\u22A4":"always true";if(e.length===1)return e[0];let n=t.style==="formal"?Le:Ie;return t.parenthesize,e.join(n)}var ln=/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)?$/;function W(e,t){if(typeof e!="string"||!ln.test(e))throw new Error(`[Directive] predicateToSQL: invalid ${t} identifier "${e}" \u2014 must match /^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)?$/`)}function Be(e,t){if(t&&!t.includes(e))throw new Error(`[Directive] predicateToSQL: column "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function dn(e){if(Array.isArray(e)){if(e.length===0)throw new Error("[Directive] predicateToSQL: select must not be empty");for(let n of e)W(n,"column");return e.join(", ")}let t=e;return t==="*"?"*":(W(t,"column"),t)}function b(e,t){return e.params.push(t),e.placeholder(e.params.length)}function de(e,t,n,r){switch(t){case "$eq":return `${e} = ${b(r,n)}`;case "$ne":return `${e} <> ${b(r,n)}`;case "$gt":return `${e} > ${b(r,n)}`;case "$gte":return `${e} >= ${b(r,n)}`;case "$lt":return `${e} < ${b(r,n)}`;case "$lte":return `${e} <= ${b(r,n)}`;case "$in":if(!Array.isArray(n))throw new Error("[Directive] predicateToSQL: $in operand must be an array");return `${e} = ANY(${b(r,n)})`;case "$nin":if(!Array.isArray(n))throw new Error("[Directive] predicateToSQL: $nin operand must be an array");return `NOT (${e} = ANY(${b(r,n)}))`;case "$exists":return n===true?`${e} IS NOT NULL`:`${e} IS NULL`;case "$between":{if(!Array.isArray(n)||n.length!==2)throw new Error("[Directive] predicateToSQL: $between operand must be a [low, high] tuple");return `${e} BETWEEN ${b(r,n[0])} AND ${b(r,n[1])}`}case "$startsWith":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $startsWith operand must be a string");return `${e} LIKE ${b(r,fe(n))} || '%' ESCAPE '\\'`;case "$endsWith":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $endsWith operand must be a string");return `${e} LIKE '%' || ${b(r,fe(n))} ESCAPE '\\'`;case "$contains":if(typeof n!="string")throw new Error("[Directive] predicateToSQL: $contains only supports string operands \u2014 array containment requires a JOIN, not a predicate");return `${e} LIKE '%' || ${b(r,fe(n))} || '%' ESCAPE '\\'`;case "$matches":{if(!(n instanceof RegExp))throw new Error("[Directive] predicateToSQL: $matches operand must be a RegExp");let i=n.flags.includes("i")?"~*":"~";return `${e} ${i} ${b(r,n.source)}`}case "$changed":throw new Error('[Directive] predicateToSQL: $changed is an effects-only operator \u2014 no server-side translation (a database row has no "prev" snapshot)');default:throw new Error(`[Directive] predicateToSQL: unknown operator "${t}" \u2014 known: ${[...a$1].join(", ")}`)}}function fe(e){return e.replace(/[\\%_]/g,"\\$&")}function We(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function fn(e){if(!We(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function pe(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToSQL: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function B(e,t,n){if(n>g)throw new Error(`[Directive] predicateToSQL: predicate depth limit (${g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error(`[Directive] predicateToSQL: predicate must be an object or array, got ${typeof e}`);if(Array.isArray(e)){if(e.length===0)return "TRUE";let i=e.map(s=>{if(!s||typeof s!="object"||!("fact"in s)||!("op"in s))throw new Error("[Directive] predicateToSQL: array-form clause must be { fact, op, value }");let o=s;return W(o.fact,"column"),Be(o.fact,t.allowed),de(o.fact,o.op,o.value,t)});return i.length===1?i[0]:`(${i.join(" AND ")})`}if("$all"in e){pe(e,"$all");let i=e.$all;if(!Array.isArray(i))throw new Error("[Directive] predicateToSQL: $all must be an array");if(i.length===0)return "TRUE";let s=i.map(o=>B(o,t,n+1));return s.length===1?s[0]:`(${s.join(" AND ")})`}if("$any"in e){pe(e,"$any");let i=e.$any;if(!Array.isArray(i))throw new Error("[Directive] predicateToSQL: $any must be an array");if(i.length===0)return "FALSE";let s=i.map(o=>B(o,t,n+1));return s.length===1?s[0]:`(${s.join(" OR ")})`}if("$not"in e){pe(e,"$not");let i=e.$not;return `NOT (${B(i,t,n+1)})`}let r=[];for(let[i,s]of Object.entries(e))if(W(i,"column"),Be(i,t.allowed),fn(s))for(let[o,u]of Object.entries(s)){if(!a$1.has(o))throw new Error(`[Directive] predicateToSQL: unknown operator "${o}" on column "${i}" \u2014 known: ${[...a$1].join(", ")}`);r.push(de(i,o,u,t));}else {if(We(s))throw new Error(`[Directive] predicateToSQL: nested predicate at "${i}" \u2014 cross-module / partial-match predicates have no SQL equivalent (single-table queries only in v1; pass a flat predicate or build JOIN by hand with predicateToWhere)`);r.push(de(i,"$eq",s,t));}return r.length===0?"TRUE":r.length===1?r[0]:`(${r.join(" AND ")})`}var Ue=e=>`$${e}`;function pn(e,t){let{table:n,allowedKeys:r}=t,i=t.placeholder??Ue,s=t.select??"*";W(n,"table");let o=dn(s),u={params:[],placeholder:i,allowed:r},a=B(e,u,0);return {sql:`SELECT ${o} FROM ${n} WHERE ${a}`,where:a,params:u.params}}function gn(e,t={}){let n=t.placeholder??Ue,r={params:[],placeholder:n,allowed:t.allowedKeys};return {where:B(e,r,0),params:r.params}}function ge(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function he(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function yn(e){if(!he(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}var hn=/^[A-Za-z_][A-Za-z0-9_]*$/,mn=/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;function Ke(e,t){if(typeof e!="string"||e.length===0)throw new Error(`[Directive] predicateToMongo: field name must be a non-empty string, got ${typeof e}`);if(e.startsWith("$"))throw new Error(`[Directive] predicateToMongo: field name "${e}" starts with "$" \u2014 reserved for Mongo operators (a top-level $where would be an injection vector)`);if(!(t.allowDottedPaths?mn:hn).test(e))throw new Error(`[Directive] predicateToMongo: invalid field name "${e}"${t.allowDottedPaths?"":' \u2014 pass options.allowDottedPaths=true to permit sub-document paths like "user.role"'}`)}function ze(e,t){if(t&&!t.includes(e))throw new Error(`[Directive] predicateToMongo: field "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function ye(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToMongo: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function He(e,t){switch(e){case "$eq":case "$ne":case "$gt":case "$gte":case "$lt":case "$lte":case "$in":case "$nin":case "$exists":return {[e]:t};case "$between":{if(!Array.isArray(t)||t.length!==2)throw new Error("[Directive] predicateToMongo: $between operand must be a [low, high] tuple");return {$gte:t[0],$lte:t[1]}}case "$startsWith":if(typeof t!="string")throw new Error("[Directive] predicateToMongo: $startsWith operand must be a string");return {$regex:`^${ge(t)}`};case "$endsWith":if(typeof t!="string")throw new Error("[Directive] predicateToMongo: $endsWith operand must be a string");return {$regex:`${ge(t)}$`};case "$contains":if(typeof t=="string")return {$regex:ge(t)};throw new Error("[Directive] predicateToMongo: $contains in Mongo expects a string operand \u2014 for array element membership use $elemMatch or $in directly");case "$matches":{if(t instanceof RegExp)return t.flags?{$regex:t.source,$options:t.flags}:{$regex:t.source};if(typeof t=="string")return {$regex:t};throw new Error("[Directive] predicateToMongo: $matches operand must be a RegExp or string")}case "$changed":throw new Error("[Directive] predicateToMongo: $changed is an effects-only operator \u2014 no MongoDB query equivalent");default:throw new Error(`[Directive] predicateToMongo: unknown operator "${e}" \u2014 known: ${[...a$1].join(", ")}`)}}function j(e,t,n){if(n>g)throw new Error(`[Directive] predicateToMongo: predicate depth limit (${g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error(`[Directive] predicateToMongo: predicate must be an object or array, got ${typeof e}`);if(Array.isArray(e)){if(e.length===0)return {};let i={},s=[];for(let o of e){if(!o||typeof o!="object"||!("fact"in o)||!("op"in o))throw new Error("[Directive] predicateToMongo: array-form clause must be { fact, op, value }");let u=o;Ke(u.fact,t),ze(u.fact,t.allowedKeys);let a=He(u.op,u.value);if(u.fact in i&&he(i[u.fact])){let c=i[u.fact];Object.keys(a).some(d=>d in c)?s.push({[u.fact]:a}):i[u.fact]={...c,...a};}else u.fact in i?s.push({[u.fact]:a}):i[u.fact]=a;}if(s.length>0){let o=[];for(let[u,a]of Object.entries(i))o.push({[u]:a});return o.push(...s),{$and:o}}return i}if("$all"in e){ye(e,"$all");let i=e.$all;if(!Array.isArray(i))throw new Error("[Directive] predicateToMongo: $all must be an array");return i.length===0?{}:i.length===1?j(i[0],t,n+1):{$and:i.map(s=>j(s,t,n+1))}}if("$any"in e){ye(e,"$any");let i=e.$any;if(!Array.isArray(i))throw new Error("[Directive] predicateToMongo: $any must be an array");return i.length===0?{$expr:{$eq:[1,0]}}:i.length===1?j(i[0],t,n+1):{$or:i.map(s=>j(s,t,n+1))}}if("$not"in e){ye(e,"$not");let i=e.$not;return {$nor:[j(i,t,n+1)]}}let r={};for(let[i,s]of Object.entries(e))if(Ke(i,t),ze(i,t.allowedKeys),yn(s)){let o={};for(let[u,a]of Object.entries(s)){if(!a$1.has(u))throw new Error(`[Directive] predicateToMongo: unknown operator "${u}" on field "${i}" \u2014 known: ${[...a$1].join(", ")}`);Object.assign(o,He(u,a));}r[i]=o;}else r[i]=s;return r}function $n(e,t={}){return j(e,t,0)}var wn=/^[A-Za-z_][A-Za-z0-9_]*$/;function Je(e,t){if(typeof e!="string"||!wn.test(e))throw new Error(`[Directive] predicateToPostgrest: invalid column identifier "${e}"`);if(t&&!t.includes(e))throw new Error(`[Directive] predicateToPostgrest: column "${e}" is not in the allowedKeys list \u2014 add it to options.allowedKeys or remove it from the predicate`)}function me(e,t){let n=Object.keys(e).filter(r=>r!==t);if(n.length>0)throw new Error(`[Directive] predicateToPostgrest: ${t} cannot coexist with sibling keys (${n.join(", ")}) \u2014 wrap them in $all together, or move them inside the ${t} children`)}function k(e){if(e==null)return "null";if(typeof e=="boolean")return e?"true":"false";if(typeof e=="number"||typeof e=="bigint")return String(e);if(e instanceof Date)return e.toISOString();if(typeof e=="string")return /[,.():"\\\s]/.test(e)?`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:e;throw new Error(`[Directive] predicateToPostgrest: cannot encode value of type ${typeof e}`)}function Qe(e){return `(${e.map(k).join(",")})`}function $e(e){return e.replace(/[\\%_*]/g,"\\$&")}function P(e,t){switch(e){case "$eq":return `eq.${k(t)}`;case "$ne":return `neq.${k(t)}`;case "$gt":return `gt.${k(t)}`;case "$gte":return `gte.${k(t)}`;case "$lt":return `lt.${k(t)}`;case "$lte":return `lte.${k(t)}`;case "$in":if(!Array.isArray(t))throw new Error("[Directive] predicateToPostgrest: $in operand must be an array");return `in.${Qe(t)}`;case "$nin":if(!Array.isArray(t))throw new Error("[Directive] predicateToPostgrest: $nin operand must be an array");return `not.in.${Qe(t)}`;case "$exists":return t===true?"not.is.null":"is.null";case "$startsWith":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $startsWith operand must be a string");return `like.${k($e(t)+"*")}`;case "$endsWith":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $endsWith operand must be a string");return `like.${k("*"+$e(t))}`;case "$contains":if(typeof t!="string")throw new Error("[Directive] predicateToPostgrest: $contains expects a string operand (array containment is the cs operator with a different shape \u2014 out of scope for v1)");return `like.${k("*"+$e(t)+"*")}`;case "$matches":if(t instanceof RegExp)return `${t.flags.includes("i")?"imatch":"match"}.${k(t.source)}`;if(typeof t=="string")return `match.${k(t)}`;throw new Error("[Directive] predicateToPostgrest: $matches operand must be a RegExp or string");case "$changed":throw new Error("[Directive] predicateToPostgrest: $changed is an effects-only operator \u2014 no server query equivalent");default:throw new Error(`[Directive] predicateToPostgrest: unknown operator "${e}" \u2014 known: ${[...a$1].join(", ")}`)}}function Xe(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function bn(e){if(!Xe(e))return false;let t=Object.keys(e);if(t.length===0)return false;for(let n of t)if(!n.startsWith("$"))return false;return true}function we(e,t){return `${e}=${t}`}function G(e,t){return `${e}=(${t.join(",")})`}function be(e,t,n,r){if(t==="$between"){if(!Array.isArray(n)||n.length!==2)throw new Error("[Directive] predicateToPostgrest: $between operand must be a [low, high] tuple");let i=r?we(e,P("$gte",n[0])):`${e}.${P("$gte",n[0])}`,s=r?we(e,P("$lte",n[1])):`${e}.${P("$lte",n[1])}`;return [i,s]}return [r?we(e,P(t,n)):`${e}.${P(t,n)}`]}function U(e,t,n,r){if(r>g)throw new Error(`[Directive] predicateToPostgrest: predicate depth limit (${g}) exceeded \u2014 flatten the predicate or check for a cyclic spec object`);if(e===null||typeof e!="object")throw new Error("[Directive] predicateToPostgrest: predicate must be an object or array");if(Array.isArray(e)){let s=[];for(let o of e){if(!o||typeof o!="object"||!("fact"in o)||!("op"in o))throw new Error("[Directive] predicateToPostgrest: array-form clause must be { fact, op, value }");let u=o;Je(u.fact,t),s.push(...be(u.fact,u.op,u.value,n));}return s}if("$all"in e){me(e,"$all");let s=e.$all;if(!Array.isArray(s))throw new Error("[Directive] predicateToPostgrest: $all must be an array");if(n){let u=[];for(let a of s)u.push(...U(a,t,true,r+1));return u}let o=[];for(let u of s)o.push(...U(u,t,false,r+1));return [G("and",o)]}if("$any"in e){me(e,"$any");let s=e.$any;if(!Array.isArray(s))throw new Error("[Directive] predicateToPostgrest: $any must be an array");if(s.length===0)return n?["id=is.null","id=not.is.null"]:[G("and",["id.is.null","id.not.is.null"])];let o=[];for(let u of s)o.push(...U(u,t,false,r+1));return [G("or",o)]}if("$not"in e){me(e,"$not");let s=e.$not,o=U(s,t,false,r+1);return [G("not.and",o)]}let i=[];for(let[s,o]of Object.entries(e))if(Je(s,t),bn(o))for(let[u,a]of Object.entries(o)){if(!a$1.has(u))throw new Error(`[Directive] predicateToPostgrest: unknown operator "${u}" on column "${s}" \u2014 known: ${[...a$1].join(", ")}`);i.push(...be(s,u,a,n));}else {if(Xe(o))throw new Error(`[Directive] predicateToPostgrest: nested predicate at "${s}" \u2014 single-table queries only`);i.push(...be(s,"$eq",o,n));}return i}function Sn(e){let t=e.indexOf("=");if(t<0)return encodeURIComponent(e);let n=e.slice(0,t),r=e.slice(t+1);return `${n}=${encodeURIComponent(r)}`}function Tn(e,t={}){let n=t.mode??"querystring",r=U(e,t.allowedKeys,true,0);return r.length===0?"":n==="raw"?r.join("&"):r.map(Sn).join("&")}function V(e=[],t,n,r,i,s,o){return {_type:void 0,_validators:e,_typeName:t,_default:n,_transform:r,_description:i,_refinements:s,_meta:o,validate(u){return V([...e,u],t,n,r,i,s,o)}}}function p(e,t,n,r,i,s,o){return {...V(e,t,n,r,i,s,o),default(a){return p(e,t,a,r,i,s,o)},transform(a){return p([],t,void 0,l=>{let d=r?r(l):l;return a(d)},i,void 0,o)},brand(){return p(e,`Branded<${t}>`,n,r,i,s,o)},describe(a){return p(e,t,n,r,a,s,o)},refine(a,c){let l=[...s??[],{predicate:a,message:c}];return p([...e,a],t,n,r,i,l,o)},nullable(){return p([a=>a===null||e.every(c=>c(a))],`${t} | null`,n,r,i,void 0,o)},optional(){return p([a=>a===void 0||e.every(c=>c(a))],`${t} | undefined`,n,r,i,void 0,o)},meta(a){return p(e,t,n,r,i,s,a)}}}var kn=((...e)=>{if(e.length===0)return p([],"union");let t=e.map(n=>n._typeName??"unknown");return p([n=>e.some(r=>r._validators.every(i=>i(n)))],t.join(" | "))}),vn={string(){let e=(t,n,r,i,s,o)=>({...p(t,"string",n,r,i,s,o),minLength(a){return e([...t,c=>c.length>=a],n,r,i,s,o)},maxLength(a){return e([...t,c=>c.length<=a],n,r,i,s,o)},pattern(a){return e([...t,c=>a.test(c)],n,r,i,s,o)},default(a){return e(t,a,r,i,s,o)},describe(a){return e(t,n,r,a,s,o)},refine(a,c){let l=[...s??[],{predicate:a,message:c}];return e([...t,a],n,r,i,l,o)},meta(a){return e(t,n,r,i,s,a)}});return e([t=>typeof t=="string"])},number(){let e=(t,n,r,i,s,o)=>({...p(t,"number",n,r,i,s,o),min(a){return e([...t,c=>c>=a],n,r,i,s,o)},max(a){return e([...t,c=>c<=a],n,r,i,s,o)},default(a){return e(t,a,r,i,s,o)},describe(a){return e(t,n,r,a,s,o)},refine(a,c){let l=[...s??[],{predicate:a,message:c}];return e([...t,a],n,r,i,l,o)},meta(a){return e(t,n,r,i,s,a)}});return e([t=>typeof t=="number"])},boolean(){return p([e=>typeof e=="boolean"],"boolean")},array(){let e=(t,n,r,i,s,o)=>{let u=p(t,"array",r,void 0,i,void 0,o),a=s??{value:-1};return {...u,get _lastFailedIndex(){return a.value},set _lastFailedIndex(l){a.value=l;},of(l){let d={value:-1};return e([...t,g=>{for(let y=0;y<g.length;y++)if(!l._validators.every($=>$(g[y])))return d.value=y,false;return true}],l,r,i,d,o)},nonEmpty(){return e([...t,l=>l.length>0],n,r,i,a,o)},maxLength(l){return e([...t,d=>d.length<=l],n,r,i,a,o)},minLength(l){return e([...t,d=>d.length>=l],n,r,i,a,o)},default(l){return e(t,n,l,i,a,o)},describe(l){return e(t,n,r,l,a,o)},meta(l){return e(t,n,r,i,a,l)}}};return e([t=>Array.isArray(t)])},object(){let e=(t,n,r,i)=>({...p(t,"object",n,void 0,r,void 0,i),shape(o){return e([...t,u=>{for(let[a,c]of Object.entries(o)){let l=u[a],d=c;if(d&&!d._validators.every(g=>g(l)))return false}return true}],n,r,i)},nonNull(){return e([...t,o=>o!=null],n,r,i)},hasKeys(...o){return e([...t,u=>o.every(a=>a in u)],n,r,i)},default(o){return e(t,o,r,i)},describe(o){return e(t,n,o,i)},meta(o){return e(t,n,r,o)}});return e([t=>typeof t=="object"&&t!==null&&!Array.isArray(t)])},enum(...e){a&&e.length===0&&console.warn("[Directive] t.enum() called with no values - this will reject all strings");let t=new Set(e);return p([n=>typeof n=="string"&&t.has(n)],`enum(${e.join("|")})`)},literal(e){return p([t=>t===e],`literal(${String(e)})`)},nullable(e){let t=e._typeName??"unknown";return V([n=>n===null?true:e._validators.every(r=>r(n))],`${t} | null`)},optional(e){let t=e._typeName??"unknown";return V([n=>n===void 0?true:e._validators.every(r=>r(n))],`${t} | undefined`)},union:kn,record(e){let t=e._typeName??"unknown";return p([n=>typeof n!="object"||n===null||Array.isArray(n)?false:Object.values(n).every(r=>e._validators.every(i=>i(r)))],`Record<string, ${t}>`)},tuple(...e){a&&e.length===0&&console.warn("[Directive] t.tuple() called with no types - this will only accept empty arrays");let t=e.map(n=>n._typeName??"unknown");return p([n=>!Array.isArray(n)||n.length!==e.length?false:e.every((r,i)=>r._validators.every(s=>s(n[i])))],`[${t.join(", ")}]`)},date(){return p([e=>e instanceof Date&&!Number.isNaN(e.getTime())],"Date")},uuid(){let e=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;return p([t=>typeof t=="string"&&e.test(t)],"uuid")},email(){let e=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;return p([t=>typeof t=="string"&&e.test(t)],"email")},url(){return p([e=>{if(typeof e!="string")return false;try{return new URL(e),!0}catch{return false}}],"url")},bigint(){return p([e=>typeof e=="bigint"],"bigint")},any(){return p([],"any")},unknown(){return p([],"unknown")}};function Mn(e){if(!e||typeof e!="string"){console.warn("[Directive] Module ID must be a non-empty string");return}/^(__[a-z][a-z0-9_-]*|[a-z][a-z0-9-]*)$/i.test(e)||console.warn(`[Directive] Module ID "${e}" should follow kebab-case convention (e.g., "my-module")`);}function Ze(e,t,n,r,i){for(let s of e)t.has(s)||console.warn(`[Directive] ${n} "${s}" not declared in ${r}`);for(let s of t)e.has(s)||console.warn(`[Directive] ${r}["${s}"] ${i}`);}function Rn(e,t){e.length===0&&console.warn("[Directive] history.snapshotEvents is an empty array \u2014 no events will create history snapshots. Omit history.snapshotEvents entirely to snapshot all events, or list specific events.");let n=new Set(Object.keys(t));for(let r of e)n.has(r)||console.warn(`[Directive] history.snapshotEvents entry "${r}" not declared in schema.events. Available events: ${[...n].join(", ")||"(none)"}`);}function An(e,t){let n=new Set(Object.keys(t));for(let[r,i]of Object.entries(e)){let s=i;typeof s.requirement=="string"&&!n.has(s.requirement)&&console.warn(`[Directive] Resolver "${r}" references unknown requirement type "${s.requirement}". Available types: ${[...n].join(", ")||"(none)"}`);}}function Dn(e,t){let n=t.schema?.facts??{},r=Object.keys(n);if(r.length===0)return;let i=new Set(["self","prev","current"]),s="crossModuleDeps"in t&&t.crossModuleDeps?Object.keys(t.crossModuleDeps):[];for(let o of s)i.add(o);for(let o of r)if(i.has(o))throw new Error(`[Directive] module '${e}': fact key '${o}' conflicts with a reserved namespace pivot or evaluation alias (self / prev / current / a crossModuleDep namespace). Three fixes:
1. Rename the fact (e.g. ${o}_)
2. Remove '${o}' from this module's crossModuleDeps if it's not actually needed
3. Move the fact under a wrapping namespace (t.object({ inner: ... }))`)}function tn(e,t){let n=t.constraints;if(n)for(let[r,i]of Object.entries(n)){let s=i?.owns;if(s){for(let o of s)if(l.has(o)||o.startsWith("$"))throw new Error(`[Directive] module '${e}' constraint '${r}': owns key '${o}' is reserved (BLOCKED_PROPS or $-prefixed)`)}}}function nn(e,t){Yt(e),t.schema?t.schema.facts||console.warn("[Directive] Module schema.facts is required"):console.warn("[Directive] Module schema is required"),Fe(new Set(Object.keys(t.derive??{})),new Set(Object.keys(t.schema?.derivations??{})),"Derivation","schema.derivations","has no matching implementation in derive"),Fe(new Set(Object.keys(t.events??{})),new Set(Object.keys(t.schema?.events??{})),"Event","schema.events","has no matching handler in events"),t.history?.snapshotEvents&&Gt(t.history.snapshotEvents,t.schema?.events??{}),t.resolvers&&t.schema?.requirements&&Vt(t.resolvers,t.schema.requirements);}function _e(e,t){en(e,t),tn(e,t),a&&nn(e,t);let n="crossModuleDeps"in t?t.crossModuleDeps:void 0;return {id:e,schema:t.schema,init:t.init,derive:t.derive??{},events:t.events??{},effects:t.effects,constraints:t.constraints,resolvers:t.resolvers,hooks:t.hooks,meta:t.meta,history:t.history,crossModuleDeps:n}}function rn(e){return t=>_e(t,e)}function de(){let e={pending:new Map,inflight:new Map,failed:new Map,errors:new Map,listeners:new Set};function t(){for(let a of e.listeners)a();}function n(a,u){let l=a.get(u);return l||(l=new Set,a.set(u,l)),l}function r(a){let u=e.pending.get(a)??new Set,l=e.inflight.get(a)??new Set,d=e.failed.get(a)??new Set,f=e.errors.get(a)??null;return {pending:u.size,inflight:l.size,failed:d.size,isLoading:u.size>0||l.size>0,hasError:d.size>0,lastError:f}}function i(){let a=new Set([...e.pending.keys(),...e.inflight.keys(),...e.failed.keys()]),u=new Map;for(let l of a)u.set(l,r(l));return u}function s(a){return e.listeners.add(a),()=>e.listeners.delete(a)}function o(){e.pending.clear(),e.inflight.clear(),e.failed.clear(),e.errors.clear(),t();}return {plugin:{name:"requirement-status",onRequirementCreated(a){let u=a.requirement.type;n(e.pending,u).add(a.id),e.failed.get(u)?.delete(a.id),t();},onResolverStart(a,u){let l=u.requirement.type;e.pending.get(l)?.delete(u.id),n(e.inflight,l).add(u.id),t();},onResolverComplete(a,u){let l=u.requirement.type;e.inflight.get(l)?.delete(u.id),e.pending.get(l)?.delete(u.id),t();},onResolverError(a,u,l){let d=u.requirement.type;e.inflight.get(d)?.delete(u.id),n(e.failed,d).add(u.id),e.errors.set(d,l instanceof Error?l:new Error(String(l))),t();},onResolverCancel(a,u){let l=u.requirement.type;e.pending.get(l)?.delete(u.id),e.inflight.get(l)?.delete(u.id),t();},onRequirementMet(a){let u=a.requirement.type;e.pending.get(u)?.delete(a.id),e.inflight.get(u)?.delete(a.id),t();}},getStatus:r,getAllStatus:i,subscribe:s,reset:o}}function on(e){return t=>e.getStatus(t)}function sn(e){let t=de(),r=[...e.plugins??[],t.plugin];return {system:a$1({module:e.module,plugins:r,trace:e.trace,errorBoundary:e.errorBoundary,tickMs:e.tickMs,zeroConfig:e.zeroConfig,initialFacts:e.initialFacts}),statusPlugin:t}}function Ne(){return {now:()=>Date.now(),setTimeout:(e,t)=>{let n=globalThis.setTimeout(e,t);return ()=>globalThis.clearTimeout(n)}}}function an(e=0){let t=e,n=0,r=[];return {now:()=>t,setTimeout:(i,s)=>{let o={id:n++,deadlineMs:t+s,cb:i,canceled:false};return r.push(o),()=>{o.canceled=true;}},advanceBy:i=>{let s=t+i;for(;;){let o=r.filter(a=>!a.canceled&&a.deadlineMs<=s).sort((a,u)=>a.deadlineMs!==u.deadlineMs?a.deadlineMs-u.deadlineMs:a.id-u.id);if(o.length===0)break;let c=o[0];t=Math.max(t,c.deadlineMs),c.canceled=true,c.cb();}t=Math.max(t,s);}}}function un(){return Ne()}function pe(){return {startedAtMs:null,pausedDurationMs:0,pausedAtMs:null,status:"idle",repeats:0}}function z(e,t){return e.startedAtMs===null?0:e.status==="paused"&&e.pausedAtMs!==null?Math.max(0,e.pausedAtMs-e.startedAtMs-e.pausedDurationMs):Math.max(0,t-e.startedAtMs-e.pausedDurationMs)}function qe(e,t,n){return Math.max(0,n-z(e,t))}function Ie(e,t){return e.status==="running"||e.status==="paused"?e:{...e,startedAtMs:t,pausedDurationMs:0,pausedAtMs:null,status:"running",repeats:0}}function Le(e,t){return e.status!=="running"?e:{...e,pausedAtMs:t,status:"paused"}}function Be(e,t){if(e.status!=="paused"||e.pausedAtMs===null)return e;let n=Math.max(0,t-e.pausedAtMs);return {...e,pausedDurationMs:e.pausedDurationMs+n,pausedAtMs:null,status:"running"}}function We(){return pe()}function Ke(e){return {...e,status:"completed"}}function Ue(e,t){return e.startedAtMs===null||e.status==="paused"?e:{...e,startedAtMs:e.startedAtMs+t,pausedDurationMs:0,pausedAtMs:null,repeats:e.repeats+1}}function ze(e,t,n){if(e.status!=="running")return {kind:"no-op"};let r=z(e,t);return n.mode==="up"?{kind:"no-op"}:n.mode==="repeat"?r>=n.ms?{kind:"repeat"}:{kind:"no-op"}:r>=n.ms?{kind:"complete"}:{kind:"no-op"}}function cn(e){return {initial:pe,start:Ie,pause:Le,resume:Be,reset:We,complete:Ke,registerRepeat:t=>Ue(t,e.ms),tick:(t,n)=>ze(t,n,e),elapsedMs:z,remainingMs:(t,n)=>qe(t,n,e.ms)}}var Wn={None:"none",Linear:"linear",Exponential:"exponential"};export{Wn as Backoff,R as MAX_REPLAY_FRAMES,Y as MAX_SWEEP_POINTS,Ke as completeTimer,_e as createModule,rn as createModuleFactory,de as createRequirementStatusPlugin,on as createStatusHook,sn as createSystemWithStatus,un as defaultClock,ve as diffClauses,At as diffRules,Ft as doctor,z as elapsedMs,T as flattenPredicate,$e as framesFromHistory,X as framesFromSnapshots,pe as initialTimerState,Le as pauseTimer,Ut as predicateToMongo,Jt as predicateToPostgrest,It as predicateToSQL,Lt as predicateToWhere,Pt as predict,Ne as realClock,Ue as registerRepeat,qe as remainingMs,L as replayUnder,We as resetTimer,Be as resumeTimer,Ie as startTimer,Mt as sweepUnder,Xt as t,ze as tickTimer,cn as timerOps,we as toReplayFrames,V as toRulesMap,an as virtualClock};//# sourceMappingURL=index.js.map
3. Move the fact under a wrapping namespace (t.object({ inner: ... }))`)}function Cn(e,t){let n=t.constraints;if(n)for(let[r,i]of Object.entries(n)){let s=i?.owns;if(s){for(let o of s)if(k$1.has(o)||o.startsWith("$"))throw new Error(`[Directive] module '${e}' constraint '${r}': owns key '${o}' is reserved (BLOCKED_PROPS or $-prefixed)`)}}}function En(e,t){Mn(e),t.schema?t.schema.facts||console.warn("[Directive] Module schema.facts is required"):console.warn("[Directive] Module schema is required"),Ze(new Set(Object.keys(t.derive??{})),new Set(Object.keys(t.schema?.derivations??{})),"Derivation","schema.derivations","has no matching implementation in derive"),Ze(new Set(Object.keys(t.events??{})),new Set(Object.keys(t.schema?.events??{})),"Event","schema.events","has no matching handler in events"),t.history?.snapshotEvents&&Rn(t.history.snapshotEvents,t.schema?.events??{}),t.resolvers&&t.schema?.requirements&&An(t.resolvers,t.schema.requirements);}function Ye(e,t){Dn(e,t),Cn(e,t),a&&En(e,t);let n="crossModuleDeps"in t?t.crossModuleDeps:void 0;return {id:e,schema:t.schema,init:t.init,derive:t.derive??{},events:t.events??{},effects:t.effects,constraints:t.constraints,resolvers:t.resolvers,hooks:t.hooks,meta:t.meta,history:t.history,crossModuleDeps:n}}function xn(e){return t=>Ye(t,e)}function Se(){let e={pending:new Map,inflight:new Map,failed:new Map,errors:new Map,listeners:new Set};function t(){for(let a of e.listeners)a();}function n(a,c){let l=a.get(c);return l||(l=new Set,a.set(c,l)),l}function r(a){let c=e.pending.get(a)??new Set,l=e.inflight.get(a)??new Set,d=e.failed.get(a)??new Set,g=e.errors.get(a)??null;return {pending:c.size,inflight:l.size,failed:d.size,isLoading:c.size>0||l.size>0,hasError:d.size>0,lastError:g}}function i(){let a=new Set([...e.pending.keys(),...e.inflight.keys(),...e.failed.keys()]),c=new Map;for(let l of a)c.set(l,r(l));return c}function s(a){return e.listeners.add(a),()=>e.listeners.delete(a)}function o(){e.pending.clear(),e.inflight.clear(),e.failed.clear(),e.errors.clear(),t();}return {plugin:{name:"requirement-status",onRequirementCreated(a){let c=a.requirement.type;n(e.pending,c).add(a.id),e.failed.get(c)?.delete(a.id),t();},onResolverStart(a,c){let l=c.requirement.type;e.pending.get(l)?.delete(c.id),n(e.inflight,l).add(c.id),t();},onResolverComplete(a,c){let l=c.requirement.type;e.inflight.get(l)?.delete(c.id),e.pending.get(l)?.delete(c.id),t();},onResolverError(a,c,l){let d=c.requirement.type;e.inflight.get(d)?.delete(c.id),n(e.failed,d).add(c.id),e.errors.set(d,l instanceof Error?l:new Error(String(l))),t();},onResolverCancel(a,c){let l=c.requirement.type;e.pending.get(l)?.delete(c.id),e.inflight.get(l)?.delete(c.id),t();},onRequirementMet(a){let c=a.requirement.type;e.pending.get(c)?.delete(a.id),e.inflight.get(c)?.delete(a.id),t();}},getStatus:r,getAllStatus:i,subscribe:s,reset:o}}function On(e){return t=>e.getStatus(t)}function jn(e){let t=Se(),r=[...e.plugins??[],t.plugin];return {system:a$2({module:e.module,plugins:r,trace:e.trace,errorBoundary:e.errorBoundary,tickMs:e.tickMs,zeroConfig:e.zeroConfig,initialFacts:e.initialFacts}),statusPlugin:t}}function Ge(){return {now:()=>Date.now(),setTimeout:(e,t)=>{let n=globalThis.setTimeout(e,t);return ()=>globalThis.clearTimeout(n)}}}function Pn(e=0){let t=e,n=0,r=[];return {now:()=>t,setTimeout:(i,s)=>{let o={id:n++,deadlineMs:t+s,cb:i,canceled:false};return r.push(o),()=>{o.canceled=true;}},advanceBy:i=>{let s=t+i;for(;;){let o=r.filter(a=>!a.canceled&&a.deadlineMs<=s).sort((a,c)=>a.deadlineMs!==c.deadlineMs?a.deadlineMs-c.deadlineMs:a.id-c.id);if(o.length===0)break;let u=o[0];t=Math.max(t,u.deadlineMs),u.canceled=true,u.cb();}t=Math.max(t,s);}}}function Fn(){return Ge()}function Te(){return {startedAtMs:null,pausedDurationMs:0,pausedAtMs:null,status:"idle",repeats:0}}function ee(e,t){return e.startedAtMs===null?0:e.status==="paused"&&e.pausedAtMs!==null?Math.max(0,e.pausedAtMs-e.startedAtMs-e.pausedDurationMs):Math.max(0,t-e.startedAtMs-e.pausedDurationMs)}function Ve(e,t,n){return Math.max(0,n-ee(e,t))}function et(e,t){return e.status==="running"||e.status==="paused"?e:{...e,startedAtMs:t,pausedDurationMs:0,pausedAtMs:null,status:"running",repeats:0}}function tt(e,t){return e.status!=="running"?e:{...e,pausedAtMs:t,status:"paused"}}function nt(e,t){if(e.status!=="paused"||e.pausedAtMs===null)return e;let n=Math.max(0,t-e.pausedAtMs);return {...e,pausedDurationMs:e.pausedDurationMs+n,pausedAtMs:null,status:"running"}}function rt(){return Te()}function it(e){return {...e,status:"completed"}}function ot(e,t){return e.startedAtMs===null||e.status==="paused"?e:{...e,startedAtMs:e.startedAtMs+t,pausedDurationMs:0,pausedAtMs:null,repeats:e.repeats+1}}function st(e,t,n){if(e.status!=="running")return {kind:"no-op"};let r=ee(e,t);return n.mode==="up"?{kind:"no-op"}:n.mode==="repeat"?r>=n.ms?{kind:"repeat"}:{kind:"no-op"}:r>=n.ms?{kind:"complete"}:{kind:"no-op"}}function Nn(e){return {initial:Te,start:et,pause:tt,resume:nt,reset:rt,complete:it,registerRepeat:t=>ot(t,e.ms),tick:(t,n)=>st(t,n,e),elapsedMs:ee,remainingMs:(t,n)=>Ve(t,n,e.ms)}}var Sr={None:"none",Linear:"linear",Exponential:"exponential"};export{Sr as Backoff,C as MAX_REPLAY_FRAMES,ae as MAX_SWEEP_POINTS,it as completeTimer,Ye as createModule,xn as createModuleFactory,Se as createRequirementStatusPlugin,On as createStatusHook,jn as createSystemWithStatus,Fn as defaultClock,Vt as describePredicate,Oe as diffClauses,zt as diffRules,Zt as doctor,ee as elapsedMs,S as flattenPredicate,De as framesFromHistory,se as framesFromSnapshots,Te as initialTimerState,tt as pauseTimer,Ht as predicateHash,$n as predicateToMongo,Tn as predicateToPostgrest,pn as predicateToSQL,gn as predicateToWhere,Qt as predict,Ge as realClock,ot as registerRepeat,Ve as remainingMs,H as replayUnder,rt as resetTimer,nt as resumeTimer,et as startTimer,qt as sweepUnder,vn as t,st as tickTimer,Nn as timerOps,Ae as toReplayFrames,ce as toRulesMap,Pn as virtualClock};//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

'use strict';var chunk7NMXRATK_cjs=require('./chunk-7NMXRATK.cjs'),chunkN4KTCKOI_cjs=require('./chunk-N4KTCKOI.cjs'),chunkEOLY64E6_cjs=require('./chunk-EOLY64E6.cjs');Object.defineProperty(exports,"createConstraintFactory",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.w}});Object.defineProperty(exports,"createConstraintsManager",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.J}});Object.defineProperty(exports,"createDerivationsManager",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.K}});Object.defineProperty(exports,"createDisabledHistory",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.D}});Object.defineProperty(exports,"createEffectsManager",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.L}});Object.defineProperty(exports,"createEngine",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.T}});Object.defineProperty(exports,"createErrorBoundaryManager",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.N}});Object.defineProperty(exports,"createFacts",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.Q}});Object.defineProperty(exports,"createFactsProxy",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.P}});Object.defineProperty(exports,"createFactsStore",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.O}});Object.defineProperty(exports,"createHistoryManager",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.C}});Object.defineProperty(exports,"createPluginManager",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.R}});Object.defineProperty(exports,"createResolverFactory",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.x}});Object.defineProperty(exports,"createResolversManager",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.S}});Object.defineProperty(exports,"createRetryLaterManager",{enumerable:true,get:function(){return chunk7NMXRATK_cjs.M}});Object.defineProperty(exports,"getCurrentDeps",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.g}});Object.defineProperty(exports,"isTracking",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.h}});Object.defineProperty(exports,"trackAccess",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.k}});Object.defineProperty(exports,"withTracking",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.i}});Object.defineProperty(exports,"withoutTracking",{enumerable:true,get:function(){return chunkN4KTCKOI_cjs.j}});Object.defineProperty(exports,"safeStringify",{enumerable:true,get:function(){return chunkEOLY64E6_cjs.n}});//# sourceMappingURL=internals.cjs.map
'use strict';var chunkENZEHIL7_cjs=require('./chunk-ENZEHIL7.cjs'),chunkT4TRJEJN_cjs=require('./chunk-T4TRJEJN.cjs'),chunkX7G7UBXU_cjs=require('./chunk-X7G7UBXU.cjs'),chunk4MNQDXH7_cjs=require('./chunk-4MNQDXH7.cjs');Object.defineProperty(exports,"createConstraintFactory",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.c}});Object.defineProperty(exports,"createConstraintsManager",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.p}});Object.defineProperty(exports,"createDerivationsManager",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.q}});Object.defineProperty(exports,"createDisabledHistory",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.j}});Object.defineProperty(exports,"createEffectsManager",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.r}});Object.defineProperty(exports,"createEngine",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.z}});Object.defineProperty(exports,"createErrorBoundaryManager",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.t}});Object.defineProperty(exports,"createFacts",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.w}});Object.defineProperty(exports,"createFactsProxy",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.v}});Object.defineProperty(exports,"createFactsStore",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.u}});Object.defineProperty(exports,"createHistoryManager",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.i}});Object.defineProperty(exports,"createPluginManager",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.x}});Object.defineProperty(exports,"createResolverFactory",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.d}});Object.defineProperty(exports,"createResolversManager",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.y}});Object.defineProperty(exports,"createRetryLaterManager",{enumerable:true,get:function(){return chunkENZEHIL7_cjs.s}});Object.defineProperty(exports,"dangerousRegex",{enumerable:true,get:function(){return chunkT4TRJEJN_cjs.m}});Object.defineProperty(exports,"getCurrentDeps",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.f}});Object.defineProperty(exports,"isTracking",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.g}});Object.defineProperty(exports,"trackAccess",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.j}});Object.defineProperty(exports,"withTracking",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.h}});Object.defineProperty(exports,"withoutTracking",{enumerable:true,get:function(){return chunkX7G7UBXU_cjs.i}});Object.defineProperty(exports,"hashObject",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.h}});Object.defineProperty(exports,"safeStringify",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.o}});Object.defineProperty(exports,"stableStringify",{enumerable:true,get:function(){return chunk4MNQDXH7_cjs.e}});//# sourceMappingURL=internals.cjs.map
//# sourceMappingURL=internals.cjs.map

@@ -1,6 +0,6 @@

import { a8 as Schema, ai as FactsStore, c as Facts, D as DefinitionMeta, E as EffectsDef, aj as ConstraintsDef, u as RequirementKeyFn, R as RequirementWithId, ak as ConstraintState, b as FactPredicate, C as ClauseResult, al as ResolversDef, am as ResolverStatus, t as Requirement, q as Plugin, aa as System, an as FactChange, H as FactsSnapshot, ao as ReconcileResult, a9 as Snapshot, v as DirectiveError, ap as RecoveryStrategy, af as TraceEntry, aq as ErrorSource, s as ErrorBoundaryConfig, ar as RetryLaterConfig, I as HistoryAPI, J as HistoryOption, ab as SystemConfig } from './plugins-Ykl_sAPE.cjs';
export { as as BatchItemResult, at as BatchResolveResults, au as ConstraintsControl, av as CrossModuleConstraintDef, k as CrossModuleConstraintsDef, aw as CrossModuleDerivationFn, i as CrossModuleDerivationsDef, ax as CrossModuleEffectDef, j as CrossModuleEffectsDef, ay as CrossModuleFactsWithSelf, az as DerivationKeys, aA as DerivationReturnType, aB as DerivationsControl, aC as DerivationsSchema, aD as DeriveAccessor, aE as DispatchEventsFromSchema, w as DistributableSnapshot, x as DistributableSnapshotOptions, aF as EffectCleanup, aG as EffectsControl, aH as EventPayloadSchema, aI as EventsAccessor, aJ as EventsAccessorFromSchema, aK as EventsDef, aL as EventsSchema, aM as FactKeys, aN as FactReturnType, aO as FlexibleEventHandler, aP as HistoryConfig, aQ as InferEventPayloadFromSchema, aR as InferRequirementPayloadFromSchema, aS as InferSchema, aT as MutableNamespacedFacts, aU as NamespacedDerivations, aV as NamespacedEventsAccessor, aW as NamespacedFacts, aX as ObservableKeys, aY as RequirementExplanation, aZ as RequirementOutput, a_ as RequirementPayloadSchema, a$ as RequirementsSchema, b0 as ResolverContext, b1 as ResolversControl, b2 as SnapshotMeta, b3 as SystemEvent, b4 as TraceConfig, b5 as TypedConstraintDef, e as TypedConstraintsDef, T as TypedDerivationsDef, d as TypedEventsDef, b6 as TypedResolverContext, b7 as TypedResolverDef, f as TypedResolversDef, b8 as UnionEvents } from './plugins-Ykl_sAPE.cjs';
import { b as DerivationsDef, c as DerivedValues } from './helpers-hh6UanB1.cjs';
export { d as DerivationState, T as TypedConstraint, e as TypedResolver, f as createConstraintFactory, g as createResolverFactory } from './helpers-hh6UanB1.cjs';
export { g as safeStringify } from './utils-BnQajqPu.cjs';
import { a8 as Schema, ai as FactsStore, a as Facts, D as DefinitionMeta, E as EffectsDef, aj as ConstraintsDef, r as RequirementKeyFn, R as RequirementWithId, ak as ConstraintState, F as FactPredicate, C as ClauseResult, al as ResolversDef, am as ResolverStatus, q as Requirement, P as Plugin, aa as System, an as FactChange, z as FactsSnapshot, ao as ReconcileResult, a9 as Snapshot, s as DirectiveError, ap as RecoveryStrategy, af as TraceEntry, aq as ErrorSource, p as ErrorBoundaryConfig, ar as RetryLaterConfig, H as HistoryAPI, G as HistoryOption, ab as SystemConfig } from './plugins-BIzXaYbg.cjs';
export { as as BatchItemResult, at as BatchResolveResults, au as ConstraintsControl, av as CrossModuleConstraintDef, i as CrossModuleConstraintsDef, aw as CrossModuleDerivationFn, g as CrossModuleDerivationsDef, ax as CrossModuleEffectDef, h as CrossModuleEffectsDef, ay as CrossModuleFactsWithSelf, az as DerivationKeys, aA as DerivationReturnType, aB as DerivationsControl, aC as DerivationsSchema, aD as DeriveAccessor, aE as DispatchEventsFromSchema, t as DistributableSnapshot, u as DistributableSnapshotOptions, aF as EffectCleanup, aG as EffectsControl, aH as EventPayloadSchema, aI as EventsAccessor, aJ as EventsAccessorFromSchema, aK as EventsDef, aL as EventsSchema, aM as FactKeys, aN as FactReturnType, aO as FlexibleEventHandler, aP as HistoryConfig, aQ as InferEventPayloadFromSchema, aR as InferRequirementPayloadFromSchema, aS as InferSchema, aT as MutableNamespacedFacts, aU as NamespacedDerivations, aV as NamespacedEventsAccessor, aW as NamespacedFacts, aX as ObservableKeys, aY as RequirementExplanation, aZ as RequirementOutput, a_ as RequirementPayloadSchema, a$ as RequirementsSchema, b0 as ResolverContext, b1 as ResolversControl, b2 as SnapshotMeta, b3 as SystemEvent, b4 as TraceConfig, b5 as TypedConstraintDef, c as TypedConstraintsDef, T as TypedDerivationsDef, b as TypedEventsDef, b6 as TypedResolverContext, b7 as TypedResolverDef, d as TypedResolversDef, b8 as UnionEvents } from './plugins-BIzXaYbg.cjs';
import { w as DerivationsDef, x as DerivedValues } from './predicate-Bnx3LN7P.cjs';
export { y as DerivationState, T as TypedConstraint, z as TypedResolver, A as createConstraintFactory, B as createResolverFactory, C as dangerousRegex } from './predicate-Bnx3LN7P.cjs';
export { h as hashObject, g as safeStringify, j as stableStringify } from './utils-Mg55IerF.cjs';

@@ -7,0 +7,0 @@ /**

@@ -1,6 +0,6 @@

import { a8 as Schema, ai as FactsStore, c as Facts, D as DefinitionMeta, E as EffectsDef, aj as ConstraintsDef, u as RequirementKeyFn, R as RequirementWithId, ak as ConstraintState, b as FactPredicate, C as ClauseResult, al as ResolversDef, am as ResolverStatus, t as Requirement, q as Plugin, aa as System, an as FactChange, H as FactsSnapshot, ao as ReconcileResult, a9 as Snapshot, v as DirectiveError, ap as RecoveryStrategy, af as TraceEntry, aq as ErrorSource, s as ErrorBoundaryConfig, ar as RetryLaterConfig, I as HistoryAPI, J as HistoryOption, ab as SystemConfig } from './plugins-Ykl_sAPE.js';
export { as as BatchItemResult, at as BatchResolveResults, au as ConstraintsControl, av as CrossModuleConstraintDef, k as CrossModuleConstraintsDef, aw as CrossModuleDerivationFn, i as CrossModuleDerivationsDef, ax as CrossModuleEffectDef, j as CrossModuleEffectsDef, ay as CrossModuleFactsWithSelf, az as DerivationKeys, aA as DerivationReturnType, aB as DerivationsControl, aC as DerivationsSchema, aD as DeriveAccessor, aE as DispatchEventsFromSchema, w as DistributableSnapshot, x as DistributableSnapshotOptions, aF as EffectCleanup, aG as EffectsControl, aH as EventPayloadSchema, aI as EventsAccessor, aJ as EventsAccessorFromSchema, aK as EventsDef, aL as EventsSchema, aM as FactKeys, aN as FactReturnType, aO as FlexibleEventHandler, aP as HistoryConfig, aQ as InferEventPayloadFromSchema, aR as InferRequirementPayloadFromSchema, aS as InferSchema, aT as MutableNamespacedFacts, aU as NamespacedDerivations, aV as NamespacedEventsAccessor, aW as NamespacedFacts, aX as ObservableKeys, aY as RequirementExplanation, aZ as RequirementOutput, a_ as RequirementPayloadSchema, a$ as RequirementsSchema, b0 as ResolverContext, b1 as ResolversControl, b2 as SnapshotMeta, b3 as SystemEvent, b4 as TraceConfig, b5 as TypedConstraintDef, e as TypedConstraintsDef, T as TypedDerivationsDef, d as TypedEventsDef, b6 as TypedResolverContext, b7 as TypedResolverDef, f as TypedResolversDef, b8 as UnionEvents } from './plugins-Ykl_sAPE.js';
import { b as DerivationsDef, c as DerivedValues } from './helpers-D2pfb6vT.js';
export { d as DerivationState, T as TypedConstraint, e as TypedResolver, f as createConstraintFactory, g as createResolverFactory } from './helpers-D2pfb6vT.js';
export { g as safeStringify } from './utils-BnQajqPu.js';
import { a8 as Schema, ai as FactsStore, a as Facts, D as DefinitionMeta, E as EffectsDef, aj as ConstraintsDef, r as RequirementKeyFn, R as RequirementWithId, ak as ConstraintState, F as FactPredicate, C as ClauseResult, al as ResolversDef, am as ResolverStatus, q as Requirement, P as Plugin, aa as System, an as FactChange, z as FactsSnapshot, ao as ReconcileResult, a9 as Snapshot, s as DirectiveError, ap as RecoveryStrategy, af as TraceEntry, aq as ErrorSource, p as ErrorBoundaryConfig, ar as RetryLaterConfig, H as HistoryAPI, G as HistoryOption, ab as SystemConfig } from './plugins-BIzXaYbg.js';
export { as as BatchItemResult, at as BatchResolveResults, au as ConstraintsControl, av as CrossModuleConstraintDef, i as CrossModuleConstraintsDef, aw as CrossModuleDerivationFn, g as CrossModuleDerivationsDef, ax as CrossModuleEffectDef, h as CrossModuleEffectsDef, ay as CrossModuleFactsWithSelf, az as DerivationKeys, aA as DerivationReturnType, aB as DerivationsControl, aC as DerivationsSchema, aD as DeriveAccessor, aE as DispatchEventsFromSchema, t as DistributableSnapshot, u as DistributableSnapshotOptions, aF as EffectCleanup, aG as EffectsControl, aH as EventPayloadSchema, aI as EventsAccessor, aJ as EventsAccessorFromSchema, aK as EventsDef, aL as EventsSchema, aM as FactKeys, aN as FactReturnType, aO as FlexibleEventHandler, aP as HistoryConfig, aQ as InferEventPayloadFromSchema, aR as InferRequirementPayloadFromSchema, aS as InferSchema, aT as MutableNamespacedFacts, aU as NamespacedDerivations, aV as NamespacedEventsAccessor, aW as NamespacedFacts, aX as ObservableKeys, aY as RequirementExplanation, aZ as RequirementOutput, a_ as RequirementPayloadSchema, a$ as RequirementsSchema, b0 as ResolverContext, b1 as ResolversControl, b2 as SnapshotMeta, b3 as SystemEvent, b4 as TraceConfig, b5 as TypedConstraintDef, c as TypedConstraintsDef, T as TypedDerivationsDef, b as TypedEventsDef, b6 as TypedResolverContext, b7 as TypedResolverDef, d as TypedResolversDef, b8 as UnionEvents } from './plugins-BIzXaYbg.js';
import { w as DerivationsDef, x as DerivedValues } from './predicate-BxQVf0ug.js';
export { y as DerivationState, T as TypedConstraint, z as TypedResolver, A as createConstraintFactory, B as createResolverFactory, C as dangerousRegex } from './predicate-BxQVf0ug.js';
export { h as hashObject, g as safeStringify, j as stableStringify } from './utils-Mg55IerF.js';

@@ -7,0 +7,0 @@ /**

@@ -1,2 +0,2 @@

export{w as createConstraintFactory,J as createConstraintsManager,K as createDerivationsManager,D as createDisabledHistory,L as createEffectsManager,T as createEngine,N as createErrorBoundaryManager,Q as createFacts,P as createFactsProxy,O as createFactsStore,C as createHistoryManager,R as createPluginManager,x as createResolverFactory,S as createResolversManager,M as createRetryLaterManager}from'./chunk-TPOKS4RY.js';export{g as getCurrentDeps,h as isTracking,k as trackAccess,i as withTracking,j as withoutTracking}from'./chunk-TZHC4E6S.js';export{n as safeStringify}from'./chunk-T6IJUWYR.js';//# sourceMappingURL=internals.js.map
export{c as createConstraintFactory,p as createConstraintsManager,q as createDerivationsManager,j as createDisabledHistory,r as createEffectsManager,z as createEngine,t as createErrorBoundaryManager,w as createFacts,v as createFactsProxy,u as createFactsStore,i as createHistoryManager,x as createPluginManager,d as createResolverFactory,y as createResolversManager,s as createRetryLaterManager}from'./chunk-R2GHSCTR.js';export{m as dangerousRegex}from'./chunk-2FF6QGOA.js';export{f as getCurrentDeps,g as isTracking,j as trackAccess,h as withTracking,i as withoutTracking}from'./chunk-I722BZA5.js';export{h as hashObject,o as safeStringify,e as stableStringify}from'./chunk-PXRV64PA.js';//# sourceMappingURL=internals.js.map
//# sourceMappingURL=internals.js.map

@@ -1,3 +0,3 @@

'use strict';var chunk4VZOZWXM_cjs=require('../chunk-4VZOZWXM.cjs'),chunkEOLY64E6_cjs=require('../chunk-EOLY64E6.cjs');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;var Oe={debug:0,info:1,warn:2,error:3};function st(e={}){let{level:s="info",filter:o=()=>true,logger:r=console,prefix:a="[Directive]"}=e,p=Oe[s],l=(t,i,...c)=>{Oe[t]<p||o(i)&&r[t](`${a} ${i}`,...c);};return {name:"logging",onInit:()=>l("debug","init"),onStart:()=>l("info","start"),onStop:()=>l("info","stop"),onDestroy:()=>l("debug","destroy"),onFactSet:(t,i,c)=>{l("debug","fact.set",{key:t,value:i,prev:c});},onFactDelete:(t,i)=>{l("debug","fact.delete",{key:t,prev:i});},onFactsBatch:t=>{l("debug","facts.batch",{count:t.length,changes:t});},onDerivationCompute:(t,i,c)=>{l("debug","derivation.compute",{id:t,value:i,deps:c});},onDerivationInvalidate:t=>{l("debug","derivation.invalidate",{id:t});},onReconcileStart:()=>{l("debug","reconcile.start");},onReconcileEnd:t=>{l("debug","reconcile.end",{unmet:t.unmet.length,inflight:t.inflight.length,completed:t.completed.length,canceled:t.canceled.length});},onConstraintEvaluate:(t,i,c)=>{if(c){let d=c.filter(y=>y.pass).length;l("debug","constraint.evaluate",{id:t,active:i,clauses:{total:c.length,passed:d}});return}l("debug","constraint.evaluate",{id:t,active:i});},onConstraintError:(t,i)=>{l("error","constraint.error",{id:t,error:i});},onRequirementCreated:t=>{l("debug","requirement.created",{id:t.id,type:t.requirement.type});},onRequirementMet:(t,i)=>{l("info","requirement.met",{id:t.id,byResolver:i});},onRequirementCanceled:t=>{l("debug","requirement.canceled",{id:t.id});},onResolverStart:(t,i)=>{l("debug","resolver.start",{resolver:t,requirementId:i.id});},onResolverComplete:(t,i,c)=>{l("info","resolver.complete",{resolver:t,requirementId:i.id,duration:c});},onResolverError:(t,i,c)=>{l("error","resolver.error",{resolver:t,requirementId:i.id,error:c});},onResolverRetry:(t,i,c)=>{l("warn","resolver.retry",{resolver:t,requirementId:i.id,attempt:c});},onResolverCancel:(t,i)=>{l("debug","resolver.cancel",{resolver:t,requirementId:i.id});},onResolverWriteRejected:t=>{l("warn","resolver.write.rejected",t.kind==="summary"?{kind:t.kind,resolver:t.resolver,requirementId:t.req.id,reason:t.reason,dropped:t.dropped}:{kind:t.kind,resolver:t.resolver,requirementId:t.req.id,reason:t.reason,fact:t.fact,expected:t.expected,actual:t.actual});},onEffectRun:t=>{l("debug","effect.run",{id:t});},onEffectError:(t,i)=>{l("error","effect.error",{id:t,error:i});},onSnapshot:t=>{l("debug","timetravel.snapshot",{id:t.id,trigger:t.trigger});},onHistoryNavigate:(t,i)=>{l("info","timetravel.jump",{from:t,to:i});},onError:t=>{l("error","error",{source:t.source,sourceId:t.sourceId,message:t.message});},onErrorRecovery:(t,i)=>{l("warn","error.recovery",{source:t.source,sourceId:t.sourceId,strategy:i});},onDefinitionRegister:(t,i)=>{l("info","definition.register",{type:t,id:i});},onDefinitionAssign:(t,i)=>{l("info","definition.assign",{type:t,id:i});},onDefinitionUnregister:(t,i)=>{l("info","definition.unregister",{type:t,id:i});},onDefinitionCall:(t,i,c)=>{l("debug","definition.call",{type:t,id:i,props:c});},onTraceComplete:t=>{l("debug","trace.complete",{id:t.id,status:t.status,duration:t.duration,factChanges:t.factChanges.length,derivationsRecomputed:t.derivationsRecomputed.length,constraintsHit:t.constraintsHit.length,resolversStarted:t.resolversStarted.length,effectsRun:t.effectsRun.length});}}}var ue=class{constructor(s){this.capacity=s;this.buf=new Array(s);}buf;head=0;_size=0;get size(){return this._size}push(s){this.buf[this.head]=s,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++;}toArray(){return this._size===0?[]:this._size<this.capacity?this.buf.slice(0,this._size):[...this.buf.slice(this.head),...this.buf.slice(0,this.head)]}clear(){this.buf=new Array(this.capacity),this.head=0,this._size=0;}};function ge(){try{if(typeof process<"u"&&process.env?.NODE_ENV==="production")return !1}catch{}try{if(typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) })<"u"&&undefined?.MODE==="production")return !1}catch{}return true}function fe(e){try{if(e===void 0)return "undefined";if(e===null)return "null";if(typeof e=="bigint")return String(e)+"n";if(typeof e=="symbol")return String(e);if(typeof e=="object"){let s=JSON.stringify(e,(o,r)=>typeof r=="bigint"?String(r)+"n":typeof r=="symbol"?String(r):r);return s.length>120?s.slice(0,117)+"...":s}return String(e)}catch{return "<error>"}}function ee(e,s){return e.length<=s?e:e.slice(0,s-3)+"..."}function se(e){try{return e.inspect()}catch{return null}}function Le(e){try{return e==null||typeof e!="object"?e:JSON.parse(JSON.stringify(e))}catch{return null}}function Pe(e){return e===void 0?1e3:!Number.isFinite(e)||e<1?(ge()&&console.warn(`[directive:devtools] Invalid maxEvents value (${e}), using default 1000`),1e3):Math.floor(e)}function Ie(){return {reconcileCount:0,reconcileTotalMs:0,resolverStats:new Map,effectRunCount:0,effectErrorCount:0,lastReconcileStartMs:0}}var it=200,ie=340,ae=16,ce=80,he=2,Se=["#8b9aff","#4ade80","#fbbf24","#c084fc","#f472b6","#22d3ee"];function $e(){return {entries:new ue(it),inflight:new Map}}function _e(){return {derivationDeps:new Map,activeConstraints:new Set,recentlyChangedFacts:new Set,recentlyComputedDerivations:new Set,recentlyActiveConstraints:new Set,animationTimer:null}}var Ne=1e4,Be=100;function je(){return {isRecording:false,recordedEvents:[],snapshots:[]}}var He=50,xe=200,b={bg:"#1a1a2e",text:"#e0e0e0",accent:"#8b9aff",muted:"#b0b0d0",border:"#333",rowBorder:"#2a2a4a",green:"#4ade80",yellow:"#fbbf24",red:"#f87171",closeBtn:"#aaa",font:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},G={nodeW:90,nodeH:16,nodeGap:6,startY:16,colGap:20,fontSize:10,labelMaxChars:11};function Ve(e,s,o,r){let a=false,p={position:"fixed",zIndex:"99999",...s.includes("bottom")?{bottom:"12px"}:{top:"12px"},...s.includes("right")?{right:"12px"}:{left:"12px"}},l=document.createElement("style");l.textContent=`[data-directive-devtools] summary:focus-visible{outline:2px solid ${b.accent};outline-offset:2px;border-radius:2px}[data-directive-devtools] button:focus-visible{outline:2px solid ${b.accent};outline-offset:2px}`,document.head.appendChild(l);let t=document.createElement("button");t.setAttribute("aria-label","Open Directive DevTools"),t.setAttribute("aria-expanded",String(o)),t.title="Ctrl+Shift+D to toggle",Object.assign(t.style,{...p,background:b.bg,color:b.text,border:`1px solid ${b.border}`,borderRadius:"6px",padding:"10px 14px",minWidth:"44px",minHeight:"44px",cursor:"pointer",fontFamily:b.font,fontSize:"12px",display:o?"none":"block"}),t.textContent="Directive";let i=document.createElement("div");i.setAttribute("role","region"),i.setAttribute("aria-label","Directive DevTools"),i.setAttribute("data-directive-devtools",""),i.tabIndex=-1,Object.assign(i.style,{...p,background:b.bg,color:b.text,border:`1px solid ${b.border}`,borderRadius:"8px",padding:"12px",fontFamily:b.font,fontSize:"11px",maxWidth:"min(380px, calc(100vw - 24px))",maxHeight:"min(500px, calc(100vh - 24px))",overflow:"auto",boxShadow:"0 4px 20px rgba(0,0,0,0.5)",display:o?"block":"none"});let c=document.createElement("div");Object.assign(c.style,{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"8px"});let d=document.createElement("strong");d.style.color=b.accent,d.textContent=e==="default"?"Directive DevTools":`DevTools (${e})`;let y=document.createElement("button");y.setAttribute("aria-label","Close DevTools"),Object.assign(y.style,{background:"none",border:"none",color:b.closeBtn,cursor:"pointer",fontSize:"16px",padding:"8px 12px",minWidth:"44px",minHeight:"44px",lineHeight:"1",display:"flex",alignItems:"center",justifyContent:"center"}),y.textContent="\xD7",c.appendChild(d),c.appendChild(y),i.appendChild(c);let I=document.createElement("div");I.style.marginBottom="6px",I.setAttribute("aria-live","polite");let N=document.createElement("span");N.style.color=b.green,N.textContent="Settled",I.appendChild(N),i.appendChild(I);let R=document.createElement("div");Object.assign(R.style,{display:"none",marginBottom:"8px",padding:"4px 8px",background:"#252545",borderRadius:"4px",alignItems:"center",gap:"6px"});let w=document.createElement("button");Object.assign(w.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"4px 10px",borderRadius:"3px",fontFamily:b.font,fontSize:"11px",minWidth:"44px",minHeight:"44px"}),w.textContent="\u25C0 Undo",w.disabled=true;let g=document.createElement("button");Object.assign(g.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"4px 10px",borderRadius:"3px",fontFamily:b.font,fontSize:"11px",minWidth:"44px",minHeight:"44px"}),g.textContent="Redo \u25B6",g.disabled=true;let f=document.createElement("span");f.style.color=b.muted,f.style.fontSize="10px",R.appendChild(w),R.appendChild(g),R.appendChild(f),i.appendChild(R);function C(z,K){let X=document.createElement("details");K&&(X.open=true),X.style.marginBottom="4px";let J=document.createElement("summary");Object.assign(J.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"});let Q=document.createElement("span");J.textContent=`${z} (`,J.appendChild(Q),J.appendChild(document.createTextNode(")")),Q.textContent="0",X.appendChild(J);let te=document.createElement("table");Object.assign(te.style,{width:"100%",borderCollapse:"collapse",fontSize:"11px"});let Re=document.createElement("thead"),De=document.createElement("tr");for(let nt of ["Key","Value"]){let pe=document.createElement("th");pe.scope="col",Object.assign(pe.style,{textAlign:"left",padding:"2px 4px",color:b.accent}),pe.textContent=nt,De.appendChild(pe);}Re.appendChild(De),te.appendChild(Re);let Ae=document.createElement("tbody");return te.appendChild(Ae),X.appendChild(te),{details:X,tbody:Ae,countSpan:Q}}function T(z,K){let X=document.createElement("details");X.style.marginBottom="4px";let J=document.createElement("summary");Object.assign(J.style,{cursor:"pointer",color:K,marginBottom:"4px"});let Q=document.createElement("span");J.textContent=`${z} (`,J.appendChild(Q),J.appendChild(document.createTextNode(")")),Q.textContent="0",X.appendChild(J);let te=document.createElement("ul");return Object.assign(te.style,{margin:"0",paddingLeft:"16px"}),X.appendChild(te),{details:X,list:te,countSpan:Q}}let P=C("Facts",true);i.appendChild(P.details);let F=C("Derivations",false);i.appendChild(F.details);let O=T("Inflight",b.yellow);i.appendChild(O.details);let Y=T("Unmet",b.red);i.appendChild(Y.details);let $=document.createElement("details");$.style.marginBottom="4px";let V=document.createElement("summary");Object.assign(V.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),V.textContent="Performance",$.appendChild(V);let _=document.createElement("div");_.style.fontSize="10px",_.style.color=b.muted,_.textContent="No data yet",$.appendChild(_),i.appendChild($);let H=document.createElement("details");H.style.marginBottom="4px";let h=document.createElement("summary");Object.assign(h.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),h.textContent="Dependency Graph",H.appendChild(h);let x=document.createElementNS("http://www.w3.org/2000/svg","svg");x.setAttribute("width","100%"),x.setAttribute("height","120"),x.setAttribute("role","img"),x.setAttribute("aria-label","System dependency graph"),x.style.display="block",x.setAttribute("viewBox","0 0 460 120"),x.setAttribute("preserveAspectRatio","xMinYMin meet"),H.appendChild(x),i.appendChild(H);let E=document.createElement("details");E.style.marginBottom="4px";let q=document.createElement("summary");Object.assign(q.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),q.textContent="Timeline",E.appendChild(q);let j=document.createElementNS("http://www.w3.org/2000/svg","svg");j.setAttribute("width","100%"),j.setAttribute("height","60"),j.setAttribute("role","img"),j.setAttribute("aria-label","Resolver execution timeline"),j.style.display="block",j.setAttribute("viewBox",`0 0 ${ie} 60`),j.setAttribute("preserveAspectRatio","xMinYMin meet");let u=document.createElementNS("http://www.w3.org/2000/svg","text");u.setAttribute("x",String(ie/2)),u.setAttribute("y","30"),u.setAttribute("text-anchor","middle"),u.setAttribute("fill",b.muted),u.setAttribute("font-size","10"),u.setAttribute("font-family",b.font),u.textContent="No resolver activity yet",j.appendChild(u),E.appendChild(j),i.appendChild(E);let M=(()=>{let z=document.createElement("details");z.style.marginBottom="4px";let K=document.createElement("summary");Object.assign(K.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"});let X=document.createElement("span");X.textContent="0",K.textContent="Constraints (",K.appendChild(X),K.appendChild(document.createTextNode(")")),z.appendChild(K);let J=document.createElement("div");Object.assign(J.style,{fontSize:"11px"});let Q=document.createElement("div");return Q.style.color=b.muted,Q.style.padding="4px",Q.style.fontStyle="italic",Q.textContent="Waiting for first evaluation\u2026",Q.className="dt-constraints-empty",J.appendChild(Q),z.appendChild(J),i.appendChild(z),{details:z,body:J,countSpan:X}})(),S,A,W,k;if(r){let z=document.createElement("details");z.style.marginBottom="4px";let K=document.createElement("summary");Object.assign(K.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),W=document.createElement("span"),W.textContent="0",K.textContent="Events (",K.appendChild(W),K.appendChild(document.createTextNode(")")),z.appendChild(K),A=document.createElement("div"),Object.assign(A.style,{maxHeight:"150px",overflow:"auto",fontSize:"10px"}),A.setAttribute("role","log"),A.setAttribute("aria-live","polite"),A.tabIndex=0;let X=document.createElement("div");X.style.color=b.muted,X.style.padding="4px",X.textContent="Waiting for events...",X.className="dt-events-empty",A.appendChild(X),z.appendChild(A),i.appendChild(z),S=z,k=document.createElement("div");}else S=document.createElement("details"),A=document.createElement("div"),W=document.createElement("span"),k=document.createElement("div"),k.style.fontSize="10px",k.style.color=b.muted,k.style.marginTop="4px",k.style.fontStyle="italic",k.textContent="Enable trace: true for event log",i.appendChild(k);let L=document.createElement("div");Object.assign(L.style,{display:"flex",gap:"6px",marginTop:"6px"});let n=document.createElement("button");Object.assign(n.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"8px 12px",borderRadius:"3px",fontFamily:b.font,fontSize:"10px",minWidth:"44px",minHeight:"44px"}),n.textContent="\u23FA Record";let m=document.createElement("button");Object.assign(m.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"8px 12px",borderRadius:"3px",fontFamily:b.font,fontSize:"10px",minWidth:"44px",minHeight:"44px"}),m.textContent="\u2913 Export",L.appendChild(n),L.appendChild(m),i.appendChild(L),i.addEventListener("wheel",z=>{let K=i,X=K.scrollTop===0&&z.deltaY<0,J=K.scrollTop+K.clientHeight>=K.scrollHeight&&z.deltaY>0;(X||J)&&z.preventDefault();},{passive:false});let v=o,D=new Set;function B(){v=true,i.style.display="block",t.style.display="none",t.setAttribute("aria-expanded","true"),y.focus();}function U(){v=false,i.style.display="none",t.style.display="block",t.setAttribute("aria-expanded","false"),t.focus();}t.addEventListener("click",B),y.addEventListener("click",U);function Z(z){z.key==="Escape"&&v&&U();}i.addEventListener("keydown",Z);function re(z){z.key==="d"&&z.shiftKey&&(z.ctrlKey||z.metaKey)&&(z.preventDefault(),v?U():B());}document.addEventListener("keydown",re);function oe(){a||(document.body.appendChild(t),document.body.appendChild(i));}document.body?oe():document.addEventListener("DOMContentLoaded",oe,{once:true});function le(){a=true,t.removeEventListener("click",B),y.removeEventListener("click",U),i.removeEventListener("keydown",Z),document.removeEventListener("keydown",re),document.removeEventListener("DOMContentLoaded",oe);for(let z of D)clearTimeout(z);D.clear(),t.remove(),i.remove(),l.remove();}return {refs:{container:i,toggleBtn:t,titleEl:d,statusEl:N,factsBody:P.tbody,factsCount:P.countSpan,derivBody:F.tbody,derivCount:F.countSpan,derivSection:F.details,inflightList:O.list,inflightSection:O.details,inflightCount:O.countSpan,unmetList:Y.list,unmetSection:Y.details,unmetCount:Y.countSpan,perfSection:$,perfBody:_,historySection:R,historyLabel:f,undoBtn:w,redoBtn:g,flowSection:H,flowSvg:x,timelineSection:E,timelineSvg:j,eventsSection:S,eventsList:A,eventsCount:W,traceHint:k,recordBtn:n,exportBtn:m,constraintsSection:M.details,constraintsBody:M.body,constraintsCount:M.countSpan},destroy:le,isOpen:()=>v,flashTimers:D}}function de(e,s,o,r,a,p){let l=fe(r),t=e.get(o);if(t){let i=t.cells;if(i[1]&&(i[1].textContent=l,a&&p)){let c=i[1];c.style.background="rgba(139, 154, 255, 0.25)";let d=setTimeout(()=>{c.style.background="",p.delete(d);},300);p.add(d);}}else {t=document.createElement("tr"),t.style.borderBottom=`1px solid ${b.rowBorder}`;let i=document.createElement("td");Object.assign(i.style,{padding:"2px 4px",color:b.muted}),i.textContent=o;let c=document.createElement("td");c.style.padding="2px 4px",c.textContent=l,t.appendChild(i),t.appendChild(c),s.appendChild(t),e.set(o,t);}}function ze(e,s){let o=e.get(s);o&&(o.remove(),e.delete(s));}function be(e,s,o){if(e.inflightList.replaceChildren(),e.inflightCount.textContent=String(s.length),s.length>0)for(let r of s){let a=document.createElement("li");a.style.fontSize="11px",a.textContent=`${r.resolverId} (${r.id})`,e.inflightList.appendChild(a);}else {let r=document.createElement("li");r.style.fontSize="10px",r.style.color=b.muted,r.textContent="None",e.inflightList.appendChild(r);}if(e.unmetList.replaceChildren(),e.unmetCount.textContent=String(o.length),o.length>0)for(let r of o){let a=document.createElement("li");a.style.fontSize="11px",a.textContent=`${r.requirement.type} from ${r.fromConstraint}`,e.unmetList.appendChild(a);}else {let r=document.createElement("li");r.style.fontSize="10px",r.style.color=b.muted,r.textContent="None",e.unmetList.appendChild(r);}}function ye(e,s,o){let r=s===0&&o===0;e.statusEl.style.color=r?b.green:b.yellow,e.statusEl.textContent=r?"Settled":"Working...",e.toggleBtn.textContent=r?"Directive":"Directive...",e.toggleBtn.setAttribute("aria-label",`Open Directive DevTools${r?"":" (system working)"}`);}function Ee(e,s,o,r){let a=Object.keys(o.derive);if(e.derivCount.textContent=String(a.length),a.length===0){s.clear(),e.derivBody.replaceChildren();let l=document.createElement("tr"),t=document.createElement("td");t.colSpan=2,t.style.color=b.muted,t.style.fontSize="10px",t.textContent="No derivations defined",l.appendChild(t),e.derivBody.appendChild(l);return}let p=new Set(a);for(let[l,t]of s)p.has(l)||(t.remove(),s.delete(l));for(let l of a){let t;try{t=fe(o.read(l));}catch{t="<error>";}de(s,e.derivBody,l,t,true,r);}}function We(e,s,o,r){let a=e.eventsList.querySelector(".dt-events-empty");a&&a.remove();let p=document.createElement("div");Object.assign(p.style,{padding:"2px 4px",borderBottom:`1px solid ${b.rowBorder}`,fontFamily:"inherit"});let l=new Date,t=`${String(l.getHours()).padStart(2,"0")}:${String(l.getMinutes()).padStart(2,"0")}:${String(l.getSeconds()).padStart(2,"0")}.${String(l.getMilliseconds()).padStart(3,"0")}`,i;try{let I=JSON.stringify(o);i=ee(I,60);}catch{i="{}";}let c=document.createElement("span");c.style.color=b.closeBtn,c.textContent=t;let d=document.createElement("span");d.style.color=b.accent,d.textContent=` ${s} `;let y=document.createElement("span");for(y.style.color=b.muted,y.textContent=i,p.appendChild(c),p.appendChild(d),p.appendChild(y),e.eventsList.prepend(p);e.eventsList.childElementCount>He;)e.eventsList.lastElementChild?.remove();e.eventsCount.textContent=String(r);}function Ue(e,s){e.perfBody.replaceChildren();let o=s.reconcileCount>0?(s.reconcileTotalMs/s.reconcileCount).toFixed(1):"\u2014",r=[`Reconciles: ${s.reconcileCount} (avg ${o}ms)`,`Effects: ${s.effectRunCount} run, ${s.effectErrorCount} errors`];for(let a of r){let p=document.createElement("div");p.style.marginBottom="2px",p.textContent=a,e.perfBody.appendChild(p);}if(s.resolverStats.size>0){let a=document.createElement("div");a.style.marginTop="4px",a.style.marginBottom="2px",a.style.color=b.accent,a.textContent="Resolvers:",e.perfBody.appendChild(a);let p=[...s.resolverStats.entries()].sort((l,t)=>t[1].totalMs-l[1].totalMs);for(let[l,t]of p){let i=t.count>0?(t.totalMs/t.count).toFixed(1):"0",c=document.createElement("div");c.style.paddingLeft="8px",c.textContent=`${l}: ${t.count}x, avg ${i}ms${t.errors>0?`, ${t.errors} err`:""}`,t.errors>0&&(c.style.color=b.red),e.perfBody.appendChild(c);}}}function Ce(e,s){let o=s.history;if(!o){e.historySection.style.display="none";return}e.historySection.style.display="flex";let r=o.currentIndex,a=o.snapshots.length;e.historyLabel.textContent=a>0?`${r+1} / ${a}`:"0 snapshots";let p=r>0,l=r<a-1;e.undoBtn.disabled=!p,e.undoBtn.style.opacity=p?"1":"0.4",e.redoBtn.disabled=!l,e.redoBtn.style.opacity=l?"1":"0.4";}function Ge(e,s){e.undoBtn.addEventListener("click",()=>{s.history&&s.history.currentIndex>0&&s.history.goBack(1);}),e.redoBtn.addEventListener("click",()=>{s.history&&s.history.currentIndex<s.history.snapshots.length-1&&s.history.goForward(1);});}var qe=Object.assign(Object.create(null),{$eq:"=",$ne:"\u2260",$gt:">",$gte:"\u2265",$lt:"<",$lte:"\u2264",$in:"\u2208",$nin:"\u2209",$exists:"exists",$between:"in",$startsWith:"starts with",$endsWith:"ends with",$contains:"contains",$matches:"matches",$changed:"changed"});function at(e){return Object.hasOwn(qe,e)?qe[e]:e}function Fe(e){return e instanceof RegExp?ee(String(e),40):fe(e)}var ct=new Set(["$all","$any","$not"]);function Ye(e){let s=document.createElement("li"),o=e.pass?"\u2713":"\u2717";if(s.style.color=e.pass?b.green:b.red,s.style.listStyle="none",ct.has(e.op)){let r=e.path?` @ ${e.path}`:"";if(s.textContent=`${o} ${e.op}${r}`,e.children&&e.children.length>0){let a=document.createElement("ul");Object.assign(a.style,{margin:"0",paddingLeft:"14px",listStyle:"none"});for(let p of e.children)a.appendChild(Ye(p));s.appendChild(a);}}else {let r=at(e.op),a=Fe(e.expected);if(e.pass)s.textContent=`${o} ${e.path} ${r} ${a}`;else {let p=Fe(e.actual);s.textContent=`${o} ${e.path} ${r} ${a} (actual: ${p})`;}}return s}function Xe(e,s,o){let r=s.get(o);if(r&&(r.remove(),s.delete(o),e.constraintsCount.textContent=String(s.size)),s.size===0&&!e.constraintsBody.querySelector(".dt-constraints-empty")){let a=document.createElement("div");a.style.color=b.muted,a.style.padding="4px",a.style.fontStyle="italic",a.textContent="Waiting for first evaluation\u2026",a.className="dt-constraints-empty",e.constraintsBody.appendChild(a);}}function Ke(e,s){let o=e.constraintsBody.querySelector(".dt-constraints-empty");o&&(o.textContent=s?"Waiting for first evaluation\u2026":"This system has no constraints");}function Je(e,s,o,r,a,p){let l=e.constraintsBody.querySelector(".dt-constraints-empty");l&&l.remove();let t=s.get(o);t||(t=document.createElement("div"),Object.assign(t.style,{marginBottom:"6px",paddingBottom:"4px",borderBottom:`1px solid ${b.rowBorder}`}),s.set(o,t),e.constraintsBody.appendChild(t),e.constraintsCount.textContent=String(s.size)),t.replaceChildren();let i=document.createElement("div");Object.assign(i.style,{fontWeight:"bold",color:r?b.green:b.muted});let c=r?"\u2713":"\u2717";if(i.textContent=p?`${c} ${o} (${p})`:`${c} ${o}`,t.appendChild(i),a&&a.length>0){let d=document.createElement("ul");Object.assign(d.style,{margin:"2px 0 0 0",paddingLeft:"14px",listStyle:"none"});for(let y of a)d.appendChild(Ye(y));t.appendChild(d);}else if(!a){let d=document.createElement("div");Object.assign(d.style,{color:b.muted,fontSize:"10px",fontStyle:"italic",paddingLeft:"14px"}),d.textContent="function-form when (no clause tree)",t.appendChild(d);}}var we=new WeakMap;function lt(e,s,o,r,a,p){return [e.join(","),s.join(","),o.map(l=>`${l.id}:${l.active}`).join(","),[...r.entries()].map(([l,t])=>`${l}:${t.status}:${t.type}`).join(","),a.join(","),p.join(",")].join("|")}function ut(e,s,o,r,a){for(let p of o){let l=e.nodes.get(`0:${p}`);if(!l)continue;let t=s.recentlyChangedFacts.has(p);l.rect.setAttribute("fill",t?b.text+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}for(let p of r){let l=e.nodes.get(`1:${p}`);if(!l)continue;let t=s.recentlyComputedDerivations.has(p);l.rect.setAttribute("fill",t?b.accent+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}for(let p of a){let l=e.nodes.get(`2:${p}`);if(!l)continue;let t=s.recentlyActiveConstraints.has(p),i=l.rect.getAttribute("stroke")??b.muted;l.rect.setAttribute("fill",t?i+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}}function Me(e,s,o){let r=se(s);if(!r)return;let a;try{a=Object.keys(s.facts.$store.toObject());}catch{a=[];}let p=Object.keys(s.derive),l=r.constraints,t=r.unmet,i=r.inflight,c=Object.keys(r.resolvers),d=new Map;for(let u of t)d.set(u.id,{type:u.requirement.type,fromConstraint:u.fromConstraint,status:"unmet"});for(let u of i)d.set(u.id,{type:u.resolverId,fromConstraint:"",status:"inflight"});if(a.length===0&&p.length===0&&l.length===0&&c.length===0){we.delete(e.flowSvg),e.flowSvg.replaceChildren(),e.flowSvg.setAttribute("viewBox","0 0 460 40");let u=document.createElementNS("http://www.w3.org/2000/svg","text");u.setAttribute("x","230"),u.setAttribute("y","24"),u.setAttribute("text-anchor","middle"),u.setAttribute("fill",b.muted),u.setAttribute("font-size","10"),u.setAttribute("font-family",b.font),u.textContent="No system topology",e.flowSvg.appendChild(u);return}let y=i.map(u=>u.resolverId).sort(),I=lt(a,p,l,d,c,y),N=we.get(e.flowSvg);if(N&&N.fingerprint===I){ut(N,o,a,p,l.map(u=>u.id));return}let R=G.nodeW+G.colGap,w=[5,5+R,5+R*2,5+R*3,5+R*4],g=w[4]+G.nodeW+5;function f(u){let M=G.startY+12;return u.map(S=>{let A={...S,y:M};return M+=G.nodeH+G.nodeGap,A})}let C=f(a.map(u=>{let M=r.facts.find(S=>S.key===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),T=f(p.map(u=>{let M=r.derivations.find(S=>S.id===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),P=f(l.map(u=>({id:u.id,label:ee(u.meta?.label??u.id,G.labelMaxChars),active:u.active,priority:u.priority}))),F=f([...d.entries()].map(([u,M])=>({id:u,type:M.type,fromConstraint:M.fromConstraint,status:M.status}))),O=f(c.map(u=>{let M=r.resolverDefs.find(S=>S.id===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),Y=Math.max(C.length,T.length,P.length,F.length,O.length,1),$=G.startY+12+Y*(G.nodeH+G.nodeGap)+8;e.flowSvg.replaceChildren(),e.flowSvg.setAttribute("viewBox",`0 0 ${g} ${$}`),e.flowSvg.setAttribute("aria-label",`Dependency graph: ${a.length} facts, ${p.length} derivations, ${l.length} constraints, ${d.size} requirements, ${c.length} resolvers`);let V=["Facts","Derivations","Constraints","Reqs","Resolvers"];for(let[u,M]of V.entries()){let S=document.createElementNS("http://www.w3.org/2000/svg","text");S.setAttribute("x",String(w[u]??0)),S.setAttribute("y","10"),S.setAttribute("fill",b.accent),S.setAttribute("font-size",String(G.fontSize)),S.setAttribute("font-family",b.font),S.textContent=M,e.flowSvg.appendChild(S);}let _={fingerprint:I,nodes:new Map};function H(u,M,S,A,W,k,L,n,m){let v=document.createElementNS("http://www.w3.org/2000/svg","g");if(m){let U=document.createElementNS("http://www.w3.org/2000/svg","title");U.textContent=m,v.appendChild(U);}let D=document.createElementNS("http://www.w3.org/2000/svg","rect");D.setAttribute("x",String(M)),D.setAttribute("y",String(S-6)),D.setAttribute("width",String(G.nodeW)),D.setAttribute("height",String(G.nodeH)),D.setAttribute("rx","3"),D.setAttribute("fill",n?k+"33":"none"),D.setAttribute("stroke",k),D.setAttribute("stroke-width",n?"2":"1"),D.setAttribute("opacity",L?"0.35":"1"),v.appendChild(D);let B=document.createElementNS("http://www.w3.org/2000/svg","text");return B.setAttribute("x",String(M+4)),B.setAttribute("y",String(S+4)),B.setAttribute("fill",k),B.setAttribute("font-size",String(G.fontSize)),B.setAttribute("font-family",b.font),B.setAttribute("opacity",L?"0.35":"1"),B.textContent=W,v.appendChild(B),e.flowSvg.appendChild(v),_.nodes.set(`${u}:${A}`,{g:v,rect:D,text:B}),{midX:M+G.nodeW/2,midY:S}}function h(u,M,S,A,W,k){let L=document.createElementNS("http://www.w3.org/2000/svg","line");L.setAttribute("x1",String(u)),L.setAttribute("y1",String(M)),L.setAttribute("x2",String(S)),L.setAttribute("y2",String(A)),L.setAttribute("stroke",W),L.setAttribute("stroke-width","1"),L.setAttribute("stroke-dasharray","3,2"),L.setAttribute("opacity","0.7"),e.flowSvg.appendChild(L);}let x=new Map,E=new Map,q=new Map,j=new Map;for(let u of C){let M=o.recentlyChangedFacts.has(u.id),S=r.facts.find(W=>W.key===u.id)?.meta,A=H(0,w[0],u.y,u.id,u.label,b.text,false,M,S?.description);x.set(u.id,A);}for(let u of T){let M=o.recentlyComputedDerivations.has(u.id),S=r.derivations.find(W=>W.id===u.id)?.meta,A=H(1,w[1],u.y,u.id,u.label,b.accent,false,M,S?.description);E.set(u.id,A);}for(let u of P){let M=o.recentlyActiveConstraints.has(u.id),S=l.find(W=>W.id===u.id)?.meta,A=H(2,w[2],u.y,u.id,u.label,S?.color??(u.active?b.yellow:b.muted),!u.active,M,S?.description);q.set(u.id,A);}for(let u of F){let M=u.status==="unmet"?b.red:b.yellow,S=H(3,w[3],u.y,u.id,ee(u.type,G.labelMaxChars),M,false,false);j.set(u.id,S);}for(let u of O){let M=i.some(A=>A.resolverId===u.id),S=r.resolverDefs.find(A=>A.id===u.id)?.meta;H(4,w[4],u.y,u.id,u.label,S?.color??(M?b.green:b.muted),!M,false,S?.description);}for(let u of T){let M=o.derivationDeps.get(u.id),S=E.get(u.id);if(M&&S)for(let A of M){let W=x.get(A);W&&h(W.midX+G.nodeW/2,W.midY,S.midX-G.nodeW/2,S.midY,b.accent);}}for(let u of F){let M=q.get(u.fromConstraint),S=j.get(u.id);M&&S&&h(M.midX+G.nodeW/2,M.midY,S.midX-G.nodeW/2,S.midY,b.muted);}for(let u of i){let M=j.get(u.id);if(M){let S=O.find(A=>A.id===u.resolverId);S&&h(M.midX+G.nodeW/2,M.midY,w[4],S.y,b.green);}}we.set(e.flowSvg,_);}function Qe(e){e.animationTimer&&clearTimeout(e.animationTimer),e.animationTimer=setTimeout(()=>{e.recentlyChangedFacts.clear(),e.recentlyComputedDerivations.clear(),e.recentlyActiveConstraints.clear(),e.animationTimer=null;},600);}function Ze(e,s){let o=s.entries.toArray();if(o.length===0)return;e.timelineSvg.replaceChildren();let r=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY;for(let R of o)R.startMs<r&&(r=R.startMs),R.endMs>a&&(a=R.endMs);let p=performance.now();for(let R of s.inflight.values())R<r&&(r=R),p>a&&(a=p);let l=a-r||1,t=ie-ce-10,i=[],c=new Set;for(let R of o)c.has(R.resolver)||(c.add(R.resolver),i.push(R.resolver));for(let R of s.inflight.keys())c.has(R)||(c.add(R),i.push(R));let y=i.slice(-12),I=ae*y.length+20;e.timelineSvg.setAttribute("viewBox",`0 0 ${ie} ${I}`),e.timelineSvg.setAttribute("height",String(Math.min(I,200)));let N=5;for(let R=0;R<=N;R++){let w=ce+t*R/N,g=l*R/N,f=document.createElementNS("http://www.w3.org/2000/svg","text");f.setAttribute("x",String(w)),f.setAttribute("y","8"),f.setAttribute("fill",b.muted),f.setAttribute("font-size","6"),f.setAttribute("font-family",b.font),f.setAttribute("text-anchor","middle"),f.textContent=g<1e3?`${g.toFixed(0)}ms`:`${(g/1e3).toFixed(1)}s`,e.timelineSvg.appendChild(f);let C=document.createElementNS("http://www.w3.org/2000/svg","line");C.setAttribute("x1",String(w)),C.setAttribute("y1","10"),C.setAttribute("x2",String(w)),C.setAttribute("y2",String(I)),C.setAttribute("stroke",b.border),C.setAttribute("stroke-width","0.5"),e.timelineSvg.appendChild(C);}for(let R=0;R<y.length;R++){let w=y[R],g=12+R*ae,f=R%Se.length,C=Se[f],T=document.createElementNS("http://www.w3.org/2000/svg","text");T.setAttribute("x",String(ce-4)),T.setAttribute("y",String(g+ae/2+3)),T.setAttribute("fill",b.muted),T.setAttribute("font-size","7"),T.setAttribute("font-family",b.font),T.setAttribute("text-anchor","end"),T.textContent=ee(w,12),e.timelineSvg.appendChild(T);let P=o.filter(O=>O.resolver===w);for(let O of P){let Y=ce+(O.startMs-r)/l*t,$=Math.max((O.endMs-O.startMs)/l*t,he),V=document.createElementNS("http://www.w3.org/2000/svg","rect");V.setAttribute("x",String(Y)),V.setAttribute("y",String(g+2)),V.setAttribute("width",String($)),V.setAttribute("height",String(ae-4)),V.setAttribute("rx","2"),V.setAttribute("fill",O.error?b.red:C),V.setAttribute("opacity","0.8");let _=document.createElementNS("http://www.w3.org/2000/svg","title"),H=O.endMs-O.startMs;_.textContent=`${w}: ${H.toFixed(1)}ms${O.error?" (error)":""}`,V.appendChild(_),e.timelineSvg.appendChild(V);}let F=s.inflight.get(w);if(F!==void 0){let O=ce+(F-r)/l*t,Y=Math.max((p-F)/l*t,he),$=document.createElementNS("http://www.w3.org/2000/svg","rect");$.setAttribute("x",String(O)),$.setAttribute("y",String(g+2)),$.setAttribute("width",String(Y)),$.setAttribute("height",String(ae-4)),$.setAttribute("rx","2"),$.setAttribute("fill",C),$.setAttribute("opacity","0.4"),$.setAttribute("stroke",C),$.setAttribute("stroke-width","1"),$.setAttribute("stroke-dasharray","3,2");let V=document.createElementNS("http://www.w3.org/2000/svg","title");V.textContent=`${w}: inflight ${(p-F).toFixed(0)}ms`,$.appendChild(V),e.timelineSvg.appendChild($);}}e.timelineSvg.setAttribute("aria-label",`Timeline: ${o.length} resolver executions across ${y.length} resolvers`);}function dt(){if(typeof window>"u")return {systems:new Map,getSystem:()=>null,getSystems:()=>[],inspect:()=>null,getEvents:()=>[],explain:()=>null,exportSession:()=>null,importSession:()=>false,clearEvents:()=>{},subscribe:()=>()=>{}};if(!window.__DIRECTIVE__){let e=new Map,s={systems:e,getSystem(o){return o?e.get(o)?.system??null:e.values().next().value?.system??null},getSystems(){return [...e.keys()]},inspect(o){let r=this.getSystem(o),a=o?e.get(o):e.values().next().value,p=r?.inspect()??null;return p&&a&&(p.resolverStats=a.resolverStats?Object.fromEntries(a.resolverStats):{}),p},getEvents(o){return o?e.get(o)?.events.toArray()??[]:e.values().next().value?.events.toArray()??[]},explain(o,r){return this.getSystem(r)?.explain(o)??null},subscribe(o,r){let a=r?e.get(r):e.values().next().value;if(!a){let p=false,t=setInterval(()=>{let c=r?e.get(r):e.values().next().value;c&&!p&&(p=true,c.subscribers.add(o));},100),i=setTimeout(()=>clearInterval(t),1e4);return ()=>{clearInterval(t),clearTimeout(i);for(let c of e.values())c.subscribers.delete(o);}}return a.subscribers.add(o),()=>{a.subscribers.delete(o);}},exportSession(o){let r=o?e.get(o):e.values().next().value;return r?JSON.stringify({version:1,name:o??e.keys().next().value??"default",exportedAt:Date.now(),events:r.events.toArray()}):null},importSession(o,r){try{if(o.length>10*1024*1024)return !1;let a=JSON.parse(o);if(!a||typeof a!="object"||Array.isArray(a)||!Array.isArray(a.events))return !1;let p=r?e.get(r):e.values().next().value;if(!p)return !1;let l=p.maxEvents,t=a.events,i=t.length>l?t.length-l:0;p.events.clear();for(let c=i;c<t.length;c++){let d=t[c];d&&typeof d=="object"&&!Array.isArray(d)&&typeof d.timestamp=="number"&&typeof d.type=="string"&&d.type!=="__proto__"&&d.type!=="constructor"&&d.type!=="prototype"&&p.events.push({timestamp:d.timestamp,type:d.type,data:d.data??null});}return !0}catch{return false}},clearEvents(o){let r=o?e.get(o):e.values().next().value;r&&r.events.clear();}};return Object.defineProperty(window,"__DIRECTIVE__",{value:s,writable:false,configurable:ge(),enumerable:true}),s}return window.__DIRECTIVE__}function mt(e={}){let{name:s="default",trace:o=false,maxEvents:r,panel:a=false,position:p="bottom-right",defaultOpen:l=false}=e,t=Pe(r),i=dt(),c={system:null,events:new ue(t),maxEvents:t,subscribers:new Set,resolverStats:new Map};i.systems.set(s,c);let d=(n,m)=>{let v={timestamp:Date.now(),type:n,data:m};o&&c.events.push(v);for(let D of c.subscribers)try{D(v);}catch{}},y=null,I=new Map,N=new Map,R=new Map,w=Ie(),g=_e(),f=je(),C=$e(),T=a&&typeof window<"u"&&typeof document<"u"&&ge(),P=null,F=0,O=1,Y=2,$=4,V=8,_=16,H=32,h=64,x=128,E=256,q=new Map,j=new Set,u=new Map,M=new Set,S=null;function A(n){F|=n,P===null&&typeof requestAnimationFrame<"u"&&(P=requestAnimationFrame(W));}function W(){if(P=null,!y||!c.system){F=0;return}let n=y.refs,m=c.system,v=F;if(F=0,v&O){for(let D of j)ze(I,D);j.clear();for(let[D,{value:B,flash:U}]of q)de(I,n.factsBody,D,B,U,y.flashTimers);q.clear(),n.factsCount.textContent=String(I.size);}if(v&Y&&Ee(n,N,m,y.flashTimers),v&E){for(let D of M)Xe(n,R,D);M.clear();for(let[D,{active:B,whenExplain:U,label:Z}]of u)Je(n,R,D,B,U,Z);u.clear();}if(v&V)if(S)ye(n,S.inflight.length,S.unmet.length);else {let D=se(m);D&&ye(n,D.inflight.length,D.unmet.length);}if(v&$)if(S)be(n,S.inflight,S.unmet);else {let D=se(m);D&&be(n,D.inflight,D.unmet);}v&_&&Ue(n,w),v&H&&Me(n,m,g),v&h&&Ce(n,m),v&x&&Ze(n,C);}function k(n,m){y&&o&&We(y.refs,n,m,c.events.size);}function L(n,m){f.isRecording&&f.recordedEvents.length<Ne&&f.recordedEvents.push({timestamp:Date.now(),type:n,data:Le(m)});}return {name:"devtools",onInit:n=>{if(c.system=n,d("init",{}),typeof window<"u"&&console.log(`%c[Directive Devtools]%c System "${s}" initialized. Access via window.__DIRECTIVE__`,"color: #7c3aed; font-weight: bold","color: inherit"),T){let m=c.system;y=Ve(s,p,l,o);let v=y.refs;try{let U=m.facts.$store.toObject();for(let[Z,re]of Object.entries(U))de(I,v.factsBody,Z,re,!1);v.factsCount.textContent=String(Object.keys(U).length);}catch{}Ee(v,N,m);let D=se(m);D&&(ye(v,D.inflight.length,D.unmet.length),be(v,D.inflight,D.unmet)),Ce(v,m),Ge(v,m),Me(v,m,g);let B=(D?.constraints?.length??0)>0;Ke(v,B),v.recordBtn.addEventListener("click",()=>{if(f.isRecording=!f.isRecording,v.recordBtn.textContent=f.isRecording?"\u23F9 Stop":"\u23FA Record",v.recordBtn.style.color=f.isRecording?b.red:b.text,f.isRecording){f.recordedEvents=[],f.snapshots=[];try{f.snapshots.push({timestamp:Date.now(),facts:m.facts.$store.toObject()});}catch{}}}),v.exportBtn.addEventListener("click",()=>{let U=f.recordedEvents.length>0?f.recordedEvents:c.events.toArray(),Z=JSON.stringify({version:1,name:s,exportedAt:Date.now(),events:U,snapshots:f.snapshots},null,2),re=new Blob([Z],{type:"application/json"}),oe=URL.createObjectURL(re),le=document.createElement("a");le.href=oe,le.download=`directive-session-${s}-${Date.now()}.json`,le.click(),URL.revokeObjectURL(oe);});}},onStart:n=>{d("start",{}),k("start",{}),L("start",{});},onStop:n=>{d("stop",{}),k("stop",{}),L("stop",{});},onDestroy:n=>{d("destroy",{}),i.systems.delete(s),P!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(P),P=null),g.animationTimer&&clearTimeout(g.animationTimer),y&&(y.destroy(),y=null,I.clear(),N.clear(),R.clear());},onFactSet:(n,m,v)=>{d("fact.set",{key:n,value:m,prev:v}),L("fact.set",{key:n,value:m,prev:v}),g.recentlyChangedFacts.add(n),y&&c.system&&(q.set(n,{value:m,flash:true}),j.delete(n),A(O),k("fact.set",{key:n,value:m}));},onFactDelete:(n,m)=>{d("fact.delete",{key:n,prev:m}),L("fact.delete",{key:n,prev:m}),y&&(j.add(n),q.delete(n),A(O),k("fact.delete",{key:n}));},onFactsBatch:n=>{if(d("facts.batch",{changes:n}),L("facts.batch",{count:n.length}),y&&c.system){for(let m of n)m.type==="delete"?(j.add(m.key),q.delete(m.key)):(g.recentlyChangedFacts.add(m.key),q.set(m.key,{value:m.value,flash:true}),j.delete(m.key));A(O),k("facts.batch",{count:n.length});}},onDerivationCompute:(n,m,v)=>{d("derivation.compute",{id:n,value:m,deps:v}),L("derivation.compute",{id:n,deps:v}),g.derivationDeps.set(n,v),g.recentlyComputedDerivations.add(n),k("derivation.compute",{id:n,deps:v});},onDerivationInvalidate:n=>{d("derivation.invalidate",{id:n}),k("derivation.invalidate",{id:n});},onReconcileStart:n=>{d("reconcile.start",{}),w.lastReconcileStartMs=performance.now(),k("reconcile.start",{}),L("reconcile.start",{});},onReconcileEnd:n=>{if(d("reconcile.end",n),L("reconcile.end",{unmet:n.unmet.length,inflight:n.inflight.length,completed:n.completed.length}),w.lastReconcileStartMs>0){let m=performance.now()-w.lastReconcileStartMs;w.reconcileCount++,w.reconcileTotalMs+=m,w.lastReconcileStartMs=0;}if(f.isRecording&&c.system&&f.snapshots.length<Be)try{f.snapshots.push({timestamp:Date.now(),facts:c.system.facts.$store.toObject()});}catch{}y&&c.system&&(S=n,Qe(g),A(Y|V|$|_|H|h),k("reconcile.end",{unmet:n.unmet.length,inflight:n.inflight.length}));},onConstraintEvaluate:(n,m,v)=>{let D=c.system?.meta?.constraint(n)?.label,B=D?{id:n,active:m,label:D}:{id:n,active:m},U=v?{...B,whenExplain:v}:B;d("constraint.evaluate",U),L("constraint.evaluate",U),m?(g.activeConstraints.add(n),g.recentlyActiveConstraints.add(n)):g.activeConstraints.delete(n),y&&(u.set(n,{active:m,whenExplain:v,label:D}),M.delete(n),A(E)),k("constraint.evaluate",{id:n,active:m});},onConstraintError:(n,m)=>{d("constraint.error",{id:n,error:String(m)}),k("constraint.error",{id:n,error:String(m)});},onRequirementCreated:n=>{d("requirement.created",{id:n.id,type:n.requirement.type}),L("requirement.created",{id:n.id,type:n.requirement.type}),k("requirement.created",{id:n.id,type:n.requirement.type});},onRequirementMet:(n,m)=>{d("requirement.met",{id:n.id,byResolver:m}),L("requirement.met",{id:n.id,byResolver:m}),k("requirement.met",{id:n.id,byResolver:m});},onRequirementCanceled:n=>{d("requirement.canceled",{id:n.id}),L("requirement.canceled",{id:n.id}),k("requirement.canceled",{id:n.id});},onResolverStart:(n,m)=>{let v=c.system?.meta?.resolver(n)?.label,D={resolver:n,requirementId:m.id},B=v?{...D,label:v}:D;d("resolver.start",B),L("resolver.start",B),C.inflight.set(n,performance.now()),y&&c.system&&(A($|V|x),k("resolver.start",{resolver:n,requirementId:m.id}));},onResolverComplete:(n,m,v)=>{let D=c.system?.meta?.resolver(n)?.label;d("resolver.complete",{resolver:n,requirementId:m.id,duration:v,...D?{label:D}:{}}),L("resolver.complete",{resolver:n,requirementId:m.id,duration:v});let B=c.resolverStats.get(n)??{count:0,totalMs:0,errors:0};if(B.count++,B.totalMs+=v,c.resolverStats.set(n,B),c.resolverStats.size>xe){let Z=c.resolverStats.keys().next().value;Z!==void 0&&c.resolverStats.delete(Z);}w.resolverStats.set(n,{...B});let U=C.inflight.get(n);C.inflight.delete(n),U!==void 0&&C.entries.push({resolver:n,startMs:U,endMs:performance.now(),error:false}),y&&c.system&&(A($|V|_|x),k("resolver.complete",{resolver:n,duration:v}));},onResolverError:(n,m,v)=>{d("resolver.error",{resolver:n,requirementId:m.id,error:String(v)}),L("resolver.error",{resolver:n,requirementId:m.id,error:String(v)});let D=c.resolverStats.get(n)??{count:0,totalMs:0,errors:0};if(D.errors++,c.resolverStats.set(n,D),c.resolverStats.size>xe){let U=c.resolverStats.keys().next().value;U!==void 0&&c.resolverStats.delete(U);}w.resolverStats.set(n,{...D});let B=C.inflight.get(n);C.inflight.delete(n),B!==void 0&&C.entries.push({resolver:n,startMs:B,endMs:performance.now(),error:true}),y&&c.system&&(A($|V|_|x),k("resolver.error",{resolver:n,error:String(v)}));},onResolverRetry:(n,m,v)=>{d("resolver.retry",{resolver:n,requirementId:m.id,attempt:v}),L("resolver.retry",{resolver:n,requirementId:m.id,attempt:v}),k("resolver.retry",{resolver:n,attempt:v});},onResolverCancel:(n,m)=>{d("resolver.cancel",{resolver:n,requirementId:m.id}),L("resolver.cancel",{resolver:n,requirementId:m.id}),C.inflight.delete(n),k("resolver.cancel",{resolver:n});},onResolverWriteRejected:n=>{let m=n.kind==="summary"?{kind:n.kind,resolver:n.resolver,requirementId:n.req.id,reason:n.reason,dropped:n.dropped}:{kind:n.kind,resolver:n.resolver,requirementId:n.req.id,reason:n.reason,fact:n.fact,expected:n.expected,actual:n.actual};d("resolver.write.rejected",m),L("resolver.write.rejected",m),k("resolver.write.rejected",n.kind==="summary"?{resolver:n.resolver,dropped:n.dropped}:{resolver:n.resolver,fact:n.fact});},onEffectRun:n=>{let m=c.system?.meta?.effect(n)?.label,v=m?{id:n,label:m}:{id:n};d("effect.run",v),L("effect.run",v),w.effectRunCount++,k("effect.run",{id:n});},onEffectError:(n,m)=>{d("effect.error",{id:n,error:String(m)}),w.effectErrorCount++,k("effect.error",{id:n,error:String(m)});},onSnapshot:n=>{d("timetravel.snapshot",{id:n.id,trigger:n.trigger}),y&&c.system&&A(h),k("timetravel.snapshot",{id:n.id,trigger:n.trigger});},onHistoryNavigate:(n,m)=>{if(d("timetravel.jump",{from:n,to:m}),L("timetravel.jump",{from:n,to:m}),y&&c.system){let v=c.system;try{let D=v.facts.$store.toObject();I.clear(),y.refs.factsBody.replaceChildren();for(let[B,U]of Object.entries(D))de(I,y.refs.factsBody,B,U,!1);y.refs.factsCount.textContent=String(Object.keys(D).length);}catch{}N.clear(),g.derivationDeps.clear(),y.refs.derivBody.replaceChildren(),R.clear(),y.refs.constraintsBody.replaceChildren(),y.refs.constraintsCount.textContent="0",S=null,A(Y|V|$|H|h),k("timetravel.jump",{from:n,to:m});}},onError:n=>{d("error",{source:n.source,sourceId:n.sourceId,message:n.message}),L("error",{source:n.source,message:n.message}),k("error",{source:n.source,message:n.message});},onErrorRecovery:(n,m)=>{d("error.recovery",{source:n.source,sourceId:n.sourceId,strategy:m}),k("error.recovery",{source:n.source,strategy:m});},onTraceComplete:n=>{d("trace.complete",{id:n.id,status:n.status,facts:n.factChanges.length,constraints:n.constraintsHit.length,requirements:n.requirementsAdded.length,resolvers:n.resolversStarted.length,effects:n.effectsRun.length}),k("trace.complete",{id:n.id});},onDefinitionRegister:(n,m)=>{d("definition.register",{type:n,id:m}),L("definition.register",{type:n,id:m}),k("definition.register",{type:n,id:m});},onDefinitionAssign:(n,m)=>{d("definition.assign",{type:n,id:m}),L("definition.assign",{type:n,id:m}),k("definition.assign",{type:n,id:m});},onDefinitionUnregister:(n,m)=>{d("definition.unregister",{type:n,id:m}),L("definition.unregister",{type:n,id:m}),k("definition.unregister",{type:n,id:m}),n==="constraint"&&y&&(M.add(m),u.delete(m),A(E));},onDefinitionCall:(n,m,v)=>{d("definition.call",{type:n,id:m,props:v}),L("definition.call",{type:n,id:m,props:v}),k("definition.call",{type:n,id:m,props:v});}}}var tt="directive-devtools-event",et=new Set(["__proto__","constructor","prototype"]),pt=Math.random().toString(36).slice(2,8);function gt(){if(typeof window<"u"){let e=`__DIRECTIVE_BRIDGE_ID_${pt}__`,s=window,o=s[e]??0;return s[e]=o+1,o+1}return 1}function ft(e){let s=false;for(let r of et)if(r in e){s=true;break}if(!s)return e;let o=Object.create(null);for(let[r,a]of Object.entries(e))et.has(r)||(o[r]=a);return o}function bt(e){if(!(typeof window>"u"))try{let s=ft(e),o={id:gt(),timestamp:Date.now(),snapshotId:null,...s};window.dispatchEvent(new CustomEvent(tt,{detail:o}));}catch{}}function yt(e){let{storage:s,key:o,include:r,exclude:a=[],debounce:p=100,onRestore:l,onSave:t,onError:i}=e,c=null,d=null,y=new Set,I=g=>a.includes(g)?false:r?r.includes(g):true,N=()=>{try{let g=s.getItem(o);if(!g)return null;let f=JSON.parse(g);return typeof f!="object"||f===null?null:chunkEOLY64E6_cjs.e(f)?f:(i?.(new Error("Potential prototype pollution detected in stored data")),null)}catch(g){return i?.(g instanceof Error?g:new Error(String(g))),null}},R=()=>{if(d)try{let g={};for(let f of y)I(f)&&(g[f]=d.facts[f]);s.setItem(o,JSON.stringify(g)),t?.(g);}catch(g){i?.(g instanceof Error?g:new Error(String(g)));}},w=()=>{c&&clearTimeout(c),c=setTimeout(R,p);};return {name:"persistence",onInit:g=>{d=g;let f=N();f&&(d.facts.$store.batch(()=>{for(let[C,T]of Object.entries(f))I(C)&&(d.facts[C]=T,y.add(C));}),l?.(f));},onDestroy:()=>{c&&clearTimeout(c),R();},onFactSet:g=>{y.add(g),I(g)&&w();},onFactDelete:g=>{y.delete(g),I(g)&&w();},onFactsBatch:g=>{let f=false;for(let C of g)C.type==="set"?y.add(C.key):y.delete(C.key),I(C.key)&&(f=true);f&&w();}}}function vt(e={}){let{onSlowConstraint:s,onSlowResolver:o,slowConstraintThresholdMs:r=16,slowResolverThresholdMs:a=1e3}=e,p=new Map,l=new Map,t=new Map,i={runs:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0},c=0,d=0,y=0;function I(g){let f=p.get(g);return f||(f={evaluations:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0,lastEvaluatedAt:0},p.set(g,f)),f}function N(g){let f=l.get(g);return f||(f={starts:0,completions:0,errors:0,retries:0,cancellations:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0,lastCompletedAt:0},l.set(g,f)),f}function R(g){let f=t.get(g);return f||(f={runs:0,errors:0,lastRunAt:0},t.set(g,f)),f}let w={name:"performance",onStart(){c=Date.now();},onConstraintEvaluate(g,f){let C=performance.now(),T=I(g);if(T.evaluations++,T.lastEvaluatedAt=Date.now(),y>0){let P=C-y;T.totalDurationMs+=P;let F=T.evaluations;T.avgDurationMs=T.totalDurationMs/F,P>T.maxDurationMs&&(T.maxDurationMs=P),P>r&&s?.(g,P);}y=C;},onResolverStart(g,f){let C=N(g);C.starts++;},onResolverComplete(g,f,C){let T=N(g);T.completions++,T.totalDurationMs+=C,T.avgDurationMs=T.totalDurationMs/T.completions,C>T.maxDurationMs&&(T.maxDurationMs=C),T.lastCompletedAt=Date.now(),C>a&&o?.(g,C);},onResolverError(g,f,C){N(g).errors++;},onResolverRetry(g,f,C){N(g).retries++;},onResolverCancel(g,f){N(g).cancellations++;},onEffectRun(g){let f=R(g);f.runs++,f.lastRunAt=Date.now();},onEffectError(g,f){R(g).errors++;},onReconcileStart(){d=performance.now(),y=0;},onReconcileEnd(){let g=performance.now()-d;i.runs++,i.totalDurationMs+=g,i.avgDurationMs=i.totalDurationMs/i.runs,g>i.maxDurationMs&&(i.maxDurationMs=g);},onDestroy(){w.reset();},getSnapshot(){let g={};for(let[T,P]of p)g[T]={...P};let f={};for(let[T,P]of l)f[T]={...P};let C={};for(let[T,P]of t)C[T]={...P};return {constraints:g,resolvers:f,effects:C,reconcile:{...i},uptime:c?Date.now()-c:0}},reset(){p.clear(),l.clear(),t.clear(),i.runs=0,i.totalDurationMs=0,i.avgDurationMs=0,i.maxDurationMs=0,y=0;}};return w}function ve(){return globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function Te(e,s){if(e.length===0)return 0;let o=[...e].sort((a,p)=>a-p),r=Math.ceil(s/100*o.length)-1;return o[Math.max(0,r)]??0}function ht(e={}){let{serviceName:s="directive-agents",metrics:o={},tracing:r={},alerts:a=[],summaryMetrics:p={},events:l={}}=e,t={requests:p.requests??"agent.requests",errors:p.errors??"agent.errors",latency:p.latency??"agent.latency",tokens:p.tokens??"agent.tokens",cost:p.cost??"agent.cost"},{enabled:i=true,exportInterval:c,exporter:d,maxDataPoints:y=1e3}=o,{enabled:I=true,sampleRate:N=1,maxSpans:R=1e3,exporter:w}=r,g=Date.now(),f=new Map,C=new Map,T=[],P=[],F=new Map,O=new Map,Y;c&&(d||w)&&(Y=setInterval(async()=>{try{if(d&&i&&await d(Array.from(O.values())),w&&I){let h=T.splice(0,100);h.length>0&&await w(h);}}catch(h){console.error("[Directive Observability] Export error:",h);}},c));function $(h){if(!i)return;let x=`${h.name}:${JSON.stringify(Object.fromEntries(Object.entries(h.labels).sort()))}`,E=f.get(x);E||(E=[],f.set(x,E)),E.push(h),E.length>y&&E.shift(),V(h.name,E),l.onMetricRecorded?.(h),_(h.name);}function V(h,x){if(x.length===0)return;let E=x.map(S=>S.value),q=E.reduce((S,A)=>S+A,0),j=x[0],u=E[E.length-1],M={name:h,type:j.type,count:x.length,sum:q,min:Math.min(...E),max:Math.max(...E),avg:q/x.length,lastValue:u,lastUpdated:Date.now()};O.set(h,M);}function _(h){for(let x of a){if(x.metric!==h)continue;let E=O.get(h);if(!E)continue;let q=`${x.metric}:${x.threshold}`,j=F.get(q),u=x.cooldownMs??6e4;if(j&&Date.now()-j<u)continue;let M=x.operator??">",S=E.lastValue,A=x.threshold,W=false;switch(M){case ">":W=S>A;break;case "<":W=S<A;break;case ">=":W=S>=A;break;case "<=":W=S<=A;break;case "==":W=S===A;break}if(W){let k={alertId:ve(),metric:h,currentValue:S,threshold:A,operator:M,action:x.action,timestamp:Date.now(),message:`Alert: ${h} ${M} ${A} (current: ${S})`};switch(P.push(k),P.length>1e3&&P.splice(0,P.length-1e3),F.set(q,Date.now()),l.onAlert?.(k),x.action){case "log":console.log(`[Observability] ${k.message}`);break;case "warn":console.warn(`[Observability] ${k.message}`);break;case "alert":console.error(`[Observability ALERT] ${k.message}`);break;case "callback":x.callback?.(E,A);break}}}}function H(h){let x=[];for(let[E,q]of f)if(E.startsWith(`${h}:`))for(let j of q)x.push(j.value);return x.length===0?{}:{p50:Te(x,50),p90:Te(x,90),p99:Te(x,99)}}return {incrementCounter(h,x={},E=1){$({name:h,type:"counter",value:E,labels:x,timestamp:Date.now()});},setGauge(h,x,E={}){$({name:h,type:"gauge",value:x,labels:E,timestamp:Date.now()});},observeHistogram(h,x,E={}){$({name:h,type:"histogram",value:x,labels:E,timestamp:Date.now()});},startSpan(h,x){if(Math.random()>N)return {traceId:"sampled-out",spanId:"sampled-out",operationName:h,serviceName:s,startTime:Date.now(),status:"ok",tags:{},logs:[]};let E={traceId:x?C.get(x)?.traceId??ve():ve(),spanId:ve(),parentSpanId:x,operationName:h,serviceName:s,startTime:Date.now(),status:"ok",tags:{},logs:[]};return I&&(C.set(E.spanId,E),l.onSpanStart?.(E)),E},endSpan(h,x="ok"){if(h==="sampled-out")return;let E=C.get(h);if(E){for(E.endTime=Date.now(),E.duration=E.endTime-E.startTime,E.status=x,C.delete(h),T.push(E);T.length>R;)T.shift();$({name:`${E.operationName}.latency`,type:"histogram",value:E.duration,labels:{},timestamp:Date.now()}),x==="error"&&$({name:`${E.operationName}.errors`,type:"counter",value:1,labels:{},timestamp:Date.now()}),l.onSpanEnd?.(E);}},addSpanLog(h,x,E="info"){if(h==="sampled-out")return;let q=C.get(h);q&&q.logs.push({timestamp:Date.now(),message:x,level:E});},addSpanTag(h,x,E){if(h==="sampled-out")return;let q=C.get(h);q&&(q.tags[x]=E);},getDashboard(){let h=O.get(t.requests),x=O.get(t.errors),E=O.get(t.latency),q=O.get(t.tokens),j=O.get(t.cost),u=h?.sum??0,M=x?.sum??0,S=u>0?M/u:0,A=E?H(t.latency):{};return {service:{name:s,uptime:Date.now()-g,startTime:g},metrics:Object.fromEntries(O),traces:[...T].slice(-100),alerts:[...P].slice(-50),summary:{totalRequests:u,totalErrors:M,errorRate:S,avgLatency:E?.avg??0,p99Latency:A.p99??0,activeSpans:C.size,totalTokens:q?.sum??0,totalCost:j?.sum??0}}},getMetric(h){let x=O.get(h);if(!x)return;let E=H(h);return {...x,...E}},getTraces(h=100){return [...T].slice(-h)},getAlerts(){return [...P]},export(){return {metrics:Array.from(O.values()),traces:[...T],alerts:[...P]}},clear(){f.clear(),O.clear(),C.clear(),T.length=0,P.length=0,F.clear();},async destroy(){Y&&(clearInterval(Y),Y=void 0);try{d&&i&&O.size>0&&await d(Array.from(O.values())),w&&I&&T.length>0&&await w([...T]);}catch(h){console.error("[Directive Observability] Error flushing data during destroy:",h);}f.clear(),O.clear(),C.clear(),T.length=0,P.length=0,F.clear();},getHealthStatus(){let h=O.get(t.requests),x=O.get(t.errors),E=h?.sum??0,q=x?.sum??0,j=E>0?q/E:0,u=P.filter(M=>Date.now()-M.timestamp<3e5).length;return {healthy:j<.1&&u===0,uptime:Date.now()-g,errorRate:j,activeAlerts:u}}}}function St(e){return {trackRun(s,o){let r={agent:s};e.incrementCounter("agent.requests",r),o.success||e.incrementCounter("agent.errors",r),e.observeHistogram("agent.latency",o.latencyMs,r),o.inputTokens!==void 0&&(e.incrementCounter("agent.tokens.input",r,o.inputTokens),e.incrementCounter("agent.tokens",r,o.inputTokens)),o.outputTokens!==void 0&&(e.incrementCounter("agent.tokens.output",r,o.outputTokens),e.incrementCounter("agent.tokens",r,o.outputTokens)),o.cost!==void 0&&e.incrementCounter("agent.cost",r,o.cost),o.toolCalls!==void 0&&e.incrementCounter("agent.tool_calls",r,o.toolCalls);},trackGuardrail(s,o){let r={guardrail:s};e.incrementCounter("guardrail.checks",r),o.passed||e.incrementCounter("guardrail.failures",r),o.blocked&&e.incrementCounter("guardrail.blocks",r),e.observeHistogram("guardrail.latency",o.latencyMs,r);},trackApproval(s,o){let r={tool:s};e.incrementCounter("approval.requests",r),o.approved?e.incrementCounter("approval.approved",r):e.incrementCounter("approval.rejected",r),o.timedOut&&e.incrementCounter("approval.timeouts",r),e.observeHistogram("approval.wait_time",o.waitTimeMs,r);},trackHandoff(s,o,r){e.incrementCounter("handoff.count",{from:s,to:o}),e.observeHistogram("handoff.latency",r);}}}function xt(e){let s=[{key:"service.name",value:{stringValue:e.serviceName??"directive-agents"}}];if(e.serviceVersion&&s.push({key:"service.version",value:{stringValue:e.serviceVersion}}),e.resourceAttributes)for(let[o,r]of Object.entries(e.resourceAttributes))s.push({key:o,value:{stringValue:r}});return {attributes:s}}function ne(e){return `${BigInt(e)*BigInt(1e6)}`}function Et(e){switch(e){case "counter":return "sum";case "gauge":return "gauge";case "histogram":return "histogram";default:return "gauge"}}function Ct(e,s,o){let r=e.map(a=>{let p=a.lastUpdated-6e4,l=[{asInt:a.type==="counter"?a.sum:void 0,asDouble:a.type!=="counter"?a.lastValue:void 0,timeUnixNano:ne(a.lastUpdated),startTimeUnixNano:ne(p),attributes:[]}],t=Et(a.type),i={name:a.name,unit:""};return t==="sum"?i.sum={dataPoints:l,aggregationTemporality:2,isMonotonic:true}:t==="histogram"?i.histogram={dataPoints:[{count:a.count,sum:a.sum,min:a.min,max:a.max,timeUnixNano:ne(a.lastUpdated),startTimeUnixNano:ne(p),attributes:[]}],aggregationTemporality:2}:i.gauge={dataPoints:l},i});return {resourceMetrics:[{resource:s,scopeMetrics:[{scope:{name:"directive",version:o},metrics:r}]}]}}function wt(e,s,o){let r=e.map(a=>{let p=a.logs.map(i=>({timeUnixNano:ne(i.timestamp),name:i.level,attributes:[{key:"message",value:{stringValue:i.message}},{key:"level",value:{stringValue:i.level}}]})),l=Object.entries(a.tags).map(([i,c])=>({key:i,value:typeof c=="string"?{stringValue:c}:typeof c=="number"?{intValue:`${c}`}:{boolValue:c}})),t=a.status==="ok"?1:a.status==="error"?2:0;return {traceId:a.traceId.replace(/-/g,"").padEnd(32,"0").slice(0,32),spanId:a.spanId.replace(/-/g,"").padEnd(16,"0").slice(0,16),parentSpanId:a.parentSpanId?a.parentSpanId.replace(/-/g,"").padEnd(16,"0").slice(0,16):void 0,name:a.operationName,kind:1,startTimeUnixNano:ne(a.startTime),endTimeUnixNano:a.endTime?ne(a.endTime):ne(a.startTime),attributes:l,events:p,status:{code:t}}});return {resourceSpans:[{resource:s,scopeSpans:[{scope:{name:"directive",version:o},spans:r}]}]}}function Mt(e){let{endpoint:s,headers:o={},scopeVersion:r="0.1.0",timeoutMs:a=1e4,fetch:p=globalThis.fetch,onError:l}=e;try{let c=new URL(s);if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error("[Directive] Only http: and https: protocols are supported")}catch(c){throw new Error(`[Directive OTLP] Invalid endpoint URL "${s}": ${c instanceof Error?c.message:String(c)}`)}if(/\/v1\/(metrics|traces)/.test(s)&&console.warn(`[Directive OTLP] Endpoint "${s}" already contains a /v1/metrics or /v1/traces path. The exporter will append /v1/metrics or /v1/traces automatically. Use the base URL (e.g., "http://localhost:4318") instead.`),a<=0||!Number.isFinite(a))throw new Error(`[Directive OTLP] timeoutMs must be > 0, got ${a}`);let t=xt(e);async function i(c,d,y){let I=`${s.replace(/\/$/,"")}${c}`,N=new AbortController,R=setTimeout(()=>N.abort(),a);try{let w=await p(I,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify(d),signal:N.signal});if(!w.ok)throw new Error(`[Directive] OTLP export failed: ${w.status} ${w.statusText}`)}catch(w){let g=w instanceof Error?w:new Error(String(w));l?l(g,y):console.error(`[Directive OTLP] Export ${y} error:`,g.message);}finally{clearTimeout(R);}}return {async exportMetrics(c){if(c.length===0)return;let d=Ct(c,t,r);await i("/v1/metrics",d,"metrics");},async exportTraces(c){if(c.length===0)return;let d=wt(c,t,r);await i("/v1/traces",d,"traces");}}}var me=class extends Error{code="CIRCUIT_OPEN";retryAfterMs;state;constructor(s,o,r="OPEN",a){let p=a?`[Directive CircuitBreaker] Circuit "${s}" is ${r}. ${a}`:`[Directive CircuitBreaker] Circuit "${s}" is ${r}. Request rejected. Try again in ${Math.ceil(o/1e3)}s.`;super(p),this.name="CircuitBreakerOpenError",this.retryAfterMs=o,this.state=r;}};function Tt(e={}){let{failureThreshold:s=5,recoveryTimeMs:o=3e4,halfOpenMaxRequests:r=3,failureWindowMs:a=6e4,observability:p,metricPrefix:l="circuit_breaker",name:t="default",isFailure:i=()=>true,onStateChange:c}=e;if(s<1||!Number.isFinite(s))throw new Error(`[Directive CircuitBreaker] failureThreshold must be >= 1, got ${s}`);if(o<=0||!Number.isFinite(o))throw new Error(`[Directive CircuitBreaker] recoveryTimeMs must be > 0, got ${o}`);if(r<1||!Number.isFinite(r))throw new Error(`[Directive CircuitBreaker] halfOpenMaxRequests must be >= 1, got ${r}`);if(a<=0||!Number.isFinite(a))throw new Error(`[Directive CircuitBreaker] failureWindowMs must be > 0, got ${a}`);let d="CLOSED",y=[],I=0,N=0,R=Date.now(),w=0,g=0,f=0,C=0,T=0,P=null,F=null;function O(_){if(d===_)return;let H=d;d=_,R=Date.now(),_==="OPEN"&&(w=Date.now()),_==="HALF_OPEN"&&(I=0,N=0),c?.(H,_),p&&p.incrementCounter(`${l}.state_change`,{name:t,from:H,to:_});}function Y(){let _=Date.now()-a;return y=y.filter(H=>H>_),y.length}function $(){C++,F=Date.now(),p&&p.incrementCounter(`${l}.success`,{name:t}),d==="HALF_OPEN"&&(N++,N>=r&&(O("CLOSED"),y=[]));}function V(_){if(!i(_)){$();return}f++,P=Date.now(),y.push(Date.now());let H=s*2;if(y.length>H&&(y=y.slice(-H)),p&&p.incrementCounter(`${l}.failure`,{name:t}),d==="HALF_OPEN"){O("OPEN");return}d==="CLOSED"&&Y()>=s&&O("OPEN");}return {async execute(_){if(g++,p&&p.incrementCounter(`${l}.requests`,{name:t}),d==="OPEN")if(Date.now()-w>=o)O("HALF_OPEN");else throw T++,p&&p.incrementCounter(`${l}.rejected`,{name:t}),new me(t,o-(Date.now()-w));if(d==="HALF_OPEN"){if(I>=r)throw T++,new me(t,o,"HALF_OPEN",`Max trial requests (${r}) reached.`);I++;}let H=Date.now();try{let h=await _();return $(),p&&p.observeHistogram(`${l}.latency`,Date.now()-H,{name:t}),h}catch(h){let x=h instanceof Error?h:new Error(String(h));throw V(x),p&&p.observeHistogram(`${l}.latency`,Date.now()-H,{name:t}),h}},getState(){return d==="OPEN"&&Date.now()-w>=o&&O("HALF_OPEN"),d},getStats(){return {state:this.getState(),totalRequests:g,totalFailures:f,totalSuccesses:C,totalRejected:T,recentFailures:Y(),lastFailureTime:P,lastSuccessTime:F,lastStateChange:R}},forceState(_){O(_);},reset(){let _=d;d="CLOSED",y=[],I=0,N=0,R=Date.now(),w=0,g=0,f=0,C=0,T=0,P=null,F=null,_!=="CLOSED"&&c?.(_,"CLOSED");},isAllowed(){return d==="CLOSED"?true:d==="OPEN"?Date.now()-w>=o:I<r}}}
Object.defineProperty(exports,"createAuditLedger",{enumerable:true,get:function(){return chunk4VZOZWXM_cjs.b}});Object.defineProperty(exports,"memorySink",{enumerable:true,get:function(){return chunk4VZOZWXM_cjs.a}});exports.CircuitBreakerOpenError=me;exports.DEVTOOLS_EVENT_NAME=tt;exports.createAgentMetrics=St;exports.createCircuitBreaker=Tt;exports.createOTLPExporter=Mt;exports.createObservability=ht;exports.devtoolsPlugin=mt;exports.emitDevToolsEvent=bt;exports.loggingPlugin=st;exports.performancePlugin=vt;exports.persistencePlugin=yt;//# sourceMappingURL=index.cjs.map
'use strict';var chunkIXRS4LM4_cjs=require('../chunk-IXRS4LM4.cjs');require('../chunk-T4TRJEJN.cjs');var chunk4MNQDXH7_cjs=require('../chunk-4MNQDXH7.cjs');var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;var Oe={debug:0,info:1,warn:2,error:3};function st(e={}){let{level:s="info",filter:o=()=>true,logger:r=console,prefix:a="[Directive]"}=e,p=Oe[s],l=(t,i,...c)=>{Oe[t]<p||o(i)&&r[t](`${a} ${i}`,...c);};return {name:"logging",onInit:()=>l("debug","init"),onStart:()=>l("info","start"),onStop:()=>l("info","stop"),onDestroy:()=>l("debug","destroy"),onFactSet:(t,i,c)=>{l("debug","fact.set",{key:t,value:i,prev:c});},onFactDelete:(t,i)=>{l("debug","fact.delete",{key:t,prev:i});},onFactsBatch:t=>{l("debug","facts.batch",{count:t.length,changes:t});},onDerivationCompute:(t,i,c)=>{l("debug","derivation.compute",{id:t,value:i,deps:c});},onDerivationInvalidate:t=>{l("debug","derivation.invalidate",{id:t});},onReconcileStart:()=>{l("debug","reconcile.start");},onReconcileEnd:t=>{l("debug","reconcile.end",{unmet:t.unmet.length,inflight:t.inflight.length,completed:t.completed.length,canceled:t.canceled.length});},onConstraintEvaluate:(t,i,c)=>{if(c){let d=c.filter(y=>y.pass).length;l("debug","constraint.evaluate",{id:t,active:i,clauses:{total:c.length,passed:d}});return}l("debug","constraint.evaluate",{id:t,active:i});},onConstraintError:(t,i)=>{l("error","constraint.error",{id:t,error:i});},onRequirementCreated:t=>{l("debug","requirement.created",{id:t.id,type:t.requirement.type});},onRequirementMet:(t,i)=>{l("info","requirement.met",{id:t.id,byResolver:i});},onRequirementCanceled:t=>{l("debug","requirement.canceled",{id:t.id});},onResolverStart:(t,i)=>{l("debug","resolver.start",{resolver:t,requirementId:i.id});},onResolverComplete:(t,i,c)=>{l("info","resolver.complete",{resolver:t,requirementId:i.id,duration:c});},onResolverError:(t,i,c)=>{l("error","resolver.error",{resolver:t,requirementId:i.id,error:c});},onResolverRetry:(t,i,c)=>{l("warn","resolver.retry",{resolver:t,requirementId:i.id,attempt:c});},onResolverCancel:(t,i)=>{l("debug","resolver.cancel",{resolver:t,requirementId:i.id});},onResolverWriteRejected:t=>{l("warn","resolver.write.rejected",t.kind==="summary"?{kind:t.kind,resolver:t.resolver,requirementId:t.req.id,reason:t.reason,dropped:t.dropped}:{kind:t.kind,resolver:t.resolver,requirementId:t.req.id,reason:t.reason,fact:t.fact,expected:t.expected,actual:t.actual});},onEffectRun:t=>{l("debug","effect.run",{id:t});},onEffectError:(t,i)=>{l("error","effect.error",{id:t,error:i});},onSnapshot:t=>{l("debug","timetravel.snapshot",{id:t.id,trigger:t.trigger});},onHistoryNavigate:(t,i)=>{l("info","timetravel.jump",{from:t,to:i});},onError:t=>{l("error","error",{source:t.source,sourceId:t.sourceId,message:t.message});},onErrorRecovery:(t,i)=>{l("warn","error.recovery",{source:t.source,sourceId:t.sourceId,strategy:i});},onDefinitionRegister:(t,i)=>{l("info","definition.register",{type:t,id:i});},onDefinitionAssign:(t,i)=>{l("info","definition.assign",{type:t,id:i});},onDefinitionUnregister:(t,i)=>{l("info","definition.unregister",{type:t,id:i});},onDefinitionCall:(t,i,c)=>{l("debug","definition.call",{type:t,id:i,props:c});},onTraceComplete:t=>{l("debug","trace.complete",{id:t.id,status:t.status,duration:t.duration,factChanges:t.factChanges.length,derivationsRecomputed:t.derivationsRecomputed.length,constraintsHit:t.constraintsHit.length,resolversStarted:t.resolversStarted.length,effectsRun:t.effectsRun.length});}}}var ue=class{constructor(s){this.capacity=s;this.buf=new Array(s);}buf;head=0;_size=0;get size(){return this._size}push(s){this.buf[this.head]=s,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++;}toArray(){return this._size===0?[]:this._size<this.capacity?this.buf.slice(0,this._size):[...this.buf.slice(this.head),...this.buf.slice(0,this.head)]}clear(){this.buf=new Array(this.capacity),this.head=0,this._size=0;}};function ge(){try{if(typeof process<"u"&&process.env?.NODE_ENV==="production")return !1}catch{}try{if(typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) })<"u"&&undefined?.MODE==="production")return !1}catch{}return true}function fe(e){try{if(e===void 0)return "undefined";if(e===null)return "null";if(typeof e=="bigint")return String(e)+"n";if(typeof e=="symbol")return String(e);if(typeof e=="object"){let s=JSON.stringify(e,(o,r)=>typeof r=="bigint"?String(r)+"n":typeof r=="symbol"?String(r):r);return s.length>120?s.slice(0,117)+"...":s}return String(e)}catch{return "<error>"}}function ee(e,s){return e.length<=s?e:e.slice(0,s-3)+"..."}function se(e){try{return e.inspect()}catch{return null}}function Le(e){try{return e==null||typeof e!="object"?e:JSON.parse(JSON.stringify(e))}catch{return null}}function Pe(e){return e===void 0?1e3:!Number.isFinite(e)||e<1?(ge()&&console.warn(`[directive:devtools] Invalid maxEvents value (${e}), using default 1000`),1e3):Math.floor(e)}function Ie(){return {reconcileCount:0,reconcileTotalMs:0,resolverStats:new Map,effectRunCount:0,effectErrorCount:0,lastReconcileStartMs:0}}var it=200,ie=340,ae=16,ce=80,he=2,Se=["#8b9aff","#4ade80","#fbbf24","#c084fc","#f472b6","#22d3ee"];function $e(){return {entries:new ue(it),inflight:new Map}}function _e(){return {derivationDeps:new Map,activeConstraints:new Set,recentlyChangedFacts:new Set,recentlyComputedDerivations:new Set,recentlyActiveConstraints:new Set,animationTimer:null}}var Ne=1e4,Be=100;function je(){return {isRecording:false,recordedEvents:[],snapshots:[]}}var He=50,xe=200,b={bg:"#1a1a2e",text:"#e0e0e0",accent:"#8b9aff",muted:"#b0b0d0",border:"#333",rowBorder:"#2a2a4a",green:"#4ade80",yellow:"#fbbf24",red:"#f87171",closeBtn:"#aaa",font:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},G={nodeW:90,nodeH:16,nodeGap:6,startY:16,colGap:20,fontSize:10,labelMaxChars:11};function Ve(e,s,o,r){let a=false,p={position:"fixed",zIndex:"99999",...s.includes("bottom")?{bottom:"12px"}:{top:"12px"},...s.includes("right")?{right:"12px"}:{left:"12px"}},l=document.createElement("style");l.textContent=`[data-directive-devtools] summary:focus-visible{outline:2px solid ${b.accent};outline-offset:2px;border-radius:2px}[data-directive-devtools] button:focus-visible{outline:2px solid ${b.accent};outline-offset:2px}`,document.head.appendChild(l);let t=document.createElement("button");t.setAttribute("aria-label","Open Directive DevTools"),t.setAttribute("aria-expanded",String(o)),t.title="Ctrl+Shift+D to toggle",Object.assign(t.style,{...p,background:b.bg,color:b.text,border:`1px solid ${b.border}`,borderRadius:"6px",padding:"10px 14px",minWidth:"44px",minHeight:"44px",cursor:"pointer",fontFamily:b.font,fontSize:"12px",display:o?"none":"block"}),t.textContent="Directive";let i=document.createElement("div");i.setAttribute("role","region"),i.setAttribute("aria-label","Directive DevTools"),i.setAttribute("data-directive-devtools",""),i.tabIndex=-1,Object.assign(i.style,{...p,background:b.bg,color:b.text,border:`1px solid ${b.border}`,borderRadius:"8px",padding:"12px",fontFamily:b.font,fontSize:"11px",maxWidth:"min(380px, calc(100vw - 24px))",maxHeight:"min(500px, calc(100vh - 24px))",overflow:"auto",boxShadow:"0 4px 20px rgba(0,0,0,0.5)",display:o?"block":"none"});let c=document.createElement("div");Object.assign(c.style,{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"8px"});let d=document.createElement("strong");d.style.color=b.accent,d.textContent=e==="default"?"Directive DevTools":`DevTools (${e})`;let y=document.createElement("button");y.setAttribute("aria-label","Close DevTools"),Object.assign(y.style,{background:"none",border:"none",color:b.closeBtn,cursor:"pointer",fontSize:"16px",padding:"8px 12px",minWidth:"44px",minHeight:"44px",lineHeight:"1",display:"flex",alignItems:"center",justifyContent:"center"}),y.textContent="\xD7",c.appendChild(d),c.appendChild(y),i.appendChild(c);let I=document.createElement("div");I.style.marginBottom="6px",I.setAttribute("aria-live","polite");let N=document.createElement("span");N.style.color=b.green,N.textContent="Settled",I.appendChild(N),i.appendChild(I);let R=document.createElement("div");Object.assign(R.style,{display:"none",marginBottom:"8px",padding:"4px 8px",background:"#252545",borderRadius:"4px",alignItems:"center",gap:"6px"});let w=document.createElement("button");Object.assign(w.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"4px 10px",borderRadius:"3px",fontFamily:b.font,fontSize:"11px",minWidth:"44px",minHeight:"44px"}),w.textContent="\u25C0 Undo",w.disabled=true;let g=document.createElement("button");Object.assign(g.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"4px 10px",borderRadius:"3px",fontFamily:b.font,fontSize:"11px",minWidth:"44px",minHeight:"44px"}),g.textContent="Redo \u25B6",g.disabled=true;let f=document.createElement("span");f.style.color=b.muted,f.style.fontSize="10px",R.appendChild(w),R.appendChild(g),R.appendChild(f),i.appendChild(R);function C(z,K){let X=document.createElement("details");K&&(X.open=true),X.style.marginBottom="4px";let J=document.createElement("summary");Object.assign(J.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"});let Q=document.createElement("span");J.textContent=`${z} (`,J.appendChild(Q),J.appendChild(document.createTextNode(")")),Q.textContent="0",X.appendChild(J);let te=document.createElement("table");Object.assign(te.style,{width:"100%",borderCollapse:"collapse",fontSize:"11px"});let Re=document.createElement("thead"),De=document.createElement("tr");for(let nt of ["Key","Value"]){let pe=document.createElement("th");pe.scope="col",Object.assign(pe.style,{textAlign:"left",padding:"2px 4px",color:b.accent}),pe.textContent=nt,De.appendChild(pe);}Re.appendChild(De),te.appendChild(Re);let Ae=document.createElement("tbody");return te.appendChild(Ae),X.appendChild(te),{details:X,tbody:Ae,countSpan:Q}}function T(z,K){let X=document.createElement("details");X.style.marginBottom="4px";let J=document.createElement("summary");Object.assign(J.style,{cursor:"pointer",color:K,marginBottom:"4px"});let Q=document.createElement("span");J.textContent=`${z} (`,J.appendChild(Q),J.appendChild(document.createTextNode(")")),Q.textContent="0",X.appendChild(J);let te=document.createElement("ul");return Object.assign(te.style,{margin:"0",paddingLeft:"16px"}),X.appendChild(te),{details:X,list:te,countSpan:Q}}let P=C("Facts",true);i.appendChild(P.details);let F=C("Derivations",false);i.appendChild(F.details);let O=T("Inflight",b.yellow);i.appendChild(O.details);let Y=T("Unmet",b.red);i.appendChild(Y.details);let $=document.createElement("details");$.style.marginBottom="4px";let V=document.createElement("summary");Object.assign(V.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),V.textContent="Performance",$.appendChild(V);let _=document.createElement("div");_.style.fontSize="10px",_.style.color=b.muted,_.textContent="No data yet",$.appendChild(_),i.appendChild($);let H=document.createElement("details");H.style.marginBottom="4px";let h=document.createElement("summary");Object.assign(h.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),h.textContent="Dependency Graph",H.appendChild(h);let x=document.createElementNS("http://www.w3.org/2000/svg","svg");x.setAttribute("width","100%"),x.setAttribute("height","120"),x.setAttribute("role","img"),x.setAttribute("aria-label","System dependency graph"),x.style.display="block",x.setAttribute("viewBox","0 0 460 120"),x.setAttribute("preserveAspectRatio","xMinYMin meet"),H.appendChild(x),i.appendChild(H);let E=document.createElement("details");E.style.marginBottom="4px";let q=document.createElement("summary");Object.assign(q.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),q.textContent="Timeline",E.appendChild(q);let j=document.createElementNS("http://www.w3.org/2000/svg","svg");j.setAttribute("width","100%"),j.setAttribute("height","60"),j.setAttribute("role","img"),j.setAttribute("aria-label","Resolver execution timeline"),j.style.display="block",j.setAttribute("viewBox",`0 0 ${ie} 60`),j.setAttribute("preserveAspectRatio","xMinYMin meet");let u=document.createElementNS("http://www.w3.org/2000/svg","text");u.setAttribute("x",String(ie/2)),u.setAttribute("y","30"),u.setAttribute("text-anchor","middle"),u.setAttribute("fill",b.muted),u.setAttribute("font-size","10"),u.setAttribute("font-family",b.font),u.textContent="No resolver activity yet",j.appendChild(u),E.appendChild(j),i.appendChild(E);let M=(()=>{let z=document.createElement("details");z.style.marginBottom="4px";let K=document.createElement("summary");Object.assign(K.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"});let X=document.createElement("span");X.textContent="0",K.textContent="Constraints (",K.appendChild(X),K.appendChild(document.createTextNode(")")),z.appendChild(K);let J=document.createElement("div");Object.assign(J.style,{fontSize:"11px"});let Q=document.createElement("div");return Q.style.color=b.muted,Q.style.padding="4px",Q.style.fontStyle="italic",Q.textContent="Waiting for first evaluation\u2026",Q.className="dt-constraints-empty",J.appendChild(Q),z.appendChild(J),i.appendChild(z),{details:z,body:J,countSpan:X}})(),S,A,W,k;if(r){let z=document.createElement("details");z.style.marginBottom="4px";let K=document.createElement("summary");Object.assign(K.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),W=document.createElement("span"),W.textContent="0",K.textContent="Events (",K.appendChild(W),K.appendChild(document.createTextNode(")")),z.appendChild(K),A=document.createElement("div"),Object.assign(A.style,{maxHeight:"150px",overflow:"auto",fontSize:"10px"}),A.setAttribute("role","log"),A.setAttribute("aria-live","polite"),A.tabIndex=0;let X=document.createElement("div");X.style.color=b.muted,X.style.padding="4px",X.textContent="Waiting for events...",X.className="dt-events-empty",A.appendChild(X),z.appendChild(A),i.appendChild(z),S=z,k=document.createElement("div");}else S=document.createElement("details"),A=document.createElement("div"),W=document.createElement("span"),k=document.createElement("div"),k.style.fontSize="10px",k.style.color=b.muted,k.style.marginTop="4px",k.style.fontStyle="italic",k.textContent="Enable trace: true for event log",i.appendChild(k);let L=document.createElement("div");Object.assign(L.style,{display:"flex",gap:"6px",marginTop:"6px"});let n=document.createElement("button");Object.assign(n.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"8px 12px",borderRadius:"3px",fontFamily:b.font,fontSize:"10px",minWidth:"44px",minHeight:"44px"}),n.textContent="\u23FA Record";let m=document.createElement("button");Object.assign(m.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"8px 12px",borderRadius:"3px",fontFamily:b.font,fontSize:"10px",minWidth:"44px",minHeight:"44px"}),m.textContent="\u2913 Export",L.appendChild(n),L.appendChild(m),i.appendChild(L),i.addEventListener("wheel",z=>{let K=i,X=K.scrollTop===0&&z.deltaY<0,J=K.scrollTop+K.clientHeight>=K.scrollHeight&&z.deltaY>0;(X||J)&&z.preventDefault();},{passive:false});let v=o,D=new Set;function B(){v=true,i.style.display="block",t.style.display="none",t.setAttribute("aria-expanded","true"),y.focus();}function U(){v=false,i.style.display="none",t.style.display="block",t.setAttribute("aria-expanded","false"),t.focus();}t.addEventListener("click",B),y.addEventListener("click",U);function Z(z){z.key==="Escape"&&v&&U();}i.addEventListener("keydown",Z);function re(z){z.key==="d"&&z.shiftKey&&(z.ctrlKey||z.metaKey)&&(z.preventDefault(),v?U():B());}document.addEventListener("keydown",re);function oe(){a||(document.body.appendChild(t),document.body.appendChild(i));}document.body?oe():document.addEventListener("DOMContentLoaded",oe,{once:true});function le(){a=true,t.removeEventListener("click",B),y.removeEventListener("click",U),i.removeEventListener("keydown",Z),document.removeEventListener("keydown",re),document.removeEventListener("DOMContentLoaded",oe);for(let z of D)clearTimeout(z);D.clear(),t.remove(),i.remove(),l.remove();}return {refs:{container:i,toggleBtn:t,titleEl:d,statusEl:N,factsBody:P.tbody,factsCount:P.countSpan,derivBody:F.tbody,derivCount:F.countSpan,derivSection:F.details,inflightList:O.list,inflightSection:O.details,inflightCount:O.countSpan,unmetList:Y.list,unmetSection:Y.details,unmetCount:Y.countSpan,perfSection:$,perfBody:_,historySection:R,historyLabel:f,undoBtn:w,redoBtn:g,flowSection:H,flowSvg:x,timelineSection:E,timelineSvg:j,eventsSection:S,eventsList:A,eventsCount:W,traceHint:k,recordBtn:n,exportBtn:m,constraintsSection:M.details,constraintsBody:M.body,constraintsCount:M.countSpan},destroy:le,isOpen:()=>v,flashTimers:D}}function de(e,s,o,r,a,p){let l=fe(r),t=e.get(o);if(t){let i=t.cells;if(i[1]&&(i[1].textContent=l,a&&p)){let c=i[1];c.style.background="rgba(139, 154, 255, 0.25)";let d=setTimeout(()=>{c.style.background="",p.delete(d);},300);p.add(d);}}else {t=document.createElement("tr"),t.style.borderBottom=`1px solid ${b.rowBorder}`;let i=document.createElement("td");Object.assign(i.style,{padding:"2px 4px",color:b.muted}),i.textContent=o;let c=document.createElement("td");c.style.padding="2px 4px",c.textContent=l,t.appendChild(i),t.appendChild(c),s.appendChild(t),e.set(o,t);}}function ze(e,s){let o=e.get(s);o&&(o.remove(),e.delete(s));}function be(e,s,o){if(e.inflightList.replaceChildren(),e.inflightCount.textContent=String(s.length),s.length>0)for(let r of s){let a=document.createElement("li");a.style.fontSize="11px",a.textContent=`${r.resolverId} (${r.id})`,e.inflightList.appendChild(a);}else {let r=document.createElement("li");r.style.fontSize="10px",r.style.color=b.muted,r.textContent="None",e.inflightList.appendChild(r);}if(e.unmetList.replaceChildren(),e.unmetCount.textContent=String(o.length),o.length>0)for(let r of o){let a=document.createElement("li");a.style.fontSize="11px",a.textContent=`${r.requirement.type} from ${r.fromConstraint}`,e.unmetList.appendChild(a);}else {let r=document.createElement("li");r.style.fontSize="10px",r.style.color=b.muted,r.textContent="None",e.unmetList.appendChild(r);}}function ye(e,s,o){let r=s===0&&o===0;e.statusEl.style.color=r?b.green:b.yellow,e.statusEl.textContent=r?"Settled":"Working...",e.toggleBtn.textContent=r?"Directive":"Directive...",e.toggleBtn.setAttribute("aria-label",`Open Directive DevTools${r?"":" (system working)"}`);}function Ee(e,s,o,r){let a=Object.keys(o.derive);if(e.derivCount.textContent=String(a.length),a.length===0){s.clear(),e.derivBody.replaceChildren();let l=document.createElement("tr"),t=document.createElement("td");t.colSpan=2,t.style.color=b.muted,t.style.fontSize="10px",t.textContent="No derivations defined",l.appendChild(t),e.derivBody.appendChild(l);return}let p=new Set(a);for(let[l,t]of s)p.has(l)||(t.remove(),s.delete(l));for(let l of a){let t;try{t=fe(o.read(l));}catch{t="<error>";}de(s,e.derivBody,l,t,true,r);}}function We(e,s,o,r){let a=e.eventsList.querySelector(".dt-events-empty");a&&a.remove();let p=document.createElement("div");Object.assign(p.style,{padding:"2px 4px",borderBottom:`1px solid ${b.rowBorder}`,fontFamily:"inherit"});let l=new Date,t=`${String(l.getHours()).padStart(2,"0")}:${String(l.getMinutes()).padStart(2,"0")}:${String(l.getSeconds()).padStart(2,"0")}.${String(l.getMilliseconds()).padStart(3,"0")}`,i;try{let I=JSON.stringify(o);i=ee(I,60);}catch{i="{}";}let c=document.createElement("span");c.style.color=b.closeBtn,c.textContent=t;let d=document.createElement("span");d.style.color=b.accent,d.textContent=` ${s} `;let y=document.createElement("span");for(y.style.color=b.muted,y.textContent=i,p.appendChild(c),p.appendChild(d),p.appendChild(y),e.eventsList.prepend(p);e.eventsList.childElementCount>He;)e.eventsList.lastElementChild?.remove();e.eventsCount.textContent=String(r);}function Ue(e,s){e.perfBody.replaceChildren();let o=s.reconcileCount>0?(s.reconcileTotalMs/s.reconcileCount).toFixed(1):"\u2014",r=[`Reconciles: ${s.reconcileCount} (avg ${o}ms)`,`Effects: ${s.effectRunCount} run, ${s.effectErrorCount} errors`];for(let a of r){let p=document.createElement("div");p.style.marginBottom="2px",p.textContent=a,e.perfBody.appendChild(p);}if(s.resolverStats.size>0){let a=document.createElement("div");a.style.marginTop="4px",a.style.marginBottom="2px",a.style.color=b.accent,a.textContent="Resolvers:",e.perfBody.appendChild(a);let p=[...s.resolverStats.entries()].sort((l,t)=>t[1].totalMs-l[1].totalMs);for(let[l,t]of p){let i=t.count>0?(t.totalMs/t.count).toFixed(1):"0",c=document.createElement("div");c.style.paddingLeft="8px",c.textContent=`${l}: ${t.count}x, avg ${i}ms${t.errors>0?`, ${t.errors} err`:""}`,t.errors>0&&(c.style.color=b.red),e.perfBody.appendChild(c);}}}function Ce(e,s){let o=s.history;if(!o){e.historySection.style.display="none";return}e.historySection.style.display="flex";let r=o.currentIndex,a=o.snapshots.length;e.historyLabel.textContent=a>0?`${r+1} / ${a}`:"0 snapshots";let p=r>0,l=r<a-1;e.undoBtn.disabled=!p,e.undoBtn.style.opacity=p?"1":"0.4",e.redoBtn.disabled=!l,e.redoBtn.style.opacity=l?"1":"0.4";}function Ge(e,s){e.undoBtn.addEventListener("click",()=>{s.history&&s.history.currentIndex>0&&s.history.goBack(1);}),e.redoBtn.addEventListener("click",()=>{s.history&&s.history.currentIndex<s.history.snapshots.length-1&&s.history.goForward(1);});}var qe=Object.assign(Object.create(null),{$eq:"=",$ne:"\u2260",$gt:">",$gte:"\u2265",$lt:"<",$lte:"\u2264",$in:"\u2208",$nin:"\u2209",$exists:"exists",$between:"in",$startsWith:"starts with",$endsWith:"ends with",$contains:"contains",$matches:"matches",$changed:"changed"});function at(e){return Object.hasOwn(qe,e)?qe[e]:e}function Fe(e){return e instanceof RegExp?ee(String(e),40):fe(e)}var ct=new Set(["$all","$any","$not"]);function Ye(e){let s=document.createElement("li"),o=e.pass?"\u2713":"\u2717";if(s.style.color=e.pass?b.green:b.red,s.style.listStyle="none",ct.has(e.op)){let r=e.path?` @ ${e.path}`:"";if(s.textContent=`${o} ${e.op}${r}`,e.children&&e.children.length>0){let a=document.createElement("ul");Object.assign(a.style,{margin:"0",paddingLeft:"14px",listStyle:"none"});for(let p of e.children)a.appendChild(Ye(p));s.appendChild(a);}}else {let r=at(e.op),a=Fe(e.expected);if(e.pass)s.textContent=`${o} ${e.path} ${r} ${a}`;else {let p=Fe(e.actual);s.textContent=`${o} ${e.path} ${r} ${a} (actual: ${p})`;}}return s}function Xe(e,s,o){let r=s.get(o);if(r&&(r.remove(),s.delete(o),e.constraintsCount.textContent=String(s.size)),s.size===0&&!e.constraintsBody.querySelector(".dt-constraints-empty")){let a=document.createElement("div");a.style.color=b.muted,a.style.padding="4px",a.style.fontStyle="italic",a.textContent="Waiting for first evaluation\u2026",a.className="dt-constraints-empty",e.constraintsBody.appendChild(a);}}function Ke(e,s){let o=e.constraintsBody.querySelector(".dt-constraints-empty");o&&(o.textContent=s?"Waiting for first evaluation\u2026":"This system has no constraints");}function Je(e,s,o,r,a,p){let l=e.constraintsBody.querySelector(".dt-constraints-empty");l&&l.remove();let t=s.get(o);t||(t=document.createElement("div"),Object.assign(t.style,{marginBottom:"6px",paddingBottom:"4px",borderBottom:`1px solid ${b.rowBorder}`}),s.set(o,t),e.constraintsBody.appendChild(t),e.constraintsCount.textContent=String(s.size)),t.replaceChildren();let i=document.createElement("div");Object.assign(i.style,{fontWeight:"bold",color:r?b.green:b.muted});let c=r?"\u2713":"\u2717";if(i.textContent=p?`${c} ${o} (${p})`:`${c} ${o}`,t.appendChild(i),a&&a.length>0){let d=document.createElement("ul");Object.assign(d.style,{margin:"2px 0 0 0",paddingLeft:"14px",listStyle:"none"});for(let y of a)d.appendChild(Ye(y));t.appendChild(d);}else if(!a){let d=document.createElement("div");Object.assign(d.style,{color:b.muted,fontSize:"10px",fontStyle:"italic",paddingLeft:"14px"}),d.textContent="function-form when (no clause tree)",t.appendChild(d);}}var we=new WeakMap;function lt(e,s,o,r,a,p){return [e.join(","),s.join(","),o.map(l=>`${l.id}:${l.active}`).join(","),[...r.entries()].map(([l,t])=>`${l}:${t.status}:${t.type}`).join(","),a.join(","),p.join(",")].join("|")}function ut(e,s,o,r,a){for(let p of o){let l=e.nodes.get(`0:${p}`);if(!l)continue;let t=s.recentlyChangedFacts.has(p);l.rect.setAttribute("fill",t?b.text+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}for(let p of r){let l=e.nodes.get(`1:${p}`);if(!l)continue;let t=s.recentlyComputedDerivations.has(p);l.rect.setAttribute("fill",t?b.accent+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}for(let p of a){let l=e.nodes.get(`2:${p}`);if(!l)continue;let t=s.recentlyActiveConstraints.has(p),i=l.rect.getAttribute("stroke")??b.muted;l.rect.setAttribute("fill",t?i+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}}function Me(e,s,o){let r=se(s);if(!r)return;let a;try{a=Object.keys(s.facts.$store.toObject());}catch{a=[];}let p=Object.keys(s.derive),l=r.constraints,t=r.unmet,i=r.inflight,c=Object.keys(r.resolvers),d=new Map;for(let u of t)d.set(u.id,{type:u.requirement.type,fromConstraint:u.fromConstraint,status:"unmet"});for(let u of i)d.set(u.id,{type:u.resolverId,fromConstraint:"",status:"inflight"});if(a.length===0&&p.length===0&&l.length===0&&c.length===0){we.delete(e.flowSvg),e.flowSvg.replaceChildren(),e.flowSvg.setAttribute("viewBox","0 0 460 40");let u=document.createElementNS("http://www.w3.org/2000/svg","text");u.setAttribute("x","230"),u.setAttribute("y","24"),u.setAttribute("text-anchor","middle"),u.setAttribute("fill",b.muted),u.setAttribute("font-size","10"),u.setAttribute("font-family",b.font),u.textContent="No system topology",e.flowSvg.appendChild(u);return}let y=i.map(u=>u.resolverId).sort(),I=lt(a,p,l,d,c,y),N=we.get(e.flowSvg);if(N&&N.fingerprint===I){ut(N,o,a,p,l.map(u=>u.id));return}let R=G.nodeW+G.colGap,w=[5,5+R,5+R*2,5+R*3,5+R*4],g=w[4]+G.nodeW+5;function f(u){let M=G.startY+12;return u.map(S=>{let A={...S,y:M};return M+=G.nodeH+G.nodeGap,A})}let C=f(a.map(u=>{let M=r.facts.find(S=>S.key===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),T=f(p.map(u=>{let M=r.derivations.find(S=>S.id===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),P=f(l.map(u=>({id:u.id,label:ee(u.meta?.label??u.id,G.labelMaxChars),active:u.active,priority:u.priority}))),F=f([...d.entries()].map(([u,M])=>({id:u,type:M.type,fromConstraint:M.fromConstraint,status:M.status}))),O=f(c.map(u=>{let M=r.resolverDefs.find(S=>S.id===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),Y=Math.max(C.length,T.length,P.length,F.length,O.length,1),$=G.startY+12+Y*(G.nodeH+G.nodeGap)+8;e.flowSvg.replaceChildren(),e.flowSvg.setAttribute("viewBox",`0 0 ${g} ${$}`),e.flowSvg.setAttribute("aria-label",`Dependency graph: ${a.length} facts, ${p.length} derivations, ${l.length} constraints, ${d.size} requirements, ${c.length} resolvers`);let V=["Facts","Derivations","Constraints","Reqs","Resolvers"];for(let[u,M]of V.entries()){let S=document.createElementNS("http://www.w3.org/2000/svg","text");S.setAttribute("x",String(w[u]??0)),S.setAttribute("y","10"),S.setAttribute("fill",b.accent),S.setAttribute("font-size",String(G.fontSize)),S.setAttribute("font-family",b.font),S.textContent=M,e.flowSvg.appendChild(S);}let _={fingerprint:I,nodes:new Map};function H(u,M,S,A,W,k,L,n,m){let v=document.createElementNS("http://www.w3.org/2000/svg","g");if(m){let U=document.createElementNS("http://www.w3.org/2000/svg","title");U.textContent=m,v.appendChild(U);}let D=document.createElementNS("http://www.w3.org/2000/svg","rect");D.setAttribute("x",String(M)),D.setAttribute("y",String(S-6)),D.setAttribute("width",String(G.nodeW)),D.setAttribute("height",String(G.nodeH)),D.setAttribute("rx","3"),D.setAttribute("fill",n?k+"33":"none"),D.setAttribute("stroke",k),D.setAttribute("stroke-width",n?"2":"1"),D.setAttribute("opacity",L?"0.35":"1"),v.appendChild(D);let B=document.createElementNS("http://www.w3.org/2000/svg","text");return B.setAttribute("x",String(M+4)),B.setAttribute("y",String(S+4)),B.setAttribute("fill",k),B.setAttribute("font-size",String(G.fontSize)),B.setAttribute("font-family",b.font),B.setAttribute("opacity",L?"0.35":"1"),B.textContent=W,v.appendChild(B),e.flowSvg.appendChild(v),_.nodes.set(`${u}:${A}`,{g:v,rect:D,text:B}),{midX:M+G.nodeW/2,midY:S}}function h(u,M,S,A,W,k){let L=document.createElementNS("http://www.w3.org/2000/svg","line");L.setAttribute("x1",String(u)),L.setAttribute("y1",String(M)),L.setAttribute("x2",String(S)),L.setAttribute("y2",String(A)),L.setAttribute("stroke",W),L.setAttribute("stroke-width","1"),L.setAttribute("stroke-dasharray","3,2"),L.setAttribute("opacity","0.7"),e.flowSvg.appendChild(L);}let x=new Map,E=new Map,q=new Map,j=new Map;for(let u of C){let M=o.recentlyChangedFacts.has(u.id),S=r.facts.find(W=>W.key===u.id)?.meta,A=H(0,w[0],u.y,u.id,u.label,b.text,false,M,S?.description);x.set(u.id,A);}for(let u of T){let M=o.recentlyComputedDerivations.has(u.id),S=r.derivations.find(W=>W.id===u.id)?.meta,A=H(1,w[1],u.y,u.id,u.label,b.accent,false,M,S?.description);E.set(u.id,A);}for(let u of P){let M=o.recentlyActiveConstraints.has(u.id),S=l.find(W=>W.id===u.id)?.meta,A=H(2,w[2],u.y,u.id,u.label,S?.color??(u.active?b.yellow:b.muted),!u.active,M,S?.description);q.set(u.id,A);}for(let u of F){let M=u.status==="unmet"?b.red:b.yellow,S=H(3,w[3],u.y,u.id,ee(u.type,G.labelMaxChars),M,false,false);j.set(u.id,S);}for(let u of O){let M=i.some(A=>A.resolverId===u.id),S=r.resolverDefs.find(A=>A.id===u.id)?.meta;H(4,w[4],u.y,u.id,u.label,S?.color??(M?b.green:b.muted),!M,false,S?.description);}for(let u of T){let M=o.derivationDeps.get(u.id),S=E.get(u.id);if(M&&S)for(let A of M){let W=x.get(A);W&&h(W.midX+G.nodeW/2,W.midY,S.midX-G.nodeW/2,S.midY,b.accent);}}for(let u of F){let M=q.get(u.fromConstraint),S=j.get(u.id);M&&S&&h(M.midX+G.nodeW/2,M.midY,S.midX-G.nodeW/2,S.midY,b.muted);}for(let u of i){let M=j.get(u.id);if(M){let S=O.find(A=>A.id===u.resolverId);S&&h(M.midX+G.nodeW/2,M.midY,w[4],S.y,b.green);}}we.set(e.flowSvg,_);}function Qe(e){e.animationTimer&&clearTimeout(e.animationTimer),e.animationTimer=setTimeout(()=>{e.recentlyChangedFacts.clear(),e.recentlyComputedDerivations.clear(),e.recentlyActiveConstraints.clear(),e.animationTimer=null;},600);}function Ze(e,s){let o=s.entries.toArray();if(o.length===0)return;e.timelineSvg.replaceChildren();let r=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY;for(let R of o)R.startMs<r&&(r=R.startMs),R.endMs>a&&(a=R.endMs);let p=performance.now();for(let R of s.inflight.values())R<r&&(r=R),p>a&&(a=p);let l=a-r||1,t=ie-ce-10,i=[],c=new Set;for(let R of o)c.has(R.resolver)||(c.add(R.resolver),i.push(R.resolver));for(let R of s.inflight.keys())c.has(R)||(c.add(R),i.push(R));let y=i.slice(-12),I=ae*y.length+20;e.timelineSvg.setAttribute("viewBox",`0 0 ${ie} ${I}`),e.timelineSvg.setAttribute("height",String(Math.min(I,200)));let N=5;for(let R=0;R<=N;R++){let w=ce+t*R/N,g=l*R/N,f=document.createElementNS("http://www.w3.org/2000/svg","text");f.setAttribute("x",String(w)),f.setAttribute("y","8"),f.setAttribute("fill",b.muted),f.setAttribute("font-size","6"),f.setAttribute("font-family",b.font),f.setAttribute("text-anchor","middle"),f.textContent=g<1e3?`${g.toFixed(0)}ms`:`${(g/1e3).toFixed(1)}s`,e.timelineSvg.appendChild(f);let C=document.createElementNS("http://www.w3.org/2000/svg","line");C.setAttribute("x1",String(w)),C.setAttribute("y1","10"),C.setAttribute("x2",String(w)),C.setAttribute("y2",String(I)),C.setAttribute("stroke",b.border),C.setAttribute("stroke-width","0.5"),e.timelineSvg.appendChild(C);}for(let R=0;R<y.length;R++){let w=y[R],g=12+R*ae,f=R%Se.length,C=Se[f],T=document.createElementNS("http://www.w3.org/2000/svg","text");T.setAttribute("x",String(ce-4)),T.setAttribute("y",String(g+ae/2+3)),T.setAttribute("fill",b.muted),T.setAttribute("font-size","7"),T.setAttribute("font-family",b.font),T.setAttribute("text-anchor","end"),T.textContent=ee(w,12),e.timelineSvg.appendChild(T);let P=o.filter(O=>O.resolver===w);for(let O of P){let Y=ce+(O.startMs-r)/l*t,$=Math.max((O.endMs-O.startMs)/l*t,he),V=document.createElementNS("http://www.w3.org/2000/svg","rect");V.setAttribute("x",String(Y)),V.setAttribute("y",String(g+2)),V.setAttribute("width",String($)),V.setAttribute("height",String(ae-4)),V.setAttribute("rx","2"),V.setAttribute("fill",O.error?b.red:C),V.setAttribute("opacity","0.8");let _=document.createElementNS("http://www.w3.org/2000/svg","title"),H=O.endMs-O.startMs;_.textContent=`${w}: ${H.toFixed(1)}ms${O.error?" (error)":""}`,V.appendChild(_),e.timelineSvg.appendChild(V);}let F=s.inflight.get(w);if(F!==void 0){let O=ce+(F-r)/l*t,Y=Math.max((p-F)/l*t,he),$=document.createElementNS("http://www.w3.org/2000/svg","rect");$.setAttribute("x",String(O)),$.setAttribute("y",String(g+2)),$.setAttribute("width",String(Y)),$.setAttribute("height",String(ae-4)),$.setAttribute("rx","2"),$.setAttribute("fill",C),$.setAttribute("opacity","0.4"),$.setAttribute("stroke",C),$.setAttribute("stroke-width","1"),$.setAttribute("stroke-dasharray","3,2");let V=document.createElementNS("http://www.w3.org/2000/svg","title");V.textContent=`${w}: inflight ${(p-F).toFixed(0)}ms`,$.appendChild(V),e.timelineSvg.appendChild($);}}e.timelineSvg.setAttribute("aria-label",`Timeline: ${o.length} resolver executions across ${y.length} resolvers`);}function dt(){if(typeof window>"u")return {systems:new Map,getSystem:()=>null,getSystems:()=>[],inspect:()=>null,getEvents:()=>[],explain:()=>null,exportSession:()=>null,importSession:()=>false,clearEvents:()=>{},subscribe:()=>()=>{}};if(!window.__DIRECTIVE__){let e=new Map,s={systems:e,getSystem(o){return o?e.get(o)?.system??null:e.values().next().value?.system??null},getSystems(){return [...e.keys()]},inspect(o){let r=this.getSystem(o),a=o?e.get(o):e.values().next().value,p=r?.inspect()??null;return p&&a&&(p.resolverStats=a.resolverStats?Object.fromEntries(a.resolverStats):{}),p},getEvents(o){return o?e.get(o)?.events.toArray()??[]:e.values().next().value?.events.toArray()??[]},explain(o,r){return this.getSystem(r)?.explain(o)??null},subscribe(o,r){let a=r?e.get(r):e.values().next().value;if(!a){let p=false,t=setInterval(()=>{let c=r?e.get(r):e.values().next().value;c&&!p&&(p=true,c.subscribers.add(o));},100),i=setTimeout(()=>clearInterval(t),1e4);return ()=>{clearInterval(t),clearTimeout(i);for(let c of e.values())c.subscribers.delete(o);}}return a.subscribers.add(o),()=>{a.subscribers.delete(o);}},exportSession(o){let r=o?e.get(o):e.values().next().value;return r?JSON.stringify({version:1,name:o??e.keys().next().value??"default",exportedAt:Date.now(),events:r.events.toArray()}):null},importSession(o,r){try{if(o.length>10*1024*1024)return !1;let a=JSON.parse(o);if(!a||typeof a!="object"||Array.isArray(a)||!Array.isArray(a.events))return !1;let p=r?e.get(r):e.values().next().value;if(!p)return !1;let l=p.maxEvents,t=a.events,i=t.length>l?t.length-l:0;p.events.clear();for(let c=i;c<t.length;c++){let d=t[c];d&&typeof d=="object"&&!Array.isArray(d)&&typeof d.timestamp=="number"&&typeof d.type=="string"&&d.type!=="__proto__"&&d.type!=="constructor"&&d.type!=="prototype"&&p.events.push({timestamp:d.timestamp,type:d.type,data:d.data??null});}return !0}catch{return false}},clearEvents(o){let r=o?e.get(o):e.values().next().value;r&&r.events.clear();}};return Object.defineProperty(window,"__DIRECTIVE__",{value:s,writable:false,configurable:ge(),enumerable:true}),s}return window.__DIRECTIVE__}function mt(e={}){let{name:s="default",trace:o=false,maxEvents:r,panel:a=false,position:p="bottom-right",defaultOpen:l=false}=e,t=Pe(r),i=dt(),c={system:null,events:new ue(t),maxEvents:t,subscribers:new Set,resolverStats:new Map};i.systems.set(s,c);let d=(n,m)=>{let v={timestamp:Date.now(),type:n,data:m};o&&c.events.push(v);for(let D of c.subscribers)try{D(v);}catch{}},y=null,I=new Map,N=new Map,R=new Map,w=Ie(),g=_e(),f=je(),C=$e(),T=a&&typeof window<"u"&&typeof document<"u"&&ge(),P=null,F=0,O=1,Y=2,$=4,V=8,_=16,H=32,h=64,x=128,E=256,q=new Map,j=new Set,u=new Map,M=new Set,S=null;function A(n){F|=n,P===null&&typeof requestAnimationFrame<"u"&&(P=requestAnimationFrame(W));}function W(){if(P=null,!y||!c.system){F=0;return}let n=y.refs,m=c.system,v=F;if(F=0,v&O){for(let D of j)ze(I,D);j.clear();for(let[D,{value:B,flash:U}]of q)de(I,n.factsBody,D,B,U,y.flashTimers);q.clear(),n.factsCount.textContent=String(I.size);}if(v&Y&&Ee(n,N,m,y.flashTimers),v&E){for(let D of M)Xe(n,R,D);M.clear();for(let[D,{active:B,whenExplain:U,label:Z}]of u)Je(n,R,D,B,U,Z);u.clear();}if(v&V)if(S)ye(n,S.inflight.length,S.unmet.length);else {let D=se(m);D&&ye(n,D.inflight.length,D.unmet.length);}if(v&$)if(S)be(n,S.inflight,S.unmet);else {let D=se(m);D&&be(n,D.inflight,D.unmet);}v&_&&Ue(n,w),v&H&&Me(n,m,g),v&h&&Ce(n,m),v&x&&Ze(n,C);}function k(n,m){y&&o&&We(y.refs,n,m,c.events.size);}function L(n,m){f.isRecording&&f.recordedEvents.length<Ne&&f.recordedEvents.push({timestamp:Date.now(),type:n,data:Le(m)});}return {name:"devtools",onInit:n=>{if(c.system=n,d("init",{}),typeof window<"u"&&console.log(`%c[Directive Devtools]%c System "${s}" initialized. Access via window.__DIRECTIVE__`,"color: #7c3aed; font-weight: bold","color: inherit"),T){let m=c.system;y=Ve(s,p,l,o);let v=y.refs;try{let U=m.facts.$store.toObject();for(let[Z,re]of Object.entries(U))de(I,v.factsBody,Z,re,!1);v.factsCount.textContent=String(Object.keys(U).length);}catch{}Ee(v,N,m);let D=se(m);D&&(ye(v,D.inflight.length,D.unmet.length),be(v,D.inflight,D.unmet)),Ce(v,m),Ge(v,m),Me(v,m,g);let B=(D?.constraints?.length??0)>0;Ke(v,B),v.recordBtn.addEventListener("click",()=>{if(f.isRecording=!f.isRecording,v.recordBtn.textContent=f.isRecording?"\u23F9 Stop":"\u23FA Record",v.recordBtn.style.color=f.isRecording?b.red:b.text,f.isRecording){f.recordedEvents=[],f.snapshots=[];try{f.snapshots.push({timestamp:Date.now(),facts:m.facts.$store.toObject()});}catch{}}}),v.exportBtn.addEventListener("click",()=>{let U=f.recordedEvents.length>0?f.recordedEvents:c.events.toArray(),Z=JSON.stringify({version:1,name:s,exportedAt:Date.now(),events:U,snapshots:f.snapshots},null,2),re=new Blob([Z],{type:"application/json"}),oe=URL.createObjectURL(re),le=document.createElement("a");le.href=oe,le.download=`directive-session-${s}-${Date.now()}.json`,le.click(),URL.revokeObjectURL(oe);});}},onStart:n=>{d("start",{}),k("start",{}),L("start",{});},onStop:n=>{d("stop",{}),k("stop",{}),L("stop",{});},onDestroy:n=>{d("destroy",{}),i.systems.delete(s),P!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(P),P=null),g.animationTimer&&clearTimeout(g.animationTimer),y&&(y.destroy(),y=null,I.clear(),N.clear(),R.clear());},onFactSet:(n,m,v)=>{d("fact.set",{key:n,value:m,prev:v}),L("fact.set",{key:n,value:m,prev:v}),g.recentlyChangedFacts.add(n),y&&c.system&&(q.set(n,{value:m,flash:true}),j.delete(n),A(O),k("fact.set",{key:n,value:m}));},onFactDelete:(n,m)=>{d("fact.delete",{key:n,prev:m}),L("fact.delete",{key:n,prev:m}),y&&(j.add(n),q.delete(n),A(O),k("fact.delete",{key:n}));},onFactsBatch:n=>{if(d("facts.batch",{changes:n}),L("facts.batch",{count:n.length}),y&&c.system){for(let m of n)m.type==="delete"?(j.add(m.key),q.delete(m.key)):(g.recentlyChangedFacts.add(m.key),q.set(m.key,{value:m.value,flash:true}),j.delete(m.key));A(O),k("facts.batch",{count:n.length});}},onDerivationCompute:(n,m,v)=>{d("derivation.compute",{id:n,value:m,deps:v}),L("derivation.compute",{id:n,deps:v}),g.derivationDeps.set(n,v),g.recentlyComputedDerivations.add(n),k("derivation.compute",{id:n,deps:v});},onDerivationInvalidate:n=>{d("derivation.invalidate",{id:n}),k("derivation.invalidate",{id:n});},onReconcileStart:n=>{d("reconcile.start",{}),w.lastReconcileStartMs=performance.now(),k("reconcile.start",{}),L("reconcile.start",{});},onReconcileEnd:n=>{if(d("reconcile.end",n),L("reconcile.end",{unmet:n.unmet.length,inflight:n.inflight.length,completed:n.completed.length}),w.lastReconcileStartMs>0){let m=performance.now()-w.lastReconcileStartMs;w.reconcileCount++,w.reconcileTotalMs+=m,w.lastReconcileStartMs=0;}if(f.isRecording&&c.system&&f.snapshots.length<Be)try{f.snapshots.push({timestamp:Date.now(),facts:c.system.facts.$store.toObject()});}catch{}y&&c.system&&(S=n,Qe(g),A(Y|V|$|_|H|h),k("reconcile.end",{unmet:n.unmet.length,inflight:n.inflight.length}));},onConstraintEvaluate:(n,m,v)=>{let D=c.system?.meta?.constraint(n)?.label,B=D?{id:n,active:m,label:D}:{id:n,active:m},U=v?{...B,whenExplain:v}:B;d("constraint.evaluate",U),L("constraint.evaluate",U),m?(g.activeConstraints.add(n),g.recentlyActiveConstraints.add(n)):g.activeConstraints.delete(n),y&&(u.set(n,{active:m,whenExplain:v,label:D}),M.delete(n),A(E)),k("constraint.evaluate",{id:n,active:m});},onConstraintError:(n,m)=>{d("constraint.error",{id:n,error:String(m)}),k("constraint.error",{id:n,error:String(m)});},onRequirementCreated:n=>{d("requirement.created",{id:n.id,type:n.requirement.type}),L("requirement.created",{id:n.id,type:n.requirement.type}),k("requirement.created",{id:n.id,type:n.requirement.type});},onRequirementMet:(n,m)=>{d("requirement.met",{id:n.id,byResolver:m}),L("requirement.met",{id:n.id,byResolver:m}),k("requirement.met",{id:n.id,byResolver:m});},onRequirementCanceled:n=>{d("requirement.canceled",{id:n.id}),L("requirement.canceled",{id:n.id}),k("requirement.canceled",{id:n.id});},onResolverStart:(n,m)=>{let v=c.system?.meta?.resolver(n)?.label,D={resolver:n,requirementId:m.id},B=v?{...D,label:v}:D;d("resolver.start",B),L("resolver.start",B),C.inflight.set(n,performance.now()),y&&c.system&&(A($|V|x),k("resolver.start",{resolver:n,requirementId:m.id}));},onResolverComplete:(n,m,v)=>{let D=c.system?.meta?.resolver(n)?.label;d("resolver.complete",{resolver:n,requirementId:m.id,duration:v,...D?{label:D}:{}}),L("resolver.complete",{resolver:n,requirementId:m.id,duration:v});let B=c.resolverStats.get(n)??{count:0,totalMs:0,errors:0};if(B.count++,B.totalMs+=v,c.resolverStats.set(n,B),c.resolverStats.size>xe){let Z=c.resolverStats.keys().next().value;Z!==void 0&&c.resolverStats.delete(Z);}w.resolverStats.set(n,{...B});let U=C.inflight.get(n);C.inflight.delete(n),U!==void 0&&C.entries.push({resolver:n,startMs:U,endMs:performance.now(),error:false}),y&&c.system&&(A($|V|_|x),k("resolver.complete",{resolver:n,duration:v}));},onResolverError:(n,m,v)=>{d("resolver.error",{resolver:n,requirementId:m.id,error:String(v)}),L("resolver.error",{resolver:n,requirementId:m.id,error:String(v)});let D=c.resolverStats.get(n)??{count:0,totalMs:0,errors:0};if(D.errors++,c.resolverStats.set(n,D),c.resolverStats.size>xe){let U=c.resolverStats.keys().next().value;U!==void 0&&c.resolverStats.delete(U);}w.resolverStats.set(n,{...D});let B=C.inflight.get(n);C.inflight.delete(n),B!==void 0&&C.entries.push({resolver:n,startMs:B,endMs:performance.now(),error:true}),y&&c.system&&(A($|V|_|x),k("resolver.error",{resolver:n,error:String(v)}));},onResolverRetry:(n,m,v)=>{d("resolver.retry",{resolver:n,requirementId:m.id,attempt:v}),L("resolver.retry",{resolver:n,requirementId:m.id,attempt:v}),k("resolver.retry",{resolver:n,attempt:v});},onResolverCancel:(n,m)=>{d("resolver.cancel",{resolver:n,requirementId:m.id}),L("resolver.cancel",{resolver:n,requirementId:m.id}),C.inflight.delete(n),k("resolver.cancel",{resolver:n});},onResolverWriteRejected:n=>{let m=n.kind==="summary"?{kind:n.kind,resolver:n.resolver,requirementId:n.req.id,reason:n.reason,dropped:n.dropped}:{kind:n.kind,resolver:n.resolver,requirementId:n.req.id,reason:n.reason,fact:n.fact,expected:n.expected,actual:n.actual};d("resolver.write.rejected",m),L("resolver.write.rejected",m),k("resolver.write.rejected",n.kind==="summary"?{resolver:n.resolver,dropped:n.dropped}:{resolver:n.resolver,fact:n.fact});},onEffectRun:n=>{let m=c.system?.meta?.effect(n)?.label,v=m?{id:n,label:m}:{id:n};d("effect.run",v),L("effect.run",v),w.effectRunCount++,k("effect.run",{id:n});},onEffectError:(n,m)=>{d("effect.error",{id:n,error:String(m)}),w.effectErrorCount++,k("effect.error",{id:n,error:String(m)});},onSnapshot:n=>{d("timetravel.snapshot",{id:n.id,trigger:n.trigger}),y&&c.system&&A(h),k("timetravel.snapshot",{id:n.id,trigger:n.trigger});},onHistoryNavigate:(n,m)=>{if(d("timetravel.jump",{from:n,to:m}),L("timetravel.jump",{from:n,to:m}),y&&c.system){let v=c.system;try{let D=v.facts.$store.toObject();I.clear(),y.refs.factsBody.replaceChildren();for(let[B,U]of Object.entries(D))de(I,y.refs.factsBody,B,U,!1);y.refs.factsCount.textContent=String(Object.keys(D).length);}catch{}N.clear(),g.derivationDeps.clear(),y.refs.derivBody.replaceChildren(),R.clear(),y.refs.constraintsBody.replaceChildren(),y.refs.constraintsCount.textContent="0",S=null,A(Y|V|$|H|h),k("timetravel.jump",{from:n,to:m});}},onError:n=>{d("error",{source:n.source,sourceId:n.sourceId,message:n.message}),L("error",{source:n.source,message:n.message}),k("error",{source:n.source,message:n.message});},onErrorRecovery:(n,m)=>{d("error.recovery",{source:n.source,sourceId:n.sourceId,strategy:m}),k("error.recovery",{source:n.source,strategy:m});},onTraceComplete:n=>{d("trace.complete",{id:n.id,status:n.status,facts:n.factChanges.length,constraints:n.constraintsHit.length,requirements:n.requirementsAdded.length,resolvers:n.resolversStarted.length,effects:n.effectsRun.length}),k("trace.complete",{id:n.id});},onDefinitionRegister:(n,m)=>{d("definition.register",{type:n,id:m}),L("definition.register",{type:n,id:m}),k("definition.register",{type:n,id:m});},onDefinitionAssign:(n,m)=>{d("definition.assign",{type:n,id:m}),L("definition.assign",{type:n,id:m}),k("definition.assign",{type:n,id:m});},onDefinitionUnregister:(n,m)=>{d("definition.unregister",{type:n,id:m}),L("definition.unregister",{type:n,id:m}),k("definition.unregister",{type:n,id:m}),n==="constraint"&&y&&(M.add(m),u.delete(m),A(E));},onDefinitionCall:(n,m,v)=>{d("definition.call",{type:n,id:m,props:v}),L("definition.call",{type:n,id:m,props:v}),k("definition.call",{type:n,id:m,props:v});}}}var tt="directive-devtools-event",et=new Set(["__proto__","constructor","prototype"]),pt=Math.random().toString(36).slice(2,8);function gt(){if(typeof window<"u"){let e=`__DIRECTIVE_BRIDGE_ID_${pt}__`,s=window,o=s[e]??0;return s[e]=o+1,o+1}return 1}function ft(e){let s=false;for(let r of et)if(r in e){s=true;break}if(!s)return e;let o=Object.create(null);for(let[r,a]of Object.entries(e))et.has(r)||(o[r]=a);return o}function bt(e){if(!(typeof window>"u"))try{let s=ft(e),o={id:gt(),timestamp:Date.now(),snapshotId:null,...s};window.dispatchEvent(new CustomEvent(tt,{detail:o}));}catch{}}function yt(e){let{storage:s,key:o,include:r,exclude:a=[],debounce:p=100,onRestore:l,onSave:t,onError:i}=e,c=null,d=null,y=new Set,I=g=>a.includes(g)?false:r?r.includes(g):true,N=()=>{try{let g=s.getItem(o);if(!g)return null;let f=JSON.parse(g);return typeof f!="object"||f===null?null:chunk4MNQDXH7_cjs.f(f)?f:(i?.(new Error("Potential prototype pollution detected in stored data")),null)}catch(g){return i?.(g instanceof Error?g:new Error(String(g))),null}},R=()=>{if(d)try{let g={};for(let f of y)I(f)&&(g[f]=d.facts[f]);s.setItem(o,JSON.stringify(g)),t?.(g);}catch(g){i?.(g instanceof Error?g:new Error(String(g)));}},w=()=>{c&&clearTimeout(c),c=setTimeout(R,p);};return {name:"persistence",onInit:g=>{d=g;let f=N();f&&(d.facts.$store.batch(()=>{for(let[C,T]of Object.entries(f))I(C)&&(d.facts[C]=T,y.add(C));}),l?.(f));},onDestroy:()=>{c&&clearTimeout(c),R();},onFactSet:g=>{y.add(g),I(g)&&w();},onFactDelete:g=>{y.delete(g),I(g)&&w();},onFactsBatch:g=>{let f=false;for(let C of g)C.type==="set"?y.add(C.key):y.delete(C.key),I(C.key)&&(f=true);f&&w();}}}function vt(e={}){let{onSlowConstraint:s,onSlowResolver:o,slowConstraintThresholdMs:r=16,slowResolverThresholdMs:a=1e3}=e,p=new Map,l=new Map,t=new Map,i={runs:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0},c=0,d=0,y=0;function I(g){let f=p.get(g);return f||(f={evaluations:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0,lastEvaluatedAt:0},p.set(g,f)),f}function N(g){let f=l.get(g);return f||(f={starts:0,completions:0,errors:0,retries:0,cancellations:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0,lastCompletedAt:0},l.set(g,f)),f}function R(g){let f=t.get(g);return f||(f={runs:0,errors:0,lastRunAt:0},t.set(g,f)),f}let w={name:"performance",onStart(){c=Date.now();},onConstraintEvaluate(g,f){let C=performance.now(),T=I(g);if(T.evaluations++,T.lastEvaluatedAt=Date.now(),y>0){let P=C-y;T.totalDurationMs+=P;let F=T.evaluations;T.avgDurationMs=T.totalDurationMs/F,P>T.maxDurationMs&&(T.maxDurationMs=P),P>r&&s?.(g,P);}y=C;},onResolverStart(g,f){let C=N(g);C.starts++;},onResolverComplete(g,f,C){let T=N(g);T.completions++,T.totalDurationMs+=C,T.avgDurationMs=T.totalDurationMs/T.completions,C>T.maxDurationMs&&(T.maxDurationMs=C),T.lastCompletedAt=Date.now(),C>a&&o?.(g,C);},onResolverError(g,f,C){N(g).errors++;},onResolverRetry(g,f,C){N(g).retries++;},onResolverCancel(g,f){N(g).cancellations++;},onEffectRun(g){let f=R(g);f.runs++,f.lastRunAt=Date.now();},onEffectError(g,f){R(g).errors++;},onReconcileStart(){d=performance.now(),y=0;},onReconcileEnd(){let g=performance.now()-d;i.runs++,i.totalDurationMs+=g,i.avgDurationMs=i.totalDurationMs/i.runs,g>i.maxDurationMs&&(i.maxDurationMs=g);},onDestroy(){w.reset();},getSnapshot(){let g={};for(let[T,P]of p)g[T]={...P};let f={};for(let[T,P]of l)f[T]={...P};let C={};for(let[T,P]of t)C[T]={...P};return {constraints:g,resolvers:f,effects:C,reconcile:{...i},uptime:c?Date.now()-c:0}},reset(){p.clear(),l.clear(),t.clear(),i.runs=0,i.totalDurationMs=0,i.avgDurationMs=0,i.maxDurationMs=0,y=0;}};return w}function ve(){return globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function Te(e,s){if(e.length===0)return 0;let o=[...e].sort((a,p)=>a-p),r=Math.ceil(s/100*o.length)-1;return o[Math.max(0,r)]??0}function ht(e={}){let{serviceName:s="directive-agents",metrics:o={},tracing:r={},alerts:a=[],summaryMetrics:p={},events:l={}}=e,t={requests:p.requests??"agent.requests",errors:p.errors??"agent.errors",latency:p.latency??"agent.latency",tokens:p.tokens??"agent.tokens",cost:p.cost??"agent.cost"},{enabled:i=true,exportInterval:c,exporter:d,maxDataPoints:y=1e3}=o,{enabled:I=true,sampleRate:N=1,maxSpans:R=1e3,exporter:w}=r,g=Date.now(),f=new Map,C=new Map,T=[],P=[],F=new Map,O=new Map,Y;c&&(d||w)&&(Y=setInterval(async()=>{try{if(d&&i&&await d(Array.from(O.values())),w&&I){let h=T.splice(0,100);h.length>0&&await w(h);}}catch(h){console.error("[Directive Observability] Export error:",h);}},c));function $(h){if(!i)return;let x=`${h.name}:${JSON.stringify(Object.fromEntries(Object.entries(h.labels).sort()))}`,E=f.get(x);E||(E=[],f.set(x,E)),E.push(h),E.length>y&&E.shift(),V(h.name,E),l.onMetricRecorded?.(h),_(h.name);}function V(h,x){if(x.length===0)return;let E=x.map(S=>S.value),q=E.reduce((S,A)=>S+A,0),j=x[0],u=E[E.length-1],M={name:h,type:j.type,count:x.length,sum:q,min:Math.min(...E),max:Math.max(...E),avg:q/x.length,lastValue:u,lastUpdated:Date.now()};O.set(h,M);}function _(h){for(let x of a){if(x.metric!==h)continue;let E=O.get(h);if(!E)continue;let q=`${x.metric}:${x.threshold}`,j=F.get(q),u=x.cooldownMs??6e4;if(j&&Date.now()-j<u)continue;let M=x.operator??">",S=E.lastValue,A=x.threshold,W=false;switch(M){case ">":W=S>A;break;case "<":W=S<A;break;case ">=":W=S>=A;break;case "<=":W=S<=A;break;case "==":W=S===A;break}if(W){let k={alertId:ve(),metric:h,currentValue:S,threshold:A,operator:M,action:x.action,timestamp:Date.now(),message:`Alert: ${h} ${M} ${A} (current: ${S})`};switch(P.push(k),P.length>1e3&&P.splice(0,P.length-1e3),F.set(q,Date.now()),l.onAlert?.(k),x.action){case "log":console.log(`[Observability] ${k.message}`);break;case "warn":console.warn(`[Observability] ${k.message}`);break;case "alert":console.error(`[Observability ALERT] ${k.message}`);break;case "callback":x.callback?.(E,A);break}}}}function H(h){let x=[];for(let[E,q]of f)if(E.startsWith(`${h}:`))for(let j of q)x.push(j.value);return x.length===0?{}:{p50:Te(x,50),p90:Te(x,90),p99:Te(x,99)}}return {incrementCounter(h,x={},E=1){$({name:h,type:"counter",value:E,labels:x,timestamp:Date.now()});},setGauge(h,x,E={}){$({name:h,type:"gauge",value:x,labels:E,timestamp:Date.now()});},observeHistogram(h,x,E={}){$({name:h,type:"histogram",value:x,labels:E,timestamp:Date.now()});},startSpan(h,x){if(Math.random()>N)return {traceId:"sampled-out",spanId:"sampled-out",operationName:h,serviceName:s,startTime:Date.now(),status:"ok",tags:{},logs:[]};let E={traceId:x?C.get(x)?.traceId??ve():ve(),spanId:ve(),parentSpanId:x,operationName:h,serviceName:s,startTime:Date.now(),status:"ok",tags:{},logs:[]};return I&&(C.set(E.spanId,E),l.onSpanStart?.(E)),E},endSpan(h,x="ok"){if(h==="sampled-out")return;let E=C.get(h);if(E){for(E.endTime=Date.now(),E.duration=E.endTime-E.startTime,E.status=x,C.delete(h),T.push(E);T.length>R;)T.shift();$({name:`${E.operationName}.latency`,type:"histogram",value:E.duration,labels:{},timestamp:Date.now()}),x==="error"&&$({name:`${E.operationName}.errors`,type:"counter",value:1,labels:{},timestamp:Date.now()}),l.onSpanEnd?.(E);}},addSpanLog(h,x,E="info"){if(h==="sampled-out")return;let q=C.get(h);q&&q.logs.push({timestamp:Date.now(),message:x,level:E});},addSpanTag(h,x,E){if(h==="sampled-out")return;let q=C.get(h);q&&(q.tags[x]=E);},getDashboard(){let h=O.get(t.requests),x=O.get(t.errors),E=O.get(t.latency),q=O.get(t.tokens),j=O.get(t.cost),u=h?.sum??0,M=x?.sum??0,S=u>0?M/u:0,A=E?H(t.latency):{};return {service:{name:s,uptime:Date.now()-g,startTime:g},metrics:Object.fromEntries(O),traces:[...T].slice(-100),alerts:[...P].slice(-50),summary:{totalRequests:u,totalErrors:M,errorRate:S,avgLatency:E?.avg??0,p99Latency:A.p99??0,activeSpans:C.size,totalTokens:q?.sum??0,totalCost:j?.sum??0}}},getMetric(h){let x=O.get(h);if(!x)return;let E=H(h);return {...x,...E}},getTraces(h=100){return [...T].slice(-h)},getAlerts(){return [...P]},export(){return {metrics:Array.from(O.values()),traces:[...T],alerts:[...P]}},clear(){f.clear(),O.clear(),C.clear(),T.length=0,P.length=0,F.clear();},async destroy(){Y&&(clearInterval(Y),Y=void 0);try{d&&i&&O.size>0&&await d(Array.from(O.values())),w&&I&&T.length>0&&await w([...T]);}catch(h){console.error("[Directive Observability] Error flushing data during destroy:",h);}f.clear(),O.clear(),C.clear(),T.length=0,P.length=0,F.clear();},getHealthStatus(){let h=O.get(t.requests),x=O.get(t.errors),E=h?.sum??0,q=x?.sum??0,j=E>0?q/E:0,u=P.filter(M=>Date.now()-M.timestamp<3e5).length;return {healthy:j<.1&&u===0,uptime:Date.now()-g,errorRate:j,activeAlerts:u}}}}function St(e){return {trackRun(s,o){let r={agent:s};e.incrementCounter("agent.requests",r),o.success||e.incrementCounter("agent.errors",r),e.observeHistogram("agent.latency",o.latencyMs,r),o.inputTokens!==void 0&&(e.incrementCounter("agent.tokens.input",r,o.inputTokens),e.incrementCounter("agent.tokens",r,o.inputTokens)),o.outputTokens!==void 0&&(e.incrementCounter("agent.tokens.output",r,o.outputTokens),e.incrementCounter("agent.tokens",r,o.outputTokens)),o.cost!==void 0&&e.incrementCounter("agent.cost",r,o.cost),o.toolCalls!==void 0&&e.incrementCounter("agent.tool_calls",r,o.toolCalls);},trackGuardrail(s,o){let r={guardrail:s};e.incrementCounter("guardrail.checks",r),o.passed||e.incrementCounter("guardrail.failures",r),o.blocked&&e.incrementCounter("guardrail.blocks",r),e.observeHistogram("guardrail.latency",o.latencyMs,r);},trackApproval(s,o){let r={tool:s};e.incrementCounter("approval.requests",r),o.approved?e.incrementCounter("approval.approved",r):e.incrementCounter("approval.rejected",r),o.timedOut&&e.incrementCounter("approval.timeouts",r),e.observeHistogram("approval.wait_time",o.waitTimeMs,r);},trackHandoff(s,o,r){e.incrementCounter("handoff.count",{from:s,to:o}),e.observeHistogram("handoff.latency",r);}}}function xt(e){let s=[{key:"service.name",value:{stringValue:e.serviceName??"directive-agents"}}];if(e.serviceVersion&&s.push({key:"service.version",value:{stringValue:e.serviceVersion}}),e.resourceAttributes)for(let[o,r]of Object.entries(e.resourceAttributes))s.push({key:o,value:{stringValue:r}});return {attributes:s}}function ne(e){return `${BigInt(e)*BigInt(1e6)}`}function Et(e){switch(e){case "counter":return "sum";case "gauge":return "gauge";case "histogram":return "histogram";default:return "gauge"}}function Ct(e,s,o){let r=e.map(a=>{let p=a.lastUpdated-6e4,l=[{asInt:a.type==="counter"?a.sum:void 0,asDouble:a.type!=="counter"?a.lastValue:void 0,timeUnixNano:ne(a.lastUpdated),startTimeUnixNano:ne(p),attributes:[]}],t=Et(a.type),i={name:a.name,unit:""};return t==="sum"?i.sum={dataPoints:l,aggregationTemporality:2,isMonotonic:true}:t==="histogram"?i.histogram={dataPoints:[{count:a.count,sum:a.sum,min:a.min,max:a.max,timeUnixNano:ne(a.lastUpdated),startTimeUnixNano:ne(p),attributes:[]}],aggregationTemporality:2}:i.gauge={dataPoints:l},i});return {resourceMetrics:[{resource:s,scopeMetrics:[{scope:{name:"directive",version:o},metrics:r}]}]}}function wt(e,s,o){let r=e.map(a=>{let p=a.logs.map(i=>({timeUnixNano:ne(i.timestamp),name:i.level,attributes:[{key:"message",value:{stringValue:i.message}},{key:"level",value:{stringValue:i.level}}]})),l=Object.entries(a.tags).map(([i,c])=>({key:i,value:typeof c=="string"?{stringValue:c}:typeof c=="number"?{intValue:`${c}`}:{boolValue:c}})),t=a.status==="ok"?1:a.status==="error"?2:0;return {traceId:a.traceId.replace(/-/g,"").padEnd(32,"0").slice(0,32),spanId:a.spanId.replace(/-/g,"").padEnd(16,"0").slice(0,16),parentSpanId:a.parentSpanId?a.parentSpanId.replace(/-/g,"").padEnd(16,"0").slice(0,16):void 0,name:a.operationName,kind:1,startTimeUnixNano:ne(a.startTime),endTimeUnixNano:a.endTime?ne(a.endTime):ne(a.startTime),attributes:l,events:p,status:{code:t}}});return {resourceSpans:[{resource:s,scopeSpans:[{scope:{name:"directive",version:o},spans:r}]}]}}function Mt(e){let{endpoint:s,headers:o={},scopeVersion:r="0.1.0",timeoutMs:a=1e4,fetch:p=globalThis.fetch,onError:l}=e;try{let c=new URL(s);if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error("[Directive] Only http: and https: protocols are supported")}catch(c){throw new Error(`[Directive OTLP] Invalid endpoint URL "${s}": ${c instanceof Error?c.message:String(c)}`)}if(/\/v1\/(metrics|traces)/.test(s)&&console.warn(`[Directive OTLP] Endpoint "${s}" already contains a /v1/metrics or /v1/traces path. The exporter will append /v1/metrics or /v1/traces automatically. Use the base URL (e.g., "http://localhost:4318") instead.`),a<=0||!Number.isFinite(a))throw new Error(`[Directive OTLP] timeoutMs must be > 0, got ${a}`);let t=xt(e);async function i(c,d,y){let I=`${s.replace(/\/$/,"")}${c}`,N=new AbortController,R=setTimeout(()=>N.abort(),a);try{let w=await p(I,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify(d),signal:N.signal});if(!w.ok)throw new Error(`[Directive] OTLP export failed: ${w.status} ${w.statusText}`)}catch(w){let g=w instanceof Error?w:new Error(String(w));l?l(g,y):console.error(`[Directive OTLP] Export ${y} error:`,g.message);}finally{clearTimeout(R);}}return {async exportMetrics(c){if(c.length===0)return;let d=Ct(c,t,r);await i("/v1/metrics",d,"metrics");},async exportTraces(c){if(c.length===0)return;let d=wt(c,t,r);await i("/v1/traces",d,"traces");}}}var me=class extends Error{code="CIRCUIT_OPEN";retryAfterMs;state;constructor(s,o,r="OPEN",a){let p=a?`[Directive CircuitBreaker] Circuit "${s}" is ${r}. ${a}`:`[Directive CircuitBreaker] Circuit "${s}" is ${r}. Request rejected. Try again in ${Math.ceil(o/1e3)}s.`;super(p),this.name="CircuitBreakerOpenError",this.retryAfterMs=o,this.state=r;}};function Tt(e={}){let{failureThreshold:s=5,recoveryTimeMs:o=3e4,halfOpenMaxRequests:r=3,failureWindowMs:a=6e4,observability:p,metricPrefix:l="circuit_breaker",name:t="default",isFailure:i=()=>true,onStateChange:c}=e;if(s<1||!Number.isFinite(s))throw new Error(`[Directive CircuitBreaker] failureThreshold must be >= 1, got ${s}`);if(o<=0||!Number.isFinite(o))throw new Error(`[Directive CircuitBreaker] recoveryTimeMs must be > 0, got ${o}`);if(r<1||!Number.isFinite(r))throw new Error(`[Directive CircuitBreaker] halfOpenMaxRequests must be >= 1, got ${r}`);if(a<=0||!Number.isFinite(a))throw new Error(`[Directive CircuitBreaker] failureWindowMs must be > 0, got ${a}`);let d="CLOSED",y=[],I=0,N=0,R=Date.now(),w=0,g=0,f=0,C=0,T=0,P=null,F=null;function O(_){if(d===_)return;let H=d;d=_,R=Date.now(),_==="OPEN"&&(w=Date.now()),_==="HALF_OPEN"&&(I=0,N=0),c?.(H,_),p&&p.incrementCounter(`${l}.state_change`,{name:t,from:H,to:_});}function Y(){let _=Date.now()-a;return y=y.filter(H=>H>_),y.length}function $(){C++,F=Date.now(),p&&p.incrementCounter(`${l}.success`,{name:t}),d==="HALF_OPEN"&&(N++,N>=r&&(O("CLOSED"),y=[]));}function V(_){if(!i(_)){$();return}f++,P=Date.now(),y.push(Date.now());let H=s*2;if(y.length>H&&(y=y.slice(-H)),p&&p.incrementCounter(`${l}.failure`,{name:t}),d==="HALF_OPEN"){O("OPEN");return}d==="CLOSED"&&Y()>=s&&O("OPEN");}return {async execute(_){if(g++,p&&p.incrementCounter(`${l}.requests`,{name:t}),d==="OPEN")if(Date.now()-w>=o)O("HALF_OPEN");else throw T++,p&&p.incrementCounter(`${l}.rejected`,{name:t}),new me(t,o-(Date.now()-w));if(d==="HALF_OPEN"){if(I>=r)throw T++,new me(t,o,"HALF_OPEN",`Max trial requests (${r}) reached.`);I++;}let H=Date.now();try{let h=await _();return $(),p&&p.observeHistogram(`${l}.latency`,Date.now()-H,{name:t}),h}catch(h){let x=h instanceof Error?h:new Error(String(h));throw V(x),p&&p.observeHistogram(`${l}.latency`,Date.now()-H,{name:t}),h}},getState(){return d==="OPEN"&&Date.now()-w>=o&&O("HALF_OPEN"),d},getStats(){return {state:this.getState(),totalRequests:g,totalFailures:f,totalSuccesses:C,totalRejected:T,recentFailures:Y(),lastFailureTime:P,lastSuccessTime:F,lastStateChange:R}},forceState(_){O(_);},reset(){let _=d;d="CLOSED",y=[],I=0,N=0,R=Date.now(),w=0,g=0,f=0,C=0,T=0,P=null,F=null,_!=="CLOSED"&&c?.(_,"CLOSED");},isAllowed(){return d==="CLOSED"?true:d==="OPEN"?Date.now()-w>=o:I<r}}}
Object.defineProperty(exports,"createAuditLedger",{enumerable:true,get:function(){return chunkIXRS4LM4_cjs.b}});Object.defineProperty(exports,"memorySink",{enumerable:true,get:function(){return chunkIXRS4LM4_cjs.a}});exports.CircuitBreakerOpenError=me;exports.DEVTOOLS_EVENT_NAME=tt;exports.createAgentMetrics=St;exports.createCircuitBreaker=Tt;exports.createOTLPExporter=Mt;exports.createObservability=ht;exports.devtoolsPlugin=mt;exports.emitDevToolsEvent=bt;exports.loggingPlugin=st;exports.performancePlugin=vt;exports.persistencePlugin=yt;//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map

@@ -1,3 +0,3 @@

export { A as AuditEntry, a as AuditEntryKind, b as AuditLedger, c as AuditLedgerOptions, d as AuditLedgerSink, Q as QueryFilter, e as createAuditLedger, m as memorySink } from '../audit-ledger-qMjEBqiP.cjs';
import { M as ModuleSchema, q as Plugin, aa as System } from '../plugins-Ykl_sAPE.cjs';
export { A as AuditEntry, a as AuditEntryKind, b as AuditLedger, c as AuditLedgerOptions, d as AuditLedgerSink, Q as QueryFilter, e as createAuditLedger, m as memorySink } from '../audit-ledger-Dc6hAXam.cjs';
import { M as ModuleSchema, P as Plugin, aa as System } from '../plugins-BIzXaYbg.cjs';

@@ -4,0 +4,0 @@ /**

@@ -1,3 +0,3 @@

export { A as AuditEntry, a as AuditEntryKind, b as AuditLedger, c as AuditLedgerOptions, d as AuditLedgerSink, Q as QueryFilter, e as createAuditLedger, m as memorySink } from '../audit-ledger-9IElAHH9.js';
import { M as ModuleSchema, q as Plugin, aa as System } from '../plugins-Ykl_sAPE.js';
export { A as AuditEntry, a as AuditEntryKind, b as AuditLedger, c as AuditLedgerOptions, d as AuditLedgerSink, Q as QueryFilter, e as createAuditLedger, m as memorySink } from '../audit-ledger-dxvslGi3.js';
import { M as ModuleSchema, P as Plugin, aa as System } from '../plugins-BIzXaYbg.js';

@@ -4,0 +4,0 @@ /**

@@ -1,3 +0,3 @@

export{b as createAuditLedger,a as memorySink}from'../chunk-7TSYQEN3.js';import {e}from'../chunk-T6IJUWYR.js';var Oe={debug:0,info:1,warn:2,error:3};function st(e={}){let{level:s="info",filter:o=()=>true,logger:r=console,prefix:a="[Directive]"}=e,p=Oe[s],l=(t,i,...c)=>{Oe[t]<p||o(i)&&r[t](`${a} ${i}`,...c);};return {name:"logging",onInit:()=>l("debug","init"),onStart:()=>l("info","start"),onStop:()=>l("info","stop"),onDestroy:()=>l("debug","destroy"),onFactSet:(t,i,c)=>{l("debug","fact.set",{key:t,value:i,prev:c});},onFactDelete:(t,i)=>{l("debug","fact.delete",{key:t,prev:i});},onFactsBatch:t=>{l("debug","facts.batch",{count:t.length,changes:t});},onDerivationCompute:(t,i,c)=>{l("debug","derivation.compute",{id:t,value:i,deps:c});},onDerivationInvalidate:t=>{l("debug","derivation.invalidate",{id:t});},onReconcileStart:()=>{l("debug","reconcile.start");},onReconcileEnd:t=>{l("debug","reconcile.end",{unmet:t.unmet.length,inflight:t.inflight.length,completed:t.completed.length,canceled:t.canceled.length});},onConstraintEvaluate:(t,i,c)=>{if(c){let d=c.filter(y=>y.pass).length;l("debug","constraint.evaluate",{id:t,active:i,clauses:{total:c.length,passed:d}});return}l("debug","constraint.evaluate",{id:t,active:i});},onConstraintError:(t,i)=>{l("error","constraint.error",{id:t,error:i});},onRequirementCreated:t=>{l("debug","requirement.created",{id:t.id,type:t.requirement.type});},onRequirementMet:(t,i)=>{l("info","requirement.met",{id:t.id,byResolver:i});},onRequirementCanceled:t=>{l("debug","requirement.canceled",{id:t.id});},onResolverStart:(t,i)=>{l("debug","resolver.start",{resolver:t,requirementId:i.id});},onResolverComplete:(t,i,c)=>{l("info","resolver.complete",{resolver:t,requirementId:i.id,duration:c});},onResolverError:(t,i,c)=>{l("error","resolver.error",{resolver:t,requirementId:i.id,error:c});},onResolverRetry:(t,i,c)=>{l("warn","resolver.retry",{resolver:t,requirementId:i.id,attempt:c});},onResolverCancel:(t,i)=>{l("debug","resolver.cancel",{resolver:t,requirementId:i.id});},onResolverWriteRejected:t=>{l("warn","resolver.write.rejected",t.kind==="summary"?{kind:t.kind,resolver:t.resolver,requirementId:t.req.id,reason:t.reason,dropped:t.dropped}:{kind:t.kind,resolver:t.resolver,requirementId:t.req.id,reason:t.reason,fact:t.fact,expected:t.expected,actual:t.actual});},onEffectRun:t=>{l("debug","effect.run",{id:t});},onEffectError:(t,i)=>{l("error","effect.error",{id:t,error:i});},onSnapshot:t=>{l("debug","timetravel.snapshot",{id:t.id,trigger:t.trigger});},onHistoryNavigate:(t,i)=>{l("info","timetravel.jump",{from:t,to:i});},onError:t=>{l("error","error",{source:t.source,sourceId:t.sourceId,message:t.message});},onErrorRecovery:(t,i)=>{l("warn","error.recovery",{source:t.source,sourceId:t.sourceId,strategy:i});},onDefinitionRegister:(t,i)=>{l("info","definition.register",{type:t,id:i});},onDefinitionAssign:(t,i)=>{l("info","definition.assign",{type:t,id:i});},onDefinitionUnregister:(t,i)=>{l("info","definition.unregister",{type:t,id:i});},onDefinitionCall:(t,i,c)=>{l("debug","definition.call",{type:t,id:i,props:c});},onTraceComplete:t=>{l("debug","trace.complete",{id:t.id,status:t.status,duration:t.duration,factChanges:t.factChanges.length,derivationsRecomputed:t.derivationsRecomputed.length,constraintsHit:t.constraintsHit.length,resolversStarted:t.resolversStarted.length,effectsRun:t.effectsRun.length});}}}var ue=class{constructor(s){this.capacity=s;this.buf=new Array(s);}buf;head=0;_size=0;get size(){return this._size}push(s){this.buf[this.head]=s,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++;}toArray(){return this._size===0?[]:this._size<this.capacity?this.buf.slice(0,this._size):[...this.buf.slice(this.head),...this.buf.slice(0,this.head)]}clear(){this.buf=new Array(this.capacity),this.head=0,this._size=0;}};function ge(){try{if(typeof process<"u"&&process.env?.NODE_ENV==="production")return !1}catch{}try{if(typeof import.meta<"u"&&import.meta.env?.MODE==="production")return !1}catch{}return true}function fe(e){try{if(e===void 0)return "undefined";if(e===null)return "null";if(typeof e=="bigint")return String(e)+"n";if(typeof e=="symbol")return String(e);if(typeof e=="object"){let s=JSON.stringify(e,(o,r)=>typeof r=="bigint"?String(r)+"n":typeof r=="symbol"?String(r):r);return s.length>120?s.slice(0,117)+"...":s}return String(e)}catch{return "<error>"}}function ee(e,s){return e.length<=s?e:e.slice(0,s-3)+"..."}function se(e){try{return e.inspect()}catch{return null}}function Le(e){try{return e==null||typeof e!="object"?e:JSON.parse(JSON.stringify(e))}catch{return null}}function Pe(e){return e===void 0?1e3:!Number.isFinite(e)||e<1?(ge()&&console.warn(`[directive:devtools] Invalid maxEvents value (${e}), using default 1000`),1e3):Math.floor(e)}function Ie(){return {reconcileCount:0,reconcileTotalMs:0,resolverStats:new Map,effectRunCount:0,effectErrorCount:0,lastReconcileStartMs:0}}var it=200,ie=340,ae=16,ce=80,he=2,Se=["#8b9aff","#4ade80","#fbbf24","#c084fc","#f472b6","#22d3ee"];function $e(){return {entries:new ue(it),inflight:new Map}}function _e(){return {derivationDeps:new Map,activeConstraints:new Set,recentlyChangedFacts:new Set,recentlyComputedDerivations:new Set,recentlyActiveConstraints:new Set,animationTimer:null}}var Ne=1e4,Be=100;function je(){return {isRecording:false,recordedEvents:[],snapshots:[]}}var He=50,xe=200,b={bg:"#1a1a2e",text:"#e0e0e0",accent:"#8b9aff",muted:"#b0b0d0",border:"#333",rowBorder:"#2a2a4a",green:"#4ade80",yellow:"#fbbf24",red:"#f87171",closeBtn:"#aaa",font:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},G={nodeW:90,nodeH:16,nodeGap:6,startY:16,colGap:20,fontSize:10,labelMaxChars:11};function Ve(e,s,o,r){let a=false,p={position:"fixed",zIndex:"99999",...s.includes("bottom")?{bottom:"12px"}:{top:"12px"},...s.includes("right")?{right:"12px"}:{left:"12px"}},l=document.createElement("style");l.textContent=`[data-directive-devtools] summary:focus-visible{outline:2px solid ${b.accent};outline-offset:2px;border-radius:2px}[data-directive-devtools] button:focus-visible{outline:2px solid ${b.accent};outline-offset:2px}`,document.head.appendChild(l);let t=document.createElement("button");t.setAttribute("aria-label","Open Directive DevTools"),t.setAttribute("aria-expanded",String(o)),t.title="Ctrl+Shift+D to toggle",Object.assign(t.style,{...p,background:b.bg,color:b.text,border:`1px solid ${b.border}`,borderRadius:"6px",padding:"10px 14px",minWidth:"44px",minHeight:"44px",cursor:"pointer",fontFamily:b.font,fontSize:"12px",display:o?"none":"block"}),t.textContent="Directive";let i=document.createElement("div");i.setAttribute("role","region"),i.setAttribute("aria-label","Directive DevTools"),i.setAttribute("data-directive-devtools",""),i.tabIndex=-1,Object.assign(i.style,{...p,background:b.bg,color:b.text,border:`1px solid ${b.border}`,borderRadius:"8px",padding:"12px",fontFamily:b.font,fontSize:"11px",maxWidth:"min(380px, calc(100vw - 24px))",maxHeight:"min(500px, calc(100vh - 24px))",overflow:"auto",boxShadow:"0 4px 20px rgba(0,0,0,0.5)",display:o?"block":"none"});let c=document.createElement("div");Object.assign(c.style,{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"8px"});let d=document.createElement("strong");d.style.color=b.accent,d.textContent=e==="default"?"Directive DevTools":`DevTools (${e})`;let y=document.createElement("button");y.setAttribute("aria-label","Close DevTools"),Object.assign(y.style,{background:"none",border:"none",color:b.closeBtn,cursor:"pointer",fontSize:"16px",padding:"8px 12px",minWidth:"44px",minHeight:"44px",lineHeight:"1",display:"flex",alignItems:"center",justifyContent:"center"}),y.textContent="\xD7",c.appendChild(d),c.appendChild(y),i.appendChild(c);let I=document.createElement("div");I.style.marginBottom="6px",I.setAttribute("aria-live","polite");let N=document.createElement("span");N.style.color=b.green,N.textContent="Settled",I.appendChild(N),i.appendChild(I);let R=document.createElement("div");Object.assign(R.style,{display:"none",marginBottom:"8px",padding:"4px 8px",background:"#252545",borderRadius:"4px",alignItems:"center",gap:"6px"});let w=document.createElement("button");Object.assign(w.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"4px 10px",borderRadius:"3px",fontFamily:b.font,fontSize:"11px",minWidth:"44px",minHeight:"44px"}),w.textContent="\u25C0 Undo",w.disabled=true;let g=document.createElement("button");Object.assign(g.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"4px 10px",borderRadius:"3px",fontFamily:b.font,fontSize:"11px",minWidth:"44px",minHeight:"44px"}),g.textContent="Redo \u25B6",g.disabled=true;let f=document.createElement("span");f.style.color=b.muted,f.style.fontSize="10px",R.appendChild(w),R.appendChild(g),R.appendChild(f),i.appendChild(R);function C(z,K){let X=document.createElement("details");K&&(X.open=true),X.style.marginBottom="4px";let J=document.createElement("summary");Object.assign(J.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"});let Q=document.createElement("span");J.textContent=`${z} (`,J.appendChild(Q),J.appendChild(document.createTextNode(")")),Q.textContent="0",X.appendChild(J);let te=document.createElement("table");Object.assign(te.style,{width:"100%",borderCollapse:"collapse",fontSize:"11px"});let Re=document.createElement("thead"),De=document.createElement("tr");for(let nt of ["Key","Value"]){let pe=document.createElement("th");pe.scope="col",Object.assign(pe.style,{textAlign:"left",padding:"2px 4px",color:b.accent}),pe.textContent=nt,De.appendChild(pe);}Re.appendChild(De),te.appendChild(Re);let Ae=document.createElement("tbody");return te.appendChild(Ae),X.appendChild(te),{details:X,tbody:Ae,countSpan:Q}}function T(z,K){let X=document.createElement("details");X.style.marginBottom="4px";let J=document.createElement("summary");Object.assign(J.style,{cursor:"pointer",color:K,marginBottom:"4px"});let Q=document.createElement("span");J.textContent=`${z} (`,J.appendChild(Q),J.appendChild(document.createTextNode(")")),Q.textContent="0",X.appendChild(J);let te=document.createElement("ul");return Object.assign(te.style,{margin:"0",paddingLeft:"16px"}),X.appendChild(te),{details:X,list:te,countSpan:Q}}let P=C("Facts",true);i.appendChild(P.details);let F=C("Derivations",false);i.appendChild(F.details);let O=T("Inflight",b.yellow);i.appendChild(O.details);let Y=T("Unmet",b.red);i.appendChild(Y.details);let $=document.createElement("details");$.style.marginBottom="4px";let V=document.createElement("summary");Object.assign(V.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),V.textContent="Performance",$.appendChild(V);let _=document.createElement("div");_.style.fontSize="10px",_.style.color=b.muted,_.textContent="No data yet",$.appendChild(_),i.appendChild($);let H=document.createElement("details");H.style.marginBottom="4px";let h=document.createElement("summary");Object.assign(h.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),h.textContent="Dependency Graph",H.appendChild(h);let x=document.createElementNS("http://www.w3.org/2000/svg","svg");x.setAttribute("width","100%"),x.setAttribute("height","120"),x.setAttribute("role","img"),x.setAttribute("aria-label","System dependency graph"),x.style.display="block",x.setAttribute("viewBox","0 0 460 120"),x.setAttribute("preserveAspectRatio","xMinYMin meet"),H.appendChild(x),i.appendChild(H);let E=document.createElement("details");E.style.marginBottom="4px";let q=document.createElement("summary");Object.assign(q.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),q.textContent="Timeline",E.appendChild(q);let j=document.createElementNS("http://www.w3.org/2000/svg","svg");j.setAttribute("width","100%"),j.setAttribute("height","60"),j.setAttribute("role","img"),j.setAttribute("aria-label","Resolver execution timeline"),j.style.display="block",j.setAttribute("viewBox",`0 0 ${ie} 60`),j.setAttribute("preserveAspectRatio","xMinYMin meet");let u=document.createElementNS("http://www.w3.org/2000/svg","text");u.setAttribute("x",String(ie/2)),u.setAttribute("y","30"),u.setAttribute("text-anchor","middle"),u.setAttribute("fill",b.muted),u.setAttribute("font-size","10"),u.setAttribute("font-family",b.font),u.textContent="No resolver activity yet",j.appendChild(u),E.appendChild(j),i.appendChild(E);let M=(()=>{let z=document.createElement("details");z.style.marginBottom="4px";let K=document.createElement("summary");Object.assign(K.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"});let X=document.createElement("span");X.textContent="0",K.textContent="Constraints (",K.appendChild(X),K.appendChild(document.createTextNode(")")),z.appendChild(K);let J=document.createElement("div");Object.assign(J.style,{fontSize:"11px"});let Q=document.createElement("div");return Q.style.color=b.muted,Q.style.padding="4px",Q.style.fontStyle="italic",Q.textContent="Waiting for first evaluation\u2026",Q.className="dt-constraints-empty",J.appendChild(Q),z.appendChild(J),i.appendChild(z),{details:z,body:J,countSpan:X}})(),S,A,W,k;if(r){let z=document.createElement("details");z.style.marginBottom="4px";let K=document.createElement("summary");Object.assign(K.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),W=document.createElement("span"),W.textContent="0",K.textContent="Events (",K.appendChild(W),K.appendChild(document.createTextNode(")")),z.appendChild(K),A=document.createElement("div"),Object.assign(A.style,{maxHeight:"150px",overflow:"auto",fontSize:"10px"}),A.setAttribute("role","log"),A.setAttribute("aria-live","polite"),A.tabIndex=0;let X=document.createElement("div");X.style.color=b.muted,X.style.padding="4px",X.textContent="Waiting for events...",X.className="dt-events-empty",A.appendChild(X),z.appendChild(A),i.appendChild(z),S=z,k=document.createElement("div");}else S=document.createElement("details"),A=document.createElement("div"),W=document.createElement("span"),k=document.createElement("div"),k.style.fontSize="10px",k.style.color=b.muted,k.style.marginTop="4px",k.style.fontStyle="italic",k.textContent="Enable trace: true for event log",i.appendChild(k);let L=document.createElement("div");Object.assign(L.style,{display:"flex",gap:"6px",marginTop:"6px"});let n=document.createElement("button");Object.assign(n.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"8px 12px",borderRadius:"3px",fontFamily:b.font,fontSize:"10px",minWidth:"44px",minHeight:"44px"}),n.textContent="\u23FA Record";let m=document.createElement("button");Object.assign(m.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"8px 12px",borderRadius:"3px",fontFamily:b.font,fontSize:"10px",minWidth:"44px",minHeight:"44px"}),m.textContent="\u2913 Export",L.appendChild(n),L.appendChild(m),i.appendChild(L),i.addEventListener("wheel",z=>{let K=i,X=K.scrollTop===0&&z.deltaY<0,J=K.scrollTop+K.clientHeight>=K.scrollHeight&&z.deltaY>0;(X||J)&&z.preventDefault();},{passive:false});let v=o,D=new Set;function B(){v=true,i.style.display="block",t.style.display="none",t.setAttribute("aria-expanded","true"),y.focus();}function U(){v=false,i.style.display="none",t.style.display="block",t.setAttribute("aria-expanded","false"),t.focus();}t.addEventListener("click",B),y.addEventListener("click",U);function Z(z){z.key==="Escape"&&v&&U();}i.addEventListener("keydown",Z);function re(z){z.key==="d"&&z.shiftKey&&(z.ctrlKey||z.metaKey)&&(z.preventDefault(),v?U():B());}document.addEventListener("keydown",re);function oe(){a||(document.body.appendChild(t),document.body.appendChild(i));}document.body?oe():document.addEventListener("DOMContentLoaded",oe,{once:true});function le(){a=true,t.removeEventListener("click",B),y.removeEventListener("click",U),i.removeEventListener("keydown",Z),document.removeEventListener("keydown",re),document.removeEventListener("DOMContentLoaded",oe);for(let z of D)clearTimeout(z);D.clear(),t.remove(),i.remove(),l.remove();}return {refs:{container:i,toggleBtn:t,titleEl:d,statusEl:N,factsBody:P.tbody,factsCount:P.countSpan,derivBody:F.tbody,derivCount:F.countSpan,derivSection:F.details,inflightList:O.list,inflightSection:O.details,inflightCount:O.countSpan,unmetList:Y.list,unmetSection:Y.details,unmetCount:Y.countSpan,perfSection:$,perfBody:_,historySection:R,historyLabel:f,undoBtn:w,redoBtn:g,flowSection:H,flowSvg:x,timelineSection:E,timelineSvg:j,eventsSection:S,eventsList:A,eventsCount:W,traceHint:k,recordBtn:n,exportBtn:m,constraintsSection:M.details,constraintsBody:M.body,constraintsCount:M.countSpan},destroy:le,isOpen:()=>v,flashTimers:D}}function de(e,s,o,r,a,p){let l=fe(r),t=e.get(o);if(t){let i=t.cells;if(i[1]&&(i[1].textContent=l,a&&p)){let c=i[1];c.style.background="rgba(139, 154, 255, 0.25)";let d=setTimeout(()=>{c.style.background="",p.delete(d);},300);p.add(d);}}else {t=document.createElement("tr"),t.style.borderBottom=`1px solid ${b.rowBorder}`;let i=document.createElement("td");Object.assign(i.style,{padding:"2px 4px",color:b.muted}),i.textContent=o;let c=document.createElement("td");c.style.padding="2px 4px",c.textContent=l,t.appendChild(i),t.appendChild(c),s.appendChild(t),e.set(o,t);}}function ze(e,s){let o=e.get(s);o&&(o.remove(),e.delete(s));}function be(e,s,o){if(e.inflightList.replaceChildren(),e.inflightCount.textContent=String(s.length),s.length>0)for(let r of s){let a=document.createElement("li");a.style.fontSize="11px",a.textContent=`${r.resolverId} (${r.id})`,e.inflightList.appendChild(a);}else {let r=document.createElement("li");r.style.fontSize="10px",r.style.color=b.muted,r.textContent="None",e.inflightList.appendChild(r);}if(e.unmetList.replaceChildren(),e.unmetCount.textContent=String(o.length),o.length>0)for(let r of o){let a=document.createElement("li");a.style.fontSize="11px",a.textContent=`${r.requirement.type} from ${r.fromConstraint}`,e.unmetList.appendChild(a);}else {let r=document.createElement("li");r.style.fontSize="10px",r.style.color=b.muted,r.textContent="None",e.unmetList.appendChild(r);}}function ye(e,s,o){let r=s===0&&o===0;e.statusEl.style.color=r?b.green:b.yellow,e.statusEl.textContent=r?"Settled":"Working...",e.toggleBtn.textContent=r?"Directive":"Directive...",e.toggleBtn.setAttribute("aria-label",`Open Directive DevTools${r?"":" (system working)"}`);}function Ee(e,s,o,r){let a=Object.keys(o.derive);if(e.derivCount.textContent=String(a.length),a.length===0){s.clear(),e.derivBody.replaceChildren();let l=document.createElement("tr"),t=document.createElement("td");t.colSpan=2,t.style.color=b.muted,t.style.fontSize="10px",t.textContent="No derivations defined",l.appendChild(t),e.derivBody.appendChild(l);return}let p=new Set(a);for(let[l,t]of s)p.has(l)||(t.remove(),s.delete(l));for(let l of a){let t;try{t=fe(o.read(l));}catch{t="<error>";}de(s,e.derivBody,l,t,true,r);}}function We(e,s,o,r){let a=e.eventsList.querySelector(".dt-events-empty");a&&a.remove();let p=document.createElement("div");Object.assign(p.style,{padding:"2px 4px",borderBottom:`1px solid ${b.rowBorder}`,fontFamily:"inherit"});let l=new Date,t=`${String(l.getHours()).padStart(2,"0")}:${String(l.getMinutes()).padStart(2,"0")}:${String(l.getSeconds()).padStart(2,"0")}.${String(l.getMilliseconds()).padStart(3,"0")}`,i;try{let I=JSON.stringify(o);i=ee(I,60);}catch{i="{}";}let c=document.createElement("span");c.style.color=b.closeBtn,c.textContent=t;let d=document.createElement("span");d.style.color=b.accent,d.textContent=` ${s} `;let y=document.createElement("span");for(y.style.color=b.muted,y.textContent=i,p.appendChild(c),p.appendChild(d),p.appendChild(y),e.eventsList.prepend(p);e.eventsList.childElementCount>He;)e.eventsList.lastElementChild?.remove();e.eventsCount.textContent=String(r);}function Ue(e,s){e.perfBody.replaceChildren();let o=s.reconcileCount>0?(s.reconcileTotalMs/s.reconcileCount).toFixed(1):"\u2014",r=[`Reconciles: ${s.reconcileCount} (avg ${o}ms)`,`Effects: ${s.effectRunCount} run, ${s.effectErrorCount} errors`];for(let a of r){let p=document.createElement("div");p.style.marginBottom="2px",p.textContent=a,e.perfBody.appendChild(p);}if(s.resolverStats.size>0){let a=document.createElement("div");a.style.marginTop="4px",a.style.marginBottom="2px",a.style.color=b.accent,a.textContent="Resolvers:",e.perfBody.appendChild(a);let p=[...s.resolverStats.entries()].sort((l,t)=>t[1].totalMs-l[1].totalMs);for(let[l,t]of p){let i=t.count>0?(t.totalMs/t.count).toFixed(1):"0",c=document.createElement("div");c.style.paddingLeft="8px",c.textContent=`${l}: ${t.count}x, avg ${i}ms${t.errors>0?`, ${t.errors} err`:""}`,t.errors>0&&(c.style.color=b.red),e.perfBody.appendChild(c);}}}function Ce(e,s){let o=s.history;if(!o){e.historySection.style.display="none";return}e.historySection.style.display="flex";let r=o.currentIndex,a=o.snapshots.length;e.historyLabel.textContent=a>0?`${r+1} / ${a}`:"0 snapshots";let p=r>0,l=r<a-1;e.undoBtn.disabled=!p,e.undoBtn.style.opacity=p?"1":"0.4",e.redoBtn.disabled=!l,e.redoBtn.style.opacity=l?"1":"0.4";}function Ge(e,s){e.undoBtn.addEventListener("click",()=>{s.history&&s.history.currentIndex>0&&s.history.goBack(1);}),e.redoBtn.addEventListener("click",()=>{s.history&&s.history.currentIndex<s.history.snapshots.length-1&&s.history.goForward(1);});}var qe=Object.assign(Object.create(null),{$eq:"=",$ne:"\u2260",$gt:">",$gte:"\u2265",$lt:"<",$lte:"\u2264",$in:"\u2208",$nin:"\u2209",$exists:"exists",$between:"in",$startsWith:"starts with",$endsWith:"ends with",$contains:"contains",$matches:"matches",$changed:"changed"});function at(e){return Object.hasOwn(qe,e)?qe[e]:e}function Fe(e){return e instanceof RegExp?ee(String(e),40):fe(e)}var ct=new Set(["$all","$any","$not"]);function Ye(e){let s=document.createElement("li"),o=e.pass?"\u2713":"\u2717";if(s.style.color=e.pass?b.green:b.red,s.style.listStyle="none",ct.has(e.op)){let r=e.path?` @ ${e.path}`:"";if(s.textContent=`${o} ${e.op}${r}`,e.children&&e.children.length>0){let a=document.createElement("ul");Object.assign(a.style,{margin:"0",paddingLeft:"14px",listStyle:"none"});for(let p of e.children)a.appendChild(Ye(p));s.appendChild(a);}}else {let r=at(e.op),a=Fe(e.expected);if(e.pass)s.textContent=`${o} ${e.path} ${r} ${a}`;else {let p=Fe(e.actual);s.textContent=`${o} ${e.path} ${r} ${a} (actual: ${p})`;}}return s}function Xe(e,s,o){let r=s.get(o);if(r&&(r.remove(),s.delete(o),e.constraintsCount.textContent=String(s.size)),s.size===0&&!e.constraintsBody.querySelector(".dt-constraints-empty")){let a=document.createElement("div");a.style.color=b.muted,a.style.padding="4px",a.style.fontStyle="italic",a.textContent="Waiting for first evaluation\u2026",a.className="dt-constraints-empty",e.constraintsBody.appendChild(a);}}function Ke(e,s){let o=e.constraintsBody.querySelector(".dt-constraints-empty");o&&(o.textContent=s?"Waiting for first evaluation\u2026":"This system has no constraints");}function Je(e,s,o,r,a,p){let l=e.constraintsBody.querySelector(".dt-constraints-empty");l&&l.remove();let t=s.get(o);t||(t=document.createElement("div"),Object.assign(t.style,{marginBottom:"6px",paddingBottom:"4px",borderBottom:`1px solid ${b.rowBorder}`}),s.set(o,t),e.constraintsBody.appendChild(t),e.constraintsCount.textContent=String(s.size)),t.replaceChildren();let i=document.createElement("div");Object.assign(i.style,{fontWeight:"bold",color:r?b.green:b.muted});let c=r?"\u2713":"\u2717";if(i.textContent=p?`${c} ${o} (${p})`:`${c} ${o}`,t.appendChild(i),a&&a.length>0){let d=document.createElement("ul");Object.assign(d.style,{margin:"2px 0 0 0",paddingLeft:"14px",listStyle:"none"});for(let y of a)d.appendChild(Ye(y));t.appendChild(d);}else if(!a){let d=document.createElement("div");Object.assign(d.style,{color:b.muted,fontSize:"10px",fontStyle:"italic",paddingLeft:"14px"}),d.textContent="function-form when (no clause tree)",t.appendChild(d);}}var we=new WeakMap;function lt(e,s,o,r,a,p){return [e.join(","),s.join(","),o.map(l=>`${l.id}:${l.active}`).join(","),[...r.entries()].map(([l,t])=>`${l}:${t.status}:${t.type}`).join(","),a.join(","),p.join(",")].join("|")}function ut(e,s,o,r,a){for(let p of o){let l=e.nodes.get(`0:${p}`);if(!l)continue;let t=s.recentlyChangedFacts.has(p);l.rect.setAttribute("fill",t?b.text+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}for(let p of r){let l=e.nodes.get(`1:${p}`);if(!l)continue;let t=s.recentlyComputedDerivations.has(p);l.rect.setAttribute("fill",t?b.accent+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}for(let p of a){let l=e.nodes.get(`2:${p}`);if(!l)continue;let t=s.recentlyActiveConstraints.has(p),i=l.rect.getAttribute("stroke")??b.muted;l.rect.setAttribute("fill",t?i+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}}function Me(e,s,o){let r=se(s);if(!r)return;let a;try{a=Object.keys(s.facts.$store.toObject());}catch{a=[];}let p=Object.keys(s.derive),l=r.constraints,t=r.unmet,i=r.inflight,c=Object.keys(r.resolvers),d=new Map;for(let u of t)d.set(u.id,{type:u.requirement.type,fromConstraint:u.fromConstraint,status:"unmet"});for(let u of i)d.set(u.id,{type:u.resolverId,fromConstraint:"",status:"inflight"});if(a.length===0&&p.length===0&&l.length===0&&c.length===0){we.delete(e.flowSvg),e.flowSvg.replaceChildren(),e.flowSvg.setAttribute("viewBox","0 0 460 40");let u=document.createElementNS("http://www.w3.org/2000/svg","text");u.setAttribute("x","230"),u.setAttribute("y","24"),u.setAttribute("text-anchor","middle"),u.setAttribute("fill",b.muted),u.setAttribute("font-size","10"),u.setAttribute("font-family",b.font),u.textContent="No system topology",e.flowSvg.appendChild(u);return}let y=i.map(u=>u.resolverId).sort(),I=lt(a,p,l,d,c,y),N=we.get(e.flowSvg);if(N&&N.fingerprint===I){ut(N,o,a,p,l.map(u=>u.id));return}let R=G.nodeW+G.colGap,w=[5,5+R,5+R*2,5+R*3,5+R*4],g=w[4]+G.nodeW+5;function f(u){let M=G.startY+12;return u.map(S=>{let A={...S,y:M};return M+=G.nodeH+G.nodeGap,A})}let C=f(a.map(u=>{let M=r.facts.find(S=>S.key===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),T=f(p.map(u=>{let M=r.derivations.find(S=>S.id===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),P=f(l.map(u=>({id:u.id,label:ee(u.meta?.label??u.id,G.labelMaxChars),active:u.active,priority:u.priority}))),F=f([...d.entries()].map(([u,M])=>({id:u,type:M.type,fromConstraint:M.fromConstraint,status:M.status}))),O=f(c.map(u=>{let M=r.resolverDefs.find(S=>S.id===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),Y=Math.max(C.length,T.length,P.length,F.length,O.length,1),$=G.startY+12+Y*(G.nodeH+G.nodeGap)+8;e.flowSvg.replaceChildren(),e.flowSvg.setAttribute("viewBox",`0 0 ${g} ${$}`),e.flowSvg.setAttribute("aria-label",`Dependency graph: ${a.length} facts, ${p.length} derivations, ${l.length} constraints, ${d.size} requirements, ${c.length} resolvers`);let V=["Facts","Derivations","Constraints","Reqs","Resolvers"];for(let[u,M]of V.entries()){let S=document.createElementNS("http://www.w3.org/2000/svg","text");S.setAttribute("x",String(w[u]??0)),S.setAttribute("y","10"),S.setAttribute("fill",b.accent),S.setAttribute("font-size",String(G.fontSize)),S.setAttribute("font-family",b.font),S.textContent=M,e.flowSvg.appendChild(S);}let _={fingerprint:I,nodes:new Map};function H(u,M,S,A,W,k,L,n,m){let v=document.createElementNS("http://www.w3.org/2000/svg","g");if(m){let U=document.createElementNS("http://www.w3.org/2000/svg","title");U.textContent=m,v.appendChild(U);}let D=document.createElementNS("http://www.w3.org/2000/svg","rect");D.setAttribute("x",String(M)),D.setAttribute("y",String(S-6)),D.setAttribute("width",String(G.nodeW)),D.setAttribute("height",String(G.nodeH)),D.setAttribute("rx","3"),D.setAttribute("fill",n?k+"33":"none"),D.setAttribute("stroke",k),D.setAttribute("stroke-width",n?"2":"1"),D.setAttribute("opacity",L?"0.35":"1"),v.appendChild(D);let B=document.createElementNS("http://www.w3.org/2000/svg","text");return B.setAttribute("x",String(M+4)),B.setAttribute("y",String(S+4)),B.setAttribute("fill",k),B.setAttribute("font-size",String(G.fontSize)),B.setAttribute("font-family",b.font),B.setAttribute("opacity",L?"0.35":"1"),B.textContent=W,v.appendChild(B),e.flowSvg.appendChild(v),_.nodes.set(`${u}:${A}`,{g:v,rect:D,text:B}),{midX:M+G.nodeW/2,midY:S}}function h(u,M,S,A,W,k){let L=document.createElementNS("http://www.w3.org/2000/svg","line");L.setAttribute("x1",String(u)),L.setAttribute("y1",String(M)),L.setAttribute("x2",String(S)),L.setAttribute("y2",String(A)),L.setAttribute("stroke",W),L.setAttribute("stroke-width","1"),L.setAttribute("stroke-dasharray","3,2"),L.setAttribute("opacity","0.7"),e.flowSvg.appendChild(L);}let x=new Map,E=new Map,q=new Map,j=new Map;for(let u of C){let M=o.recentlyChangedFacts.has(u.id),S=r.facts.find(W=>W.key===u.id)?.meta,A=H(0,w[0],u.y,u.id,u.label,b.text,false,M,S?.description);x.set(u.id,A);}for(let u of T){let M=o.recentlyComputedDerivations.has(u.id),S=r.derivations.find(W=>W.id===u.id)?.meta,A=H(1,w[1],u.y,u.id,u.label,b.accent,false,M,S?.description);E.set(u.id,A);}for(let u of P){let M=o.recentlyActiveConstraints.has(u.id),S=l.find(W=>W.id===u.id)?.meta,A=H(2,w[2],u.y,u.id,u.label,S?.color??(u.active?b.yellow:b.muted),!u.active,M,S?.description);q.set(u.id,A);}for(let u of F){let M=u.status==="unmet"?b.red:b.yellow,S=H(3,w[3],u.y,u.id,ee(u.type,G.labelMaxChars),M,false,false);j.set(u.id,S);}for(let u of O){let M=i.some(A=>A.resolverId===u.id),S=r.resolverDefs.find(A=>A.id===u.id)?.meta;H(4,w[4],u.y,u.id,u.label,S?.color??(M?b.green:b.muted),!M,false,S?.description);}for(let u of T){let M=o.derivationDeps.get(u.id),S=E.get(u.id);if(M&&S)for(let A of M){let W=x.get(A);W&&h(W.midX+G.nodeW/2,W.midY,S.midX-G.nodeW/2,S.midY,b.accent);}}for(let u of F){let M=q.get(u.fromConstraint),S=j.get(u.id);M&&S&&h(M.midX+G.nodeW/2,M.midY,S.midX-G.nodeW/2,S.midY,b.muted);}for(let u of i){let M=j.get(u.id);if(M){let S=O.find(A=>A.id===u.resolverId);S&&h(M.midX+G.nodeW/2,M.midY,w[4],S.y,b.green);}}we.set(e.flowSvg,_);}function Qe(e){e.animationTimer&&clearTimeout(e.animationTimer),e.animationTimer=setTimeout(()=>{e.recentlyChangedFacts.clear(),e.recentlyComputedDerivations.clear(),e.recentlyActiveConstraints.clear(),e.animationTimer=null;},600);}function Ze(e,s){let o=s.entries.toArray();if(o.length===0)return;e.timelineSvg.replaceChildren();let r=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY;for(let R of o)R.startMs<r&&(r=R.startMs),R.endMs>a&&(a=R.endMs);let p=performance.now();for(let R of s.inflight.values())R<r&&(r=R),p>a&&(a=p);let l=a-r||1,t=ie-ce-10,i=[],c=new Set;for(let R of o)c.has(R.resolver)||(c.add(R.resolver),i.push(R.resolver));for(let R of s.inflight.keys())c.has(R)||(c.add(R),i.push(R));let y=i.slice(-12),I=ae*y.length+20;e.timelineSvg.setAttribute("viewBox",`0 0 ${ie} ${I}`),e.timelineSvg.setAttribute("height",String(Math.min(I,200)));let N=5;for(let R=0;R<=N;R++){let w=ce+t*R/N,g=l*R/N,f=document.createElementNS("http://www.w3.org/2000/svg","text");f.setAttribute("x",String(w)),f.setAttribute("y","8"),f.setAttribute("fill",b.muted),f.setAttribute("font-size","6"),f.setAttribute("font-family",b.font),f.setAttribute("text-anchor","middle"),f.textContent=g<1e3?`${g.toFixed(0)}ms`:`${(g/1e3).toFixed(1)}s`,e.timelineSvg.appendChild(f);let C=document.createElementNS("http://www.w3.org/2000/svg","line");C.setAttribute("x1",String(w)),C.setAttribute("y1","10"),C.setAttribute("x2",String(w)),C.setAttribute("y2",String(I)),C.setAttribute("stroke",b.border),C.setAttribute("stroke-width","0.5"),e.timelineSvg.appendChild(C);}for(let R=0;R<y.length;R++){let w=y[R],g=12+R*ae,f=R%Se.length,C=Se[f],T=document.createElementNS("http://www.w3.org/2000/svg","text");T.setAttribute("x",String(ce-4)),T.setAttribute("y",String(g+ae/2+3)),T.setAttribute("fill",b.muted),T.setAttribute("font-size","7"),T.setAttribute("font-family",b.font),T.setAttribute("text-anchor","end"),T.textContent=ee(w,12),e.timelineSvg.appendChild(T);let P=o.filter(O=>O.resolver===w);for(let O of P){let Y=ce+(O.startMs-r)/l*t,$=Math.max((O.endMs-O.startMs)/l*t,he),V=document.createElementNS("http://www.w3.org/2000/svg","rect");V.setAttribute("x",String(Y)),V.setAttribute("y",String(g+2)),V.setAttribute("width",String($)),V.setAttribute("height",String(ae-4)),V.setAttribute("rx","2"),V.setAttribute("fill",O.error?b.red:C),V.setAttribute("opacity","0.8");let _=document.createElementNS("http://www.w3.org/2000/svg","title"),H=O.endMs-O.startMs;_.textContent=`${w}: ${H.toFixed(1)}ms${O.error?" (error)":""}`,V.appendChild(_),e.timelineSvg.appendChild(V);}let F=s.inflight.get(w);if(F!==void 0){let O=ce+(F-r)/l*t,Y=Math.max((p-F)/l*t,he),$=document.createElementNS("http://www.w3.org/2000/svg","rect");$.setAttribute("x",String(O)),$.setAttribute("y",String(g+2)),$.setAttribute("width",String(Y)),$.setAttribute("height",String(ae-4)),$.setAttribute("rx","2"),$.setAttribute("fill",C),$.setAttribute("opacity","0.4"),$.setAttribute("stroke",C),$.setAttribute("stroke-width","1"),$.setAttribute("stroke-dasharray","3,2");let V=document.createElementNS("http://www.w3.org/2000/svg","title");V.textContent=`${w}: inflight ${(p-F).toFixed(0)}ms`,$.appendChild(V),e.timelineSvg.appendChild($);}}e.timelineSvg.setAttribute("aria-label",`Timeline: ${o.length} resolver executions across ${y.length} resolvers`);}function dt(){if(typeof window>"u")return {systems:new Map,getSystem:()=>null,getSystems:()=>[],inspect:()=>null,getEvents:()=>[],explain:()=>null,exportSession:()=>null,importSession:()=>false,clearEvents:()=>{},subscribe:()=>()=>{}};if(!window.__DIRECTIVE__){let e=new Map,s={systems:e,getSystem(o){return o?e.get(o)?.system??null:e.values().next().value?.system??null},getSystems(){return [...e.keys()]},inspect(o){let r=this.getSystem(o),a=o?e.get(o):e.values().next().value,p=r?.inspect()??null;return p&&a&&(p.resolverStats=a.resolverStats?Object.fromEntries(a.resolverStats):{}),p},getEvents(o){return o?e.get(o)?.events.toArray()??[]:e.values().next().value?.events.toArray()??[]},explain(o,r){return this.getSystem(r)?.explain(o)??null},subscribe(o,r){let a=r?e.get(r):e.values().next().value;if(!a){let p=false,t=setInterval(()=>{let c=r?e.get(r):e.values().next().value;c&&!p&&(p=true,c.subscribers.add(o));},100),i=setTimeout(()=>clearInterval(t),1e4);return ()=>{clearInterval(t),clearTimeout(i);for(let c of e.values())c.subscribers.delete(o);}}return a.subscribers.add(o),()=>{a.subscribers.delete(o);}},exportSession(o){let r=o?e.get(o):e.values().next().value;return r?JSON.stringify({version:1,name:o??e.keys().next().value??"default",exportedAt:Date.now(),events:r.events.toArray()}):null},importSession(o,r){try{if(o.length>10*1024*1024)return !1;let a=JSON.parse(o);if(!a||typeof a!="object"||Array.isArray(a)||!Array.isArray(a.events))return !1;let p=r?e.get(r):e.values().next().value;if(!p)return !1;let l=p.maxEvents,t=a.events,i=t.length>l?t.length-l:0;p.events.clear();for(let c=i;c<t.length;c++){let d=t[c];d&&typeof d=="object"&&!Array.isArray(d)&&typeof d.timestamp=="number"&&typeof d.type=="string"&&d.type!=="__proto__"&&d.type!=="constructor"&&d.type!=="prototype"&&p.events.push({timestamp:d.timestamp,type:d.type,data:d.data??null});}return !0}catch{return false}},clearEvents(o){let r=o?e.get(o):e.values().next().value;r&&r.events.clear();}};return Object.defineProperty(window,"__DIRECTIVE__",{value:s,writable:false,configurable:ge(),enumerable:true}),s}return window.__DIRECTIVE__}function mt(e={}){let{name:s="default",trace:o=false,maxEvents:r,panel:a=false,position:p="bottom-right",defaultOpen:l=false}=e,t=Pe(r),i=dt(),c={system:null,events:new ue(t),maxEvents:t,subscribers:new Set,resolverStats:new Map};i.systems.set(s,c);let d=(n,m)=>{let v={timestamp:Date.now(),type:n,data:m};o&&c.events.push(v);for(let D of c.subscribers)try{D(v);}catch{}},y=null,I=new Map,N=new Map,R=new Map,w=Ie(),g=_e(),f=je(),C=$e(),T=a&&typeof window<"u"&&typeof document<"u"&&ge(),P=null,F=0,O=1,Y=2,$=4,V=8,_=16,H=32,h=64,x=128,E=256,q=new Map,j=new Set,u=new Map,M=new Set,S=null;function A(n){F|=n,P===null&&typeof requestAnimationFrame<"u"&&(P=requestAnimationFrame(W));}function W(){if(P=null,!y||!c.system){F=0;return}let n=y.refs,m=c.system,v=F;if(F=0,v&O){for(let D of j)ze(I,D);j.clear();for(let[D,{value:B,flash:U}]of q)de(I,n.factsBody,D,B,U,y.flashTimers);q.clear(),n.factsCount.textContent=String(I.size);}if(v&Y&&Ee(n,N,m,y.flashTimers),v&E){for(let D of M)Xe(n,R,D);M.clear();for(let[D,{active:B,whenExplain:U,label:Z}]of u)Je(n,R,D,B,U,Z);u.clear();}if(v&V)if(S)ye(n,S.inflight.length,S.unmet.length);else {let D=se(m);D&&ye(n,D.inflight.length,D.unmet.length);}if(v&$)if(S)be(n,S.inflight,S.unmet);else {let D=se(m);D&&be(n,D.inflight,D.unmet);}v&_&&Ue(n,w),v&H&&Me(n,m,g),v&h&&Ce(n,m),v&x&&Ze(n,C);}function k(n,m){y&&o&&We(y.refs,n,m,c.events.size);}function L(n,m){f.isRecording&&f.recordedEvents.length<Ne&&f.recordedEvents.push({timestamp:Date.now(),type:n,data:Le(m)});}return {name:"devtools",onInit:n=>{if(c.system=n,d("init",{}),typeof window<"u"&&console.log(`%c[Directive Devtools]%c System "${s}" initialized. Access via window.__DIRECTIVE__`,"color: #7c3aed; font-weight: bold","color: inherit"),T){let m=c.system;y=Ve(s,p,l,o);let v=y.refs;try{let U=m.facts.$store.toObject();for(let[Z,re]of Object.entries(U))de(I,v.factsBody,Z,re,!1);v.factsCount.textContent=String(Object.keys(U).length);}catch{}Ee(v,N,m);let D=se(m);D&&(ye(v,D.inflight.length,D.unmet.length),be(v,D.inflight,D.unmet)),Ce(v,m),Ge(v,m),Me(v,m,g);let B=(D?.constraints?.length??0)>0;Ke(v,B),v.recordBtn.addEventListener("click",()=>{if(f.isRecording=!f.isRecording,v.recordBtn.textContent=f.isRecording?"\u23F9 Stop":"\u23FA Record",v.recordBtn.style.color=f.isRecording?b.red:b.text,f.isRecording){f.recordedEvents=[],f.snapshots=[];try{f.snapshots.push({timestamp:Date.now(),facts:m.facts.$store.toObject()});}catch{}}}),v.exportBtn.addEventListener("click",()=>{let U=f.recordedEvents.length>0?f.recordedEvents:c.events.toArray(),Z=JSON.stringify({version:1,name:s,exportedAt:Date.now(),events:U,snapshots:f.snapshots},null,2),re=new Blob([Z],{type:"application/json"}),oe=URL.createObjectURL(re),le=document.createElement("a");le.href=oe,le.download=`directive-session-${s}-${Date.now()}.json`,le.click(),URL.revokeObjectURL(oe);});}},onStart:n=>{d("start",{}),k("start",{}),L("start",{});},onStop:n=>{d("stop",{}),k("stop",{}),L("stop",{});},onDestroy:n=>{d("destroy",{}),i.systems.delete(s),P!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(P),P=null),g.animationTimer&&clearTimeout(g.animationTimer),y&&(y.destroy(),y=null,I.clear(),N.clear(),R.clear());},onFactSet:(n,m,v)=>{d("fact.set",{key:n,value:m,prev:v}),L("fact.set",{key:n,value:m,prev:v}),g.recentlyChangedFacts.add(n),y&&c.system&&(q.set(n,{value:m,flash:true}),j.delete(n),A(O),k("fact.set",{key:n,value:m}));},onFactDelete:(n,m)=>{d("fact.delete",{key:n,prev:m}),L("fact.delete",{key:n,prev:m}),y&&(j.add(n),q.delete(n),A(O),k("fact.delete",{key:n}));},onFactsBatch:n=>{if(d("facts.batch",{changes:n}),L("facts.batch",{count:n.length}),y&&c.system){for(let m of n)m.type==="delete"?(j.add(m.key),q.delete(m.key)):(g.recentlyChangedFacts.add(m.key),q.set(m.key,{value:m.value,flash:true}),j.delete(m.key));A(O),k("facts.batch",{count:n.length});}},onDerivationCompute:(n,m,v)=>{d("derivation.compute",{id:n,value:m,deps:v}),L("derivation.compute",{id:n,deps:v}),g.derivationDeps.set(n,v),g.recentlyComputedDerivations.add(n),k("derivation.compute",{id:n,deps:v});},onDerivationInvalidate:n=>{d("derivation.invalidate",{id:n}),k("derivation.invalidate",{id:n});},onReconcileStart:n=>{d("reconcile.start",{}),w.lastReconcileStartMs=performance.now(),k("reconcile.start",{}),L("reconcile.start",{});},onReconcileEnd:n=>{if(d("reconcile.end",n),L("reconcile.end",{unmet:n.unmet.length,inflight:n.inflight.length,completed:n.completed.length}),w.lastReconcileStartMs>0){let m=performance.now()-w.lastReconcileStartMs;w.reconcileCount++,w.reconcileTotalMs+=m,w.lastReconcileStartMs=0;}if(f.isRecording&&c.system&&f.snapshots.length<Be)try{f.snapshots.push({timestamp:Date.now(),facts:c.system.facts.$store.toObject()});}catch{}y&&c.system&&(S=n,Qe(g),A(Y|V|$|_|H|h),k("reconcile.end",{unmet:n.unmet.length,inflight:n.inflight.length}));},onConstraintEvaluate:(n,m,v)=>{let D=c.system?.meta?.constraint(n)?.label,B=D?{id:n,active:m,label:D}:{id:n,active:m},U=v?{...B,whenExplain:v}:B;d("constraint.evaluate",U),L("constraint.evaluate",U),m?(g.activeConstraints.add(n),g.recentlyActiveConstraints.add(n)):g.activeConstraints.delete(n),y&&(u.set(n,{active:m,whenExplain:v,label:D}),M.delete(n),A(E)),k("constraint.evaluate",{id:n,active:m});},onConstraintError:(n,m)=>{d("constraint.error",{id:n,error:String(m)}),k("constraint.error",{id:n,error:String(m)});},onRequirementCreated:n=>{d("requirement.created",{id:n.id,type:n.requirement.type}),L("requirement.created",{id:n.id,type:n.requirement.type}),k("requirement.created",{id:n.id,type:n.requirement.type});},onRequirementMet:(n,m)=>{d("requirement.met",{id:n.id,byResolver:m}),L("requirement.met",{id:n.id,byResolver:m}),k("requirement.met",{id:n.id,byResolver:m});},onRequirementCanceled:n=>{d("requirement.canceled",{id:n.id}),L("requirement.canceled",{id:n.id}),k("requirement.canceled",{id:n.id});},onResolverStart:(n,m)=>{let v=c.system?.meta?.resolver(n)?.label,D={resolver:n,requirementId:m.id},B=v?{...D,label:v}:D;d("resolver.start",B),L("resolver.start",B),C.inflight.set(n,performance.now()),y&&c.system&&(A($|V|x),k("resolver.start",{resolver:n,requirementId:m.id}));},onResolverComplete:(n,m,v)=>{let D=c.system?.meta?.resolver(n)?.label;d("resolver.complete",{resolver:n,requirementId:m.id,duration:v,...D?{label:D}:{}}),L("resolver.complete",{resolver:n,requirementId:m.id,duration:v});let B=c.resolverStats.get(n)??{count:0,totalMs:0,errors:0};if(B.count++,B.totalMs+=v,c.resolverStats.set(n,B),c.resolverStats.size>xe){let Z=c.resolverStats.keys().next().value;Z!==void 0&&c.resolverStats.delete(Z);}w.resolverStats.set(n,{...B});let U=C.inflight.get(n);C.inflight.delete(n),U!==void 0&&C.entries.push({resolver:n,startMs:U,endMs:performance.now(),error:false}),y&&c.system&&(A($|V|_|x),k("resolver.complete",{resolver:n,duration:v}));},onResolverError:(n,m,v)=>{d("resolver.error",{resolver:n,requirementId:m.id,error:String(v)}),L("resolver.error",{resolver:n,requirementId:m.id,error:String(v)});let D=c.resolverStats.get(n)??{count:0,totalMs:0,errors:0};if(D.errors++,c.resolverStats.set(n,D),c.resolverStats.size>xe){let U=c.resolverStats.keys().next().value;U!==void 0&&c.resolverStats.delete(U);}w.resolverStats.set(n,{...D});let B=C.inflight.get(n);C.inflight.delete(n),B!==void 0&&C.entries.push({resolver:n,startMs:B,endMs:performance.now(),error:true}),y&&c.system&&(A($|V|_|x),k("resolver.error",{resolver:n,error:String(v)}));},onResolverRetry:(n,m,v)=>{d("resolver.retry",{resolver:n,requirementId:m.id,attempt:v}),L("resolver.retry",{resolver:n,requirementId:m.id,attempt:v}),k("resolver.retry",{resolver:n,attempt:v});},onResolverCancel:(n,m)=>{d("resolver.cancel",{resolver:n,requirementId:m.id}),L("resolver.cancel",{resolver:n,requirementId:m.id}),C.inflight.delete(n),k("resolver.cancel",{resolver:n});},onResolverWriteRejected:n=>{let m=n.kind==="summary"?{kind:n.kind,resolver:n.resolver,requirementId:n.req.id,reason:n.reason,dropped:n.dropped}:{kind:n.kind,resolver:n.resolver,requirementId:n.req.id,reason:n.reason,fact:n.fact,expected:n.expected,actual:n.actual};d("resolver.write.rejected",m),L("resolver.write.rejected",m),k("resolver.write.rejected",n.kind==="summary"?{resolver:n.resolver,dropped:n.dropped}:{resolver:n.resolver,fact:n.fact});},onEffectRun:n=>{let m=c.system?.meta?.effect(n)?.label,v=m?{id:n,label:m}:{id:n};d("effect.run",v),L("effect.run",v),w.effectRunCount++,k("effect.run",{id:n});},onEffectError:(n,m)=>{d("effect.error",{id:n,error:String(m)}),w.effectErrorCount++,k("effect.error",{id:n,error:String(m)});},onSnapshot:n=>{d("timetravel.snapshot",{id:n.id,trigger:n.trigger}),y&&c.system&&A(h),k("timetravel.snapshot",{id:n.id,trigger:n.trigger});},onHistoryNavigate:(n,m)=>{if(d("timetravel.jump",{from:n,to:m}),L("timetravel.jump",{from:n,to:m}),y&&c.system){let v=c.system;try{let D=v.facts.$store.toObject();I.clear(),y.refs.factsBody.replaceChildren();for(let[B,U]of Object.entries(D))de(I,y.refs.factsBody,B,U,!1);y.refs.factsCount.textContent=String(Object.keys(D).length);}catch{}N.clear(),g.derivationDeps.clear(),y.refs.derivBody.replaceChildren(),R.clear(),y.refs.constraintsBody.replaceChildren(),y.refs.constraintsCount.textContent="0",S=null,A(Y|V|$|H|h),k("timetravel.jump",{from:n,to:m});}},onError:n=>{d("error",{source:n.source,sourceId:n.sourceId,message:n.message}),L("error",{source:n.source,message:n.message}),k("error",{source:n.source,message:n.message});},onErrorRecovery:(n,m)=>{d("error.recovery",{source:n.source,sourceId:n.sourceId,strategy:m}),k("error.recovery",{source:n.source,strategy:m});},onTraceComplete:n=>{d("trace.complete",{id:n.id,status:n.status,facts:n.factChanges.length,constraints:n.constraintsHit.length,requirements:n.requirementsAdded.length,resolvers:n.resolversStarted.length,effects:n.effectsRun.length}),k("trace.complete",{id:n.id});},onDefinitionRegister:(n,m)=>{d("definition.register",{type:n,id:m}),L("definition.register",{type:n,id:m}),k("definition.register",{type:n,id:m});},onDefinitionAssign:(n,m)=>{d("definition.assign",{type:n,id:m}),L("definition.assign",{type:n,id:m}),k("definition.assign",{type:n,id:m});},onDefinitionUnregister:(n,m)=>{d("definition.unregister",{type:n,id:m}),L("definition.unregister",{type:n,id:m}),k("definition.unregister",{type:n,id:m}),n==="constraint"&&y&&(M.add(m),u.delete(m),A(E));},onDefinitionCall:(n,m,v)=>{d("definition.call",{type:n,id:m,props:v}),L("definition.call",{type:n,id:m,props:v}),k("definition.call",{type:n,id:m,props:v});}}}var tt="directive-devtools-event",et=new Set(["__proto__","constructor","prototype"]),pt=Math.random().toString(36).slice(2,8);function gt(){if(typeof window<"u"){let e=`__DIRECTIVE_BRIDGE_ID_${pt}__`,s=window,o=s[e]??0;return s[e]=o+1,o+1}return 1}function ft(e){let s=false;for(let r of et)if(r in e){s=true;break}if(!s)return e;let o=Object.create(null);for(let[r,a]of Object.entries(e))et.has(r)||(o[r]=a);return o}function bt(e){if(!(typeof window>"u"))try{let s=ft(e),o={id:gt(),timestamp:Date.now(),snapshotId:null,...s};window.dispatchEvent(new CustomEvent(tt,{detail:o}));}catch{}}function yt(e$1){let{storage:s,key:o,include:r,exclude:a=[],debounce:p=100,onRestore:l,onSave:t,onError:i}=e$1,c=null,d=null,y=new Set,I=g=>a.includes(g)?false:r?r.includes(g):true,N=()=>{try{let g=s.getItem(o);if(!g)return null;let f=JSON.parse(g);return typeof f!="object"||f===null?null:e(f)?f:(i?.(new Error("Potential prototype pollution detected in stored data")),null)}catch(g){return i?.(g instanceof Error?g:new Error(String(g))),null}},R=()=>{if(d)try{let g={};for(let f of y)I(f)&&(g[f]=d.facts[f]);s.setItem(o,JSON.stringify(g)),t?.(g);}catch(g){i?.(g instanceof Error?g:new Error(String(g)));}},w=()=>{c&&clearTimeout(c),c=setTimeout(R,p);};return {name:"persistence",onInit:g=>{d=g;let f=N();f&&(d.facts.$store.batch(()=>{for(let[C,T]of Object.entries(f))I(C)&&(d.facts[C]=T,y.add(C));}),l?.(f));},onDestroy:()=>{c&&clearTimeout(c),R();},onFactSet:g=>{y.add(g),I(g)&&w();},onFactDelete:g=>{y.delete(g),I(g)&&w();},onFactsBatch:g=>{let f=false;for(let C of g)C.type==="set"?y.add(C.key):y.delete(C.key),I(C.key)&&(f=true);f&&w();}}}function vt(e={}){let{onSlowConstraint:s,onSlowResolver:o,slowConstraintThresholdMs:r=16,slowResolverThresholdMs:a=1e3}=e,p=new Map,l=new Map,t=new Map,i={runs:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0},c=0,d=0,y=0;function I(g){let f=p.get(g);return f||(f={evaluations:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0,lastEvaluatedAt:0},p.set(g,f)),f}function N(g){let f=l.get(g);return f||(f={starts:0,completions:0,errors:0,retries:0,cancellations:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0,lastCompletedAt:0},l.set(g,f)),f}function R(g){let f=t.get(g);return f||(f={runs:0,errors:0,lastRunAt:0},t.set(g,f)),f}let w={name:"performance",onStart(){c=Date.now();},onConstraintEvaluate(g,f){let C=performance.now(),T=I(g);if(T.evaluations++,T.lastEvaluatedAt=Date.now(),y>0){let P=C-y;T.totalDurationMs+=P;let F=T.evaluations;T.avgDurationMs=T.totalDurationMs/F,P>T.maxDurationMs&&(T.maxDurationMs=P),P>r&&s?.(g,P);}y=C;},onResolverStart(g,f){let C=N(g);C.starts++;},onResolverComplete(g,f,C){let T=N(g);T.completions++,T.totalDurationMs+=C,T.avgDurationMs=T.totalDurationMs/T.completions,C>T.maxDurationMs&&(T.maxDurationMs=C),T.lastCompletedAt=Date.now(),C>a&&o?.(g,C);},onResolverError(g,f,C){N(g).errors++;},onResolverRetry(g,f,C){N(g).retries++;},onResolverCancel(g,f){N(g).cancellations++;},onEffectRun(g){let f=R(g);f.runs++,f.lastRunAt=Date.now();},onEffectError(g,f){R(g).errors++;},onReconcileStart(){d=performance.now(),y=0;},onReconcileEnd(){let g=performance.now()-d;i.runs++,i.totalDurationMs+=g,i.avgDurationMs=i.totalDurationMs/i.runs,g>i.maxDurationMs&&(i.maxDurationMs=g);},onDestroy(){w.reset();},getSnapshot(){let g={};for(let[T,P]of p)g[T]={...P};let f={};for(let[T,P]of l)f[T]={...P};let C={};for(let[T,P]of t)C[T]={...P};return {constraints:g,resolvers:f,effects:C,reconcile:{...i},uptime:c?Date.now()-c:0}},reset(){p.clear(),l.clear(),t.clear(),i.runs=0,i.totalDurationMs=0,i.avgDurationMs=0,i.maxDurationMs=0,y=0;}};return w}function ve(){return globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function Te(e,s){if(e.length===0)return 0;let o=[...e].sort((a,p)=>a-p),r=Math.ceil(s/100*o.length)-1;return o[Math.max(0,r)]??0}function ht(e={}){let{serviceName:s="directive-agents",metrics:o={},tracing:r={},alerts:a=[],summaryMetrics:p={},events:l={}}=e,t={requests:p.requests??"agent.requests",errors:p.errors??"agent.errors",latency:p.latency??"agent.latency",tokens:p.tokens??"agent.tokens",cost:p.cost??"agent.cost"},{enabled:i=true,exportInterval:c,exporter:d,maxDataPoints:y=1e3}=o,{enabled:I=true,sampleRate:N=1,maxSpans:R=1e3,exporter:w}=r,g=Date.now(),f=new Map,C=new Map,T=[],P=[],F=new Map,O=new Map,Y;c&&(d||w)&&(Y=setInterval(async()=>{try{if(d&&i&&await d(Array.from(O.values())),w&&I){let h=T.splice(0,100);h.length>0&&await w(h);}}catch(h){console.error("[Directive Observability] Export error:",h);}},c));function $(h){if(!i)return;let x=`${h.name}:${JSON.stringify(Object.fromEntries(Object.entries(h.labels).sort()))}`,E=f.get(x);E||(E=[],f.set(x,E)),E.push(h),E.length>y&&E.shift(),V(h.name,E),l.onMetricRecorded?.(h),_(h.name);}function V(h,x){if(x.length===0)return;let E=x.map(S=>S.value),q=E.reduce((S,A)=>S+A,0),j=x[0],u=E[E.length-1],M={name:h,type:j.type,count:x.length,sum:q,min:Math.min(...E),max:Math.max(...E),avg:q/x.length,lastValue:u,lastUpdated:Date.now()};O.set(h,M);}function _(h){for(let x of a){if(x.metric!==h)continue;let E=O.get(h);if(!E)continue;let q=`${x.metric}:${x.threshold}`,j=F.get(q),u=x.cooldownMs??6e4;if(j&&Date.now()-j<u)continue;let M=x.operator??">",S=E.lastValue,A=x.threshold,W=false;switch(M){case ">":W=S>A;break;case "<":W=S<A;break;case ">=":W=S>=A;break;case "<=":W=S<=A;break;case "==":W=S===A;break}if(W){let k={alertId:ve(),metric:h,currentValue:S,threshold:A,operator:M,action:x.action,timestamp:Date.now(),message:`Alert: ${h} ${M} ${A} (current: ${S})`};switch(P.push(k),P.length>1e3&&P.splice(0,P.length-1e3),F.set(q,Date.now()),l.onAlert?.(k),x.action){case "log":console.log(`[Observability] ${k.message}`);break;case "warn":console.warn(`[Observability] ${k.message}`);break;case "alert":console.error(`[Observability ALERT] ${k.message}`);break;case "callback":x.callback?.(E,A);break}}}}function H(h){let x=[];for(let[E,q]of f)if(E.startsWith(`${h}:`))for(let j of q)x.push(j.value);return x.length===0?{}:{p50:Te(x,50),p90:Te(x,90),p99:Te(x,99)}}return {incrementCounter(h,x={},E=1){$({name:h,type:"counter",value:E,labels:x,timestamp:Date.now()});},setGauge(h,x,E={}){$({name:h,type:"gauge",value:x,labels:E,timestamp:Date.now()});},observeHistogram(h,x,E={}){$({name:h,type:"histogram",value:x,labels:E,timestamp:Date.now()});},startSpan(h,x){if(Math.random()>N)return {traceId:"sampled-out",spanId:"sampled-out",operationName:h,serviceName:s,startTime:Date.now(),status:"ok",tags:{},logs:[]};let E={traceId:x?C.get(x)?.traceId??ve():ve(),spanId:ve(),parentSpanId:x,operationName:h,serviceName:s,startTime:Date.now(),status:"ok",tags:{},logs:[]};return I&&(C.set(E.spanId,E),l.onSpanStart?.(E)),E},endSpan(h,x="ok"){if(h==="sampled-out")return;let E=C.get(h);if(E){for(E.endTime=Date.now(),E.duration=E.endTime-E.startTime,E.status=x,C.delete(h),T.push(E);T.length>R;)T.shift();$({name:`${E.operationName}.latency`,type:"histogram",value:E.duration,labels:{},timestamp:Date.now()}),x==="error"&&$({name:`${E.operationName}.errors`,type:"counter",value:1,labels:{},timestamp:Date.now()}),l.onSpanEnd?.(E);}},addSpanLog(h,x,E="info"){if(h==="sampled-out")return;let q=C.get(h);q&&q.logs.push({timestamp:Date.now(),message:x,level:E});},addSpanTag(h,x,E){if(h==="sampled-out")return;let q=C.get(h);q&&(q.tags[x]=E);},getDashboard(){let h=O.get(t.requests),x=O.get(t.errors),E=O.get(t.latency),q=O.get(t.tokens),j=O.get(t.cost),u=h?.sum??0,M=x?.sum??0,S=u>0?M/u:0,A=E?H(t.latency):{};return {service:{name:s,uptime:Date.now()-g,startTime:g},metrics:Object.fromEntries(O),traces:[...T].slice(-100),alerts:[...P].slice(-50),summary:{totalRequests:u,totalErrors:M,errorRate:S,avgLatency:E?.avg??0,p99Latency:A.p99??0,activeSpans:C.size,totalTokens:q?.sum??0,totalCost:j?.sum??0}}},getMetric(h){let x=O.get(h);if(!x)return;let E=H(h);return {...x,...E}},getTraces(h=100){return [...T].slice(-h)},getAlerts(){return [...P]},export(){return {metrics:Array.from(O.values()),traces:[...T],alerts:[...P]}},clear(){f.clear(),O.clear(),C.clear(),T.length=0,P.length=0,F.clear();},async destroy(){Y&&(clearInterval(Y),Y=void 0);try{d&&i&&O.size>0&&await d(Array.from(O.values())),w&&I&&T.length>0&&await w([...T]);}catch(h){console.error("[Directive Observability] Error flushing data during destroy:",h);}f.clear(),O.clear(),C.clear(),T.length=0,P.length=0,F.clear();},getHealthStatus(){let h=O.get(t.requests),x=O.get(t.errors),E=h?.sum??0,q=x?.sum??0,j=E>0?q/E:0,u=P.filter(M=>Date.now()-M.timestamp<3e5).length;return {healthy:j<.1&&u===0,uptime:Date.now()-g,errorRate:j,activeAlerts:u}}}}function St(e){return {trackRun(s,o){let r={agent:s};e.incrementCounter("agent.requests",r),o.success||e.incrementCounter("agent.errors",r),e.observeHistogram("agent.latency",o.latencyMs,r),o.inputTokens!==void 0&&(e.incrementCounter("agent.tokens.input",r,o.inputTokens),e.incrementCounter("agent.tokens",r,o.inputTokens)),o.outputTokens!==void 0&&(e.incrementCounter("agent.tokens.output",r,o.outputTokens),e.incrementCounter("agent.tokens",r,o.outputTokens)),o.cost!==void 0&&e.incrementCounter("agent.cost",r,o.cost),o.toolCalls!==void 0&&e.incrementCounter("agent.tool_calls",r,o.toolCalls);},trackGuardrail(s,o){let r={guardrail:s};e.incrementCounter("guardrail.checks",r),o.passed||e.incrementCounter("guardrail.failures",r),o.blocked&&e.incrementCounter("guardrail.blocks",r),e.observeHistogram("guardrail.latency",o.latencyMs,r);},trackApproval(s,o){let r={tool:s};e.incrementCounter("approval.requests",r),o.approved?e.incrementCounter("approval.approved",r):e.incrementCounter("approval.rejected",r),o.timedOut&&e.incrementCounter("approval.timeouts",r),e.observeHistogram("approval.wait_time",o.waitTimeMs,r);},trackHandoff(s,o,r){e.incrementCounter("handoff.count",{from:s,to:o}),e.observeHistogram("handoff.latency",r);}}}function xt(e){let s=[{key:"service.name",value:{stringValue:e.serviceName??"directive-agents"}}];if(e.serviceVersion&&s.push({key:"service.version",value:{stringValue:e.serviceVersion}}),e.resourceAttributes)for(let[o,r]of Object.entries(e.resourceAttributes))s.push({key:o,value:{stringValue:r}});return {attributes:s}}function ne(e){return `${BigInt(e)*BigInt(1e6)}`}function Et(e){switch(e){case "counter":return "sum";case "gauge":return "gauge";case "histogram":return "histogram";default:return "gauge"}}function Ct(e,s,o){let r=e.map(a=>{let p=a.lastUpdated-6e4,l=[{asInt:a.type==="counter"?a.sum:void 0,asDouble:a.type!=="counter"?a.lastValue:void 0,timeUnixNano:ne(a.lastUpdated),startTimeUnixNano:ne(p),attributes:[]}],t=Et(a.type),i={name:a.name,unit:""};return t==="sum"?i.sum={dataPoints:l,aggregationTemporality:2,isMonotonic:true}:t==="histogram"?i.histogram={dataPoints:[{count:a.count,sum:a.sum,min:a.min,max:a.max,timeUnixNano:ne(a.lastUpdated),startTimeUnixNano:ne(p),attributes:[]}],aggregationTemporality:2}:i.gauge={dataPoints:l},i});return {resourceMetrics:[{resource:s,scopeMetrics:[{scope:{name:"directive",version:o},metrics:r}]}]}}function wt(e,s,o){let r=e.map(a=>{let p=a.logs.map(i=>({timeUnixNano:ne(i.timestamp),name:i.level,attributes:[{key:"message",value:{stringValue:i.message}},{key:"level",value:{stringValue:i.level}}]})),l=Object.entries(a.tags).map(([i,c])=>({key:i,value:typeof c=="string"?{stringValue:c}:typeof c=="number"?{intValue:`${c}`}:{boolValue:c}})),t=a.status==="ok"?1:a.status==="error"?2:0;return {traceId:a.traceId.replace(/-/g,"").padEnd(32,"0").slice(0,32),spanId:a.spanId.replace(/-/g,"").padEnd(16,"0").slice(0,16),parentSpanId:a.parentSpanId?a.parentSpanId.replace(/-/g,"").padEnd(16,"0").slice(0,16):void 0,name:a.operationName,kind:1,startTimeUnixNano:ne(a.startTime),endTimeUnixNano:a.endTime?ne(a.endTime):ne(a.startTime),attributes:l,events:p,status:{code:t}}});return {resourceSpans:[{resource:s,scopeSpans:[{scope:{name:"directive",version:o},spans:r}]}]}}function Mt(e){let{endpoint:s,headers:o={},scopeVersion:r="0.1.0",timeoutMs:a=1e4,fetch:p=globalThis.fetch,onError:l}=e;try{let c=new URL(s);if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error("[Directive] Only http: and https: protocols are supported")}catch(c){throw new Error(`[Directive OTLP] Invalid endpoint URL "${s}": ${c instanceof Error?c.message:String(c)}`)}if(/\/v1\/(metrics|traces)/.test(s)&&console.warn(`[Directive OTLP] Endpoint "${s}" already contains a /v1/metrics or /v1/traces path. The exporter will append /v1/metrics or /v1/traces automatically. Use the base URL (e.g., "http://localhost:4318") instead.`),a<=0||!Number.isFinite(a))throw new Error(`[Directive OTLP] timeoutMs must be > 0, got ${a}`);let t=xt(e);async function i(c,d,y){let I=`${s.replace(/\/$/,"")}${c}`,N=new AbortController,R=setTimeout(()=>N.abort(),a);try{let w=await p(I,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify(d),signal:N.signal});if(!w.ok)throw new Error(`[Directive] OTLP export failed: ${w.status} ${w.statusText}`)}catch(w){let g=w instanceof Error?w:new Error(String(w));l?l(g,y):console.error(`[Directive OTLP] Export ${y} error:`,g.message);}finally{clearTimeout(R);}}return {async exportMetrics(c){if(c.length===0)return;let d=Ct(c,t,r);await i("/v1/metrics",d,"metrics");},async exportTraces(c){if(c.length===0)return;let d=wt(c,t,r);await i("/v1/traces",d,"traces");}}}var me=class extends Error{code="CIRCUIT_OPEN";retryAfterMs;state;constructor(s,o,r="OPEN",a){let p=a?`[Directive CircuitBreaker] Circuit "${s}" is ${r}. ${a}`:`[Directive CircuitBreaker] Circuit "${s}" is ${r}. Request rejected. Try again in ${Math.ceil(o/1e3)}s.`;super(p),this.name="CircuitBreakerOpenError",this.retryAfterMs=o,this.state=r;}};function Tt(e={}){let{failureThreshold:s=5,recoveryTimeMs:o=3e4,halfOpenMaxRequests:r=3,failureWindowMs:a=6e4,observability:p,metricPrefix:l="circuit_breaker",name:t="default",isFailure:i=()=>true,onStateChange:c}=e;if(s<1||!Number.isFinite(s))throw new Error(`[Directive CircuitBreaker] failureThreshold must be >= 1, got ${s}`);if(o<=0||!Number.isFinite(o))throw new Error(`[Directive CircuitBreaker] recoveryTimeMs must be > 0, got ${o}`);if(r<1||!Number.isFinite(r))throw new Error(`[Directive CircuitBreaker] halfOpenMaxRequests must be >= 1, got ${r}`);if(a<=0||!Number.isFinite(a))throw new Error(`[Directive CircuitBreaker] failureWindowMs must be > 0, got ${a}`);let d="CLOSED",y=[],I=0,N=0,R=Date.now(),w=0,g=0,f=0,C=0,T=0,P=null,F=null;function O(_){if(d===_)return;let H=d;d=_,R=Date.now(),_==="OPEN"&&(w=Date.now()),_==="HALF_OPEN"&&(I=0,N=0),c?.(H,_),p&&p.incrementCounter(`${l}.state_change`,{name:t,from:H,to:_});}function Y(){let _=Date.now()-a;return y=y.filter(H=>H>_),y.length}function $(){C++,F=Date.now(),p&&p.incrementCounter(`${l}.success`,{name:t}),d==="HALF_OPEN"&&(N++,N>=r&&(O("CLOSED"),y=[]));}function V(_){if(!i(_)){$();return}f++,P=Date.now(),y.push(Date.now());let H=s*2;if(y.length>H&&(y=y.slice(-H)),p&&p.incrementCounter(`${l}.failure`,{name:t}),d==="HALF_OPEN"){O("OPEN");return}d==="CLOSED"&&Y()>=s&&O("OPEN");}return {async execute(_){if(g++,p&&p.incrementCounter(`${l}.requests`,{name:t}),d==="OPEN")if(Date.now()-w>=o)O("HALF_OPEN");else throw T++,p&&p.incrementCounter(`${l}.rejected`,{name:t}),new me(t,o-(Date.now()-w));if(d==="HALF_OPEN"){if(I>=r)throw T++,new me(t,o,"HALF_OPEN",`Max trial requests (${r}) reached.`);I++;}let H=Date.now();try{let h=await _();return $(),p&&p.observeHistogram(`${l}.latency`,Date.now()-H,{name:t}),h}catch(h){let x=h instanceof Error?h:new Error(String(h));throw V(x),p&&p.observeHistogram(`${l}.latency`,Date.now()-H,{name:t}),h}},getState(){return d==="OPEN"&&Date.now()-w>=o&&O("HALF_OPEN"),d},getStats(){return {state:this.getState(),totalRequests:g,totalFailures:f,totalSuccesses:C,totalRejected:T,recentFailures:Y(),lastFailureTime:P,lastSuccessTime:F,lastStateChange:R}},forceState(_){O(_);},reset(){let _=d;d="CLOSED",y=[],I=0,N=0,R=Date.now(),w=0,g=0,f=0,C=0,T=0,P=null,F=null,_!=="CLOSED"&&c?.(_,"CLOSED");},isAllowed(){return d==="CLOSED"?true:d==="OPEN"?Date.now()-w>=o:I<r}}}
export{b as createAuditLedger,a as memorySink}from'../chunk-PA6VC32N.js';import'../chunk-2FF6QGOA.js';import {f}from'../chunk-PXRV64PA.js';var Oe={debug:0,info:1,warn:2,error:3};function st(e={}){let{level:s="info",filter:o=()=>true,logger:r=console,prefix:a="[Directive]"}=e,p=Oe[s],l=(t,i,...c)=>{Oe[t]<p||o(i)&&r[t](`${a} ${i}`,...c);};return {name:"logging",onInit:()=>l("debug","init"),onStart:()=>l("info","start"),onStop:()=>l("info","stop"),onDestroy:()=>l("debug","destroy"),onFactSet:(t,i,c)=>{l("debug","fact.set",{key:t,value:i,prev:c});},onFactDelete:(t,i)=>{l("debug","fact.delete",{key:t,prev:i});},onFactsBatch:t=>{l("debug","facts.batch",{count:t.length,changes:t});},onDerivationCompute:(t,i,c)=>{l("debug","derivation.compute",{id:t,value:i,deps:c});},onDerivationInvalidate:t=>{l("debug","derivation.invalidate",{id:t});},onReconcileStart:()=>{l("debug","reconcile.start");},onReconcileEnd:t=>{l("debug","reconcile.end",{unmet:t.unmet.length,inflight:t.inflight.length,completed:t.completed.length,canceled:t.canceled.length});},onConstraintEvaluate:(t,i,c)=>{if(c){let d=c.filter(y=>y.pass).length;l("debug","constraint.evaluate",{id:t,active:i,clauses:{total:c.length,passed:d}});return}l("debug","constraint.evaluate",{id:t,active:i});},onConstraintError:(t,i)=>{l("error","constraint.error",{id:t,error:i});},onRequirementCreated:t=>{l("debug","requirement.created",{id:t.id,type:t.requirement.type});},onRequirementMet:(t,i)=>{l("info","requirement.met",{id:t.id,byResolver:i});},onRequirementCanceled:t=>{l("debug","requirement.canceled",{id:t.id});},onResolverStart:(t,i)=>{l("debug","resolver.start",{resolver:t,requirementId:i.id});},onResolverComplete:(t,i,c)=>{l("info","resolver.complete",{resolver:t,requirementId:i.id,duration:c});},onResolverError:(t,i,c)=>{l("error","resolver.error",{resolver:t,requirementId:i.id,error:c});},onResolverRetry:(t,i,c)=>{l("warn","resolver.retry",{resolver:t,requirementId:i.id,attempt:c});},onResolverCancel:(t,i)=>{l("debug","resolver.cancel",{resolver:t,requirementId:i.id});},onResolverWriteRejected:t=>{l("warn","resolver.write.rejected",t.kind==="summary"?{kind:t.kind,resolver:t.resolver,requirementId:t.req.id,reason:t.reason,dropped:t.dropped}:{kind:t.kind,resolver:t.resolver,requirementId:t.req.id,reason:t.reason,fact:t.fact,expected:t.expected,actual:t.actual});},onEffectRun:t=>{l("debug","effect.run",{id:t});},onEffectError:(t,i)=>{l("error","effect.error",{id:t,error:i});},onSnapshot:t=>{l("debug","timetravel.snapshot",{id:t.id,trigger:t.trigger});},onHistoryNavigate:(t,i)=>{l("info","timetravel.jump",{from:t,to:i});},onError:t=>{l("error","error",{source:t.source,sourceId:t.sourceId,message:t.message});},onErrorRecovery:(t,i)=>{l("warn","error.recovery",{source:t.source,sourceId:t.sourceId,strategy:i});},onDefinitionRegister:(t,i)=>{l("info","definition.register",{type:t,id:i});},onDefinitionAssign:(t,i)=>{l("info","definition.assign",{type:t,id:i});},onDefinitionUnregister:(t,i)=>{l("info","definition.unregister",{type:t,id:i});},onDefinitionCall:(t,i,c)=>{l("debug","definition.call",{type:t,id:i,props:c});},onTraceComplete:t=>{l("debug","trace.complete",{id:t.id,status:t.status,duration:t.duration,factChanges:t.factChanges.length,derivationsRecomputed:t.derivationsRecomputed.length,constraintsHit:t.constraintsHit.length,resolversStarted:t.resolversStarted.length,effectsRun:t.effectsRun.length});}}}var ue=class{constructor(s){this.capacity=s;this.buf=new Array(s);}buf;head=0;_size=0;get size(){return this._size}push(s){this.buf[this.head]=s,this.head=(this.head+1)%this.capacity,this._size<this.capacity&&this._size++;}toArray(){return this._size===0?[]:this._size<this.capacity?this.buf.slice(0,this._size):[...this.buf.slice(this.head),...this.buf.slice(0,this.head)]}clear(){this.buf=new Array(this.capacity),this.head=0,this._size=0;}};function ge(){try{if(typeof process<"u"&&process.env?.NODE_ENV==="production")return !1}catch{}try{if(typeof import.meta<"u"&&import.meta.env?.MODE==="production")return !1}catch{}return true}function fe(e){try{if(e===void 0)return "undefined";if(e===null)return "null";if(typeof e=="bigint")return String(e)+"n";if(typeof e=="symbol")return String(e);if(typeof e=="object"){let s=JSON.stringify(e,(o,r)=>typeof r=="bigint"?String(r)+"n":typeof r=="symbol"?String(r):r);return s.length>120?s.slice(0,117)+"...":s}return String(e)}catch{return "<error>"}}function ee(e,s){return e.length<=s?e:e.slice(0,s-3)+"..."}function se(e){try{return e.inspect()}catch{return null}}function Le(e){try{return e==null||typeof e!="object"?e:JSON.parse(JSON.stringify(e))}catch{return null}}function Pe(e){return e===void 0?1e3:!Number.isFinite(e)||e<1?(ge()&&console.warn(`[directive:devtools] Invalid maxEvents value (${e}), using default 1000`),1e3):Math.floor(e)}function Ie(){return {reconcileCount:0,reconcileTotalMs:0,resolverStats:new Map,effectRunCount:0,effectErrorCount:0,lastReconcileStartMs:0}}var it=200,ie=340,ae=16,ce=80,he=2,Se=["#8b9aff","#4ade80","#fbbf24","#c084fc","#f472b6","#22d3ee"];function $e(){return {entries:new ue(it),inflight:new Map}}function _e(){return {derivationDeps:new Map,activeConstraints:new Set,recentlyChangedFacts:new Set,recentlyComputedDerivations:new Set,recentlyActiveConstraints:new Set,animationTimer:null}}var Ne=1e4,Be=100;function je(){return {isRecording:false,recordedEvents:[],snapshots:[]}}var He=50,xe=200,b={bg:"#1a1a2e",text:"#e0e0e0",accent:"#8b9aff",muted:"#b0b0d0",border:"#333",rowBorder:"#2a2a4a",green:"#4ade80",yellow:"#fbbf24",red:"#f87171",closeBtn:"#aaa",font:"ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace"},G={nodeW:90,nodeH:16,nodeGap:6,startY:16,colGap:20,fontSize:10,labelMaxChars:11};function Ve(e,s,o,r){let a=false,p={position:"fixed",zIndex:"99999",...s.includes("bottom")?{bottom:"12px"}:{top:"12px"},...s.includes("right")?{right:"12px"}:{left:"12px"}},l=document.createElement("style");l.textContent=`[data-directive-devtools] summary:focus-visible{outline:2px solid ${b.accent};outline-offset:2px;border-radius:2px}[data-directive-devtools] button:focus-visible{outline:2px solid ${b.accent};outline-offset:2px}`,document.head.appendChild(l);let t=document.createElement("button");t.setAttribute("aria-label","Open Directive DevTools"),t.setAttribute("aria-expanded",String(o)),t.title="Ctrl+Shift+D to toggle",Object.assign(t.style,{...p,background:b.bg,color:b.text,border:`1px solid ${b.border}`,borderRadius:"6px",padding:"10px 14px",minWidth:"44px",minHeight:"44px",cursor:"pointer",fontFamily:b.font,fontSize:"12px",display:o?"none":"block"}),t.textContent="Directive";let i=document.createElement("div");i.setAttribute("role","region"),i.setAttribute("aria-label","Directive DevTools"),i.setAttribute("data-directive-devtools",""),i.tabIndex=-1,Object.assign(i.style,{...p,background:b.bg,color:b.text,border:`1px solid ${b.border}`,borderRadius:"8px",padding:"12px",fontFamily:b.font,fontSize:"11px",maxWidth:"min(380px, calc(100vw - 24px))",maxHeight:"min(500px, calc(100vh - 24px))",overflow:"auto",boxShadow:"0 4px 20px rgba(0,0,0,0.5)",display:o?"block":"none"});let c=document.createElement("div");Object.assign(c.style,{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"8px"});let d=document.createElement("strong");d.style.color=b.accent,d.textContent=e==="default"?"Directive DevTools":`DevTools (${e})`;let y=document.createElement("button");y.setAttribute("aria-label","Close DevTools"),Object.assign(y.style,{background:"none",border:"none",color:b.closeBtn,cursor:"pointer",fontSize:"16px",padding:"8px 12px",minWidth:"44px",minHeight:"44px",lineHeight:"1",display:"flex",alignItems:"center",justifyContent:"center"}),y.textContent="\xD7",c.appendChild(d),c.appendChild(y),i.appendChild(c);let I=document.createElement("div");I.style.marginBottom="6px",I.setAttribute("aria-live","polite");let N=document.createElement("span");N.style.color=b.green,N.textContent="Settled",I.appendChild(N),i.appendChild(I);let R=document.createElement("div");Object.assign(R.style,{display:"none",marginBottom:"8px",padding:"4px 8px",background:"#252545",borderRadius:"4px",alignItems:"center",gap:"6px"});let w=document.createElement("button");Object.assign(w.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"4px 10px",borderRadius:"3px",fontFamily:b.font,fontSize:"11px",minWidth:"44px",minHeight:"44px"}),w.textContent="\u25C0 Undo",w.disabled=true;let g=document.createElement("button");Object.assign(g.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"4px 10px",borderRadius:"3px",fontFamily:b.font,fontSize:"11px",minWidth:"44px",minHeight:"44px"}),g.textContent="Redo \u25B6",g.disabled=true;let f=document.createElement("span");f.style.color=b.muted,f.style.fontSize="10px",R.appendChild(w),R.appendChild(g),R.appendChild(f),i.appendChild(R);function C(z,K){let X=document.createElement("details");K&&(X.open=true),X.style.marginBottom="4px";let J=document.createElement("summary");Object.assign(J.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"});let Q=document.createElement("span");J.textContent=`${z} (`,J.appendChild(Q),J.appendChild(document.createTextNode(")")),Q.textContent="0",X.appendChild(J);let te=document.createElement("table");Object.assign(te.style,{width:"100%",borderCollapse:"collapse",fontSize:"11px"});let Re=document.createElement("thead"),De=document.createElement("tr");for(let nt of ["Key","Value"]){let pe=document.createElement("th");pe.scope="col",Object.assign(pe.style,{textAlign:"left",padding:"2px 4px",color:b.accent}),pe.textContent=nt,De.appendChild(pe);}Re.appendChild(De),te.appendChild(Re);let Ae=document.createElement("tbody");return te.appendChild(Ae),X.appendChild(te),{details:X,tbody:Ae,countSpan:Q}}function T(z,K){let X=document.createElement("details");X.style.marginBottom="4px";let J=document.createElement("summary");Object.assign(J.style,{cursor:"pointer",color:K,marginBottom:"4px"});let Q=document.createElement("span");J.textContent=`${z} (`,J.appendChild(Q),J.appendChild(document.createTextNode(")")),Q.textContent="0",X.appendChild(J);let te=document.createElement("ul");return Object.assign(te.style,{margin:"0",paddingLeft:"16px"}),X.appendChild(te),{details:X,list:te,countSpan:Q}}let P=C("Facts",true);i.appendChild(P.details);let F=C("Derivations",false);i.appendChild(F.details);let O=T("Inflight",b.yellow);i.appendChild(O.details);let Y=T("Unmet",b.red);i.appendChild(Y.details);let $=document.createElement("details");$.style.marginBottom="4px";let V=document.createElement("summary");Object.assign(V.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),V.textContent="Performance",$.appendChild(V);let _=document.createElement("div");_.style.fontSize="10px",_.style.color=b.muted,_.textContent="No data yet",$.appendChild(_),i.appendChild($);let H=document.createElement("details");H.style.marginBottom="4px";let h=document.createElement("summary");Object.assign(h.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),h.textContent="Dependency Graph",H.appendChild(h);let x=document.createElementNS("http://www.w3.org/2000/svg","svg");x.setAttribute("width","100%"),x.setAttribute("height","120"),x.setAttribute("role","img"),x.setAttribute("aria-label","System dependency graph"),x.style.display="block",x.setAttribute("viewBox","0 0 460 120"),x.setAttribute("preserveAspectRatio","xMinYMin meet"),H.appendChild(x),i.appendChild(H);let E=document.createElement("details");E.style.marginBottom="4px";let q=document.createElement("summary");Object.assign(q.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),q.textContent="Timeline",E.appendChild(q);let j=document.createElementNS("http://www.w3.org/2000/svg","svg");j.setAttribute("width","100%"),j.setAttribute("height","60"),j.setAttribute("role","img"),j.setAttribute("aria-label","Resolver execution timeline"),j.style.display="block",j.setAttribute("viewBox",`0 0 ${ie} 60`),j.setAttribute("preserveAspectRatio","xMinYMin meet");let u=document.createElementNS("http://www.w3.org/2000/svg","text");u.setAttribute("x",String(ie/2)),u.setAttribute("y","30"),u.setAttribute("text-anchor","middle"),u.setAttribute("fill",b.muted),u.setAttribute("font-size","10"),u.setAttribute("font-family",b.font),u.textContent="No resolver activity yet",j.appendChild(u),E.appendChild(j),i.appendChild(E);let M=(()=>{let z=document.createElement("details");z.style.marginBottom="4px";let K=document.createElement("summary");Object.assign(K.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"});let X=document.createElement("span");X.textContent="0",K.textContent="Constraints (",K.appendChild(X),K.appendChild(document.createTextNode(")")),z.appendChild(K);let J=document.createElement("div");Object.assign(J.style,{fontSize:"11px"});let Q=document.createElement("div");return Q.style.color=b.muted,Q.style.padding="4px",Q.style.fontStyle="italic",Q.textContent="Waiting for first evaluation\u2026",Q.className="dt-constraints-empty",J.appendChild(Q),z.appendChild(J),i.appendChild(z),{details:z,body:J,countSpan:X}})(),S,A,W,k;if(r){let z=document.createElement("details");z.style.marginBottom="4px";let K=document.createElement("summary");Object.assign(K.style,{cursor:"pointer",color:b.accent,marginBottom:"4px"}),W=document.createElement("span"),W.textContent="0",K.textContent="Events (",K.appendChild(W),K.appendChild(document.createTextNode(")")),z.appendChild(K),A=document.createElement("div"),Object.assign(A.style,{maxHeight:"150px",overflow:"auto",fontSize:"10px"}),A.setAttribute("role","log"),A.setAttribute("aria-live","polite"),A.tabIndex=0;let X=document.createElement("div");X.style.color=b.muted,X.style.padding="4px",X.textContent="Waiting for events...",X.className="dt-events-empty",A.appendChild(X),z.appendChild(A),i.appendChild(z),S=z,k=document.createElement("div");}else S=document.createElement("details"),A=document.createElement("div"),W=document.createElement("span"),k=document.createElement("div"),k.style.fontSize="10px",k.style.color=b.muted,k.style.marginTop="4px",k.style.fontStyle="italic",k.textContent="Enable trace: true for event log",i.appendChild(k);let L=document.createElement("div");Object.assign(L.style,{display:"flex",gap:"6px",marginTop:"6px"});let n=document.createElement("button");Object.assign(n.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"8px 12px",borderRadius:"3px",fontFamily:b.font,fontSize:"10px",minWidth:"44px",minHeight:"44px"}),n.textContent="\u23FA Record";let m=document.createElement("button");Object.assign(m.style,{background:"none",border:`1px solid ${b.border}`,color:b.text,cursor:"pointer",padding:"8px 12px",borderRadius:"3px",fontFamily:b.font,fontSize:"10px",minWidth:"44px",minHeight:"44px"}),m.textContent="\u2913 Export",L.appendChild(n),L.appendChild(m),i.appendChild(L),i.addEventListener("wheel",z=>{let K=i,X=K.scrollTop===0&&z.deltaY<0,J=K.scrollTop+K.clientHeight>=K.scrollHeight&&z.deltaY>0;(X||J)&&z.preventDefault();},{passive:false});let v=o,D=new Set;function B(){v=true,i.style.display="block",t.style.display="none",t.setAttribute("aria-expanded","true"),y.focus();}function U(){v=false,i.style.display="none",t.style.display="block",t.setAttribute("aria-expanded","false"),t.focus();}t.addEventListener("click",B),y.addEventListener("click",U);function Z(z){z.key==="Escape"&&v&&U();}i.addEventListener("keydown",Z);function re(z){z.key==="d"&&z.shiftKey&&(z.ctrlKey||z.metaKey)&&(z.preventDefault(),v?U():B());}document.addEventListener("keydown",re);function oe(){a||(document.body.appendChild(t),document.body.appendChild(i));}document.body?oe():document.addEventListener("DOMContentLoaded",oe,{once:true});function le(){a=true,t.removeEventListener("click",B),y.removeEventListener("click",U),i.removeEventListener("keydown",Z),document.removeEventListener("keydown",re),document.removeEventListener("DOMContentLoaded",oe);for(let z of D)clearTimeout(z);D.clear(),t.remove(),i.remove(),l.remove();}return {refs:{container:i,toggleBtn:t,titleEl:d,statusEl:N,factsBody:P.tbody,factsCount:P.countSpan,derivBody:F.tbody,derivCount:F.countSpan,derivSection:F.details,inflightList:O.list,inflightSection:O.details,inflightCount:O.countSpan,unmetList:Y.list,unmetSection:Y.details,unmetCount:Y.countSpan,perfSection:$,perfBody:_,historySection:R,historyLabel:f,undoBtn:w,redoBtn:g,flowSection:H,flowSvg:x,timelineSection:E,timelineSvg:j,eventsSection:S,eventsList:A,eventsCount:W,traceHint:k,recordBtn:n,exportBtn:m,constraintsSection:M.details,constraintsBody:M.body,constraintsCount:M.countSpan},destroy:le,isOpen:()=>v,flashTimers:D}}function de(e,s,o,r,a,p){let l=fe(r),t=e.get(o);if(t){let i=t.cells;if(i[1]&&(i[1].textContent=l,a&&p)){let c=i[1];c.style.background="rgba(139, 154, 255, 0.25)";let d=setTimeout(()=>{c.style.background="",p.delete(d);},300);p.add(d);}}else {t=document.createElement("tr"),t.style.borderBottom=`1px solid ${b.rowBorder}`;let i=document.createElement("td");Object.assign(i.style,{padding:"2px 4px",color:b.muted}),i.textContent=o;let c=document.createElement("td");c.style.padding="2px 4px",c.textContent=l,t.appendChild(i),t.appendChild(c),s.appendChild(t),e.set(o,t);}}function ze(e,s){let o=e.get(s);o&&(o.remove(),e.delete(s));}function be(e,s,o){if(e.inflightList.replaceChildren(),e.inflightCount.textContent=String(s.length),s.length>0)for(let r of s){let a=document.createElement("li");a.style.fontSize="11px",a.textContent=`${r.resolverId} (${r.id})`,e.inflightList.appendChild(a);}else {let r=document.createElement("li");r.style.fontSize="10px",r.style.color=b.muted,r.textContent="None",e.inflightList.appendChild(r);}if(e.unmetList.replaceChildren(),e.unmetCount.textContent=String(o.length),o.length>0)for(let r of o){let a=document.createElement("li");a.style.fontSize="11px",a.textContent=`${r.requirement.type} from ${r.fromConstraint}`,e.unmetList.appendChild(a);}else {let r=document.createElement("li");r.style.fontSize="10px",r.style.color=b.muted,r.textContent="None",e.unmetList.appendChild(r);}}function ye(e,s,o){let r=s===0&&o===0;e.statusEl.style.color=r?b.green:b.yellow,e.statusEl.textContent=r?"Settled":"Working...",e.toggleBtn.textContent=r?"Directive":"Directive...",e.toggleBtn.setAttribute("aria-label",`Open Directive DevTools${r?"":" (system working)"}`);}function Ee(e,s,o,r){let a=Object.keys(o.derive);if(e.derivCount.textContent=String(a.length),a.length===0){s.clear(),e.derivBody.replaceChildren();let l=document.createElement("tr"),t=document.createElement("td");t.colSpan=2,t.style.color=b.muted,t.style.fontSize="10px",t.textContent="No derivations defined",l.appendChild(t),e.derivBody.appendChild(l);return}let p=new Set(a);for(let[l,t]of s)p.has(l)||(t.remove(),s.delete(l));for(let l of a){let t;try{t=fe(o.read(l));}catch{t="<error>";}de(s,e.derivBody,l,t,true,r);}}function We(e,s,o,r){let a=e.eventsList.querySelector(".dt-events-empty");a&&a.remove();let p=document.createElement("div");Object.assign(p.style,{padding:"2px 4px",borderBottom:`1px solid ${b.rowBorder}`,fontFamily:"inherit"});let l=new Date,t=`${String(l.getHours()).padStart(2,"0")}:${String(l.getMinutes()).padStart(2,"0")}:${String(l.getSeconds()).padStart(2,"0")}.${String(l.getMilliseconds()).padStart(3,"0")}`,i;try{let I=JSON.stringify(o);i=ee(I,60);}catch{i="{}";}let c=document.createElement("span");c.style.color=b.closeBtn,c.textContent=t;let d=document.createElement("span");d.style.color=b.accent,d.textContent=` ${s} `;let y=document.createElement("span");for(y.style.color=b.muted,y.textContent=i,p.appendChild(c),p.appendChild(d),p.appendChild(y),e.eventsList.prepend(p);e.eventsList.childElementCount>He;)e.eventsList.lastElementChild?.remove();e.eventsCount.textContent=String(r);}function Ue(e,s){e.perfBody.replaceChildren();let o=s.reconcileCount>0?(s.reconcileTotalMs/s.reconcileCount).toFixed(1):"\u2014",r=[`Reconciles: ${s.reconcileCount} (avg ${o}ms)`,`Effects: ${s.effectRunCount} run, ${s.effectErrorCount} errors`];for(let a of r){let p=document.createElement("div");p.style.marginBottom="2px",p.textContent=a,e.perfBody.appendChild(p);}if(s.resolverStats.size>0){let a=document.createElement("div");a.style.marginTop="4px",a.style.marginBottom="2px",a.style.color=b.accent,a.textContent="Resolvers:",e.perfBody.appendChild(a);let p=[...s.resolverStats.entries()].sort((l,t)=>t[1].totalMs-l[1].totalMs);for(let[l,t]of p){let i=t.count>0?(t.totalMs/t.count).toFixed(1):"0",c=document.createElement("div");c.style.paddingLeft="8px",c.textContent=`${l}: ${t.count}x, avg ${i}ms${t.errors>0?`, ${t.errors} err`:""}`,t.errors>0&&(c.style.color=b.red),e.perfBody.appendChild(c);}}}function Ce(e,s){let o=s.history;if(!o){e.historySection.style.display="none";return}e.historySection.style.display="flex";let r=o.currentIndex,a=o.snapshots.length;e.historyLabel.textContent=a>0?`${r+1} / ${a}`:"0 snapshots";let p=r>0,l=r<a-1;e.undoBtn.disabled=!p,e.undoBtn.style.opacity=p?"1":"0.4",e.redoBtn.disabled=!l,e.redoBtn.style.opacity=l?"1":"0.4";}function Ge(e,s){e.undoBtn.addEventListener("click",()=>{s.history&&s.history.currentIndex>0&&s.history.goBack(1);}),e.redoBtn.addEventListener("click",()=>{s.history&&s.history.currentIndex<s.history.snapshots.length-1&&s.history.goForward(1);});}var qe=Object.assign(Object.create(null),{$eq:"=",$ne:"\u2260",$gt:">",$gte:"\u2265",$lt:"<",$lte:"\u2264",$in:"\u2208",$nin:"\u2209",$exists:"exists",$between:"in",$startsWith:"starts with",$endsWith:"ends with",$contains:"contains",$matches:"matches",$changed:"changed"});function at(e){return Object.hasOwn(qe,e)?qe[e]:e}function Fe(e){return e instanceof RegExp?ee(String(e),40):fe(e)}var ct=new Set(["$all","$any","$not"]);function Ye(e){let s=document.createElement("li"),o=e.pass?"\u2713":"\u2717";if(s.style.color=e.pass?b.green:b.red,s.style.listStyle="none",ct.has(e.op)){let r=e.path?` @ ${e.path}`:"";if(s.textContent=`${o} ${e.op}${r}`,e.children&&e.children.length>0){let a=document.createElement("ul");Object.assign(a.style,{margin:"0",paddingLeft:"14px",listStyle:"none"});for(let p of e.children)a.appendChild(Ye(p));s.appendChild(a);}}else {let r=at(e.op),a=Fe(e.expected);if(e.pass)s.textContent=`${o} ${e.path} ${r} ${a}`;else {let p=Fe(e.actual);s.textContent=`${o} ${e.path} ${r} ${a} (actual: ${p})`;}}return s}function Xe(e,s,o){let r=s.get(o);if(r&&(r.remove(),s.delete(o),e.constraintsCount.textContent=String(s.size)),s.size===0&&!e.constraintsBody.querySelector(".dt-constraints-empty")){let a=document.createElement("div");a.style.color=b.muted,a.style.padding="4px",a.style.fontStyle="italic",a.textContent="Waiting for first evaluation\u2026",a.className="dt-constraints-empty",e.constraintsBody.appendChild(a);}}function Ke(e,s){let o=e.constraintsBody.querySelector(".dt-constraints-empty");o&&(o.textContent=s?"Waiting for first evaluation\u2026":"This system has no constraints");}function Je(e,s,o,r,a,p){let l=e.constraintsBody.querySelector(".dt-constraints-empty");l&&l.remove();let t=s.get(o);t||(t=document.createElement("div"),Object.assign(t.style,{marginBottom:"6px",paddingBottom:"4px",borderBottom:`1px solid ${b.rowBorder}`}),s.set(o,t),e.constraintsBody.appendChild(t),e.constraintsCount.textContent=String(s.size)),t.replaceChildren();let i=document.createElement("div");Object.assign(i.style,{fontWeight:"bold",color:r?b.green:b.muted});let c=r?"\u2713":"\u2717";if(i.textContent=p?`${c} ${o} (${p})`:`${c} ${o}`,t.appendChild(i),a&&a.length>0){let d=document.createElement("ul");Object.assign(d.style,{margin:"2px 0 0 0",paddingLeft:"14px",listStyle:"none"});for(let y of a)d.appendChild(Ye(y));t.appendChild(d);}else if(!a){let d=document.createElement("div");Object.assign(d.style,{color:b.muted,fontSize:"10px",fontStyle:"italic",paddingLeft:"14px"}),d.textContent="function-form when (no clause tree)",t.appendChild(d);}}var we=new WeakMap;function lt(e,s,o,r,a,p){return [e.join(","),s.join(","),o.map(l=>`${l.id}:${l.active}`).join(","),[...r.entries()].map(([l,t])=>`${l}:${t.status}:${t.type}`).join(","),a.join(","),p.join(",")].join("|")}function ut(e,s,o,r,a){for(let p of o){let l=e.nodes.get(`0:${p}`);if(!l)continue;let t=s.recentlyChangedFacts.has(p);l.rect.setAttribute("fill",t?b.text+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}for(let p of r){let l=e.nodes.get(`1:${p}`);if(!l)continue;let t=s.recentlyComputedDerivations.has(p);l.rect.setAttribute("fill",t?b.accent+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}for(let p of a){let l=e.nodes.get(`2:${p}`);if(!l)continue;let t=s.recentlyActiveConstraints.has(p),i=l.rect.getAttribute("stroke")??b.muted;l.rect.setAttribute("fill",t?i+"33":"none"),l.rect.setAttribute("stroke-width",t?"2":"1");}}function Me(e,s,o){let r=se(s);if(!r)return;let a;try{a=Object.keys(s.facts.$store.toObject());}catch{a=[];}let p=Object.keys(s.derive),l=r.constraints,t=r.unmet,i=r.inflight,c=Object.keys(r.resolvers),d=new Map;for(let u of t)d.set(u.id,{type:u.requirement.type,fromConstraint:u.fromConstraint,status:"unmet"});for(let u of i)d.set(u.id,{type:u.resolverId,fromConstraint:"",status:"inflight"});if(a.length===0&&p.length===0&&l.length===0&&c.length===0){we.delete(e.flowSvg),e.flowSvg.replaceChildren(),e.flowSvg.setAttribute("viewBox","0 0 460 40");let u=document.createElementNS("http://www.w3.org/2000/svg","text");u.setAttribute("x","230"),u.setAttribute("y","24"),u.setAttribute("text-anchor","middle"),u.setAttribute("fill",b.muted),u.setAttribute("font-size","10"),u.setAttribute("font-family",b.font),u.textContent="No system topology",e.flowSvg.appendChild(u);return}let y=i.map(u=>u.resolverId).sort(),I=lt(a,p,l,d,c,y),N=we.get(e.flowSvg);if(N&&N.fingerprint===I){ut(N,o,a,p,l.map(u=>u.id));return}let R=G.nodeW+G.colGap,w=[5,5+R,5+R*2,5+R*3,5+R*4],g=w[4]+G.nodeW+5;function f(u){let M=G.startY+12;return u.map(S=>{let A={...S,y:M};return M+=G.nodeH+G.nodeGap,A})}let C=f(a.map(u=>{let M=r.facts.find(S=>S.key===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),T=f(p.map(u=>{let M=r.derivations.find(S=>S.id===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),P=f(l.map(u=>({id:u.id,label:ee(u.meta?.label??u.id,G.labelMaxChars),active:u.active,priority:u.priority}))),F=f([...d.entries()].map(([u,M])=>({id:u,type:M.type,fromConstraint:M.fromConstraint,status:M.status}))),O=f(c.map(u=>{let M=r.resolverDefs.find(S=>S.id===u);return {id:u,label:ee(M?.meta?.label??u,G.labelMaxChars)}})),Y=Math.max(C.length,T.length,P.length,F.length,O.length,1),$=G.startY+12+Y*(G.nodeH+G.nodeGap)+8;e.flowSvg.replaceChildren(),e.flowSvg.setAttribute("viewBox",`0 0 ${g} ${$}`),e.flowSvg.setAttribute("aria-label",`Dependency graph: ${a.length} facts, ${p.length} derivations, ${l.length} constraints, ${d.size} requirements, ${c.length} resolvers`);let V=["Facts","Derivations","Constraints","Reqs","Resolvers"];for(let[u,M]of V.entries()){let S=document.createElementNS("http://www.w3.org/2000/svg","text");S.setAttribute("x",String(w[u]??0)),S.setAttribute("y","10"),S.setAttribute("fill",b.accent),S.setAttribute("font-size",String(G.fontSize)),S.setAttribute("font-family",b.font),S.textContent=M,e.flowSvg.appendChild(S);}let _={fingerprint:I,nodes:new Map};function H(u,M,S,A,W,k,L,n,m){let v=document.createElementNS("http://www.w3.org/2000/svg","g");if(m){let U=document.createElementNS("http://www.w3.org/2000/svg","title");U.textContent=m,v.appendChild(U);}let D=document.createElementNS("http://www.w3.org/2000/svg","rect");D.setAttribute("x",String(M)),D.setAttribute("y",String(S-6)),D.setAttribute("width",String(G.nodeW)),D.setAttribute("height",String(G.nodeH)),D.setAttribute("rx","3"),D.setAttribute("fill",n?k+"33":"none"),D.setAttribute("stroke",k),D.setAttribute("stroke-width",n?"2":"1"),D.setAttribute("opacity",L?"0.35":"1"),v.appendChild(D);let B=document.createElementNS("http://www.w3.org/2000/svg","text");return B.setAttribute("x",String(M+4)),B.setAttribute("y",String(S+4)),B.setAttribute("fill",k),B.setAttribute("font-size",String(G.fontSize)),B.setAttribute("font-family",b.font),B.setAttribute("opacity",L?"0.35":"1"),B.textContent=W,v.appendChild(B),e.flowSvg.appendChild(v),_.nodes.set(`${u}:${A}`,{g:v,rect:D,text:B}),{midX:M+G.nodeW/2,midY:S}}function h(u,M,S,A,W,k){let L=document.createElementNS("http://www.w3.org/2000/svg","line");L.setAttribute("x1",String(u)),L.setAttribute("y1",String(M)),L.setAttribute("x2",String(S)),L.setAttribute("y2",String(A)),L.setAttribute("stroke",W),L.setAttribute("stroke-width","1"),L.setAttribute("stroke-dasharray","3,2"),L.setAttribute("opacity","0.7"),e.flowSvg.appendChild(L);}let x=new Map,E=new Map,q=new Map,j=new Map;for(let u of C){let M=o.recentlyChangedFacts.has(u.id),S=r.facts.find(W=>W.key===u.id)?.meta,A=H(0,w[0],u.y,u.id,u.label,b.text,false,M,S?.description);x.set(u.id,A);}for(let u of T){let M=o.recentlyComputedDerivations.has(u.id),S=r.derivations.find(W=>W.id===u.id)?.meta,A=H(1,w[1],u.y,u.id,u.label,b.accent,false,M,S?.description);E.set(u.id,A);}for(let u of P){let M=o.recentlyActiveConstraints.has(u.id),S=l.find(W=>W.id===u.id)?.meta,A=H(2,w[2],u.y,u.id,u.label,S?.color??(u.active?b.yellow:b.muted),!u.active,M,S?.description);q.set(u.id,A);}for(let u of F){let M=u.status==="unmet"?b.red:b.yellow,S=H(3,w[3],u.y,u.id,ee(u.type,G.labelMaxChars),M,false,false);j.set(u.id,S);}for(let u of O){let M=i.some(A=>A.resolverId===u.id),S=r.resolverDefs.find(A=>A.id===u.id)?.meta;H(4,w[4],u.y,u.id,u.label,S?.color??(M?b.green:b.muted),!M,false,S?.description);}for(let u of T){let M=o.derivationDeps.get(u.id),S=E.get(u.id);if(M&&S)for(let A of M){let W=x.get(A);W&&h(W.midX+G.nodeW/2,W.midY,S.midX-G.nodeW/2,S.midY,b.accent);}}for(let u of F){let M=q.get(u.fromConstraint),S=j.get(u.id);M&&S&&h(M.midX+G.nodeW/2,M.midY,S.midX-G.nodeW/2,S.midY,b.muted);}for(let u of i){let M=j.get(u.id);if(M){let S=O.find(A=>A.id===u.resolverId);S&&h(M.midX+G.nodeW/2,M.midY,w[4],S.y,b.green);}}we.set(e.flowSvg,_);}function Qe(e){e.animationTimer&&clearTimeout(e.animationTimer),e.animationTimer=setTimeout(()=>{e.recentlyChangedFacts.clear(),e.recentlyComputedDerivations.clear(),e.recentlyActiveConstraints.clear(),e.animationTimer=null;},600);}function Ze(e,s){let o=s.entries.toArray();if(o.length===0)return;e.timelineSvg.replaceChildren();let r=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY;for(let R of o)R.startMs<r&&(r=R.startMs),R.endMs>a&&(a=R.endMs);let p=performance.now();for(let R of s.inflight.values())R<r&&(r=R),p>a&&(a=p);let l=a-r||1,t=ie-ce-10,i=[],c=new Set;for(let R of o)c.has(R.resolver)||(c.add(R.resolver),i.push(R.resolver));for(let R of s.inflight.keys())c.has(R)||(c.add(R),i.push(R));let y=i.slice(-12),I=ae*y.length+20;e.timelineSvg.setAttribute("viewBox",`0 0 ${ie} ${I}`),e.timelineSvg.setAttribute("height",String(Math.min(I,200)));let N=5;for(let R=0;R<=N;R++){let w=ce+t*R/N,g=l*R/N,f=document.createElementNS("http://www.w3.org/2000/svg","text");f.setAttribute("x",String(w)),f.setAttribute("y","8"),f.setAttribute("fill",b.muted),f.setAttribute("font-size","6"),f.setAttribute("font-family",b.font),f.setAttribute("text-anchor","middle"),f.textContent=g<1e3?`${g.toFixed(0)}ms`:`${(g/1e3).toFixed(1)}s`,e.timelineSvg.appendChild(f);let C=document.createElementNS("http://www.w3.org/2000/svg","line");C.setAttribute("x1",String(w)),C.setAttribute("y1","10"),C.setAttribute("x2",String(w)),C.setAttribute("y2",String(I)),C.setAttribute("stroke",b.border),C.setAttribute("stroke-width","0.5"),e.timelineSvg.appendChild(C);}for(let R=0;R<y.length;R++){let w=y[R],g=12+R*ae,f=R%Se.length,C=Se[f],T=document.createElementNS("http://www.w3.org/2000/svg","text");T.setAttribute("x",String(ce-4)),T.setAttribute("y",String(g+ae/2+3)),T.setAttribute("fill",b.muted),T.setAttribute("font-size","7"),T.setAttribute("font-family",b.font),T.setAttribute("text-anchor","end"),T.textContent=ee(w,12),e.timelineSvg.appendChild(T);let P=o.filter(O=>O.resolver===w);for(let O of P){let Y=ce+(O.startMs-r)/l*t,$=Math.max((O.endMs-O.startMs)/l*t,he),V=document.createElementNS("http://www.w3.org/2000/svg","rect");V.setAttribute("x",String(Y)),V.setAttribute("y",String(g+2)),V.setAttribute("width",String($)),V.setAttribute("height",String(ae-4)),V.setAttribute("rx","2"),V.setAttribute("fill",O.error?b.red:C),V.setAttribute("opacity","0.8");let _=document.createElementNS("http://www.w3.org/2000/svg","title"),H=O.endMs-O.startMs;_.textContent=`${w}: ${H.toFixed(1)}ms${O.error?" (error)":""}`,V.appendChild(_),e.timelineSvg.appendChild(V);}let F=s.inflight.get(w);if(F!==void 0){let O=ce+(F-r)/l*t,Y=Math.max((p-F)/l*t,he),$=document.createElementNS("http://www.w3.org/2000/svg","rect");$.setAttribute("x",String(O)),$.setAttribute("y",String(g+2)),$.setAttribute("width",String(Y)),$.setAttribute("height",String(ae-4)),$.setAttribute("rx","2"),$.setAttribute("fill",C),$.setAttribute("opacity","0.4"),$.setAttribute("stroke",C),$.setAttribute("stroke-width","1"),$.setAttribute("stroke-dasharray","3,2");let V=document.createElementNS("http://www.w3.org/2000/svg","title");V.textContent=`${w}: inflight ${(p-F).toFixed(0)}ms`,$.appendChild(V),e.timelineSvg.appendChild($);}}e.timelineSvg.setAttribute("aria-label",`Timeline: ${o.length} resolver executions across ${y.length} resolvers`);}function dt(){if(typeof window>"u")return {systems:new Map,getSystem:()=>null,getSystems:()=>[],inspect:()=>null,getEvents:()=>[],explain:()=>null,exportSession:()=>null,importSession:()=>false,clearEvents:()=>{},subscribe:()=>()=>{}};if(!window.__DIRECTIVE__){let e=new Map,s={systems:e,getSystem(o){return o?e.get(o)?.system??null:e.values().next().value?.system??null},getSystems(){return [...e.keys()]},inspect(o){let r=this.getSystem(o),a=o?e.get(o):e.values().next().value,p=r?.inspect()??null;return p&&a&&(p.resolverStats=a.resolverStats?Object.fromEntries(a.resolverStats):{}),p},getEvents(o){return o?e.get(o)?.events.toArray()??[]:e.values().next().value?.events.toArray()??[]},explain(o,r){return this.getSystem(r)?.explain(o)??null},subscribe(o,r){let a=r?e.get(r):e.values().next().value;if(!a){let p=false,t=setInterval(()=>{let c=r?e.get(r):e.values().next().value;c&&!p&&(p=true,c.subscribers.add(o));},100),i=setTimeout(()=>clearInterval(t),1e4);return ()=>{clearInterval(t),clearTimeout(i);for(let c of e.values())c.subscribers.delete(o);}}return a.subscribers.add(o),()=>{a.subscribers.delete(o);}},exportSession(o){let r=o?e.get(o):e.values().next().value;return r?JSON.stringify({version:1,name:o??e.keys().next().value??"default",exportedAt:Date.now(),events:r.events.toArray()}):null},importSession(o,r){try{if(o.length>10*1024*1024)return !1;let a=JSON.parse(o);if(!a||typeof a!="object"||Array.isArray(a)||!Array.isArray(a.events))return !1;let p=r?e.get(r):e.values().next().value;if(!p)return !1;let l=p.maxEvents,t=a.events,i=t.length>l?t.length-l:0;p.events.clear();for(let c=i;c<t.length;c++){let d=t[c];d&&typeof d=="object"&&!Array.isArray(d)&&typeof d.timestamp=="number"&&typeof d.type=="string"&&d.type!=="__proto__"&&d.type!=="constructor"&&d.type!=="prototype"&&p.events.push({timestamp:d.timestamp,type:d.type,data:d.data??null});}return !0}catch{return false}},clearEvents(o){let r=o?e.get(o):e.values().next().value;r&&r.events.clear();}};return Object.defineProperty(window,"__DIRECTIVE__",{value:s,writable:false,configurable:ge(),enumerable:true}),s}return window.__DIRECTIVE__}function mt(e={}){let{name:s="default",trace:o=false,maxEvents:r,panel:a=false,position:p="bottom-right",defaultOpen:l=false}=e,t=Pe(r),i=dt(),c={system:null,events:new ue(t),maxEvents:t,subscribers:new Set,resolverStats:new Map};i.systems.set(s,c);let d=(n,m)=>{let v={timestamp:Date.now(),type:n,data:m};o&&c.events.push(v);for(let D of c.subscribers)try{D(v);}catch{}},y=null,I=new Map,N=new Map,R=new Map,w=Ie(),g=_e(),f=je(),C=$e(),T=a&&typeof window<"u"&&typeof document<"u"&&ge(),P=null,F=0,O=1,Y=2,$=4,V=8,_=16,H=32,h=64,x=128,E=256,q=new Map,j=new Set,u=new Map,M=new Set,S=null;function A(n){F|=n,P===null&&typeof requestAnimationFrame<"u"&&(P=requestAnimationFrame(W));}function W(){if(P=null,!y||!c.system){F=0;return}let n=y.refs,m=c.system,v=F;if(F=0,v&O){for(let D of j)ze(I,D);j.clear();for(let[D,{value:B,flash:U}]of q)de(I,n.factsBody,D,B,U,y.flashTimers);q.clear(),n.factsCount.textContent=String(I.size);}if(v&Y&&Ee(n,N,m,y.flashTimers),v&E){for(let D of M)Xe(n,R,D);M.clear();for(let[D,{active:B,whenExplain:U,label:Z}]of u)Je(n,R,D,B,U,Z);u.clear();}if(v&V)if(S)ye(n,S.inflight.length,S.unmet.length);else {let D=se(m);D&&ye(n,D.inflight.length,D.unmet.length);}if(v&$)if(S)be(n,S.inflight,S.unmet);else {let D=se(m);D&&be(n,D.inflight,D.unmet);}v&_&&Ue(n,w),v&H&&Me(n,m,g),v&h&&Ce(n,m),v&x&&Ze(n,C);}function k(n,m){y&&o&&We(y.refs,n,m,c.events.size);}function L(n,m){f.isRecording&&f.recordedEvents.length<Ne&&f.recordedEvents.push({timestamp:Date.now(),type:n,data:Le(m)});}return {name:"devtools",onInit:n=>{if(c.system=n,d("init",{}),typeof window<"u"&&console.log(`%c[Directive Devtools]%c System "${s}" initialized. Access via window.__DIRECTIVE__`,"color: #7c3aed; font-weight: bold","color: inherit"),T){let m=c.system;y=Ve(s,p,l,o);let v=y.refs;try{let U=m.facts.$store.toObject();for(let[Z,re]of Object.entries(U))de(I,v.factsBody,Z,re,!1);v.factsCount.textContent=String(Object.keys(U).length);}catch{}Ee(v,N,m);let D=se(m);D&&(ye(v,D.inflight.length,D.unmet.length),be(v,D.inflight,D.unmet)),Ce(v,m),Ge(v,m),Me(v,m,g);let B=(D?.constraints?.length??0)>0;Ke(v,B),v.recordBtn.addEventListener("click",()=>{if(f.isRecording=!f.isRecording,v.recordBtn.textContent=f.isRecording?"\u23F9 Stop":"\u23FA Record",v.recordBtn.style.color=f.isRecording?b.red:b.text,f.isRecording){f.recordedEvents=[],f.snapshots=[];try{f.snapshots.push({timestamp:Date.now(),facts:m.facts.$store.toObject()});}catch{}}}),v.exportBtn.addEventListener("click",()=>{let U=f.recordedEvents.length>0?f.recordedEvents:c.events.toArray(),Z=JSON.stringify({version:1,name:s,exportedAt:Date.now(),events:U,snapshots:f.snapshots},null,2),re=new Blob([Z],{type:"application/json"}),oe=URL.createObjectURL(re),le=document.createElement("a");le.href=oe,le.download=`directive-session-${s}-${Date.now()}.json`,le.click(),URL.revokeObjectURL(oe);});}},onStart:n=>{d("start",{}),k("start",{}),L("start",{});},onStop:n=>{d("stop",{}),k("stop",{}),L("stop",{});},onDestroy:n=>{d("destroy",{}),i.systems.delete(s),P!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(P),P=null),g.animationTimer&&clearTimeout(g.animationTimer),y&&(y.destroy(),y=null,I.clear(),N.clear(),R.clear());},onFactSet:(n,m,v)=>{d("fact.set",{key:n,value:m,prev:v}),L("fact.set",{key:n,value:m,prev:v}),g.recentlyChangedFacts.add(n),y&&c.system&&(q.set(n,{value:m,flash:true}),j.delete(n),A(O),k("fact.set",{key:n,value:m}));},onFactDelete:(n,m)=>{d("fact.delete",{key:n,prev:m}),L("fact.delete",{key:n,prev:m}),y&&(j.add(n),q.delete(n),A(O),k("fact.delete",{key:n}));},onFactsBatch:n=>{if(d("facts.batch",{changes:n}),L("facts.batch",{count:n.length}),y&&c.system){for(let m of n)m.type==="delete"?(j.add(m.key),q.delete(m.key)):(g.recentlyChangedFacts.add(m.key),q.set(m.key,{value:m.value,flash:true}),j.delete(m.key));A(O),k("facts.batch",{count:n.length});}},onDerivationCompute:(n,m,v)=>{d("derivation.compute",{id:n,value:m,deps:v}),L("derivation.compute",{id:n,deps:v}),g.derivationDeps.set(n,v),g.recentlyComputedDerivations.add(n),k("derivation.compute",{id:n,deps:v});},onDerivationInvalidate:n=>{d("derivation.invalidate",{id:n}),k("derivation.invalidate",{id:n});},onReconcileStart:n=>{d("reconcile.start",{}),w.lastReconcileStartMs=performance.now(),k("reconcile.start",{}),L("reconcile.start",{});},onReconcileEnd:n=>{if(d("reconcile.end",n),L("reconcile.end",{unmet:n.unmet.length,inflight:n.inflight.length,completed:n.completed.length}),w.lastReconcileStartMs>0){let m=performance.now()-w.lastReconcileStartMs;w.reconcileCount++,w.reconcileTotalMs+=m,w.lastReconcileStartMs=0;}if(f.isRecording&&c.system&&f.snapshots.length<Be)try{f.snapshots.push({timestamp:Date.now(),facts:c.system.facts.$store.toObject()});}catch{}y&&c.system&&(S=n,Qe(g),A(Y|V|$|_|H|h),k("reconcile.end",{unmet:n.unmet.length,inflight:n.inflight.length}));},onConstraintEvaluate:(n,m,v)=>{let D=c.system?.meta?.constraint(n)?.label,B=D?{id:n,active:m,label:D}:{id:n,active:m},U=v?{...B,whenExplain:v}:B;d("constraint.evaluate",U),L("constraint.evaluate",U),m?(g.activeConstraints.add(n),g.recentlyActiveConstraints.add(n)):g.activeConstraints.delete(n),y&&(u.set(n,{active:m,whenExplain:v,label:D}),M.delete(n),A(E)),k("constraint.evaluate",{id:n,active:m});},onConstraintError:(n,m)=>{d("constraint.error",{id:n,error:String(m)}),k("constraint.error",{id:n,error:String(m)});},onRequirementCreated:n=>{d("requirement.created",{id:n.id,type:n.requirement.type}),L("requirement.created",{id:n.id,type:n.requirement.type}),k("requirement.created",{id:n.id,type:n.requirement.type});},onRequirementMet:(n,m)=>{d("requirement.met",{id:n.id,byResolver:m}),L("requirement.met",{id:n.id,byResolver:m}),k("requirement.met",{id:n.id,byResolver:m});},onRequirementCanceled:n=>{d("requirement.canceled",{id:n.id}),L("requirement.canceled",{id:n.id}),k("requirement.canceled",{id:n.id});},onResolverStart:(n,m)=>{let v=c.system?.meta?.resolver(n)?.label,D={resolver:n,requirementId:m.id},B=v?{...D,label:v}:D;d("resolver.start",B),L("resolver.start",B),C.inflight.set(n,performance.now()),y&&c.system&&(A($|V|x),k("resolver.start",{resolver:n,requirementId:m.id}));},onResolverComplete:(n,m,v)=>{let D=c.system?.meta?.resolver(n)?.label;d("resolver.complete",{resolver:n,requirementId:m.id,duration:v,...D?{label:D}:{}}),L("resolver.complete",{resolver:n,requirementId:m.id,duration:v});let B=c.resolverStats.get(n)??{count:0,totalMs:0,errors:0};if(B.count++,B.totalMs+=v,c.resolverStats.set(n,B),c.resolverStats.size>xe){let Z=c.resolverStats.keys().next().value;Z!==void 0&&c.resolverStats.delete(Z);}w.resolverStats.set(n,{...B});let U=C.inflight.get(n);C.inflight.delete(n),U!==void 0&&C.entries.push({resolver:n,startMs:U,endMs:performance.now(),error:false}),y&&c.system&&(A($|V|_|x),k("resolver.complete",{resolver:n,duration:v}));},onResolverError:(n,m,v)=>{d("resolver.error",{resolver:n,requirementId:m.id,error:String(v)}),L("resolver.error",{resolver:n,requirementId:m.id,error:String(v)});let D=c.resolverStats.get(n)??{count:0,totalMs:0,errors:0};if(D.errors++,c.resolverStats.set(n,D),c.resolverStats.size>xe){let U=c.resolverStats.keys().next().value;U!==void 0&&c.resolverStats.delete(U);}w.resolverStats.set(n,{...D});let B=C.inflight.get(n);C.inflight.delete(n),B!==void 0&&C.entries.push({resolver:n,startMs:B,endMs:performance.now(),error:true}),y&&c.system&&(A($|V|_|x),k("resolver.error",{resolver:n,error:String(v)}));},onResolverRetry:(n,m,v)=>{d("resolver.retry",{resolver:n,requirementId:m.id,attempt:v}),L("resolver.retry",{resolver:n,requirementId:m.id,attempt:v}),k("resolver.retry",{resolver:n,attempt:v});},onResolverCancel:(n,m)=>{d("resolver.cancel",{resolver:n,requirementId:m.id}),L("resolver.cancel",{resolver:n,requirementId:m.id}),C.inflight.delete(n),k("resolver.cancel",{resolver:n});},onResolverWriteRejected:n=>{let m=n.kind==="summary"?{kind:n.kind,resolver:n.resolver,requirementId:n.req.id,reason:n.reason,dropped:n.dropped}:{kind:n.kind,resolver:n.resolver,requirementId:n.req.id,reason:n.reason,fact:n.fact,expected:n.expected,actual:n.actual};d("resolver.write.rejected",m),L("resolver.write.rejected",m),k("resolver.write.rejected",n.kind==="summary"?{resolver:n.resolver,dropped:n.dropped}:{resolver:n.resolver,fact:n.fact});},onEffectRun:n=>{let m=c.system?.meta?.effect(n)?.label,v=m?{id:n,label:m}:{id:n};d("effect.run",v),L("effect.run",v),w.effectRunCount++,k("effect.run",{id:n});},onEffectError:(n,m)=>{d("effect.error",{id:n,error:String(m)}),w.effectErrorCount++,k("effect.error",{id:n,error:String(m)});},onSnapshot:n=>{d("timetravel.snapshot",{id:n.id,trigger:n.trigger}),y&&c.system&&A(h),k("timetravel.snapshot",{id:n.id,trigger:n.trigger});},onHistoryNavigate:(n,m)=>{if(d("timetravel.jump",{from:n,to:m}),L("timetravel.jump",{from:n,to:m}),y&&c.system){let v=c.system;try{let D=v.facts.$store.toObject();I.clear(),y.refs.factsBody.replaceChildren();for(let[B,U]of Object.entries(D))de(I,y.refs.factsBody,B,U,!1);y.refs.factsCount.textContent=String(Object.keys(D).length);}catch{}N.clear(),g.derivationDeps.clear(),y.refs.derivBody.replaceChildren(),R.clear(),y.refs.constraintsBody.replaceChildren(),y.refs.constraintsCount.textContent="0",S=null,A(Y|V|$|H|h),k("timetravel.jump",{from:n,to:m});}},onError:n=>{d("error",{source:n.source,sourceId:n.sourceId,message:n.message}),L("error",{source:n.source,message:n.message}),k("error",{source:n.source,message:n.message});},onErrorRecovery:(n,m)=>{d("error.recovery",{source:n.source,sourceId:n.sourceId,strategy:m}),k("error.recovery",{source:n.source,strategy:m});},onTraceComplete:n=>{d("trace.complete",{id:n.id,status:n.status,facts:n.factChanges.length,constraints:n.constraintsHit.length,requirements:n.requirementsAdded.length,resolvers:n.resolversStarted.length,effects:n.effectsRun.length}),k("trace.complete",{id:n.id});},onDefinitionRegister:(n,m)=>{d("definition.register",{type:n,id:m}),L("definition.register",{type:n,id:m}),k("definition.register",{type:n,id:m});},onDefinitionAssign:(n,m)=>{d("definition.assign",{type:n,id:m}),L("definition.assign",{type:n,id:m}),k("definition.assign",{type:n,id:m});},onDefinitionUnregister:(n,m)=>{d("definition.unregister",{type:n,id:m}),L("definition.unregister",{type:n,id:m}),k("definition.unregister",{type:n,id:m}),n==="constraint"&&y&&(M.add(m),u.delete(m),A(E));},onDefinitionCall:(n,m,v)=>{d("definition.call",{type:n,id:m,props:v}),L("definition.call",{type:n,id:m,props:v}),k("definition.call",{type:n,id:m,props:v});}}}var tt="directive-devtools-event",et=new Set(["__proto__","constructor","prototype"]),pt=Math.random().toString(36).slice(2,8);function gt(){if(typeof window<"u"){let e=`__DIRECTIVE_BRIDGE_ID_${pt}__`,s=window,o=s[e]??0;return s[e]=o+1,o+1}return 1}function ft(e){let s=false;for(let r of et)if(r in e){s=true;break}if(!s)return e;let o=Object.create(null);for(let[r,a]of Object.entries(e))et.has(r)||(o[r]=a);return o}function bt(e){if(!(typeof window>"u"))try{let s=ft(e),o={id:gt(),timestamp:Date.now(),snapshotId:null,...s};window.dispatchEvent(new CustomEvent(tt,{detail:o}));}catch{}}function yt(e){let{storage:s,key:o,include:r,exclude:a=[],debounce:p=100,onRestore:l,onSave:t,onError:i}=e,c=null,d=null,y=new Set,I=g=>a.includes(g)?false:r?r.includes(g):true,N=()=>{try{let g=s.getItem(o);if(!g)return null;let f$1=JSON.parse(g);return typeof f$1!="object"||f$1===null?null:f(f$1)?f$1:(i?.(new Error("Potential prototype pollution detected in stored data")),null)}catch(g){return i?.(g instanceof Error?g:new Error(String(g))),null}},R=()=>{if(d)try{let g={};for(let f of y)I(f)&&(g[f]=d.facts[f]);s.setItem(o,JSON.stringify(g)),t?.(g);}catch(g){i?.(g instanceof Error?g:new Error(String(g)));}},w=()=>{c&&clearTimeout(c),c=setTimeout(R,p);};return {name:"persistence",onInit:g=>{d=g;let f=N();f&&(d.facts.$store.batch(()=>{for(let[C,T]of Object.entries(f))I(C)&&(d.facts[C]=T,y.add(C));}),l?.(f));},onDestroy:()=>{c&&clearTimeout(c),R();},onFactSet:g=>{y.add(g),I(g)&&w();},onFactDelete:g=>{y.delete(g),I(g)&&w();},onFactsBatch:g=>{let f=false;for(let C of g)C.type==="set"?y.add(C.key):y.delete(C.key),I(C.key)&&(f=true);f&&w();}}}function vt(e={}){let{onSlowConstraint:s,onSlowResolver:o,slowConstraintThresholdMs:r=16,slowResolverThresholdMs:a=1e3}=e,p=new Map,l=new Map,t=new Map,i={runs:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0},c=0,d=0,y=0;function I(g){let f=p.get(g);return f||(f={evaluations:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0,lastEvaluatedAt:0},p.set(g,f)),f}function N(g){let f=l.get(g);return f||(f={starts:0,completions:0,errors:0,retries:0,cancellations:0,totalDurationMs:0,avgDurationMs:0,maxDurationMs:0,lastCompletedAt:0},l.set(g,f)),f}function R(g){let f=t.get(g);return f||(f={runs:0,errors:0,lastRunAt:0},t.set(g,f)),f}let w={name:"performance",onStart(){c=Date.now();},onConstraintEvaluate(g,f){let C=performance.now(),T=I(g);if(T.evaluations++,T.lastEvaluatedAt=Date.now(),y>0){let P=C-y;T.totalDurationMs+=P;let F=T.evaluations;T.avgDurationMs=T.totalDurationMs/F,P>T.maxDurationMs&&(T.maxDurationMs=P),P>r&&s?.(g,P);}y=C;},onResolverStart(g,f){let C=N(g);C.starts++;},onResolverComplete(g,f,C){let T=N(g);T.completions++,T.totalDurationMs+=C,T.avgDurationMs=T.totalDurationMs/T.completions,C>T.maxDurationMs&&(T.maxDurationMs=C),T.lastCompletedAt=Date.now(),C>a&&o?.(g,C);},onResolverError(g,f,C){N(g).errors++;},onResolverRetry(g,f,C){N(g).retries++;},onResolverCancel(g,f){N(g).cancellations++;},onEffectRun(g){let f=R(g);f.runs++,f.lastRunAt=Date.now();},onEffectError(g,f){R(g).errors++;},onReconcileStart(){d=performance.now(),y=0;},onReconcileEnd(){let g=performance.now()-d;i.runs++,i.totalDurationMs+=g,i.avgDurationMs=i.totalDurationMs/i.runs,g>i.maxDurationMs&&(i.maxDurationMs=g);},onDestroy(){w.reset();},getSnapshot(){let g={};for(let[T,P]of p)g[T]={...P};let f={};for(let[T,P]of l)f[T]={...P};let C={};for(let[T,P]of t)C[T]={...P};return {constraints:g,resolvers:f,effects:C,reconcile:{...i},uptime:c?Date.now()-c:0}},reset(){p.clear(),l.clear(),t.clear(),i.runs=0,i.totalDurationMs=0,i.avgDurationMs=0,i.maxDurationMs=0,y=0;}};return w}function ve(){return globalThis.crypto?.randomUUID?.()??`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,11)}`}function Te(e,s){if(e.length===0)return 0;let o=[...e].sort((a,p)=>a-p),r=Math.ceil(s/100*o.length)-1;return o[Math.max(0,r)]??0}function ht(e={}){let{serviceName:s="directive-agents",metrics:o={},tracing:r={},alerts:a=[],summaryMetrics:p={},events:l={}}=e,t={requests:p.requests??"agent.requests",errors:p.errors??"agent.errors",latency:p.latency??"agent.latency",tokens:p.tokens??"agent.tokens",cost:p.cost??"agent.cost"},{enabled:i=true,exportInterval:c,exporter:d,maxDataPoints:y=1e3}=o,{enabled:I=true,sampleRate:N=1,maxSpans:R=1e3,exporter:w}=r,g=Date.now(),f=new Map,C=new Map,T=[],P=[],F=new Map,O=new Map,Y;c&&(d||w)&&(Y=setInterval(async()=>{try{if(d&&i&&await d(Array.from(O.values())),w&&I){let h=T.splice(0,100);h.length>0&&await w(h);}}catch(h){console.error("[Directive Observability] Export error:",h);}},c));function $(h){if(!i)return;let x=`${h.name}:${JSON.stringify(Object.fromEntries(Object.entries(h.labels).sort()))}`,E=f.get(x);E||(E=[],f.set(x,E)),E.push(h),E.length>y&&E.shift(),V(h.name,E),l.onMetricRecorded?.(h),_(h.name);}function V(h,x){if(x.length===0)return;let E=x.map(S=>S.value),q=E.reduce((S,A)=>S+A,0),j=x[0],u=E[E.length-1],M={name:h,type:j.type,count:x.length,sum:q,min:Math.min(...E),max:Math.max(...E),avg:q/x.length,lastValue:u,lastUpdated:Date.now()};O.set(h,M);}function _(h){for(let x of a){if(x.metric!==h)continue;let E=O.get(h);if(!E)continue;let q=`${x.metric}:${x.threshold}`,j=F.get(q),u=x.cooldownMs??6e4;if(j&&Date.now()-j<u)continue;let M=x.operator??">",S=E.lastValue,A=x.threshold,W=false;switch(M){case ">":W=S>A;break;case "<":W=S<A;break;case ">=":W=S>=A;break;case "<=":W=S<=A;break;case "==":W=S===A;break}if(W){let k={alertId:ve(),metric:h,currentValue:S,threshold:A,operator:M,action:x.action,timestamp:Date.now(),message:`Alert: ${h} ${M} ${A} (current: ${S})`};switch(P.push(k),P.length>1e3&&P.splice(0,P.length-1e3),F.set(q,Date.now()),l.onAlert?.(k),x.action){case "log":console.log(`[Observability] ${k.message}`);break;case "warn":console.warn(`[Observability] ${k.message}`);break;case "alert":console.error(`[Observability ALERT] ${k.message}`);break;case "callback":x.callback?.(E,A);break}}}}function H(h){let x=[];for(let[E,q]of f)if(E.startsWith(`${h}:`))for(let j of q)x.push(j.value);return x.length===0?{}:{p50:Te(x,50),p90:Te(x,90),p99:Te(x,99)}}return {incrementCounter(h,x={},E=1){$({name:h,type:"counter",value:E,labels:x,timestamp:Date.now()});},setGauge(h,x,E={}){$({name:h,type:"gauge",value:x,labels:E,timestamp:Date.now()});},observeHistogram(h,x,E={}){$({name:h,type:"histogram",value:x,labels:E,timestamp:Date.now()});},startSpan(h,x){if(Math.random()>N)return {traceId:"sampled-out",spanId:"sampled-out",operationName:h,serviceName:s,startTime:Date.now(),status:"ok",tags:{},logs:[]};let E={traceId:x?C.get(x)?.traceId??ve():ve(),spanId:ve(),parentSpanId:x,operationName:h,serviceName:s,startTime:Date.now(),status:"ok",tags:{},logs:[]};return I&&(C.set(E.spanId,E),l.onSpanStart?.(E)),E},endSpan(h,x="ok"){if(h==="sampled-out")return;let E=C.get(h);if(E){for(E.endTime=Date.now(),E.duration=E.endTime-E.startTime,E.status=x,C.delete(h),T.push(E);T.length>R;)T.shift();$({name:`${E.operationName}.latency`,type:"histogram",value:E.duration,labels:{},timestamp:Date.now()}),x==="error"&&$({name:`${E.operationName}.errors`,type:"counter",value:1,labels:{},timestamp:Date.now()}),l.onSpanEnd?.(E);}},addSpanLog(h,x,E="info"){if(h==="sampled-out")return;let q=C.get(h);q&&q.logs.push({timestamp:Date.now(),message:x,level:E});},addSpanTag(h,x,E){if(h==="sampled-out")return;let q=C.get(h);q&&(q.tags[x]=E);},getDashboard(){let h=O.get(t.requests),x=O.get(t.errors),E=O.get(t.latency),q=O.get(t.tokens),j=O.get(t.cost),u=h?.sum??0,M=x?.sum??0,S=u>0?M/u:0,A=E?H(t.latency):{};return {service:{name:s,uptime:Date.now()-g,startTime:g},metrics:Object.fromEntries(O),traces:[...T].slice(-100),alerts:[...P].slice(-50),summary:{totalRequests:u,totalErrors:M,errorRate:S,avgLatency:E?.avg??0,p99Latency:A.p99??0,activeSpans:C.size,totalTokens:q?.sum??0,totalCost:j?.sum??0}}},getMetric(h){let x=O.get(h);if(!x)return;let E=H(h);return {...x,...E}},getTraces(h=100){return [...T].slice(-h)},getAlerts(){return [...P]},export(){return {metrics:Array.from(O.values()),traces:[...T],alerts:[...P]}},clear(){f.clear(),O.clear(),C.clear(),T.length=0,P.length=0,F.clear();},async destroy(){Y&&(clearInterval(Y),Y=void 0);try{d&&i&&O.size>0&&await d(Array.from(O.values())),w&&I&&T.length>0&&await w([...T]);}catch(h){console.error("[Directive Observability] Error flushing data during destroy:",h);}f.clear(),O.clear(),C.clear(),T.length=0,P.length=0,F.clear();},getHealthStatus(){let h=O.get(t.requests),x=O.get(t.errors),E=h?.sum??0,q=x?.sum??0,j=E>0?q/E:0,u=P.filter(M=>Date.now()-M.timestamp<3e5).length;return {healthy:j<.1&&u===0,uptime:Date.now()-g,errorRate:j,activeAlerts:u}}}}function St(e){return {trackRun(s,o){let r={agent:s};e.incrementCounter("agent.requests",r),o.success||e.incrementCounter("agent.errors",r),e.observeHistogram("agent.latency",o.latencyMs,r),o.inputTokens!==void 0&&(e.incrementCounter("agent.tokens.input",r,o.inputTokens),e.incrementCounter("agent.tokens",r,o.inputTokens)),o.outputTokens!==void 0&&(e.incrementCounter("agent.tokens.output",r,o.outputTokens),e.incrementCounter("agent.tokens",r,o.outputTokens)),o.cost!==void 0&&e.incrementCounter("agent.cost",r,o.cost),o.toolCalls!==void 0&&e.incrementCounter("agent.tool_calls",r,o.toolCalls);},trackGuardrail(s,o){let r={guardrail:s};e.incrementCounter("guardrail.checks",r),o.passed||e.incrementCounter("guardrail.failures",r),o.blocked&&e.incrementCounter("guardrail.blocks",r),e.observeHistogram("guardrail.latency",o.latencyMs,r);},trackApproval(s,o){let r={tool:s};e.incrementCounter("approval.requests",r),o.approved?e.incrementCounter("approval.approved",r):e.incrementCounter("approval.rejected",r),o.timedOut&&e.incrementCounter("approval.timeouts",r),e.observeHistogram("approval.wait_time",o.waitTimeMs,r);},trackHandoff(s,o,r){e.incrementCounter("handoff.count",{from:s,to:o}),e.observeHistogram("handoff.latency",r);}}}function xt(e){let s=[{key:"service.name",value:{stringValue:e.serviceName??"directive-agents"}}];if(e.serviceVersion&&s.push({key:"service.version",value:{stringValue:e.serviceVersion}}),e.resourceAttributes)for(let[o,r]of Object.entries(e.resourceAttributes))s.push({key:o,value:{stringValue:r}});return {attributes:s}}function ne(e){return `${BigInt(e)*BigInt(1e6)}`}function Et(e){switch(e){case "counter":return "sum";case "gauge":return "gauge";case "histogram":return "histogram";default:return "gauge"}}function Ct(e,s,o){let r=e.map(a=>{let p=a.lastUpdated-6e4,l=[{asInt:a.type==="counter"?a.sum:void 0,asDouble:a.type!=="counter"?a.lastValue:void 0,timeUnixNano:ne(a.lastUpdated),startTimeUnixNano:ne(p),attributes:[]}],t=Et(a.type),i={name:a.name,unit:""};return t==="sum"?i.sum={dataPoints:l,aggregationTemporality:2,isMonotonic:true}:t==="histogram"?i.histogram={dataPoints:[{count:a.count,sum:a.sum,min:a.min,max:a.max,timeUnixNano:ne(a.lastUpdated),startTimeUnixNano:ne(p),attributes:[]}],aggregationTemporality:2}:i.gauge={dataPoints:l},i});return {resourceMetrics:[{resource:s,scopeMetrics:[{scope:{name:"directive",version:o},metrics:r}]}]}}function wt(e,s,o){let r=e.map(a=>{let p=a.logs.map(i=>({timeUnixNano:ne(i.timestamp),name:i.level,attributes:[{key:"message",value:{stringValue:i.message}},{key:"level",value:{stringValue:i.level}}]})),l=Object.entries(a.tags).map(([i,c])=>({key:i,value:typeof c=="string"?{stringValue:c}:typeof c=="number"?{intValue:`${c}`}:{boolValue:c}})),t=a.status==="ok"?1:a.status==="error"?2:0;return {traceId:a.traceId.replace(/-/g,"").padEnd(32,"0").slice(0,32),spanId:a.spanId.replace(/-/g,"").padEnd(16,"0").slice(0,16),parentSpanId:a.parentSpanId?a.parentSpanId.replace(/-/g,"").padEnd(16,"0").slice(0,16):void 0,name:a.operationName,kind:1,startTimeUnixNano:ne(a.startTime),endTimeUnixNano:a.endTime?ne(a.endTime):ne(a.startTime),attributes:l,events:p,status:{code:t}}});return {resourceSpans:[{resource:s,scopeSpans:[{scope:{name:"directive",version:o},spans:r}]}]}}function Mt(e){let{endpoint:s,headers:o={},scopeVersion:r="0.1.0",timeoutMs:a=1e4,fetch:p=globalThis.fetch,onError:l}=e;try{let c=new URL(s);if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error("[Directive] Only http: and https: protocols are supported")}catch(c){throw new Error(`[Directive OTLP] Invalid endpoint URL "${s}": ${c instanceof Error?c.message:String(c)}`)}if(/\/v1\/(metrics|traces)/.test(s)&&console.warn(`[Directive OTLP] Endpoint "${s}" already contains a /v1/metrics or /v1/traces path. The exporter will append /v1/metrics or /v1/traces automatically. Use the base URL (e.g., "http://localhost:4318") instead.`),a<=0||!Number.isFinite(a))throw new Error(`[Directive OTLP] timeoutMs must be > 0, got ${a}`);let t=xt(e);async function i(c,d,y){let I=`${s.replace(/\/$/,"")}${c}`,N=new AbortController,R=setTimeout(()=>N.abort(),a);try{let w=await p(I,{method:"POST",headers:{"Content-Type":"application/json",...o},body:JSON.stringify(d),signal:N.signal});if(!w.ok)throw new Error(`[Directive] OTLP export failed: ${w.status} ${w.statusText}`)}catch(w){let g=w instanceof Error?w:new Error(String(w));l?l(g,y):console.error(`[Directive OTLP] Export ${y} error:`,g.message);}finally{clearTimeout(R);}}return {async exportMetrics(c){if(c.length===0)return;let d=Ct(c,t,r);await i("/v1/metrics",d,"metrics");},async exportTraces(c){if(c.length===0)return;let d=wt(c,t,r);await i("/v1/traces",d,"traces");}}}var me=class extends Error{code="CIRCUIT_OPEN";retryAfterMs;state;constructor(s,o,r="OPEN",a){let p=a?`[Directive CircuitBreaker] Circuit "${s}" is ${r}. ${a}`:`[Directive CircuitBreaker] Circuit "${s}" is ${r}. Request rejected. Try again in ${Math.ceil(o/1e3)}s.`;super(p),this.name="CircuitBreakerOpenError",this.retryAfterMs=o,this.state=r;}};function Tt(e={}){let{failureThreshold:s=5,recoveryTimeMs:o=3e4,halfOpenMaxRequests:r=3,failureWindowMs:a=6e4,observability:p,metricPrefix:l="circuit_breaker",name:t="default",isFailure:i=()=>true,onStateChange:c}=e;if(s<1||!Number.isFinite(s))throw new Error(`[Directive CircuitBreaker] failureThreshold must be >= 1, got ${s}`);if(o<=0||!Number.isFinite(o))throw new Error(`[Directive CircuitBreaker] recoveryTimeMs must be > 0, got ${o}`);if(r<1||!Number.isFinite(r))throw new Error(`[Directive CircuitBreaker] halfOpenMaxRequests must be >= 1, got ${r}`);if(a<=0||!Number.isFinite(a))throw new Error(`[Directive CircuitBreaker] failureWindowMs must be > 0, got ${a}`);let d="CLOSED",y=[],I=0,N=0,R=Date.now(),w=0,g=0,f=0,C=0,T=0,P=null,F=null;function O(_){if(d===_)return;let H=d;d=_,R=Date.now(),_==="OPEN"&&(w=Date.now()),_==="HALF_OPEN"&&(I=0,N=0),c?.(H,_),p&&p.incrementCounter(`${l}.state_change`,{name:t,from:H,to:_});}function Y(){let _=Date.now()-a;return y=y.filter(H=>H>_),y.length}function $(){C++,F=Date.now(),p&&p.incrementCounter(`${l}.success`,{name:t}),d==="HALF_OPEN"&&(N++,N>=r&&(O("CLOSED"),y=[]));}function V(_){if(!i(_)){$();return}f++,P=Date.now(),y.push(Date.now());let H=s*2;if(y.length>H&&(y=y.slice(-H)),p&&p.incrementCounter(`${l}.failure`,{name:t}),d==="HALF_OPEN"){O("OPEN");return}d==="CLOSED"&&Y()>=s&&O("OPEN");}return {async execute(_){if(g++,p&&p.incrementCounter(`${l}.requests`,{name:t}),d==="OPEN")if(Date.now()-w>=o)O("HALF_OPEN");else throw T++,p&&p.incrementCounter(`${l}.rejected`,{name:t}),new me(t,o-(Date.now()-w));if(d==="HALF_OPEN"){if(I>=r)throw T++,new me(t,o,"HALF_OPEN",`Max trial requests (${r}) reached.`);I++;}let H=Date.now();try{let h=await _();return $(),p&&p.observeHistogram(`${l}.latency`,Date.now()-H,{name:t}),h}catch(h){let x=h instanceof Error?h:new Error(String(h));throw V(x),p&&p.observeHistogram(`${l}.latency`,Date.now()-H,{name:t}),h}},getState(){return d==="OPEN"&&Date.now()-w>=o&&O("HALF_OPEN"),d},getStats(){return {state:this.getState(),totalRequests:g,totalFailures:f,totalSuccesses:C,totalRejected:T,recentFailures:Y(),lastFailureTime:P,lastSuccessTime:F,lastStateChange:R}},forceState(_){O(_);},reset(){let _=d;d="CLOSED",y=[],I=0,N=0,R=Date.now(),w=0,g=0,f=0,C=0,T=0,P=null,F=null,_!=="CLOSED"&&c?.(_,"CLOSED");},isAllowed(){return d==="CLOSED"?true:d==="OPEN"?Date.now()-w>=o:I<r}}}
export{me as CircuitBreakerOpenError,tt as DEVTOOLS_EVENT_NAME,St as createAgentMetrics,Tt as createCircuitBreaker,Mt as createOTLPExporter,ht as createObservability,mt as devtoolsPlugin,bt as emitDevToolsEvent,st as loggingPlugin,vt as performancePlugin,yt as persistencePlugin};//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map

@@ -1,2 +0,2 @@

'use strict';var chunkEX3XG667_cjs=require('./chunk-EX3XG667.cjs');require('./chunk-7NMXRATK.cjs'),require('./chunk-N4KTCKOI.cjs'),require('./chunk-EOLY64E6.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=chunkEX3XG667_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=chunkEX3XG667_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
'use strict';var chunkNPX5EKPP_cjs=require('./chunk-NPX5EKPP.cjs');require('./chunk-ENZEHIL7.cjs'),require('./chunk-T4TRJEJN.cjs'),require('./chunk-X7G7UBXU.cjs'),require('./chunk-4MNQDXH7.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=chunkNPX5EKPP_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=chunkNPX5EKPP_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
//# sourceMappingURL=testing.cjs.map

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/utils/testing.ts"],"names":["flushMicrotasks","i","flushAsync","r","settleWithFakeTimers","system","advanceTime","options","totalTime","stepSize","maxIterations","elapsed","iterations","finalInspection","resolverIds","createFakeTimers","currentTime","timers","ms","targetTime","timer","createMockResolver","typeOrOptions","req","calls","_req","ctx","resolve","mockResolver","_requirementType","pending","result","item","error","_ctx","reject","val","createTestSystem","createTestSystemSingle","createTestSystemNamed","eventHistory","resolverCalls","allRequirements","factsHistory","mockResolvers","type","mockOptions","moduleWithMocks","createSystem","fullKey","value","previousValue","requirement","originalDispatch","event","maxWait","startTime","checkIdle","inspection","times","key","changes","c","actualValues","modulesWithMocks","name","module","moduleNamespaces","sepIndex","namespace","possibleNamespace","assertDynamic","id","getDynamicCheck","assertNotDynamic","createCoverageTracker","constraintsHit","resolversRun","effectsRun","derivationsComputed","unsub","scenario","allConstraints","allResolvers","constraintsMissed","resolversMissed","createTestObserver","events","e"],"mappings":"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","file":"testing.cjs","sourcesContent":["/**\n * Testing Utilities - Helpers for testing Directive systems\n *\n * Features:\n * - Mock resolvers with manual resolve/reject\n * - Fake timers integration (works with Vitest/Jest fake timers)\n * - Assertion helpers\n * - Facts history tracking\n * - Pending requirements tracking\n */\n\nimport { createSystem } from \"../core/system.js\";\nimport type {\n CreateSystemOptionsNamed,\n CreateSystemOptionsSingle,\n ModuleDef,\n ModuleSchema,\n ModulesMap,\n NamespacedSystem,\n Requirement,\n RequirementWithId,\n SingleModuleSystem,\n SystemInspection,\n} from \"../core/types.js\";\n\n// ============================================================================\n// Fake Timers Integration\n// ============================================================================\n\n/**\n * Flush all pending microtasks by awaiting multiple rounds of `Promise.resolve()`.\n *\n * Call this after advancing fake timers to ensure all Promise callbacks\n * (including nested microtasks) have run before making assertions.\n *\n * @returns A promise that resolves after all pending microtasks have been drained.\n *\n * @example\n * ```typescript\n * vi.useFakeTimers();\n * system.start();\n * system.facts.userId = 1; // Triggers constraint\n * await flushMicrotasks(); // Let reconciliation start\n * vi.advanceTimersByTime(100); // Advance resolver delay\n * await flushMicrotasks(); // Let resolver complete\n * ```\n *\n * @public\n */\nexport async function flushMicrotasks(): Promise<void> {\n // Multiple rounds to catch nested microtasks\n for (let i = 0; i < 10; i++) {\n await Promise.resolve();\n }\n}\n\n/**\n * Drain a full constraint → resolver → effect pipeline, including macrotasks.\n *\n * Performs a 3-pass / 2-`setTimeout(0)` sequence that empties microtask queues\n * twice across two macrotask boundaries. Use this when a single\n * {@link flushMicrotasks} pass is not enough to reach quiescence — typically\n * when constraints schedule resolvers that schedule further constraints, or\n * when test code uses `queueMicrotask` / `Promise.resolve()` chains that\n * cross a `setTimeout(..., 0)` boundary inside the engine.\n *\n * @remarks\n * **When to use which:**\n * - {@link flushMicrotasks}: Fast path for a single microtask drain (e.g.\n * waiting for one Promise chain to settle).\n * - `flushAsync`: Heavier pass for full constraint+resolver pipelines where\n * reconciliation may emit follow-up requirements, retries, or batched\n * resolver flushes that span a macrotask.\n *\n * The exact shape (3 microtask rounds → setTimeout 0 → 3 microtask rounds →\n * setTimeout 0 → 3 microtask rounds) was extracted from a helper duplicated\n * across 50+ migration tests; centralizing it here keeps the drain semantics\n * consistent and lets the engine evolve without fan-out edits.\n *\n * @returns A promise that resolves after the full drain completes.\n *\n * @example\n * ```typescript\n * system.facts.userId = 1; // triggers constraint → resolver chain\n * await flushAsync(); // drains constraint + resolver + follow-up effects\n * expect(system.facts.user).toEqual({ id: 1, ... });\n * ```\n *\n * @public\n */\nexport async function flushAsync(): Promise<void> {\n for (let i = 0; i < 10; i++) await Promise.resolve();\n await new Promise((r) => setTimeout(r, 0));\n for (let i = 0; i < 10; i++) await Promise.resolve();\n await new Promise((r) => setTimeout(r, 0));\n for (let i = 0; i < 10; i++) await Promise.resolve();\n}\n\n/**\n * Wait for the system to settle with fake timers enabled.\n *\n * Repeatedly advances fake timers in discrete steps while flushing microtasks,\n * until no resolvers remain inflight or the time budget is exhausted.\n *\n * @param system - The Directive system to wait on (must expose {@link SystemInspection} via `inspect()`).\n * @param advanceTime - Function that advances fake timers by a given number of milliseconds (e.g., `vi.advanceTimersByTime`).\n * @param options - Configuration for total time budget, step size, and iteration limit.\n * @returns A promise that resolves once the system is idle.\n *\n * @throws Error if the system does not settle within the configured time budget.\n *\n * @example\n * ```typescript\n * vi.useFakeTimers();\n * const system = createSystem({ modules: [myModule] });\n * system.start();\n * system.dispatch({ type: \"triggerAsync\" });\n *\n * await settleWithFakeTimers(system, vi.advanceTimersByTime, {\n * totalTime: 1000,\n * stepSize: 10,\n * });\n *\n * expect(system.facts.result).toBe(\"done\");\n * ```\n *\n * @public\n */\nexport async function settleWithFakeTimers(\n system: { inspect(): SystemInspection },\n advanceTime: (ms: number) => void,\n options: {\n /** Total time to advance (default: 5000ms) */\n totalTime?: number;\n /** Time to advance each step (default: 10ms) */\n stepSize?: number;\n /** Maximum iterations before giving up (default: 1000) */\n maxIterations?: number;\n } = {},\n): Promise<void> {\n const { totalTime = 5000, stepSize = 10, maxIterations = 1000 } = options;\n\n let elapsed = 0;\n let iterations = 0;\n\n while (elapsed < totalTime && iterations < maxIterations) {\n // Flush microtasks first (handles queueMicrotask, Promise.resolve)\n await flushMicrotasks();\n\n // Check if settled\n const inspection = system.inspect();\n if (inspection.inflight.length === 0) {\n // One more flush to be safe\n await flushMicrotasks();\n return;\n }\n\n // Advance fake timers\n advanceTime(stepSize);\n elapsed += stepSize;\n iterations++;\n }\n\n // Final check\n const finalInspection = system.inspect();\n if (finalInspection.inflight.length > 0) {\n const resolverIds = finalInspection.inflight\n .map((r) => r.resolverId)\n .join(\", \");\n throw new Error(\n `[Directive] settleWithFakeTimers did not settle after ${totalTime}ms. ${finalInspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n}\n\n// ============================================================================\n// Fake Timers (for standalone use without vi.useFakeTimers)\n// ============================================================================\n\n/**\n * Standalone fake timer controller for tests that do not use Vitest/Jest fake timers.\n *\n * @remarks\n * For most tests, prefer Vitest's `vi.useFakeTimers()` paired with\n * {@link settleWithFakeTimers} for better integration. Use this interface\n * only when you need a lightweight, framework-independent timer mock.\n *\n * @public\n */\nexport interface FakeTimers {\n /** Advance time by a number of milliseconds, firing any timers that fall within the window. */\n advance(ms: number): Promise<void>;\n /** Advance to the next scheduled timer and fire its callback. */\n next(): Promise<void>;\n /** Run all pending timers in chronological order. */\n runAll(): Promise<void>;\n /** Get the current fake time in milliseconds. */\n now(): number;\n /** Reset the clock to time 0 and discard all scheduled timers. */\n reset(): void;\n}\n\n/**\n * Create standalone fake timers for testing without a framework timer mock.\n *\n * @remarks\n * For most tests, prefer Vitest's `vi.useFakeTimers()` paired with\n * {@link settleWithFakeTimers}. This factory is useful when you need an\n * isolated timer that does not interfere with global timer state.\n *\n * @returns A {@link FakeTimers} controller with `advance`, `next`, `runAll`, `now`, and `reset` methods.\n *\n * @example\n * ```typescript\n * const timers = createFakeTimers();\n * // schedule work, then:\n * await timers.advance(500);\n * expect(timers.now()).toBe(500);\n * ```\n *\n * @public\n */\nexport function createFakeTimers(): FakeTimers {\n let currentTime = 0;\n const timers: Array<{ time: number; callback: () => void }> = [];\n\n return {\n async advance(ms: number): Promise<void> {\n const targetTime = currentTime + ms;\n\n // Run all timers that would fire during this advance\n while (timers.length > 0 && timers[0]!.time <= targetTime) {\n const timer = timers.shift()!;\n currentTime = timer.time;\n timer.callback();\n await Promise.resolve(); // Allow microtasks\n }\n\n currentTime = targetTime;\n },\n\n async next(): Promise<void> {\n if (timers.length === 0) return;\n\n const timer = timers.shift()!;\n currentTime = timer.time;\n timer.callback();\n await Promise.resolve();\n },\n\n async runAll(): Promise<void> {\n while (timers.length > 0) {\n await this.next();\n }\n },\n\n now(): number {\n return currentTime;\n },\n\n reset(): void {\n currentTime = 0;\n timers.length = 0;\n },\n };\n}\n\n// ============================================================================\n// Mock Resolvers\n// ============================================================================\n\n/**\n * Context passed to mock resolver resolve functions.\n *\n * @public\n */\nexport interface MockResolverContext {\n /** Facts object (use type assertion for specific facts) */\n // biome-ignore lint/suspicious/noExplicitAny: Facts type varies by system\n facts: any;\n /** Abort signal for cancellation */\n signal: AbortSignal;\n}\n\n/**\n * Configuration for a simple mock resolver created via {@link createMockResolver}.\n *\n * @typeParam R - The requirement type this resolver handles.\n *\n * @public\n */\nexport interface MockResolverOptions<R extends Requirement = Requirement> {\n /** Predicate to check if this resolver handles a given requirement. */\n requirement?: (req: Requirement) => req is R;\n /** Mock implementation invoked when the resolver runs. */\n resolve?: (req: R, ctx: MockResolverContext) => void | Promise<void>;\n /** Artificial delay in milliseconds before the resolver completes. */\n delay?: number;\n /** Error (or message string) to throw, simulating a resolver failure. */\n error?: Error | string;\n /** Array that receives every requirement passed to this resolver. */\n calls?: R[];\n}\n\n/** Internal resolver definition type for mock resolvers */\ninterface MockResolverDef {\n requirement: (req: Requirement) => boolean;\n resolve: (req: Requirement, ctx: MockResolverContext) => Promise<void>;\n}\n\n/**\n * Create a simple mock resolver that matches requirements by type and optionally\n * records calls, injects delays, or throws errors.\n *\n * @param typeOrOptions - A requirement type string, or a full {@link MockResolverOptions} object.\n * @returns A resolver definition that can be spread into a module's `resolvers` map.\n *\n * @example\n * ```typescript\n * const calls: Requirement[] = [];\n * const mock = createMockResolver({ requirement: (r): r is MyReq => r.type === \"LOAD\", calls });\n * ```\n *\n * @public\n */\nexport function createMockResolver<R extends Requirement = Requirement>(\n typeOrOptions: string | MockResolverOptions<R>,\n): MockResolverDef {\n const options: MockResolverOptions<R> =\n typeof typeOrOptions === \"string\"\n ? {\n requirement: ((req: Requirement) => req.type === typeOrOptions) as (\n req: Requirement,\n ) => req is R,\n }\n : typeOrOptions;\n\n const calls: R[] = options.calls ?? [];\n\n return {\n requirement:\n options.requirement ?? ((_req: Requirement): _req is R => true),\n async resolve(req: Requirement, ctx: MockResolverContext): Promise<void> {\n calls.push(req as R);\n\n if (options.delay) {\n await new Promise((resolve) => setTimeout(resolve, options.delay));\n }\n\n if (options.error) {\n throw typeof options.error === \"string\"\n ? new Error(options.error)\n : options.error;\n }\n\n if (options.resolve) {\n await options.resolve(req as R, ctx);\n }\n },\n };\n}\n\n// ============================================================================\n// Mock Resolver (Advanced)\n// ============================================================================\n\n/**\n * A mock resolver that captures requirements for manual resolution.\n *\n * @remarks\n * Use this when you need fine-grained control over when and how requirements\n * resolve. Requirements are queued in `pending` and stay unresolved until you\n * explicitly call `resolve()` or `reject()`.\n *\n * @typeParam R - The requirement type this resolver handles.\n *\n * @public\n */\nexport interface MockResolver<R extends Requirement = Requirement> {\n /** All requirements received by this resolver */\n readonly calls: R[];\n /** Pending requirements waiting to be resolved/rejected */\n readonly pending: Array<{\n requirement: R;\n resolve: (result?: unknown) => void;\n reject: (error: Error) => void;\n }>;\n /** Resolve the next pending requirement */\n resolve(result?: unknown): void;\n /** Reject the next pending requirement */\n reject(error: Error): void;\n /** Resolve all pending requirements */\n resolveAll(result?: unknown): void;\n /** Reject all pending requirements */\n rejectAll(error: Error): void;\n /** Clear call history and pending queue */\n reset(): void;\n}\n\n/**\n * Create a mock resolver that captures requirements instead of resolving them,\n * giving you manual control over when and how each requirement completes.\n *\n * @param _requirementType - The requirement `type` string this mock handles (used for documentation; matching is done by the test harness).\n * @returns A {@link MockResolver} with a `handler` function suitable for passing to {@link createTestSystem} mocks.\n *\n * @example\n * ```typescript\n * const fetchMock = mockResolver<{ type: \"FETCH_USER\"; id: string }>(\"FETCH_USER\");\n *\n * const system = createTestSystem({\n * modules: [userModule],\n * mocks: {\n * resolvers: {\n * FETCH_USER: { resolve: fetchMock.handler },\n * },\n * },\n * });\n *\n * system.facts.userId = \"123\";\n * await flushMicrotasks();\n *\n * // Requirement is pending\n * expect(fetchMock.calls).toHaveLength(1);\n * expect(fetchMock.calls[0].id).toBe(\"123\");\n *\n * // Manually resolve it\n * fetchMock.resolve({ name: \"John\" });\n * await flushMicrotasks();\n *\n * expect(system.facts.user).toEqual({ name: \"John\" });\n * ```\n *\n * @public\n */\nexport function mockResolver<R extends Requirement = Requirement>(\n _requirementType: string,\n): MockResolver<R> & {\n /** Handler that can be passed to createTestSystem mocks */\n handler: (req: Requirement, ctx: MockResolverContext) => Promise<void>;\n} {\n const calls: R[] = [];\n const pending: Array<{\n requirement: R;\n resolve: (result?: unknown) => void;\n reject: (error: Error) => void;\n }> = [];\n\n const mock: MockResolver<R> = {\n get calls() {\n return calls;\n },\n get pending() {\n return pending;\n },\n resolve(result?: unknown) {\n const item = pending.shift();\n if (item) {\n item.resolve(result);\n }\n },\n reject(error: Error) {\n const item = pending.shift();\n if (item) {\n item.reject(error);\n }\n },\n resolveAll(result?: unknown) {\n while (pending.length > 0) {\n this.resolve(result);\n }\n },\n rejectAll(error: Error) {\n while (pending.length > 0) {\n this.reject(error);\n }\n },\n reset() {\n calls.length = 0;\n pending.length = 0;\n },\n };\n\n const handler = (\n req: Requirement,\n _ctx: MockResolverContext,\n ): Promise<void> => {\n calls.push(req as R);\n return new Promise<void>((resolve, reject) => {\n pending.push({\n requirement: req as R,\n resolve: (val?: unknown) => resolve(val as void),\n reject,\n });\n });\n };\n\n return {\n ...mock,\n handler,\n };\n}\n\n// ============================================================================\n// Fact Change Tracking\n// ============================================================================\n\n/**\n * Record of a single fact change captured by the test tracking plugin.\n *\n * @public\n */\nexport interface FactChangeRecord {\n /** The fact key that changed (without namespace prefix for namespaced systems) */\n key: string;\n /** The full key including namespace prefix (e.g., \"test::value\") */\n fullKey: string;\n /** The namespace (e.g., \"test\") - undefined for single-module systems */\n namespace?: string;\n /** The previous value */\n previousValue: unknown;\n /** The new value */\n newValue: unknown;\n /** Timestamp of the change */\n timestamp: number;\n}\n\n// ============================================================================\n// Test System\n// ============================================================================\n\n/** Common testing utilities shared by both single-module and namespaced test systems. */\nexport interface TestSystemBase {\n /**\n * Wait for all pending operations to complete.\n * @param maxWait - Maximum time to wait in ms (default: 5000)\n * @throws Error if timeout is exceeded with resolvers still inflight\n */\n waitForIdle(maxWait?: number): Promise<void>;\n /** Get the history of dispatched events */\n eventHistory: Array<{ type: string; [key: string]: unknown }>;\n /** Get resolver call history */\n resolverCalls: Map<string, Requirement[]>;\n /**\n * Get all requirements that have been generated (both resolved and pending).\n * Unlike `inspect().unmet`, this includes requirements that have already been handled.\n */\n readonly allRequirements: RequirementWithId[];\n /**\n * Get all fact changes since system start or last reset.\n */\n getFactsHistory(): FactChangeRecord[];\n /**\n * Reset the facts history tracking.\n */\n resetFactsHistory(): void;\n /** Assert that a requirement was created */\n assertRequirement(type: string): void;\n /** Assert that a resolver was called */\n assertResolverCalled(type: string, times?: number): void;\n /**\n * Assert that a fact was set to a specific value.\n */\n assertFactSet(key: string, value?: unknown): void;\n /**\n * Assert the number of times a fact was changed.\n */\n assertFactChanges(key: string, times: number): void;\n}\n\n/**\n * A single-module Directive system augmented with testing utilities.\n *\n * @remarks\n * Extends {@link SingleModuleSystem} with event/resolver/fact tracking, idle\n * waiting, and assertion helpers. Created via {@link createTestSystem}.\n *\n * @typeParam S - The module schema.\n *\n * @public\n */\nexport interface TestSystemSingle<S extends ModuleSchema>\n extends SingleModuleSystem<S>,\n TestSystemBase {}\n\n/**\n * A Directive system augmented with testing utilities.\n *\n * @remarks\n * Extends {@link NamespacedSystem} with event/resolver/fact tracking, idle\n * waiting, and assertion helpers. Created via {@link createTestSystem}.\n *\n * @typeParam Modules - The modules map that defines the system's schema.\n *\n * @public\n */\nexport interface TestSystem<Modules extends ModulesMap>\n extends NamespacedSystem<Modules>,\n TestSystemBase {}\n\n/**\n * Options for {@link createTestSystem}, extending the standard system options\n * with mock resolver injection and automatic tracking.\n *\n * @typeParam Modules - The modules map that defines the system's schema.\n *\n * @public\n */\nexport interface CreateTestSystemOptions<Modules extends ModulesMap>\n extends Omit<CreateSystemOptionsNamed<Modules>, \"plugins\"> {\n /** Mock resolvers by type */\n mocks?: {\n resolvers?: Record<string, MockResolverOptions>;\n };\n /** Additional plugins (tracking plugin is added automatically) */\n // biome-ignore lint/suspicious/noExplicitAny: Plugins are schema-agnostic\n plugins?: any[];\n}\n\n/**\n * Options for {@link createTestSystem} with a single module (no namespacing).\n *\n * @typeParam S - The module schema.\n *\n * @public\n */\nexport interface CreateTestSystemOptionsSingle<S extends ModuleSchema>\n extends Omit<CreateSystemOptionsSingle<S>, \"plugins\"> {\n /** Mock resolvers by type */\n mocks?: {\n resolvers?: Record<string, MockResolverOptions>;\n };\n /** Additional plugins (tracking plugin is added automatically) */\n // biome-ignore lint/suspicious/noExplicitAny: Plugins are schema-agnostic\n plugins?: any[];\n}\n\n/**\n * Create a Directive system instrumented for testing.\n *\n * Wraps {@link createSystem} with an automatic tracking plugin that records\n * dispatched events, resolver calls, fact changes, and generated requirements.\n * Mock resolvers can be injected via `options.mocks.resolvers` to replace\n * real resolvers by requirement type.\n *\n * @param options - System configuration with optional mock resolvers and additional plugins.\n * @returns A {@link TestSystem} or {@link TestSystemSingle} with assertion helpers, idle waiting, and history tracking.\n *\n * @example\n * ```typescript\n * // Namespaced (multiple modules)\n * const system = createTestSystem({\n * modules: { counter: counterModule },\n * mocks: { resolvers: { INCREMENT: { resolve: (req, context) => { context.facts.count++; } } } },\n * });\n *\n * // Single module\n * const system = createTestSystem({\n * module: counterModule,\n * });\n * system.start();\n * ```\n *\n * @public\n */\nexport function createTestSystem<S extends ModuleSchema>(\n options: CreateTestSystemOptionsSingle<S>,\n): TestSystemSingle<S>;\nexport function createTestSystem<Modules extends ModulesMap>(\n options: CreateTestSystemOptions<Modules>,\n): TestSystem<Modules>;\n/** @internal — implementation signature for the overloads above. */\nexport function createTestSystem<\n S extends ModuleSchema,\n Modules extends ModulesMap,\n>(\n options: CreateTestSystemOptionsSingle<S> | CreateTestSystemOptions<Modules>,\n): TestSystemSingle<S> | TestSystem<Modules> {\n // Single module mode: wrap into namespaced and delegate\n if (\"module\" in options) {\n return createTestSystemSingle(options as CreateTestSystemOptionsSingle<S>);\n }\n\n return createTestSystemNamed(options as CreateTestSystemOptions<Modules>);\n}\n\nfunction createTestSystemSingle<S extends ModuleSchema>(\n options: CreateTestSystemOptionsSingle<S>,\n): TestSystemSingle<S> {\n const eventHistory: Array<{ type: string; [key: string]: unknown }> = [];\n const resolverCalls = new Map<string, Requirement[]>();\n const allRequirements: RequirementWithId[] = [];\n const factsHistory: FactChangeRecord[] = [];\n\n // Create mock resolvers\n const mockResolvers: Record<string, MockResolverDef> = {};\n if (options.mocks?.resolvers) {\n for (const [type, mockOptions] of Object.entries(options.mocks.resolvers)) {\n const calls: Requirement[] = [];\n resolverCalls.set(type, calls);\n mockResolvers[type] = createMockResolver({ ...mockOptions, calls });\n }\n }\n\n // Create module with mock resolvers\n // biome-ignore lint/suspicious/noExplicitAny: Mock resolvers have simplified types\n const moduleWithMocks: ModuleDef<S> = {\n ...options.module,\n resolvers: {\n ...options.module.resolvers,\n ...mockResolvers,\n } as any,\n };\n\n // Create tracking plugin\n const trackingPlugin = {\n name: \"__test-tracking__\",\n onFactSet: (fullKey: string, value: unknown, previousValue: unknown) => {\n factsHistory.push({\n key: fullKey,\n fullKey,\n namespace: undefined,\n previousValue,\n newValue: value,\n timestamp: Date.now(),\n });\n },\n onRequirementCreated: (requirement: RequirementWithId) => {\n allRequirements.push(requirement);\n },\n };\n\n // Create the underlying single-module system\n const system = createSystem({\n ...options,\n module: moduleWithMocks,\n plugins: [trackingPlugin, ...(options.plugins ?? [])],\n // biome-ignore lint/suspicious/noExplicitAny: Internal overload compatibility\n } as any) as SingleModuleSystem<S>;\n\n // Wrap dispatch to track events\n const originalDispatch = system.dispatch.bind(system);\n // biome-ignore lint/suspicious/noExplicitAny: Event type varies\n (system as any).dispatch = (event: any) => {\n eventHistory.push(event);\n originalDispatch(event);\n };\n\n const testSystem: TestSystemSingle<S> = {\n ...system,\n eventHistory,\n resolverCalls,\n\n get allRequirements() {\n return allRequirements;\n },\n\n getFactsHistory(): FactChangeRecord[] {\n return [...factsHistory];\n },\n\n resetFactsHistory(): void {\n factsHistory.length = 0;\n },\n\n async waitForIdle(maxWait = 5000): Promise<void> {\n const startTime = Date.now();\n\n const checkIdle = async (): Promise<void> => {\n await new Promise((resolve) => setTimeout(resolve, 0));\n const inspection = system.inspect();\n if (inspection.inflight.length > 0) {\n if (Date.now() - startTime > maxWait) {\n const resolverIds = inspection.inflight.map((r) => r.id).join(\", \");\n throw new Error(\n `[Directive] waitForIdle timed out after ${maxWait}ms. ${inspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n await new Promise((resolve) => setTimeout(resolve, 10));\n\n return checkIdle();\n }\n };\n\n return checkIdle();\n },\n\n assertRequirement(type: string): void {\n const hasRequirement = allRequirements.some(\n (r) => r.requirement.type === type,\n );\n if (!hasRequirement) {\n throw new Error(\n `[Directive] Expected requirement of type \"${type}\" but none found`,\n );\n }\n },\n\n assertResolverCalled(type: string, times?: number): void {\n const calls = resolverCalls.get(type) ?? [];\n if (times !== undefined) {\n if (calls.length !== times) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called ${times} times but was called ${calls.length} times`,\n );\n }\n } else if (calls.length === 0) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called but it was not`,\n );\n }\n },\n\n assertFactSet(key: string, value?: unknown): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length === 0) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set but it was not`,\n );\n }\n if (value !== undefined) {\n const hasValue = changes.some((c) => c.newValue === value);\n if (!hasValue) {\n const actualValues = changes\n .map((c) => JSON.stringify(c.newValue))\n .join(\", \");\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set to ${JSON.stringify(value)} but got: ${actualValues}`,\n );\n }\n }\n },\n\n assertFactChanges(key: string, times: number): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length !== times) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to change ${times} times but it changed ${changes.length} times`,\n );\n }\n },\n };\n\n return testSystem;\n}\n\nfunction createTestSystemNamed<Modules extends ModulesMap>(\n options: CreateTestSystemOptions<Modules>,\n): TestSystem<Modules> {\n const eventHistory: Array<{ type: string; [key: string]: unknown }> = [];\n const resolverCalls = new Map<string, Requirement[]>();\n const allRequirements: RequirementWithId[] = [];\n const factsHistory: FactChangeRecord[] = [];\n\n // Create mock resolvers\n const mockResolvers: Record<string, MockResolverDef> = {};\n if (options.mocks?.resolvers) {\n for (const [type, mockOptions] of Object.entries(options.mocks.resolvers)) {\n const calls: Requirement[] = [];\n resolverCalls.set(type, calls);\n mockResolvers[type] = createMockResolver({ ...mockOptions, calls });\n }\n }\n\n // Create modules with mock resolvers\n const modulesWithMocks: Modules = {} as Modules;\n for (const [name, module] of Object.entries(options.modules)) {\n // biome-ignore lint/suspicious/noExplicitAny: Module types are complex\n (modulesWithMocks as any)[name] = {\n ...module,\n resolvers: {\n ...module.resolvers,\n ...mockResolvers,\n },\n };\n }\n\n // Get module namespaces for key parsing\n const moduleNamespaces = new Set(Object.keys(options.modules));\n\n // Create tracking plugin\n const trackingPlugin = {\n name: \"__test-tracking__\",\n onFactSet: (fullKey: string, value: unknown, previousValue: unknown) => {\n // Parse namespaced key (e.g., \"test::value\" -> namespace: \"test\", key: \"value\")\n const SEPARATOR = \"::\";\n const sepIndex = fullKey.indexOf(SEPARATOR);\n let namespace: string | undefined;\n let key: string;\n\n if (sepIndex > 0) {\n const possibleNamespace = fullKey.substring(0, sepIndex);\n if (moduleNamespaces.has(possibleNamespace)) {\n namespace = possibleNamespace;\n key = fullKey.substring(sepIndex + SEPARATOR.length);\n } else {\n key = fullKey;\n }\n } else {\n key = fullKey;\n }\n\n factsHistory.push({\n key,\n fullKey,\n namespace,\n previousValue,\n newValue: value,\n timestamp: Date.now(),\n });\n },\n onRequirementCreated: (requirement: RequirementWithId) => {\n allRequirements.push(requirement);\n },\n };\n\n // Create the underlying system\n const system = createSystem({\n ...options,\n modules: modulesWithMocks,\n plugins: [trackingPlugin, ...(options.plugins ?? [])],\n }) as NamespacedSystem<Modules>;\n\n // Wrap dispatch to track events\n const originalDispatch = system.dispatch.bind(system);\n // biome-ignore lint/suspicious/noExplicitAny: Event type varies\n (system as any).dispatch = (event: any) => {\n eventHistory.push(event);\n originalDispatch(event);\n };\n\n const testSystem: TestSystem<Modules> = {\n ...system,\n eventHistory,\n resolverCalls,\n\n get allRequirements() {\n return allRequirements;\n },\n\n getFactsHistory(): FactChangeRecord[] {\n return [...factsHistory];\n },\n\n resetFactsHistory(): void {\n factsHistory.length = 0;\n },\n\n async waitForIdle(maxWait = 5000): Promise<void> {\n const startTime = Date.now();\n\n const checkIdle = async (): Promise<void> => {\n // Wait for microtasks\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n // Check if there are inflight resolvers\n const inspection = system.inspect();\n if (inspection.inflight.length > 0) {\n // Check timeout\n if (Date.now() - startTime > maxWait) {\n const resolverIds = inspection.inflight.map((r) => r.id).join(\", \");\n throw new Error(\n `[Directive] waitForIdle timed out after ${maxWait}ms. ${inspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n // Wait a bit more and check again\n await new Promise((resolve) => setTimeout(resolve, 10));\n return checkIdle();\n }\n };\n\n return checkIdle();\n },\n\n assertRequirement(type: string): void {\n const hasRequirement = allRequirements.some(\n (r) => r.requirement.type === type,\n );\n if (!hasRequirement) {\n throw new Error(\n `[Directive] Expected requirement of type \"${type}\" but none found`,\n );\n }\n },\n\n assertResolverCalled(type: string, times?: number): void {\n const calls = resolverCalls.get(type) ?? [];\n if (times !== undefined) {\n if (calls.length !== times) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called ${times} times but was called ${calls.length} times`,\n );\n }\n } else if (calls.length === 0) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called but it was not`,\n );\n }\n },\n\n assertFactSet(key: string, value?: unknown): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length === 0) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set but it was not`,\n );\n }\n if (value !== undefined) {\n const hasValue = changes.some((c) => c.newValue === value);\n if (!hasValue) {\n const actualValues = changes\n .map((c) => JSON.stringify(c.newValue))\n .join(\", \");\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set to ${JSON.stringify(value)} but got: ${actualValues}`,\n );\n }\n }\n },\n\n assertFactChanges(key: string, times: number): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length !== times) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to change ${times} times but it changed ${changes.length} times`,\n );\n }\n },\n };\n\n return testSystem;\n}\n\n// ============================================================================\n// Dynamic Definition Assertions\n// ============================================================================\n\n/**\n * Assert that a definition was dynamically registered on the system.\n *\n * @param system - The Directive system to check.\n * @param type - The definition type: \"constraint\", \"resolver\", \"derivation\", or \"effect\".\n * @param id - The definition ID.\n * @throws Error if the definition is not dynamic.\n *\n * @example\n * ```typescript\n * system.constraints.register(\"myRule\", { when: () => true, require: { type: \"DO\" } });\n * assertDynamic(system, \"constraint\", \"myRule\"); // passes\n * assertDynamic(system, \"constraint\", \"staticRule\"); // throws\n * ```\n *\n * @public\n */\nexport function assertDynamic(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): void {\n const isDynamic = getDynamicCheck(system, type, id);\n if (!isDynamic) {\n throw new Error(\n `[Directive] Expected ${type} \"${id}\" to be dynamic, but it is not.`,\n );\n }\n}\n\n/**\n * Assert that a definition is NOT dynamically registered (i.e., is static or does not exist).\n *\n * @param system - The Directive system to check.\n * @param type - The definition type: \"constraint\", \"resolver\", \"derivation\", or \"effect\".\n * @param id - The definition ID.\n * @throws Error if the definition is dynamic.\n *\n * @example\n * ```typescript\n * assertNotDynamic(system, \"constraint\", \"staticRule\"); // passes\n * system.constraints.register(\"myRule\", def);\n * assertNotDynamic(system, \"constraint\", \"myRule\"); // throws\n * ```\n *\n * @public\n */\nexport function assertNotDynamic(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): void {\n const isDynamic = getDynamicCheck(system, type, id);\n if (isDynamic) {\n throw new Error(\n `[Directive] Expected ${type} \"${id}\" to NOT be dynamic, but it is.`,\n );\n }\n}\n\n/** @internal */\nfunction getDynamicCheck(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): boolean {\n switch (type) {\n case \"constraint\":\n return system.constraints.isDynamic(id);\n case \"resolver\":\n return system.resolvers.isDynamic(id);\n case \"derivation\":\n return system.derive.isDynamic(id);\n case \"effect\":\n return system.effects.isDynamic(id);\n }\n}\n\n// ============================================================================\n// Constraint Coverage\n// ============================================================================\n\n/** Coverage report for a Directive system. */\nexport interface CoverageReport {\n /** Constraints that evaluated to true at least once. */\n constraintsHit: Set<string>;\n /** Constraints that never evaluated to true. */\n constraintsMissed: Set<string>;\n /** Resolvers that started at least once. */\n resolversRun: Set<string>;\n /** Resolvers that never started. */\n resolversMissed: Set<string>;\n /** Effects that ran at least once. */\n effectsRun: Set<string>;\n /** Derivations that recomputed at least once. */\n derivationsComputed: Set<string>;\n /** Coverage percentage (constraintsHit / total constraints). */\n constraintCoverage: number;\n /** Coverage percentage (resolversRun / total resolvers). */\n resolverCoverage: number;\n /** Coverage percentage (effectsRun / total effects). */\n effectCoverage: number;\n /** Coverage percentage (derivationsComputed / total derivations). */\n derivationCoverage: number;\n}\n\n/**\n * Track which constraints, resolvers, effects, and derivations are exercised\n * during a test scenario. Returns a coverage report after the scenario runs.\n *\n * @example\n * ```typescript\n * const { run, report } = createCoverageTracker(system);\n *\n * await run(async () => {\n * system.facts.userId = 123;\n * await system.settle();\n * system.facts.userId = 0;\n * await system.settle();\n * });\n *\n * const coverage = report();\n * expect(coverage.constraintCoverage).toBe(1); // All constraints hit\n * expect(coverage.constraintsMissed.size).toBe(0);\n * ```\n */\nexport function createCoverageTracker(\n // biome-ignore lint/suspicious/noExplicitAny: Works with any system type\n system: SingleModuleSystem<any> | NamespacedSystem<any>,\n): {\n /** Run a test scenario while tracking coverage. */\n run: (scenario: () => Promise<void> | void) => Promise<void>;\n /** Get the coverage report. */\n report: () => CoverageReport;\n} {\n const constraintsHit = new Set<string>();\n const resolversRun = new Set<string>();\n const effectsRun = new Set<string>();\n const derivationsComputed = new Set<string>();\n\n let unsub: (() => void) | null = null;\n\n return {\n async run(scenario) {\n unsub = system.observe((event) => {\n switch (event.type) {\n case \"constraint.evaluate\":\n if (event.active) constraintsHit.add(event.id);\n break;\n case \"resolver.start\":\n resolversRun.add(event.resolver);\n break;\n case \"effect.run\":\n effectsRun.add(event.id);\n break;\n case \"derivation.compute\":\n derivationsComputed.add(event.id);\n break;\n }\n });\n\n try {\n await scenario();\n } finally {\n unsub?.();\n unsub = null;\n }\n },\n\n report(): CoverageReport {\n const inspection = system.inspect();\n\n const allConstraints = new Set(inspection.constraints.map((c) => c.id));\n const allResolvers = new Set(inspection.resolverDefs.map((r) => r.id));\n\n const constraintsMissed = new Set<string>();\n for (const id of allConstraints) {\n if (!constraintsHit.has(id)) constraintsMissed.add(id);\n }\n\n const resolversMissed = new Set<string>();\n for (const id of allResolvers) {\n if (!resolversRun.has(id)) resolversMissed.add(id);\n }\n\n return {\n constraintsHit,\n constraintsMissed,\n resolversRun,\n resolversMissed,\n effectsRun,\n derivationsComputed,\n constraintCoverage:\n allConstraints.size === 0\n ? 1\n : constraintsHit.size / allConstraints.size,\n resolverCoverage:\n allResolvers.size === 0 ? 1 : resolversRun.size / allResolvers.size,\n effectCoverage:\n inspection.effects.length === 0\n ? 1\n : effectsRun.size / inspection.effects.length,\n derivationCoverage:\n inspection.derivations.length === 0\n ? 1\n : derivationsComputed.size / inspection.derivations.length,\n };\n },\n };\n}\n\n// ============================================================================\n// Test Observer\n// ============================================================================\n\n/**\n * Create a test observer that collects all observation events.\n * Useful for assertion-based testing of system behavior.\n *\n * @example\n * ```typescript\n * const observer = createTestObserver(system);\n *\n * system.facts.count = 5;\n * await system.settle();\n *\n * expect(observer.events.filter(e => e.type === \"constraint.evaluate\")).toHaveLength(1);\n * expect(observer.ofType(\"resolver.complete\")).toHaveLength(1);\n *\n * observer.clear();\n * observer.dispose();\n * ```\n */\nexport function createTestObserver(\n // biome-ignore lint/suspicious/noExplicitAny: Works with any system type\n system: SingleModuleSystem<any> | NamespacedSystem<any>,\n): {\n /** All collected events. */\n events: import(\"../core/types/system.js\").ObservationEvent[];\n /** Filter events by type. */\n ofType: <\n T extends import(\"../core/types/system.js\").ObservationEvent[\"type\"],\n >(\n type: T,\n ) => Extract<\n import(\"../core/types/system.js\").ObservationEvent,\n { type: T }\n >[];\n /** Clear collected events. */\n clear: () => void;\n /** Stop observing. */\n dispose: () => void;\n} {\n const events: import(\"../core/types/system.js\").ObservationEvent[] = [];\n const unsub = system.observe((event) => events.push(event));\n\n return {\n events,\n ofType(type) {\n return events.filter((e) => e.type === type) as any;\n },\n clear() {\n events.length = 0;\n },\n dispose() {\n unsub();\n },\n };\n}\n"]}
{"version":3,"sources":["../src/utils/testing.ts"],"names":["flushMicrotasks","i","flushAsync","r","settleWithFakeTimers","system","advanceTime","options","totalTime","stepSize","maxIterations","elapsed","iterations","finalInspection","resolverIds","createFakeTimers","currentTime","timers","ms","targetTime","timer","createMockResolver","typeOrOptions","req","calls","_req","ctx","resolve","mockResolver","_requirementType","pending","result","item","error","_ctx","reject","val","createTestSystem","createTestSystemSingle","createTestSystemNamed","eventHistory","resolverCalls","allRequirements","factsHistory","mockResolvers","type","mockOptions","moduleWithMocks","createSystem","fullKey","value","previousValue","requirement","originalDispatch","event","maxWait","startTime","checkIdle","inspection","times","key","changes","c","actualValues","modulesWithMocks","name","module","moduleNamespaces","sepIndex","namespace","possibleNamespace","assertDynamic","id","getDynamicCheck","assertNotDynamic","createCoverageTracker","constraintsHit","resolversRun","effectsRun","derivationsComputed","unsub","scenario","allConstraints","allResolvers","constraintsMissed","resolversMissed","createTestObserver","events","e"],"mappings":"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","file":"testing.cjs","sourcesContent":["/**\n * Testing Utilities - Helpers for testing Directive systems\n *\n * Features:\n * - Mock resolvers with manual resolve/reject\n * - Fake timers integration (works with Vitest/Jest fake timers)\n * - Assertion helpers\n * - Facts history tracking\n * - Pending requirements tracking\n */\n\nimport { createSystem } from \"../core/system.js\";\nimport type {\n CreateSystemOptionsNamed,\n CreateSystemOptionsSingle,\n ModuleDef,\n ModuleSchema,\n ModulesMap,\n NamespacedSystem,\n Requirement,\n RequirementWithId,\n SingleModuleSystem,\n SystemInspection,\n} from \"../core/types.js\";\n\n// ============================================================================\n// Fake Timers Integration\n// ============================================================================\n\n/**\n * Flush all pending microtasks by awaiting multiple rounds of `Promise.resolve()`.\n *\n * Call this after advancing fake timers to ensure all Promise callbacks\n * (including nested microtasks) have run before making assertions.\n *\n * @returns A promise that resolves after all pending microtasks have been drained.\n *\n * @example\n * ```typescript\n * vi.useFakeTimers();\n * system.start();\n * system.facts.userId = 1; // Triggers constraint\n * await flushMicrotasks(); // Let reconciliation start\n * vi.advanceTimersByTime(100); // Advance resolver delay\n * await flushMicrotasks(); // Let resolver complete\n * ```\n *\n * @public\n */\nexport async function flushMicrotasks(): Promise<void> {\n // Multiple rounds to catch nested microtasks\n for (let i = 0; i < 10; i++) {\n await Promise.resolve();\n }\n}\n\n/**\n * Drain a full constraint → resolver → effect pipeline, including macrotasks.\n *\n * Performs a 3-pass / 2-`setTimeout(0)` sequence that empties microtask queues\n * twice across two macrotask boundaries. Use this when a single\n * {@link flushMicrotasks} pass is not enough to reach quiescence — typically\n * when constraints schedule resolvers that schedule further constraints, or\n * when test code uses `queueMicrotask` / `Promise.resolve()` chains that\n * cross a `setTimeout(..., 0)` boundary inside the engine.\n *\n * @remarks\n * **When to use which:**\n * - {@link flushMicrotasks}: Fast path for a single microtask drain (e.g.\n * waiting for one Promise chain to settle).\n * - `flushAsync`: Heavier pass for full constraint+resolver pipelines where\n * reconciliation may emit follow-up requirements, retries, or batched\n * resolver flushes that span a macrotask.\n *\n * The exact shape (3 microtask rounds → setTimeout 0 → 3 microtask rounds →\n * setTimeout 0 → 3 microtask rounds) was extracted from a helper duplicated\n * across 50+ migration tests; centralizing it here keeps the drain semantics\n * consistent and lets the engine evolve without fan-out edits.\n *\n * @returns A promise that resolves after the full drain completes.\n *\n * @example\n * ```typescript\n * system.facts.userId = 1; // triggers constraint → resolver chain\n * await flushAsync(); // drains constraint + resolver + follow-up effects\n * expect(system.facts.user).toEqual({ id: 1, ... });\n * ```\n *\n * @public\n */\nexport async function flushAsync(): Promise<void> {\n for (let i = 0; i < 10; i++) await Promise.resolve();\n await new Promise((r) => setTimeout(r, 0));\n for (let i = 0; i < 10; i++) await Promise.resolve();\n await new Promise((r) => setTimeout(r, 0));\n for (let i = 0; i < 10; i++) await Promise.resolve();\n}\n\n/**\n * Wait for the system to settle with fake timers enabled.\n *\n * Repeatedly advances fake timers in discrete steps while flushing microtasks,\n * until no resolvers remain inflight or the time budget is exhausted.\n *\n * @param system - The Directive system to wait on (must expose {@link SystemInspection} via `inspect()`).\n * @param advanceTime - Function that advances fake timers by a given number of milliseconds (e.g., `vi.advanceTimersByTime`).\n * @param options - Configuration for total time budget, step size, and iteration limit.\n * @returns A promise that resolves once the system is idle.\n *\n * @throws Error if the system does not settle within the configured time budget.\n *\n * @example\n * ```typescript\n * vi.useFakeTimers();\n * const system = createSystem({ modules: [myModule] });\n * system.start();\n * system.dispatch({ type: \"triggerAsync\" });\n *\n * await settleWithFakeTimers(system, vi.advanceTimersByTime, {\n * totalTime: 1000,\n * stepSize: 10,\n * });\n *\n * expect(system.facts.result).toBe(\"done\");\n * ```\n *\n * @public\n */\nexport async function settleWithFakeTimers(\n system: { inspect(): SystemInspection },\n advanceTime: (ms: number) => void,\n options: {\n /** Total time to advance (default: 5000ms) */\n totalTime?: number;\n /** Time to advance each step (default: 10ms) */\n stepSize?: number;\n /** Maximum iterations before giving up (default: 1000) */\n maxIterations?: number;\n } = {},\n): Promise<void> {\n const { totalTime = 5000, stepSize = 10, maxIterations = 1000 } = options;\n\n let elapsed = 0;\n let iterations = 0;\n\n while (elapsed < totalTime && iterations < maxIterations) {\n // Flush microtasks first (handles queueMicrotask, Promise.resolve)\n await flushMicrotasks();\n\n // Check if settled\n const inspection = system.inspect();\n if (inspection.inflight.length === 0) {\n // One more flush to be safe\n await flushMicrotasks();\n return;\n }\n\n // Advance fake timers\n advanceTime(stepSize);\n elapsed += stepSize;\n iterations++;\n }\n\n // Final check\n const finalInspection = system.inspect();\n if (finalInspection.inflight.length > 0) {\n const resolverIds = finalInspection.inflight\n .map((r) => r.resolverId)\n .join(\", \");\n throw new Error(\n `[Directive] settleWithFakeTimers did not settle after ${totalTime}ms. ${finalInspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n}\n\n// ============================================================================\n// Fake Timers (for standalone use without vi.useFakeTimers)\n// ============================================================================\n\n/**\n * Standalone fake timer controller for tests that do not use Vitest/Jest fake timers.\n *\n * @remarks\n * For most tests, prefer Vitest's `vi.useFakeTimers()` paired with\n * {@link settleWithFakeTimers} for better integration. Use this interface\n * only when you need a lightweight, framework-independent timer mock.\n *\n * @public\n */\nexport interface FakeTimers {\n /** Advance time by a number of milliseconds, firing any timers that fall within the window. */\n advance(ms: number): Promise<void>;\n /** Advance to the next scheduled timer and fire its callback. */\n next(): Promise<void>;\n /** Run all pending timers in chronological order. */\n runAll(): Promise<void>;\n /** Get the current fake time in milliseconds. */\n now(): number;\n /** Reset the clock to time 0 and discard all scheduled timers. */\n reset(): void;\n}\n\n/**\n * Create standalone fake timers for testing without a framework timer mock.\n *\n * @remarks\n * For most tests, prefer Vitest's `vi.useFakeTimers()` paired with\n * {@link settleWithFakeTimers}. This factory is useful when you need an\n * isolated timer that does not interfere with global timer state.\n *\n * @returns A {@link FakeTimers} controller with `advance`, `next`, `runAll`, `now`, and `reset` methods.\n *\n * @example\n * ```typescript\n * const timers = createFakeTimers();\n * // schedule work, then:\n * await timers.advance(500);\n * expect(timers.now()).toBe(500);\n * ```\n *\n * @public\n */\nexport function createFakeTimers(): FakeTimers {\n let currentTime = 0;\n const timers: Array<{ time: number; callback: () => void }> = [];\n\n return {\n async advance(ms: number): Promise<void> {\n const targetTime = currentTime + ms;\n\n // Run all timers that would fire during this advance\n while (timers.length > 0 && timers[0]!.time <= targetTime) {\n const timer = timers.shift()!;\n currentTime = timer.time;\n timer.callback();\n await Promise.resolve(); // Allow microtasks\n }\n\n currentTime = targetTime;\n },\n\n async next(): Promise<void> {\n if (timers.length === 0) return;\n\n const timer = timers.shift()!;\n currentTime = timer.time;\n timer.callback();\n await Promise.resolve();\n },\n\n async runAll(): Promise<void> {\n while (timers.length > 0) {\n await this.next();\n }\n },\n\n now(): number {\n return currentTime;\n },\n\n reset(): void {\n currentTime = 0;\n timers.length = 0;\n },\n };\n}\n\n// ============================================================================\n// Mock Resolvers\n// ============================================================================\n\n/**\n * Context passed to mock resolver resolve functions.\n *\n * @public\n */\nexport interface MockResolverContext {\n /** Facts object (use type assertion for specific facts) */\n // biome-ignore lint/suspicious/noExplicitAny: Facts type varies by system\n facts: any;\n /** Abort signal for cancellation */\n signal: AbortSignal;\n}\n\n/**\n * Configuration for a simple mock resolver created via {@link createMockResolver}.\n *\n * @typeParam R - The requirement type this resolver handles.\n *\n * @public\n */\nexport interface MockResolverOptions<R extends Requirement = Requirement> {\n /** Predicate to check if this resolver handles a given requirement. */\n requirement?: (req: Requirement) => req is R;\n /** Mock implementation invoked when the resolver runs. */\n resolve?: (req: R, ctx: MockResolverContext) => void | Promise<void>;\n /** Artificial delay in milliseconds before the resolver completes. */\n delay?: number;\n /** Error (or message string) to throw, simulating a resolver failure. */\n error?: Error | string;\n /** Array that receives every requirement passed to this resolver. */\n calls?: R[];\n}\n\n/** Internal resolver definition type for mock resolvers */\ninterface MockResolverDef {\n requirement: (req: Requirement) => boolean;\n resolve: (req: Requirement, ctx: MockResolverContext) => Promise<void>;\n}\n\n/**\n * Create a simple mock resolver that matches requirements by type and optionally\n * records calls, injects delays, or throws errors.\n *\n * @param typeOrOptions - A requirement type string, or a full {@link MockResolverOptions} object.\n * @returns A resolver definition that can be spread into a module's `resolvers` map.\n *\n * @example\n * ```typescript\n * const calls: Requirement[] = [];\n * const mock = createMockResolver({ requirement: (r): r is MyReq => r.type === \"LOAD\", calls });\n * ```\n *\n * @public\n */\nexport function createMockResolver<R extends Requirement = Requirement>(\n typeOrOptions: string | MockResolverOptions<R>,\n): MockResolverDef {\n const options: MockResolverOptions<R> =\n typeof typeOrOptions === \"string\"\n ? {\n requirement: ((req: Requirement) => req.type === typeOrOptions) as (\n req: Requirement,\n ) => req is R,\n }\n : typeOrOptions;\n\n const calls: R[] = options.calls ?? [];\n\n return {\n requirement:\n options.requirement ?? ((_req: Requirement): _req is R => true),\n async resolve(req: Requirement, ctx: MockResolverContext): Promise<void> {\n calls.push(req as R);\n\n if (options.delay) {\n await new Promise((resolve) => setTimeout(resolve, options.delay));\n }\n\n if (options.error) {\n throw typeof options.error === \"string\"\n ? new Error(options.error)\n : options.error;\n }\n\n if (options.resolve) {\n await options.resolve(req as R, ctx);\n }\n },\n };\n}\n\n// ============================================================================\n// Mock Resolver (Advanced)\n// ============================================================================\n\n/**\n * A mock resolver that captures requirements for manual resolution.\n *\n * @remarks\n * Use this when you need fine-grained control over when and how requirements\n * resolve. Requirements are queued in `pending` and stay unresolved until you\n * explicitly call `resolve()` or `reject()`.\n *\n * @typeParam R - The requirement type this resolver handles.\n *\n * @public\n */\nexport interface MockResolver<R extends Requirement = Requirement> {\n /** All requirements received by this resolver */\n readonly calls: R[];\n /** Pending requirements waiting to be resolved/rejected */\n readonly pending: Array<{\n requirement: R;\n resolve: (result?: unknown) => void;\n reject: (error: Error) => void;\n }>;\n /** Resolve the next pending requirement */\n resolve(result?: unknown): void;\n /** Reject the next pending requirement */\n reject(error: Error): void;\n /** Resolve all pending requirements */\n resolveAll(result?: unknown): void;\n /** Reject all pending requirements */\n rejectAll(error: Error): void;\n /** Clear call history and pending queue */\n reset(): void;\n}\n\n/**\n * Create a mock resolver that captures requirements instead of resolving them,\n * giving you manual control over when and how each requirement completes.\n *\n * @param _requirementType - The requirement `type` string this mock handles (used for documentation; matching is done by the test harness).\n * @returns A {@link MockResolver} with a `handler` function suitable for passing to {@link createTestSystem} mocks.\n *\n * @example\n * ```typescript\n * const fetchMock = mockResolver<{ type: \"FETCH_USER\"; id: string }>(\"FETCH_USER\");\n *\n * const system = createTestSystem({\n * modules: [userModule],\n * mocks: {\n * resolvers: {\n * FETCH_USER: { resolve: fetchMock.handler },\n * },\n * },\n * });\n *\n * system.facts.userId = \"123\";\n * await flushMicrotasks();\n *\n * // Requirement is pending\n * expect(fetchMock.calls).toHaveLength(1);\n * expect(fetchMock.calls[0].id).toBe(\"123\");\n *\n * // Manually resolve it\n * fetchMock.resolve({ name: \"John\" });\n * await flushMicrotasks();\n *\n * expect(system.facts.user).toEqual({ name: \"John\" });\n * ```\n *\n * @public\n */\nexport function mockResolver<R extends Requirement = Requirement>(\n _requirementType: string,\n): MockResolver<R> & {\n /** Handler that can be passed to createTestSystem mocks */\n handler: (req: Requirement, ctx: MockResolverContext) => Promise<void>;\n} {\n const calls: R[] = [];\n const pending: Array<{\n requirement: R;\n resolve: (result?: unknown) => void;\n reject: (error: Error) => void;\n }> = [];\n\n const mock: MockResolver<R> = {\n get calls() {\n return calls;\n },\n get pending() {\n return pending;\n },\n resolve(result?: unknown) {\n const item = pending.shift();\n if (item) {\n item.resolve(result);\n }\n },\n reject(error: Error) {\n const item = pending.shift();\n if (item) {\n item.reject(error);\n }\n },\n resolveAll(result?: unknown) {\n while (pending.length > 0) {\n this.resolve(result);\n }\n },\n rejectAll(error: Error) {\n while (pending.length > 0) {\n this.reject(error);\n }\n },\n reset() {\n calls.length = 0;\n pending.length = 0;\n },\n };\n\n const handler = (\n req: Requirement,\n _ctx: MockResolverContext,\n ): Promise<void> => {\n calls.push(req as R);\n return new Promise<void>((resolve, reject) => {\n pending.push({\n requirement: req as R,\n resolve: (val?: unknown) => resolve(val as void),\n reject,\n });\n });\n };\n\n return {\n ...mock,\n handler,\n };\n}\n\n// ============================================================================\n// Fact Change Tracking\n// ============================================================================\n\n/**\n * Record of a single fact change captured by the test tracking plugin.\n *\n * @public\n */\nexport interface FactChangeRecord {\n /** The fact key that changed (without namespace prefix for namespaced systems) */\n key: string;\n /** The full key including namespace prefix (e.g., \"test::value\") */\n fullKey: string;\n /** The namespace (e.g., \"test\") - undefined for single-module systems */\n namespace?: string;\n /** The previous value */\n previousValue: unknown;\n /** The new value */\n newValue: unknown;\n /** Timestamp of the change */\n timestamp: number;\n}\n\n// ============================================================================\n// Test System\n// ============================================================================\n\n/** Common testing utilities shared by both single-module and namespaced test systems. */\nexport interface TestSystemBase {\n /**\n * Wait for all pending operations to complete.\n * @param maxWait - Maximum time to wait in ms (default: 5000)\n * @throws Error if timeout is exceeded with resolvers still inflight\n */\n waitForIdle(maxWait?: number): Promise<void>;\n /** Get the history of dispatched events */\n eventHistory: Array<{ type: string; [key: string]: unknown }>;\n /** Get resolver call history */\n resolverCalls: Map<string, Requirement[]>;\n /**\n * Get all requirements that have been generated (both resolved and pending).\n * Unlike `inspect().unmet`, this includes requirements that have already been handled.\n */\n readonly allRequirements: RequirementWithId[];\n /**\n * Get all fact changes since system start or last reset.\n */\n getFactsHistory(): FactChangeRecord[];\n /**\n * Reset the facts history tracking.\n */\n resetFactsHistory(): void;\n /** Assert that a requirement was created */\n assertRequirement(type: string): void;\n /** Assert that a resolver was called */\n assertResolverCalled(type: string, times?: number): void;\n /**\n * Assert that a fact was set to a specific value.\n */\n assertFactSet(key: string, value?: unknown): void;\n /**\n * Assert the number of times a fact was changed.\n */\n assertFactChanges(key: string, times: number): void;\n}\n\n/**\n * A single-module Directive system augmented with testing utilities.\n *\n * @remarks\n * Extends {@link SingleModuleSystem} with event/resolver/fact tracking, idle\n * waiting, and assertion helpers. Created via {@link createTestSystem}.\n *\n * @typeParam S - The module schema.\n *\n * @public\n */\nexport interface TestSystemSingle<S extends ModuleSchema>\n extends SingleModuleSystem<S>,\n TestSystemBase {}\n\n/**\n * A Directive system augmented with testing utilities.\n *\n * @remarks\n * Extends {@link NamespacedSystem} with event/resolver/fact tracking, idle\n * waiting, and assertion helpers. Created via {@link createTestSystem}.\n *\n * @typeParam Modules - The modules map that defines the system's schema.\n *\n * @public\n */\nexport interface TestSystem<Modules extends ModulesMap>\n extends NamespacedSystem<Modules>,\n TestSystemBase {}\n\n/**\n * Options for {@link createTestSystem}, extending the standard system options\n * with mock resolver injection and automatic tracking.\n *\n * @typeParam Modules - The modules map that defines the system's schema.\n *\n * @public\n */\nexport interface CreateTestSystemOptions<Modules extends ModulesMap>\n extends Omit<CreateSystemOptionsNamed<Modules>, \"plugins\"> {\n /** Mock resolvers by type */\n mocks?: {\n resolvers?: Record<string, MockResolverOptions>;\n };\n /** Additional plugins (tracking plugin is added automatically) */\n // biome-ignore lint/suspicious/noExplicitAny: Plugins are schema-agnostic\n plugins?: any[];\n}\n\n/**\n * Options for {@link createTestSystem} with a single module (no namespacing).\n *\n * @typeParam S - The module schema.\n *\n * @public\n */\nexport interface CreateTestSystemOptionsSingle<S extends ModuleSchema>\n extends Omit<CreateSystemOptionsSingle<S>, \"plugins\"> {\n /** Mock resolvers by type */\n mocks?: {\n resolvers?: Record<string, MockResolverOptions>;\n };\n /** Additional plugins (tracking plugin is added automatically) */\n // biome-ignore lint/suspicious/noExplicitAny: Plugins are schema-agnostic\n plugins?: any[];\n}\n\n/**\n * Create a Directive system instrumented for testing.\n *\n * Wraps {@link createSystem} with an automatic tracking plugin that records\n * dispatched events, resolver calls, fact changes, and generated requirements.\n * Mock resolvers can be injected via `options.mocks.resolvers` to replace\n * real resolvers by requirement type.\n *\n * @param options - System configuration with optional mock resolvers and additional plugins.\n * @returns A {@link TestSystem} or {@link TestSystemSingle} with assertion helpers, idle waiting, and history tracking.\n *\n * @example\n * ```typescript\n * // Namespaced (multiple modules)\n * const system = createTestSystem({\n * modules: { counter: counterModule },\n * mocks: { resolvers: { INCREMENT: { resolve: (req, context) => { context.facts.count++; } } } },\n * });\n *\n * // Single module\n * const system = createTestSystem({\n * module: counterModule,\n * });\n * system.start();\n * ```\n *\n * @public\n */\nexport function createTestSystem<S extends ModuleSchema>(\n options: CreateTestSystemOptionsSingle<S>,\n): TestSystemSingle<S>;\nexport function createTestSystem<Modules extends ModulesMap>(\n options: CreateTestSystemOptions<Modules>,\n): TestSystem<Modules>;\n/** @internal — implementation signature for the overloads above. */\nexport function createTestSystem<\n S extends ModuleSchema,\n Modules extends ModulesMap,\n>(\n options: CreateTestSystemOptionsSingle<S> | CreateTestSystemOptions<Modules>,\n): TestSystemSingle<S> | TestSystem<Modules> {\n // Single module mode: wrap into namespaced and delegate\n if (\"module\" in options) {\n return createTestSystemSingle(options as CreateTestSystemOptionsSingle<S>);\n }\n\n return createTestSystemNamed(options as CreateTestSystemOptions<Modules>);\n}\n\nfunction createTestSystemSingle<S extends ModuleSchema>(\n options: CreateTestSystemOptionsSingle<S>,\n): TestSystemSingle<S> {\n const eventHistory: Array<{ type: string; [key: string]: unknown }> = [];\n const resolverCalls = new Map<string, Requirement[]>();\n const allRequirements: RequirementWithId[] = [];\n const factsHistory: FactChangeRecord[] = [];\n\n // Create mock resolvers\n const mockResolvers: Record<string, MockResolverDef> = {};\n if (options.mocks?.resolvers) {\n for (const [type, mockOptions] of Object.entries(options.mocks.resolvers)) {\n const calls: Requirement[] = [];\n resolverCalls.set(type, calls);\n mockResolvers[type] = createMockResolver({ ...mockOptions, calls });\n }\n }\n\n // Create module with mock resolvers\n // biome-ignore lint/suspicious/noExplicitAny: Mock resolvers have simplified types\n const moduleWithMocks: ModuleDef<S> = {\n ...options.module,\n resolvers: {\n ...options.module.resolvers,\n ...mockResolvers,\n } as any,\n };\n\n // Create tracking plugin\n const trackingPlugin = {\n name: \"__test-tracking__\",\n onFactSet: (fullKey: string, value: unknown, previousValue: unknown) => {\n factsHistory.push({\n key: fullKey,\n fullKey,\n namespace: undefined,\n previousValue,\n newValue: value,\n timestamp: Date.now(),\n });\n },\n onRequirementCreated: (requirement: RequirementWithId) => {\n allRequirements.push(requirement);\n },\n };\n\n // Create the underlying single-module system\n const system = createSystem({\n ...options,\n module: moduleWithMocks,\n plugins: [trackingPlugin, ...(options.plugins ?? [])],\n // biome-ignore lint/suspicious/noExplicitAny: Internal overload compatibility\n } as any) as SingleModuleSystem<S>;\n\n // Wrap dispatch to track events\n const originalDispatch = system.dispatch.bind(system);\n // biome-ignore lint/suspicious/noExplicitAny: Event type varies\n (system as any).dispatch = (event: any) => {\n eventHistory.push(event);\n originalDispatch(event);\n };\n\n const testSystem: TestSystemSingle<S> = {\n ...system,\n eventHistory,\n resolverCalls,\n\n get allRequirements() {\n return allRequirements;\n },\n\n getFactsHistory(): FactChangeRecord[] {\n return [...factsHistory];\n },\n\n resetFactsHistory(): void {\n factsHistory.length = 0;\n },\n\n async waitForIdle(maxWait = 5000): Promise<void> {\n const startTime = Date.now();\n\n const checkIdle = async (): Promise<void> => {\n await new Promise((resolve) => setTimeout(resolve, 0));\n const inspection = system.inspect();\n if (inspection.inflight.length > 0) {\n if (Date.now() - startTime > maxWait) {\n const resolverIds = inspection.inflight.map((r) => r.id).join(\", \");\n throw new Error(\n `[Directive] waitForIdle timed out after ${maxWait}ms. ${inspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n await new Promise((resolve) => setTimeout(resolve, 10));\n\n return checkIdle();\n }\n };\n\n return checkIdle();\n },\n\n assertRequirement(type: string): void {\n const hasRequirement = allRequirements.some(\n (r) => r.requirement.type === type,\n );\n if (!hasRequirement) {\n throw new Error(\n `[Directive] Expected requirement of type \"${type}\" but none found`,\n );\n }\n },\n\n assertResolverCalled(type: string, times?: number): void {\n const calls = resolverCalls.get(type) ?? [];\n if (times !== undefined) {\n if (calls.length !== times) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called ${times} times but was called ${calls.length} times`,\n );\n }\n } else if (calls.length === 0) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called but it was not`,\n );\n }\n },\n\n assertFactSet(key: string, value?: unknown): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length === 0) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set but it was not`,\n );\n }\n if (value !== undefined) {\n const hasValue = changes.some((c) => c.newValue === value);\n if (!hasValue) {\n const actualValues = changes\n .map((c) => JSON.stringify(c.newValue))\n .join(\", \");\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set to ${JSON.stringify(value)} but got: ${actualValues}`,\n );\n }\n }\n },\n\n assertFactChanges(key: string, times: number): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length !== times) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to change ${times} times but it changed ${changes.length} times`,\n );\n }\n },\n };\n\n return testSystem;\n}\n\nfunction createTestSystemNamed<Modules extends ModulesMap>(\n options: CreateTestSystemOptions<Modules>,\n): TestSystem<Modules> {\n const eventHistory: Array<{ type: string; [key: string]: unknown }> = [];\n const resolverCalls = new Map<string, Requirement[]>();\n const allRequirements: RequirementWithId[] = [];\n const factsHistory: FactChangeRecord[] = [];\n\n // Create mock resolvers\n const mockResolvers: Record<string, MockResolverDef> = {};\n if (options.mocks?.resolvers) {\n for (const [type, mockOptions] of Object.entries(options.mocks.resolvers)) {\n const calls: Requirement[] = [];\n resolverCalls.set(type, calls);\n mockResolvers[type] = createMockResolver({ ...mockOptions, calls });\n }\n }\n\n // Create modules with mock resolvers\n const modulesWithMocks: Modules = {} as Modules;\n for (const [name, module] of Object.entries(options.modules)) {\n // biome-ignore lint/suspicious/noExplicitAny: Module types are complex\n (modulesWithMocks as any)[name] = {\n ...module,\n resolvers: {\n ...module.resolvers,\n ...mockResolvers,\n },\n };\n }\n\n // Get module namespaces for key parsing\n const moduleNamespaces = new Set(Object.keys(options.modules));\n\n // Create tracking plugin\n const trackingPlugin = {\n name: \"__test-tracking__\",\n onFactSet: (fullKey: string, value: unknown, previousValue: unknown) => {\n // Parse namespaced key (e.g., \"test::value\" -> namespace: \"test\", key: \"value\")\n const SEPARATOR = \"::\";\n const sepIndex = fullKey.indexOf(SEPARATOR);\n let namespace: string | undefined;\n let key: string;\n\n if (sepIndex > 0) {\n const possibleNamespace = fullKey.substring(0, sepIndex);\n if (moduleNamespaces.has(possibleNamespace)) {\n namespace = possibleNamespace;\n key = fullKey.substring(sepIndex + SEPARATOR.length);\n } else {\n key = fullKey;\n }\n } else {\n key = fullKey;\n }\n\n factsHistory.push({\n key,\n fullKey,\n namespace,\n previousValue,\n newValue: value,\n timestamp: Date.now(),\n });\n },\n onRequirementCreated: (requirement: RequirementWithId) => {\n allRequirements.push(requirement);\n },\n };\n\n // Create the underlying system\n const system = createSystem({\n ...options,\n modules: modulesWithMocks,\n plugins: [trackingPlugin, ...(options.plugins ?? [])],\n }) as NamespacedSystem<Modules>;\n\n // Wrap dispatch to track events\n const originalDispatch = system.dispatch.bind(system);\n // biome-ignore lint/suspicious/noExplicitAny: Event type varies\n (system as any).dispatch = (event: any) => {\n eventHistory.push(event);\n originalDispatch(event);\n };\n\n const testSystem: TestSystem<Modules> = {\n ...system,\n eventHistory,\n resolverCalls,\n\n get allRequirements() {\n return allRequirements;\n },\n\n getFactsHistory(): FactChangeRecord[] {\n return [...factsHistory];\n },\n\n resetFactsHistory(): void {\n factsHistory.length = 0;\n },\n\n async waitForIdle(maxWait = 5000): Promise<void> {\n const startTime = Date.now();\n\n const checkIdle = async (): Promise<void> => {\n // Wait for microtasks\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n // Check if there are inflight resolvers\n const inspection = system.inspect();\n if (inspection.inflight.length > 0) {\n // Check timeout\n if (Date.now() - startTime > maxWait) {\n const resolverIds = inspection.inflight.map((r) => r.id).join(\", \");\n throw new Error(\n `[Directive] waitForIdle timed out after ${maxWait}ms. ${inspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n // Wait a bit more and check again\n await new Promise((resolve) => setTimeout(resolve, 10));\n return checkIdle();\n }\n };\n\n return checkIdle();\n },\n\n assertRequirement(type: string): void {\n const hasRequirement = allRequirements.some(\n (r) => r.requirement.type === type,\n );\n if (!hasRequirement) {\n throw new Error(\n `[Directive] Expected requirement of type \"${type}\" but none found`,\n );\n }\n },\n\n assertResolverCalled(type: string, times?: number): void {\n const calls = resolverCalls.get(type) ?? [];\n if (times !== undefined) {\n if (calls.length !== times) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called ${times} times but was called ${calls.length} times`,\n );\n }\n } else if (calls.length === 0) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called but it was not`,\n );\n }\n },\n\n assertFactSet(key: string, value?: unknown): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length === 0) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set but it was not`,\n );\n }\n if (value !== undefined) {\n const hasValue = changes.some((c) => c.newValue === value);\n if (!hasValue) {\n const actualValues = changes\n .map((c) => JSON.stringify(c.newValue))\n .join(\", \");\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set to ${JSON.stringify(value)} but got: ${actualValues}`,\n );\n }\n }\n },\n\n assertFactChanges(key: string, times: number): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length !== times) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to change ${times} times but it changed ${changes.length} times`,\n );\n }\n },\n };\n\n return testSystem;\n}\n\n// ============================================================================\n// Dynamic Definition Assertions\n// ============================================================================\n\n/**\n * Assert that a definition was dynamically registered on the system.\n *\n * @param system - The Directive system to check.\n * @param type - The definition type: \"constraint\", \"resolver\", \"derivation\", or \"effect\".\n * @param id - The definition ID.\n * @throws Error if the definition is not dynamic.\n *\n * @example\n * ```typescript\n * system.constraints.register(\"myRule\", { when: () => true, require: { type: \"DO\" } });\n * assertDynamic(system, \"constraint\", \"myRule\"); // passes\n * assertDynamic(system, \"constraint\", \"staticRule\"); // throws\n * ```\n *\n * @public\n */\nexport function assertDynamic(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): void {\n const isDynamic = getDynamicCheck(system, type, id);\n if (!isDynamic) {\n throw new Error(\n `[Directive] Expected ${type} \"${id}\" to be dynamic, but it is not.`,\n );\n }\n}\n\n/**\n * Assert that a definition is NOT dynamically registered (i.e., is static or does not exist).\n *\n * @param system - The Directive system to check.\n * @param type - The definition type: \"constraint\", \"resolver\", \"derivation\", or \"effect\".\n * @param id - The definition ID.\n * @throws Error if the definition is dynamic.\n *\n * @example\n * ```typescript\n * assertNotDynamic(system, \"constraint\", \"staticRule\"); // passes\n * system.constraints.register(\"myRule\", def);\n * assertNotDynamic(system, \"constraint\", \"myRule\"); // throws\n * ```\n *\n * @public\n */\nexport function assertNotDynamic(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): void {\n const isDynamic = getDynamicCheck(system, type, id);\n if (isDynamic) {\n throw new Error(\n `[Directive] Expected ${type} \"${id}\" to NOT be dynamic, but it is.`,\n );\n }\n}\n\n/** @internal */\nfunction getDynamicCheck(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): boolean {\n switch (type) {\n case \"constraint\":\n return system.constraints.isDynamic(id);\n case \"resolver\":\n return system.resolvers.isDynamic(id);\n case \"derivation\":\n return system.derive.isDynamic(id);\n case \"effect\":\n return system.effects.isDynamic(id);\n }\n}\n\n// ============================================================================\n// Constraint Coverage\n// ============================================================================\n\n/** Coverage report for a Directive system. */\nexport interface CoverageReport {\n /** Constraints that evaluated to true at least once. */\n constraintsHit: Set<string>;\n /** Constraints that never evaluated to true. */\n constraintsMissed: Set<string>;\n /** Resolvers that started at least once. */\n resolversRun: Set<string>;\n /** Resolvers that never started. */\n resolversMissed: Set<string>;\n /** Effects that ran at least once. */\n effectsRun: Set<string>;\n /** Derivations that recomputed at least once. */\n derivationsComputed: Set<string>;\n /** Coverage percentage (constraintsHit / total constraints). */\n constraintCoverage: number;\n /** Coverage percentage (resolversRun / total resolvers). */\n resolverCoverage: number;\n /** Coverage percentage (effectsRun / total effects). */\n effectCoverage: number;\n /** Coverage percentage (derivationsComputed / total derivations). */\n derivationCoverage: number;\n}\n\n/**\n * Track which constraints, resolvers, effects, and derivations are exercised\n * during a test scenario. Returns a coverage report after the scenario runs.\n *\n * @example\n * ```typescript\n * const { run, report } = createCoverageTracker(system);\n *\n * await run(async () => {\n * system.facts.userId = 123;\n * await system.settle();\n * system.facts.userId = 0;\n * await system.settle();\n * });\n *\n * const coverage = report();\n * expect(coverage.constraintCoverage).toBe(1); // All constraints hit\n * expect(coverage.constraintsMissed.size).toBe(0);\n * ```\n */\nexport function createCoverageTracker(\n // biome-ignore lint/suspicious/noExplicitAny: Works with any system type\n system: SingleModuleSystem<any> | NamespacedSystem<any>,\n): {\n /** Run a test scenario while tracking coverage. */\n run: (scenario: () => Promise<void> | void) => Promise<void>;\n /** Get the coverage report. */\n report: () => CoverageReport;\n} {\n const constraintsHit = new Set<string>();\n const resolversRun = new Set<string>();\n const effectsRun = new Set<string>();\n const derivationsComputed = new Set<string>();\n\n let unsub: (() => void) | null = null;\n\n return {\n async run(scenario) {\n unsub = system.observe((event) => {\n switch (event.type) {\n case \"constraint.evaluate\":\n if (event.active) constraintsHit.add(event.id);\n break;\n case \"resolver.start\":\n resolversRun.add(event.resolver);\n break;\n case \"effect.run\":\n effectsRun.add(event.id);\n break;\n case \"derivation.compute\":\n derivationsComputed.add(event.id);\n break;\n }\n });\n\n try {\n await scenario();\n } finally {\n unsub?.();\n unsub = null;\n }\n },\n\n report(): CoverageReport {\n const inspection = system.inspect();\n\n const allConstraints = new Set(inspection.constraints.map((c) => c.id));\n const allResolvers = new Set(inspection.resolverDefs.map((r) => r.id));\n\n const constraintsMissed = new Set<string>();\n for (const id of allConstraints) {\n if (!constraintsHit.has(id)) constraintsMissed.add(id);\n }\n\n const resolversMissed = new Set<string>();\n for (const id of allResolvers) {\n if (!resolversRun.has(id)) resolversMissed.add(id);\n }\n\n return {\n constraintsHit,\n constraintsMissed,\n resolversRun,\n resolversMissed,\n effectsRun,\n derivationsComputed,\n constraintCoverage:\n allConstraints.size === 0\n ? 1\n : constraintsHit.size / allConstraints.size,\n resolverCoverage:\n allResolvers.size === 0 ? 1 : resolversRun.size / allResolvers.size,\n effectCoverage:\n inspection.effects.length === 0\n ? 1\n : effectsRun.size / inspection.effects.length,\n derivationCoverage:\n inspection.derivations.length === 0\n ? 1\n : derivationsComputed.size / inspection.derivations.length,\n };\n },\n };\n}\n\n// ============================================================================\n// Test Observer\n// ============================================================================\n\n/**\n * Create a test observer that collects all observation events.\n * Useful for assertion-based testing of system behavior.\n *\n * @example\n * ```typescript\n * const observer = createTestObserver(system);\n *\n * system.facts.count = 5;\n * await system.settle();\n *\n * expect(observer.events.filter(e => e.type === \"constraint.evaluate\")).toHaveLength(1);\n * expect(observer.ofType(\"resolver.complete\")).toHaveLength(1);\n *\n * observer.clear();\n * observer.dispose();\n * ```\n */\nexport function createTestObserver(\n // biome-ignore lint/suspicious/noExplicitAny: Works with any system type\n system: SingleModuleSystem<any> | NamespacedSystem<any>,\n): {\n /** All collected events. */\n events: import(\"../core/types/system.js\").ObservationEvent[];\n /** Filter events by type. */\n ofType: <\n T extends import(\"../core/types/system.js\").ObservationEvent[\"type\"],\n >(\n type: T,\n ) => Extract<\n import(\"../core/types/system.js\").ObservationEvent,\n { type: T }\n >[];\n /** Clear collected events. */\n clear: () => void;\n /** Stop observing. */\n dispose: () => void;\n} {\n const events: import(\"../core/types/system.js\").ObservationEvent[] = [];\n const unsub = system.observe((event) => events.push(event));\n\n return {\n events,\n ofType(type) {\n return events.filter((e) => e.type === type) as any;\n },\n clear() {\n events.length = 0;\n },\n dispose() {\n unsub();\n },\n };\n}\n"]}

@@ -1,2 +0,2 @@

import { o as ModulesMap, p as CreateSystemOptionsNamed, t as Requirement, M as ModuleSchema, m as CreateSystemOptionsSingle, N as NamespacedSystem, R as RequirementWithId, n as SingleModuleSystem, $ as ObservationEvent, ac as SystemInspection } from './plugins-Ykl_sAPE.cjs';
import { m as ModulesMap, n as CreateSystemOptionsNamed, q as Requirement, M as ModuleSchema, k as CreateSystemOptionsSingle, N as NamespacedSystem, R as RequirementWithId, l as SingleModuleSystem, Z as ObservationEvent, ac as SystemInspection } from './plugins-BIzXaYbg.cjs';

@@ -3,0 +3,0 @@ /**

@@ -1,2 +0,2 @@

import { o as ModulesMap, p as CreateSystemOptionsNamed, t as Requirement, M as ModuleSchema, m as CreateSystemOptionsSingle, N as NamespacedSystem, R as RequirementWithId, n as SingleModuleSystem, $ as ObservationEvent, ac as SystemInspection } from './plugins-Ykl_sAPE.js';
import { m as ModulesMap, n as CreateSystemOptionsNamed, q as Requirement, M as ModuleSchema, k as CreateSystemOptionsSingle, N as NamespacedSystem, R as RequirementWithId, l as SingleModuleSystem, Z as ObservationEvent, ac as SystemInspection } from './plugins-BIzXaYbg.js';

@@ -3,0 +3,0 @@ /**

@@ -1,2 +0,2 @@

import {a}from'./chunk-26Z5VNPZ.js';import'./chunk-TPOKS4RY.js';import'./chunk-TZHC4E6S.js';import'./chunk-T6IJUWYR.js';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=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=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();}}}export{O as assertDynamic,$ as assertNotDynamic,F as createCoverageTracker,C as createFakeTimers,b as createMockResolver,I as createTestObserver,P as createTestSystem,T as flushAsync,R as flushMicrotasks,E as mockResolver,D as settleWithFakeTimers};//# sourceMappingURL=testing.js.map
import {a}from'./chunk-644QZVTT.js';import'./chunk-R2GHSCTR.js';import'./chunk-2FF6QGOA.js';import'./chunk-I722BZA5.js';import'./chunk-PXRV64PA.js';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=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=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();}}}export{O as assertDynamic,$ as assertNotDynamic,F as createCoverageTracker,C as createFakeTimers,b as createMockResolver,I as createTestObserver,P as createTestSystem,T as flushAsync,R as flushMicrotasks,E as mockResolver,D as settleWithFakeTimers};//# sourceMappingURL=testing.js.map
//# sourceMappingURL=testing.js.map

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/utils/testing.ts"],"names":["flushMicrotasks","i","flushAsync","r","settleWithFakeTimers","system","advanceTime","options","totalTime","stepSize","maxIterations","elapsed","iterations","finalInspection","resolverIds","createFakeTimers","currentTime","timers","ms","targetTime","timer","createMockResolver","typeOrOptions","req","calls","_req","ctx","resolve","mockResolver","_requirementType","pending","result","item","error","_ctx","reject","val","createTestSystem","createTestSystemSingle","createTestSystemNamed","eventHistory","resolverCalls","allRequirements","factsHistory","mockResolvers","type","mockOptions","moduleWithMocks","createSystem","fullKey","value","previousValue","requirement","originalDispatch","event","maxWait","startTime","checkIdle","inspection","times","key","changes","c","actualValues","modulesWithMocks","name","module","moduleNamespaces","sepIndex","namespace","possibleNamespace","assertDynamic","id","getDynamicCheck","assertNotDynamic","createCoverageTracker","constraintsHit","resolversRun","effectsRun","derivationsComputed","unsub","scenario","allConstraints","allResolvers","constraintsMissed","resolversMissed","createTestObserver","events","e"],"mappings":"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","file":"testing.js","sourcesContent":["/**\n * Testing Utilities - Helpers for testing Directive systems\n *\n * Features:\n * - Mock resolvers with manual resolve/reject\n * - Fake timers integration (works with Vitest/Jest fake timers)\n * - Assertion helpers\n * - Facts history tracking\n * - Pending requirements tracking\n */\n\nimport { createSystem } from \"../core/system.js\";\nimport type {\n CreateSystemOptionsNamed,\n CreateSystemOptionsSingle,\n ModuleDef,\n ModuleSchema,\n ModulesMap,\n NamespacedSystem,\n Requirement,\n RequirementWithId,\n SingleModuleSystem,\n SystemInspection,\n} from \"../core/types.js\";\n\n// ============================================================================\n// Fake Timers Integration\n// ============================================================================\n\n/**\n * Flush all pending microtasks by awaiting multiple rounds of `Promise.resolve()`.\n *\n * Call this after advancing fake timers to ensure all Promise callbacks\n * (including nested microtasks) have run before making assertions.\n *\n * @returns A promise that resolves after all pending microtasks have been drained.\n *\n * @example\n * ```typescript\n * vi.useFakeTimers();\n * system.start();\n * system.facts.userId = 1; // Triggers constraint\n * await flushMicrotasks(); // Let reconciliation start\n * vi.advanceTimersByTime(100); // Advance resolver delay\n * await flushMicrotasks(); // Let resolver complete\n * ```\n *\n * @public\n */\nexport async function flushMicrotasks(): Promise<void> {\n // Multiple rounds to catch nested microtasks\n for (let i = 0; i < 10; i++) {\n await Promise.resolve();\n }\n}\n\n/**\n * Drain a full constraint → resolver → effect pipeline, including macrotasks.\n *\n * Performs a 3-pass / 2-`setTimeout(0)` sequence that empties microtask queues\n * twice across two macrotask boundaries. Use this when a single\n * {@link flushMicrotasks} pass is not enough to reach quiescence — typically\n * when constraints schedule resolvers that schedule further constraints, or\n * when test code uses `queueMicrotask` / `Promise.resolve()` chains that\n * cross a `setTimeout(..., 0)` boundary inside the engine.\n *\n * @remarks\n * **When to use which:**\n * - {@link flushMicrotasks}: Fast path for a single microtask drain (e.g.\n * waiting for one Promise chain to settle).\n * - `flushAsync`: Heavier pass for full constraint+resolver pipelines where\n * reconciliation may emit follow-up requirements, retries, or batched\n * resolver flushes that span a macrotask.\n *\n * The exact shape (3 microtask rounds → setTimeout 0 → 3 microtask rounds →\n * setTimeout 0 → 3 microtask rounds) was extracted from a helper duplicated\n * across 50+ migration tests; centralizing it here keeps the drain semantics\n * consistent and lets the engine evolve without fan-out edits.\n *\n * @returns A promise that resolves after the full drain completes.\n *\n * @example\n * ```typescript\n * system.facts.userId = 1; // triggers constraint → resolver chain\n * await flushAsync(); // drains constraint + resolver + follow-up effects\n * expect(system.facts.user).toEqual({ id: 1, ... });\n * ```\n *\n * @public\n */\nexport async function flushAsync(): Promise<void> {\n for (let i = 0; i < 10; i++) await Promise.resolve();\n await new Promise((r) => setTimeout(r, 0));\n for (let i = 0; i < 10; i++) await Promise.resolve();\n await new Promise((r) => setTimeout(r, 0));\n for (let i = 0; i < 10; i++) await Promise.resolve();\n}\n\n/**\n * Wait for the system to settle with fake timers enabled.\n *\n * Repeatedly advances fake timers in discrete steps while flushing microtasks,\n * until no resolvers remain inflight or the time budget is exhausted.\n *\n * @param system - The Directive system to wait on (must expose {@link SystemInspection} via `inspect()`).\n * @param advanceTime - Function that advances fake timers by a given number of milliseconds (e.g., `vi.advanceTimersByTime`).\n * @param options - Configuration for total time budget, step size, and iteration limit.\n * @returns A promise that resolves once the system is idle.\n *\n * @throws Error if the system does not settle within the configured time budget.\n *\n * @example\n * ```typescript\n * vi.useFakeTimers();\n * const system = createSystem({ modules: [myModule] });\n * system.start();\n * system.dispatch({ type: \"triggerAsync\" });\n *\n * await settleWithFakeTimers(system, vi.advanceTimersByTime, {\n * totalTime: 1000,\n * stepSize: 10,\n * });\n *\n * expect(system.facts.result).toBe(\"done\");\n * ```\n *\n * @public\n */\nexport async function settleWithFakeTimers(\n system: { inspect(): SystemInspection },\n advanceTime: (ms: number) => void,\n options: {\n /** Total time to advance (default: 5000ms) */\n totalTime?: number;\n /** Time to advance each step (default: 10ms) */\n stepSize?: number;\n /** Maximum iterations before giving up (default: 1000) */\n maxIterations?: number;\n } = {},\n): Promise<void> {\n const { totalTime = 5000, stepSize = 10, maxIterations = 1000 } = options;\n\n let elapsed = 0;\n let iterations = 0;\n\n while (elapsed < totalTime && iterations < maxIterations) {\n // Flush microtasks first (handles queueMicrotask, Promise.resolve)\n await flushMicrotasks();\n\n // Check if settled\n const inspection = system.inspect();\n if (inspection.inflight.length === 0) {\n // One more flush to be safe\n await flushMicrotasks();\n return;\n }\n\n // Advance fake timers\n advanceTime(stepSize);\n elapsed += stepSize;\n iterations++;\n }\n\n // Final check\n const finalInspection = system.inspect();\n if (finalInspection.inflight.length > 0) {\n const resolverIds = finalInspection.inflight\n .map((r) => r.resolverId)\n .join(\", \");\n throw new Error(\n `[Directive] settleWithFakeTimers did not settle after ${totalTime}ms. ${finalInspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n}\n\n// ============================================================================\n// Fake Timers (for standalone use without vi.useFakeTimers)\n// ============================================================================\n\n/**\n * Standalone fake timer controller for tests that do not use Vitest/Jest fake timers.\n *\n * @remarks\n * For most tests, prefer Vitest's `vi.useFakeTimers()` paired with\n * {@link settleWithFakeTimers} for better integration. Use this interface\n * only when you need a lightweight, framework-independent timer mock.\n *\n * @public\n */\nexport interface FakeTimers {\n /** Advance time by a number of milliseconds, firing any timers that fall within the window. */\n advance(ms: number): Promise<void>;\n /** Advance to the next scheduled timer and fire its callback. */\n next(): Promise<void>;\n /** Run all pending timers in chronological order. */\n runAll(): Promise<void>;\n /** Get the current fake time in milliseconds. */\n now(): number;\n /** Reset the clock to time 0 and discard all scheduled timers. */\n reset(): void;\n}\n\n/**\n * Create standalone fake timers for testing without a framework timer mock.\n *\n * @remarks\n * For most tests, prefer Vitest's `vi.useFakeTimers()` paired with\n * {@link settleWithFakeTimers}. This factory is useful when you need an\n * isolated timer that does not interfere with global timer state.\n *\n * @returns A {@link FakeTimers} controller with `advance`, `next`, `runAll`, `now`, and `reset` methods.\n *\n * @example\n * ```typescript\n * const timers = createFakeTimers();\n * // schedule work, then:\n * await timers.advance(500);\n * expect(timers.now()).toBe(500);\n * ```\n *\n * @public\n */\nexport function createFakeTimers(): FakeTimers {\n let currentTime = 0;\n const timers: Array<{ time: number; callback: () => void }> = [];\n\n return {\n async advance(ms: number): Promise<void> {\n const targetTime = currentTime + ms;\n\n // Run all timers that would fire during this advance\n while (timers.length > 0 && timers[0]!.time <= targetTime) {\n const timer = timers.shift()!;\n currentTime = timer.time;\n timer.callback();\n await Promise.resolve(); // Allow microtasks\n }\n\n currentTime = targetTime;\n },\n\n async next(): Promise<void> {\n if (timers.length === 0) return;\n\n const timer = timers.shift()!;\n currentTime = timer.time;\n timer.callback();\n await Promise.resolve();\n },\n\n async runAll(): Promise<void> {\n while (timers.length > 0) {\n await this.next();\n }\n },\n\n now(): number {\n return currentTime;\n },\n\n reset(): void {\n currentTime = 0;\n timers.length = 0;\n },\n };\n}\n\n// ============================================================================\n// Mock Resolvers\n// ============================================================================\n\n/**\n * Context passed to mock resolver resolve functions.\n *\n * @public\n */\nexport interface MockResolverContext {\n /** Facts object (use type assertion for specific facts) */\n // biome-ignore lint/suspicious/noExplicitAny: Facts type varies by system\n facts: any;\n /** Abort signal for cancellation */\n signal: AbortSignal;\n}\n\n/**\n * Configuration for a simple mock resolver created via {@link createMockResolver}.\n *\n * @typeParam R - The requirement type this resolver handles.\n *\n * @public\n */\nexport interface MockResolverOptions<R extends Requirement = Requirement> {\n /** Predicate to check if this resolver handles a given requirement. */\n requirement?: (req: Requirement) => req is R;\n /** Mock implementation invoked when the resolver runs. */\n resolve?: (req: R, ctx: MockResolverContext) => void | Promise<void>;\n /** Artificial delay in milliseconds before the resolver completes. */\n delay?: number;\n /** Error (or message string) to throw, simulating a resolver failure. */\n error?: Error | string;\n /** Array that receives every requirement passed to this resolver. */\n calls?: R[];\n}\n\n/** Internal resolver definition type for mock resolvers */\ninterface MockResolverDef {\n requirement: (req: Requirement) => boolean;\n resolve: (req: Requirement, ctx: MockResolverContext) => Promise<void>;\n}\n\n/**\n * Create a simple mock resolver that matches requirements by type and optionally\n * records calls, injects delays, or throws errors.\n *\n * @param typeOrOptions - A requirement type string, or a full {@link MockResolverOptions} object.\n * @returns A resolver definition that can be spread into a module's `resolvers` map.\n *\n * @example\n * ```typescript\n * const calls: Requirement[] = [];\n * const mock = createMockResolver({ requirement: (r): r is MyReq => r.type === \"LOAD\", calls });\n * ```\n *\n * @public\n */\nexport function createMockResolver<R extends Requirement = Requirement>(\n typeOrOptions: string | MockResolverOptions<R>,\n): MockResolverDef {\n const options: MockResolverOptions<R> =\n typeof typeOrOptions === \"string\"\n ? {\n requirement: ((req: Requirement) => req.type === typeOrOptions) as (\n req: Requirement,\n ) => req is R,\n }\n : typeOrOptions;\n\n const calls: R[] = options.calls ?? [];\n\n return {\n requirement:\n options.requirement ?? ((_req: Requirement): _req is R => true),\n async resolve(req: Requirement, ctx: MockResolverContext): Promise<void> {\n calls.push(req as R);\n\n if (options.delay) {\n await new Promise((resolve) => setTimeout(resolve, options.delay));\n }\n\n if (options.error) {\n throw typeof options.error === \"string\"\n ? new Error(options.error)\n : options.error;\n }\n\n if (options.resolve) {\n await options.resolve(req as R, ctx);\n }\n },\n };\n}\n\n// ============================================================================\n// Mock Resolver (Advanced)\n// ============================================================================\n\n/**\n * A mock resolver that captures requirements for manual resolution.\n *\n * @remarks\n * Use this when you need fine-grained control over when and how requirements\n * resolve. Requirements are queued in `pending` and stay unresolved until you\n * explicitly call `resolve()` or `reject()`.\n *\n * @typeParam R - The requirement type this resolver handles.\n *\n * @public\n */\nexport interface MockResolver<R extends Requirement = Requirement> {\n /** All requirements received by this resolver */\n readonly calls: R[];\n /** Pending requirements waiting to be resolved/rejected */\n readonly pending: Array<{\n requirement: R;\n resolve: (result?: unknown) => void;\n reject: (error: Error) => void;\n }>;\n /** Resolve the next pending requirement */\n resolve(result?: unknown): void;\n /** Reject the next pending requirement */\n reject(error: Error): void;\n /** Resolve all pending requirements */\n resolveAll(result?: unknown): void;\n /** Reject all pending requirements */\n rejectAll(error: Error): void;\n /** Clear call history and pending queue */\n reset(): void;\n}\n\n/**\n * Create a mock resolver that captures requirements instead of resolving them,\n * giving you manual control over when and how each requirement completes.\n *\n * @param _requirementType - The requirement `type` string this mock handles (used for documentation; matching is done by the test harness).\n * @returns A {@link MockResolver} with a `handler` function suitable for passing to {@link createTestSystem} mocks.\n *\n * @example\n * ```typescript\n * const fetchMock = mockResolver<{ type: \"FETCH_USER\"; id: string }>(\"FETCH_USER\");\n *\n * const system = createTestSystem({\n * modules: [userModule],\n * mocks: {\n * resolvers: {\n * FETCH_USER: { resolve: fetchMock.handler },\n * },\n * },\n * });\n *\n * system.facts.userId = \"123\";\n * await flushMicrotasks();\n *\n * // Requirement is pending\n * expect(fetchMock.calls).toHaveLength(1);\n * expect(fetchMock.calls[0].id).toBe(\"123\");\n *\n * // Manually resolve it\n * fetchMock.resolve({ name: \"John\" });\n * await flushMicrotasks();\n *\n * expect(system.facts.user).toEqual({ name: \"John\" });\n * ```\n *\n * @public\n */\nexport function mockResolver<R extends Requirement = Requirement>(\n _requirementType: string,\n): MockResolver<R> & {\n /** Handler that can be passed to createTestSystem mocks */\n handler: (req: Requirement, ctx: MockResolverContext) => Promise<void>;\n} {\n const calls: R[] = [];\n const pending: Array<{\n requirement: R;\n resolve: (result?: unknown) => void;\n reject: (error: Error) => void;\n }> = [];\n\n const mock: MockResolver<R> = {\n get calls() {\n return calls;\n },\n get pending() {\n return pending;\n },\n resolve(result?: unknown) {\n const item = pending.shift();\n if (item) {\n item.resolve(result);\n }\n },\n reject(error: Error) {\n const item = pending.shift();\n if (item) {\n item.reject(error);\n }\n },\n resolveAll(result?: unknown) {\n while (pending.length > 0) {\n this.resolve(result);\n }\n },\n rejectAll(error: Error) {\n while (pending.length > 0) {\n this.reject(error);\n }\n },\n reset() {\n calls.length = 0;\n pending.length = 0;\n },\n };\n\n const handler = (\n req: Requirement,\n _ctx: MockResolverContext,\n ): Promise<void> => {\n calls.push(req as R);\n return new Promise<void>((resolve, reject) => {\n pending.push({\n requirement: req as R,\n resolve: (val?: unknown) => resolve(val as void),\n reject,\n });\n });\n };\n\n return {\n ...mock,\n handler,\n };\n}\n\n// ============================================================================\n// Fact Change Tracking\n// ============================================================================\n\n/**\n * Record of a single fact change captured by the test tracking plugin.\n *\n * @public\n */\nexport interface FactChangeRecord {\n /** The fact key that changed (without namespace prefix for namespaced systems) */\n key: string;\n /** The full key including namespace prefix (e.g., \"test::value\") */\n fullKey: string;\n /** The namespace (e.g., \"test\") - undefined for single-module systems */\n namespace?: string;\n /** The previous value */\n previousValue: unknown;\n /** The new value */\n newValue: unknown;\n /** Timestamp of the change */\n timestamp: number;\n}\n\n// ============================================================================\n// Test System\n// ============================================================================\n\n/** Common testing utilities shared by both single-module and namespaced test systems. */\nexport interface TestSystemBase {\n /**\n * Wait for all pending operations to complete.\n * @param maxWait - Maximum time to wait in ms (default: 5000)\n * @throws Error if timeout is exceeded with resolvers still inflight\n */\n waitForIdle(maxWait?: number): Promise<void>;\n /** Get the history of dispatched events */\n eventHistory: Array<{ type: string; [key: string]: unknown }>;\n /** Get resolver call history */\n resolverCalls: Map<string, Requirement[]>;\n /**\n * Get all requirements that have been generated (both resolved and pending).\n * Unlike `inspect().unmet`, this includes requirements that have already been handled.\n */\n readonly allRequirements: RequirementWithId[];\n /**\n * Get all fact changes since system start or last reset.\n */\n getFactsHistory(): FactChangeRecord[];\n /**\n * Reset the facts history tracking.\n */\n resetFactsHistory(): void;\n /** Assert that a requirement was created */\n assertRequirement(type: string): void;\n /** Assert that a resolver was called */\n assertResolverCalled(type: string, times?: number): void;\n /**\n * Assert that a fact was set to a specific value.\n */\n assertFactSet(key: string, value?: unknown): void;\n /**\n * Assert the number of times a fact was changed.\n */\n assertFactChanges(key: string, times: number): void;\n}\n\n/**\n * A single-module Directive system augmented with testing utilities.\n *\n * @remarks\n * Extends {@link SingleModuleSystem} with event/resolver/fact tracking, idle\n * waiting, and assertion helpers. Created via {@link createTestSystem}.\n *\n * @typeParam S - The module schema.\n *\n * @public\n */\nexport interface TestSystemSingle<S extends ModuleSchema>\n extends SingleModuleSystem<S>,\n TestSystemBase {}\n\n/**\n * A Directive system augmented with testing utilities.\n *\n * @remarks\n * Extends {@link NamespacedSystem} with event/resolver/fact tracking, idle\n * waiting, and assertion helpers. Created via {@link createTestSystem}.\n *\n * @typeParam Modules - The modules map that defines the system's schema.\n *\n * @public\n */\nexport interface TestSystem<Modules extends ModulesMap>\n extends NamespacedSystem<Modules>,\n TestSystemBase {}\n\n/**\n * Options for {@link createTestSystem}, extending the standard system options\n * with mock resolver injection and automatic tracking.\n *\n * @typeParam Modules - The modules map that defines the system's schema.\n *\n * @public\n */\nexport interface CreateTestSystemOptions<Modules extends ModulesMap>\n extends Omit<CreateSystemOptionsNamed<Modules>, \"plugins\"> {\n /** Mock resolvers by type */\n mocks?: {\n resolvers?: Record<string, MockResolverOptions>;\n };\n /** Additional plugins (tracking plugin is added automatically) */\n // biome-ignore lint/suspicious/noExplicitAny: Plugins are schema-agnostic\n plugins?: any[];\n}\n\n/**\n * Options for {@link createTestSystem} with a single module (no namespacing).\n *\n * @typeParam S - The module schema.\n *\n * @public\n */\nexport interface CreateTestSystemOptionsSingle<S extends ModuleSchema>\n extends Omit<CreateSystemOptionsSingle<S>, \"plugins\"> {\n /** Mock resolvers by type */\n mocks?: {\n resolvers?: Record<string, MockResolverOptions>;\n };\n /** Additional plugins (tracking plugin is added automatically) */\n // biome-ignore lint/suspicious/noExplicitAny: Plugins are schema-agnostic\n plugins?: any[];\n}\n\n/**\n * Create a Directive system instrumented for testing.\n *\n * Wraps {@link createSystem} with an automatic tracking plugin that records\n * dispatched events, resolver calls, fact changes, and generated requirements.\n * Mock resolvers can be injected via `options.mocks.resolvers` to replace\n * real resolvers by requirement type.\n *\n * @param options - System configuration with optional mock resolvers and additional plugins.\n * @returns A {@link TestSystem} or {@link TestSystemSingle} with assertion helpers, idle waiting, and history tracking.\n *\n * @example\n * ```typescript\n * // Namespaced (multiple modules)\n * const system = createTestSystem({\n * modules: { counter: counterModule },\n * mocks: { resolvers: { INCREMENT: { resolve: (req, context) => { context.facts.count++; } } } },\n * });\n *\n * // Single module\n * const system = createTestSystem({\n * module: counterModule,\n * });\n * system.start();\n * ```\n *\n * @public\n */\nexport function createTestSystem<S extends ModuleSchema>(\n options: CreateTestSystemOptionsSingle<S>,\n): TestSystemSingle<S>;\nexport function createTestSystem<Modules extends ModulesMap>(\n options: CreateTestSystemOptions<Modules>,\n): TestSystem<Modules>;\n/** @internal — implementation signature for the overloads above. */\nexport function createTestSystem<\n S extends ModuleSchema,\n Modules extends ModulesMap,\n>(\n options: CreateTestSystemOptionsSingle<S> | CreateTestSystemOptions<Modules>,\n): TestSystemSingle<S> | TestSystem<Modules> {\n // Single module mode: wrap into namespaced and delegate\n if (\"module\" in options) {\n return createTestSystemSingle(options as CreateTestSystemOptionsSingle<S>);\n }\n\n return createTestSystemNamed(options as CreateTestSystemOptions<Modules>);\n}\n\nfunction createTestSystemSingle<S extends ModuleSchema>(\n options: CreateTestSystemOptionsSingle<S>,\n): TestSystemSingle<S> {\n const eventHistory: Array<{ type: string; [key: string]: unknown }> = [];\n const resolverCalls = new Map<string, Requirement[]>();\n const allRequirements: RequirementWithId[] = [];\n const factsHistory: FactChangeRecord[] = [];\n\n // Create mock resolvers\n const mockResolvers: Record<string, MockResolverDef> = {};\n if (options.mocks?.resolvers) {\n for (const [type, mockOptions] of Object.entries(options.mocks.resolvers)) {\n const calls: Requirement[] = [];\n resolverCalls.set(type, calls);\n mockResolvers[type] = createMockResolver({ ...mockOptions, calls });\n }\n }\n\n // Create module with mock resolvers\n // biome-ignore lint/suspicious/noExplicitAny: Mock resolvers have simplified types\n const moduleWithMocks: ModuleDef<S> = {\n ...options.module,\n resolvers: {\n ...options.module.resolvers,\n ...mockResolvers,\n } as any,\n };\n\n // Create tracking plugin\n const trackingPlugin = {\n name: \"__test-tracking__\",\n onFactSet: (fullKey: string, value: unknown, previousValue: unknown) => {\n factsHistory.push({\n key: fullKey,\n fullKey,\n namespace: undefined,\n previousValue,\n newValue: value,\n timestamp: Date.now(),\n });\n },\n onRequirementCreated: (requirement: RequirementWithId) => {\n allRequirements.push(requirement);\n },\n };\n\n // Create the underlying single-module system\n const system = createSystem({\n ...options,\n module: moduleWithMocks,\n plugins: [trackingPlugin, ...(options.plugins ?? [])],\n // biome-ignore lint/suspicious/noExplicitAny: Internal overload compatibility\n } as any) as SingleModuleSystem<S>;\n\n // Wrap dispatch to track events\n const originalDispatch = system.dispatch.bind(system);\n // biome-ignore lint/suspicious/noExplicitAny: Event type varies\n (system as any).dispatch = (event: any) => {\n eventHistory.push(event);\n originalDispatch(event);\n };\n\n const testSystem: TestSystemSingle<S> = {\n ...system,\n eventHistory,\n resolverCalls,\n\n get allRequirements() {\n return allRequirements;\n },\n\n getFactsHistory(): FactChangeRecord[] {\n return [...factsHistory];\n },\n\n resetFactsHistory(): void {\n factsHistory.length = 0;\n },\n\n async waitForIdle(maxWait = 5000): Promise<void> {\n const startTime = Date.now();\n\n const checkIdle = async (): Promise<void> => {\n await new Promise((resolve) => setTimeout(resolve, 0));\n const inspection = system.inspect();\n if (inspection.inflight.length > 0) {\n if (Date.now() - startTime > maxWait) {\n const resolverIds = inspection.inflight.map((r) => r.id).join(\", \");\n throw new Error(\n `[Directive] waitForIdle timed out after ${maxWait}ms. ${inspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n await new Promise((resolve) => setTimeout(resolve, 10));\n\n return checkIdle();\n }\n };\n\n return checkIdle();\n },\n\n assertRequirement(type: string): void {\n const hasRequirement = allRequirements.some(\n (r) => r.requirement.type === type,\n );\n if (!hasRequirement) {\n throw new Error(\n `[Directive] Expected requirement of type \"${type}\" but none found`,\n );\n }\n },\n\n assertResolverCalled(type: string, times?: number): void {\n const calls = resolverCalls.get(type) ?? [];\n if (times !== undefined) {\n if (calls.length !== times) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called ${times} times but was called ${calls.length} times`,\n );\n }\n } else if (calls.length === 0) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called but it was not`,\n );\n }\n },\n\n assertFactSet(key: string, value?: unknown): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length === 0) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set but it was not`,\n );\n }\n if (value !== undefined) {\n const hasValue = changes.some((c) => c.newValue === value);\n if (!hasValue) {\n const actualValues = changes\n .map((c) => JSON.stringify(c.newValue))\n .join(\", \");\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set to ${JSON.stringify(value)} but got: ${actualValues}`,\n );\n }\n }\n },\n\n assertFactChanges(key: string, times: number): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length !== times) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to change ${times} times but it changed ${changes.length} times`,\n );\n }\n },\n };\n\n return testSystem;\n}\n\nfunction createTestSystemNamed<Modules extends ModulesMap>(\n options: CreateTestSystemOptions<Modules>,\n): TestSystem<Modules> {\n const eventHistory: Array<{ type: string; [key: string]: unknown }> = [];\n const resolverCalls = new Map<string, Requirement[]>();\n const allRequirements: RequirementWithId[] = [];\n const factsHistory: FactChangeRecord[] = [];\n\n // Create mock resolvers\n const mockResolvers: Record<string, MockResolverDef> = {};\n if (options.mocks?.resolvers) {\n for (const [type, mockOptions] of Object.entries(options.mocks.resolvers)) {\n const calls: Requirement[] = [];\n resolverCalls.set(type, calls);\n mockResolvers[type] = createMockResolver({ ...mockOptions, calls });\n }\n }\n\n // Create modules with mock resolvers\n const modulesWithMocks: Modules = {} as Modules;\n for (const [name, module] of Object.entries(options.modules)) {\n // biome-ignore lint/suspicious/noExplicitAny: Module types are complex\n (modulesWithMocks as any)[name] = {\n ...module,\n resolvers: {\n ...module.resolvers,\n ...mockResolvers,\n },\n };\n }\n\n // Get module namespaces for key parsing\n const moduleNamespaces = new Set(Object.keys(options.modules));\n\n // Create tracking plugin\n const trackingPlugin = {\n name: \"__test-tracking__\",\n onFactSet: (fullKey: string, value: unknown, previousValue: unknown) => {\n // Parse namespaced key (e.g., \"test::value\" -> namespace: \"test\", key: \"value\")\n const SEPARATOR = \"::\";\n const sepIndex = fullKey.indexOf(SEPARATOR);\n let namespace: string | undefined;\n let key: string;\n\n if (sepIndex > 0) {\n const possibleNamespace = fullKey.substring(0, sepIndex);\n if (moduleNamespaces.has(possibleNamespace)) {\n namespace = possibleNamespace;\n key = fullKey.substring(sepIndex + SEPARATOR.length);\n } else {\n key = fullKey;\n }\n } else {\n key = fullKey;\n }\n\n factsHistory.push({\n key,\n fullKey,\n namespace,\n previousValue,\n newValue: value,\n timestamp: Date.now(),\n });\n },\n onRequirementCreated: (requirement: RequirementWithId) => {\n allRequirements.push(requirement);\n },\n };\n\n // Create the underlying system\n const system = createSystem({\n ...options,\n modules: modulesWithMocks,\n plugins: [trackingPlugin, ...(options.plugins ?? [])],\n }) as NamespacedSystem<Modules>;\n\n // Wrap dispatch to track events\n const originalDispatch = system.dispatch.bind(system);\n // biome-ignore lint/suspicious/noExplicitAny: Event type varies\n (system as any).dispatch = (event: any) => {\n eventHistory.push(event);\n originalDispatch(event);\n };\n\n const testSystem: TestSystem<Modules> = {\n ...system,\n eventHistory,\n resolverCalls,\n\n get allRequirements() {\n return allRequirements;\n },\n\n getFactsHistory(): FactChangeRecord[] {\n return [...factsHistory];\n },\n\n resetFactsHistory(): void {\n factsHistory.length = 0;\n },\n\n async waitForIdle(maxWait = 5000): Promise<void> {\n const startTime = Date.now();\n\n const checkIdle = async (): Promise<void> => {\n // Wait for microtasks\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n // Check if there are inflight resolvers\n const inspection = system.inspect();\n if (inspection.inflight.length > 0) {\n // Check timeout\n if (Date.now() - startTime > maxWait) {\n const resolverIds = inspection.inflight.map((r) => r.id).join(\", \");\n throw new Error(\n `[Directive] waitForIdle timed out after ${maxWait}ms. ${inspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n // Wait a bit more and check again\n await new Promise((resolve) => setTimeout(resolve, 10));\n return checkIdle();\n }\n };\n\n return checkIdle();\n },\n\n assertRequirement(type: string): void {\n const hasRequirement = allRequirements.some(\n (r) => r.requirement.type === type,\n );\n if (!hasRequirement) {\n throw new Error(\n `[Directive] Expected requirement of type \"${type}\" but none found`,\n );\n }\n },\n\n assertResolverCalled(type: string, times?: number): void {\n const calls = resolverCalls.get(type) ?? [];\n if (times !== undefined) {\n if (calls.length !== times) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called ${times} times but was called ${calls.length} times`,\n );\n }\n } else if (calls.length === 0) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called but it was not`,\n );\n }\n },\n\n assertFactSet(key: string, value?: unknown): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length === 0) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set but it was not`,\n );\n }\n if (value !== undefined) {\n const hasValue = changes.some((c) => c.newValue === value);\n if (!hasValue) {\n const actualValues = changes\n .map((c) => JSON.stringify(c.newValue))\n .join(\", \");\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set to ${JSON.stringify(value)} but got: ${actualValues}`,\n );\n }\n }\n },\n\n assertFactChanges(key: string, times: number): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length !== times) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to change ${times} times but it changed ${changes.length} times`,\n );\n }\n },\n };\n\n return testSystem;\n}\n\n// ============================================================================\n// Dynamic Definition Assertions\n// ============================================================================\n\n/**\n * Assert that a definition was dynamically registered on the system.\n *\n * @param system - The Directive system to check.\n * @param type - The definition type: \"constraint\", \"resolver\", \"derivation\", or \"effect\".\n * @param id - The definition ID.\n * @throws Error if the definition is not dynamic.\n *\n * @example\n * ```typescript\n * system.constraints.register(\"myRule\", { when: () => true, require: { type: \"DO\" } });\n * assertDynamic(system, \"constraint\", \"myRule\"); // passes\n * assertDynamic(system, \"constraint\", \"staticRule\"); // throws\n * ```\n *\n * @public\n */\nexport function assertDynamic(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): void {\n const isDynamic = getDynamicCheck(system, type, id);\n if (!isDynamic) {\n throw new Error(\n `[Directive] Expected ${type} \"${id}\" to be dynamic, but it is not.`,\n );\n }\n}\n\n/**\n * Assert that a definition is NOT dynamically registered (i.e., is static or does not exist).\n *\n * @param system - The Directive system to check.\n * @param type - The definition type: \"constraint\", \"resolver\", \"derivation\", or \"effect\".\n * @param id - The definition ID.\n * @throws Error if the definition is dynamic.\n *\n * @example\n * ```typescript\n * assertNotDynamic(system, \"constraint\", \"staticRule\"); // passes\n * system.constraints.register(\"myRule\", def);\n * assertNotDynamic(system, \"constraint\", \"myRule\"); // throws\n * ```\n *\n * @public\n */\nexport function assertNotDynamic(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): void {\n const isDynamic = getDynamicCheck(system, type, id);\n if (isDynamic) {\n throw new Error(\n `[Directive] Expected ${type} \"${id}\" to NOT be dynamic, but it is.`,\n );\n }\n}\n\n/** @internal */\nfunction getDynamicCheck(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): boolean {\n switch (type) {\n case \"constraint\":\n return system.constraints.isDynamic(id);\n case \"resolver\":\n return system.resolvers.isDynamic(id);\n case \"derivation\":\n return system.derive.isDynamic(id);\n case \"effect\":\n return system.effects.isDynamic(id);\n }\n}\n\n// ============================================================================\n// Constraint Coverage\n// ============================================================================\n\n/** Coverage report for a Directive system. */\nexport interface CoverageReport {\n /** Constraints that evaluated to true at least once. */\n constraintsHit: Set<string>;\n /** Constraints that never evaluated to true. */\n constraintsMissed: Set<string>;\n /** Resolvers that started at least once. */\n resolversRun: Set<string>;\n /** Resolvers that never started. */\n resolversMissed: Set<string>;\n /** Effects that ran at least once. */\n effectsRun: Set<string>;\n /** Derivations that recomputed at least once. */\n derivationsComputed: Set<string>;\n /** Coverage percentage (constraintsHit / total constraints). */\n constraintCoverage: number;\n /** Coverage percentage (resolversRun / total resolvers). */\n resolverCoverage: number;\n /** Coverage percentage (effectsRun / total effects). */\n effectCoverage: number;\n /** Coverage percentage (derivationsComputed / total derivations). */\n derivationCoverage: number;\n}\n\n/**\n * Track which constraints, resolvers, effects, and derivations are exercised\n * during a test scenario. Returns a coverage report after the scenario runs.\n *\n * @example\n * ```typescript\n * const { run, report } = createCoverageTracker(system);\n *\n * await run(async () => {\n * system.facts.userId = 123;\n * await system.settle();\n * system.facts.userId = 0;\n * await system.settle();\n * });\n *\n * const coverage = report();\n * expect(coverage.constraintCoverage).toBe(1); // All constraints hit\n * expect(coverage.constraintsMissed.size).toBe(0);\n * ```\n */\nexport function createCoverageTracker(\n // biome-ignore lint/suspicious/noExplicitAny: Works with any system type\n system: SingleModuleSystem<any> | NamespacedSystem<any>,\n): {\n /** Run a test scenario while tracking coverage. */\n run: (scenario: () => Promise<void> | void) => Promise<void>;\n /** Get the coverage report. */\n report: () => CoverageReport;\n} {\n const constraintsHit = new Set<string>();\n const resolversRun = new Set<string>();\n const effectsRun = new Set<string>();\n const derivationsComputed = new Set<string>();\n\n let unsub: (() => void) | null = null;\n\n return {\n async run(scenario) {\n unsub = system.observe((event) => {\n switch (event.type) {\n case \"constraint.evaluate\":\n if (event.active) constraintsHit.add(event.id);\n break;\n case \"resolver.start\":\n resolversRun.add(event.resolver);\n break;\n case \"effect.run\":\n effectsRun.add(event.id);\n break;\n case \"derivation.compute\":\n derivationsComputed.add(event.id);\n break;\n }\n });\n\n try {\n await scenario();\n } finally {\n unsub?.();\n unsub = null;\n }\n },\n\n report(): CoverageReport {\n const inspection = system.inspect();\n\n const allConstraints = new Set(inspection.constraints.map((c) => c.id));\n const allResolvers = new Set(inspection.resolverDefs.map((r) => r.id));\n\n const constraintsMissed = new Set<string>();\n for (const id of allConstraints) {\n if (!constraintsHit.has(id)) constraintsMissed.add(id);\n }\n\n const resolversMissed = new Set<string>();\n for (const id of allResolvers) {\n if (!resolversRun.has(id)) resolversMissed.add(id);\n }\n\n return {\n constraintsHit,\n constraintsMissed,\n resolversRun,\n resolversMissed,\n effectsRun,\n derivationsComputed,\n constraintCoverage:\n allConstraints.size === 0\n ? 1\n : constraintsHit.size / allConstraints.size,\n resolverCoverage:\n allResolvers.size === 0 ? 1 : resolversRun.size / allResolvers.size,\n effectCoverage:\n inspection.effects.length === 0\n ? 1\n : effectsRun.size / inspection.effects.length,\n derivationCoverage:\n inspection.derivations.length === 0\n ? 1\n : derivationsComputed.size / inspection.derivations.length,\n };\n },\n };\n}\n\n// ============================================================================\n// Test Observer\n// ============================================================================\n\n/**\n * Create a test observer that collects all observation events.\n * Useful for assertion-based testing of system behavior.\n *\n * @example\n * ```typescript\n * const observer = createTestObserver(system);\n *\n * system.facts.count = 5;\n * await system.settle();\n *\n * expect(observer.events.filter(e => e.type === \"constraint.evaluate\")).toHaveLength(1);\n * expect(observer.ofType(\"resolver.complete\")).toHaveLength(1);\n *\n * observer.clear();\n * observer.dispose();\n * ```\n */\nexport function createTestObserver(\n // biome-ignore lint/suspicious/noExplicitAny: Works with any system type\n system: SingleModuleSystem<any> | NamespacedSystem<any>,\n): {\n /** All collected events. */\n events: import(\"../core/types/system.js\").ObservationEvent[];\n /** Filter events by type. */\n ofType: <\n T extends import(\"../core/types/system.js\").ObservationEvent[\"type\"],\n >(\n type: T,\n ) => Extract<\n import(\"../core/types/system.js\").ObservationEvent,\n { type: T }\n >[];\n /** Clear collected events. */\n clear: () => void;\n /** Stop observing. */\n dispose: () => void;\n} {\n const events: import(\"../core/types/system.js\").ObservationEvent[] = [];\n const unsub = system.observe((event) => events.push(event));\n\n return {\n events,\n ofType(type) {\n return events.filter((e) => e.type === type) as any;\n },\n clear() {\n events.length = 0;\n },\n dispose() {\n unsub();\n },\n };\n}\n"]}
{"version":3,"sources":["../src/utils/testing.ts"],"names":["flushMicrotasks","i","flushAsync","r","settleWithFakeTimers","system","advanceTime","options","totalTime","stepSize","maxIterations","elapsed","iterations","finalInspection","resolverIds","createFakeTimers","currentTime","timers","ms","targetTime","timer","createMockResolver","typeOrOptions","req","calls","_req","ctx","resolve","mockResolver","_requirementType","pending","result","item","error","_ctx","reject","val","createTestSystem","createTestSystemSingle","createTestSystemNamed","eventHistory","resolverCalls","allRequirements","factsHistory","mockResolvers","type","mockOptions","moduleWithMocks","createSystem","fullKey","value","previousValue","requirement","originalDispatch","event","maxWait","startTime","checkIdle","inspection","times","key","changes","c","actualValues","modulesWithMocks","name","module","moduleNamespaces","sepIndex","namespace","possibleNamespace","assertDynamic","id","getDynamicCheck","assertNotDynamic","createCoverageTracker","constraintsHit","resolversRun","effectsRun","derivationsComputed","unsub","scenario","allConstraints","allResolvers","constraintsMissed","resolversMissed","createTestObserver","events","e"],"mappings":"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","file":"testing.js","sourcesContent":["/**\n * Testing Utilities - Helpers for testing Directive systems\n *\n * Features:\n * - Mock resolvers with manual resolve/reject\n * - Fake timers integration (works with Vitest/Jest fake timers)\n * - Assertion helpers\n * - Facts history tracking\n * - Pending requirements tracking\n */\n\nimport { createSystem } from \"../core/system.js\";\nimport type {\n CreateSystemOptionsNamed,\n CreateSystemOptionsSingle,\n ModuleDef,\n ModuleSchema,\n ModulesMap,\n NamespacedSystem,\n Requirement,\n RequirementWithId,\n SingleModuleSystem,\n SystemInspection,\n} from \"../core/types.js\";\n\n// ============================================================================\n// Fake Timers Integration\n// ============================================================================\n\n/**\n * Flush all pending microtasks by awaiting multiple rounds of `Promise.resolve()`.\n *\n * Call this after advancing fake timers to ensure all Promise callbacks\n * (including nested microtasks) have run before making assertions.\n *\n * @returns A promise that resolves after all pending microtasks have been drained.\n *\n * @example\n * ```typescript\n * vi.useFakeTimers();\n * system.start();\n * system.facts.userId = 1; // Triggers constraint\n * await flushMicrotasks(); // Let reconciliation start\n * vi.advanceTimersByTime(100); // Advance resolver delay\n * await flushMicrotasks(); // Let resolver complete\n * ```\n *\n * @public\n */\nexport async function flushMicrotasks(): Promise<void> {\n // Multiple rounds to catch nested microtasks\n for (let i = 0; i < 10; i++) {\n await Promise.resolve();\n }\n}\n\n/**\n * Drain a full constraint → resolver → effect pipeline, including macrotasks.\n *\n * Performs a 3-pass / 2-`setTimeout(0)` sequence that empties microtask queues\n * twice across two macrotask boundaries. Use this when a single\n * {@link flushMicrotasks} pass is not enough to reach quiescence — typically\n * when constraints schedule resolvers that schedule further constraints, or\n * when test code uses `queueMicrotask` / `Promise.resolve()` chains that\n * cross a `setTimeout(..., 0)` boundary inside the engine.\n *\n * @remarks\n * **When to use which:**\n * - {@link flushMicrotasks}: Fast path for a single microtask drain (e.g.\n * waiting for one Promise chain to settle).\n * - `flushAsync`: Heavier pass for full constraint+resolver pipelines where\n * reconciliation may emit follow-up requirements, retries, or batched\n * resolver flushes that span a macrotask.\n *\n * The exact shape (3 microtask rounds → setTimeout 0 → 3 microtask rounds →\n * setTimeout 0 → 3 microtask rounds) was extracted from a helper duplicated\n * across 50+ migration tests; centralizing it here keeps the drain semantics\n * consistent and lets the engine evolve without fan-out edits.\n *\n * @returns A promise that resolves after the full drain completes.\n *\n * @example\n * ```typescript\n * system.facts.userId = 1; // triggers constraint → resolver chain\n * await flushAsync(); // drains constraint + resolver + follow-up effects\n * expect(system.facts.user).toEqual({ id: 1, ... });\n * ```\n *\n * @public\n */\nexport async function flushAsync(): Promise<void> {\n for (let i = 0; i < 10; i++) await Promise.resolve();\n await new Promise((r) => setTimeout(r, 0));\n for (let i = 0; i < 10; i++) await Promise.resolve();\n await new Promise((r) => setTimeout(r, 0));\n for (let i = 0; i < 10; i++) await Promise.resolve();\n}\n\n/**\n * Wait for the system to settle with fake timers enabled.\n *\n * Repeatedly advances fake timers in discrete steps while flushing microtasks,\n * until no resolvers remain inflight or the time budget is exhausted.\n *\n * @param system - The Directive system to wait on (must expose {@link SystemInspection} via `inspect()`).\n * @param advanceTime - Function that advances fake timers by a given number of milliseconds (e.g., `vi.advanceTimersByTime`).\n * @param options - Configuration for total time budget, step size, and iteration limit.\n * @returns A promise that resolves once the system is idle.\n *\n * @throws Error if the system does not settle within the configured time budget.\n *\n * @example\n * ```typescript\n * vi.useFakeTimers();\n * const system = createSystem({ modules: [myModule] });\n * system.start();\n * system.dispatch({ type: \"triggerAsync\" });\n *\n * await settleWithFakeTimers(system, vi.advanceTimersByTime, {\n * totalTime: 1000,\n * stepSize: 10,\n * });\n *\n * expect(system.facts.result).toBe(\"done\");\n * ```\n *\n * @public\n */\nexport async function settleWithFakeTimers(\n system: { inspect(): SystemInspection },\n advanceTime: (ms: number) => void,\n options: {\n /** Total time to advance (default: 5000ms) */\n totalTime?: number;\n /** Time to advance each step (default: 10ms) */\n stepSize?: number;\n /** Maximum iterations before giving up (default: 1000) */\n maxIterations?: number;\n } = {},\n): Promise<void> {\n const { totalTime = 5000, stepSize = 10, maxIterations = 1000 } = options;\n\n let elapsed = 0;\n let iterations = 0;\n\n while (elapsed < totalTime && iterations < maxIterations) {\n // Flush microtasks first (handles queueMicrotask, Promise.resolve)\n await flushMicrotasks();\n\n // Check if settled\n const inspection = system.inspect();\n if (inspection.inflight.length === 0) {\n // One more flush to be safe\n await flushMicrotasks();\n return;\n }\n\n // Advance fake timers\n advanceTime(stepSize);\n elapsed += stepSize;\n iterations++;\n }\n\n // Final check\n const finalInspection = system.inspect();\n if (finalInspection.inflight.length > 0) {\n const resolverIds = finalInspection.inflight\n .map((r) => r.resolverId)\n .join(\", \");\n throw new Error(\n `[Directive] settleWithFakeTimers did not settle after ${totalTime}ms. ${finalInspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n}\n\n// ============================================================================\n// Fake Timers (for standalone use without vi.useFakeTimers)\n// ============================================================================\n\n/**\n * Standalone fake timer controller for tests that do not use Vitest/Jest fake timers.\n *\n * @remarks\n * For most tests, prefer Vitest's `vi.useFakeTimers()` paired with\n * {@link settleWithFakeTimers} for better integration. Use this interface\n * only when you need a lightweight, framework-independent timer mock.\n *\n * @public\n */\nexport interface FakeTimers {\n /** Advance time by a number of milliseconds, firing any timers that fall within the window. */\n advance(ms: number): Promise<void>;\n /** Advance to the next scheduled timer and fire its callback. */\n next(): Promise<void>;\n /** Run all pending timers in chronological order. */\n runAll(): Promise<void>;\n /** Get the current fake time in milliseconds. */\n now(): number;\n /** Reset the clock to time 0 and discard all scheduled timers. */\n reset(): void;\n}\n\n/**\n * Create standalone fake timers for testing without a framework timer mock.\n *\n * @remarks\n * For most tests, prefer Vitest's `vi.useFakeTimers()` paired with\n * {@link settleWithFakeTimers}. This factory is useful when you need an\n * isolated timer that does not interfere with global timer state.\n *\n * @returns A {@link FakeTimers} controller with `advance`, `next`, `runAll`, `now`, and `reset` methods.\n *\n * @example\n * ```typescript\n * const timers = createFakeTimers();\n * // schedule work, then:\n * await timers.advance(500);\n * expect(timers.now()).toBe(500);\n * ```\n *\n * @public\n */\nexport function createFakeTimers(): FakeTimers {\n let currentTime = 0;\n const timers: Array<{ time: number; callback: () => void }> = [];\n\n return {\n async advance(ms: number): Promise<void> {\n const targetTime = currentTime + ms;\n\n // Run all timers that would fire during this advance\n while (timers.length > 0 && timers[0]!.time <= targetTime) {\n const timer = timers.shift()!;\n currentTime = timer.time;\n timer.callback();\n await Promise.resolve(); // Allow microtasks\n }\n\n currentTime = targetTime;\n },\n\n async next(): Promise<void> {\n if (timers.length === 0) return;\n\n const timer = timers.shift()!;\n currentTime = timer.time;\n timer.callback();\n await Promise.resolve();\n },\n\n async runAll(): Promise<void> {\n while (timers.length > 0) {\n await this.next();\n }\n },\n\n now(): number {\n return currentTime;\n },\n\n reset(): void {\n currentTime = 0;\n timers.length = 0;\n },\n };\n}\n\n// ============================================================================\n// Mock Resolvers\n// ============================================================================\n\n/**\n * Context passed to mock resolver resolve functions.\n *\n * @public\n */\nexport interface MockResolverContext {\n /** Facts object (use type assertion for specific facts) */\n // biome-ignore lint/suspicious/noExplicitAny: Facts type varies by system\n facts: any;\n /** Abort signal for cancellation */\n signal: AbortSignal;\n}\n\n/**\n * Configuration for a simple mock resolver created via {@link createMockResolver}.\n *\n * @typeParam R - The requirement type this resolver handles.\n *\n * @public\n */\nexport interface MockResolverOptions<R extends Requirement = Requirement> {\n /** Predicate to check if this resolver handles a given requirement. */\n requirement?: (req: Requirement) => req is R;\n /** Mock implementation invoked when the resolver runs. */\n resolve?: (req: R, ctx: MockResolverContext) => void | Promise<void>;\n /** Artificial delay in milliseconds before the resolver completes. */\n delay?: number;\n /** Error (or message string) to throw, simulating a resolver failure. */\n error?: Error | string;\n /** Array that receives every requirement passed to this resolver. */\n calls?: R[];\n}\n\n/** Internal resolver definition type for mock resolvers */\ninterface MockResolverDef {\n requirement: (req: Requirement) => boolean;\n resolve: (req: Requirement, ctx: MockResolverContext) => Promise<void>;\n}\n\n/**\n * Create a simple mock resolver that matches requirements by type and optionally\n * records calls, injects delays, or throws errors.\n *\n * @param typeOrOptions - A requirement type string, or a full {@link MockResolverOptions} object.\n * @returns A resolver definition that can be spread into a module's `resolvers` map.\n *\n * @example\n * ```typescript\n * const calls: Requirement[] = [];\n * const mock = createMockResolver({ requirement: (r): r is MyReq => r.type === \"LOAD\", calls });\n * ```\n *\n * @public\n */\nexport function createMockResolver<R extends Requirement = Requirement>(\n typeOrOptions: string | MockResolverOptions<R>,\n): MockResolverDef {\n const options: MockResolverOptions<R> =\n typeof typeOrOptions === \"string\"\n ? {\n requirement: ((req: Requirement) => req.type === typeOrOptions) as (\n req: Requirement,\n ) => req is R,\n }\n : typeOrOptions;\n\n const calls: R[] = options.calls ?? [];\n\n return {\n requirement:\n options.requirement ?? ((_req: Requirement): _req is R => true),\n async resolve(req: Requirement, ctx: MockResolverContext): Promise<void> {\n calls.push(req as R);\n\n if (options.delay) {\n await new Promise((resolve) => setTimeout(resolve, options.delay));\n }\n\n if (options.error) {\n throw typeof options.error === \"string\"\n ? new Error(options.error)\n : options.error;\n }\n\n if (options.resolve) {\n await options.resolve(req as R, ctx);\n }\n },\n };\n}\n\n// ============================================================================\n// Mock Resolver (Advanced)\n// ============================================================================\n\n/**\n * A mock resolver that captures requirements for manual resolution.\n *\n * @remarks\n * Use this when you need fine-grained control over when and how requirements\n * resolve. Requirements are queued in `pending` and stay unresolved until you\n * explicitly call `resolve()` or `reject()`.\n *\n * @typeParam R - The requirement type this resolver handles.\n *\n * @public\n */\nexport interface MockResolver<R extends Requirement = Requirement> {\n /** All requirements received by this resolver */\n readonly calls: R[];\n /** Pending requirements waiting to be resolved/rejected */\n readonly pending: Array<{\n requirement: R;\n resolve: (result?: unknown) => void;\n reject: (error: Error) => void;\n }>;\n /** Resolve the next pending requirement */\n resolve(result?: unknown): void;\n /** Reject the next pending requirement */\n reject(error: Error): void;\n /** Resolve all pending requirements */\n resolveAll(result?: unknown): void;\n /** Reject all pending requirements */\n rejectAll(error: Error): void;\n /** Clear call history and pending queue */\n reset(): void;\n}\n\n/**\n * Create a mock resolver that captures requirements instead of resolving them,\n * giving you manual control over when and how each requirement completes.\n *\n * @param _requirementType - The requirement `type` string this mock handles (used for documentation; matching is done by the test harness).\n * @returns A {@link MockResolver} with a `handler` function suitable for passing to {@link createTestSystem} mocks.\n *\n * @example\n * ```typescript\n * const fetchMock = mockResolver<{ type: \"FETCH_USER\"; id: string }>(\"FETCH_USER\");\n *\n * const system = createTestSystem({\n * modules: [userModule],\n * mocks: {\n * resolvers: {\n * FETCH_USER: { resolve: fetchMock.handler },\n * },\n * },\n * });\n *\n * system.facts.userId = \"123\";\n * await flushMicrotasks();\n *\n * // Requirement is pending\n * expect(fetchMock.calls).toHaveLength(1);\n * expect(fetchMock.calls[0].id).toBe(\"123\");\n *\n * // Manually resolve it\n * fetchMock.resolve({ name: \"John\" });\n * await flushMicrotasks();\n *\n * expect(system.facts.user).toEqual({ name: \"John\" });\n * ```\n *\n * @public\n */\nexport function mockResolver<R extends Requirement = Requirement>(\n _requirementType: string,\n): MockResolver<R> & {\n /** Handler that can be passed to createTestSystem mocks */\n handler: (req: Requirement, ctx: MockResolverContext) => Promise<void>;\n} {\n const calls: R[] = [];\n const pending: Array<{\n requirement: R;\n resolve: (result?: unknown) => void;\n reject: (error: Error) => void;\n }> = [];\n\n const mock: MockResolver<R> = {\n get calls() {\n return calls;\n },\n get pending() {\n return pending;\n },\n resolve(result?: unknown) {\n const item = pending.shift();\n if (item) {\n item.resolve(result);\n }\n },\n reject(error: Error) {\n const item = pending.shift();\n if (item) {\n item.reject(error);\n }\n },\n resolveAll(result?: unknown) {\n while (pending.length > 0) {\n this.resolve(result);\n }\n },\n rejectAll(error: Error) {\n while (pending.length > 0) {\n this.reject(error);\n }\n },\n reset() {\n calls.length = 0;\n pending.length = 0;\n },\n };\n\n const handler = (\n req: Requirement,\n _ctx: MockResolverContext,\n ): Promise<void> => {\n calls.push(req as R);\n return new Promise<void>((resolve, reject) => {\n pending.push({\n requirement: req as R,\n resolve: (val?: unknown) => resolve(val as void),\n reject,\n });\n });\n };\n\n return {\n ...mock,\n handler,\n };\n}\n\n// ============================================================================\n// Fact Change Tracking\n// ============================================================================\n\n/**\n * Record of a single fact change captured by the test tracking plugin.\n *\n * @public\n */\nexport interface FactChangeRecord {\n /** The fact key that changed (without namespace prefix for namespaced systems) */\n key: string;\n /** The full key including namespace prefix (e.g., \"test::value\") */\n fullKey: string;\n /** The namespace (e.g., \"test\") - undefined for single-module systems */\n namespace?: string;\n /** The previous value */\n previousValue: unknown;\n /** The new value */\n newValue: unknown;\n /** Timestamp of the change */\n timestamp: number;\n}\n\n// ============================================================================\n// Test System\n// ============================================================================\n\n/** Common testing utilities shared by both single-module and namespaced test systems. */\nexport interface TestSystemBase {\n /**\n * Wait for all pending operations to complete.\n * @param maxWait - Maximum time to wait in ms (default: 5000)\n * @throws Error if timeout is exceeded with resolvers still inflight\n */\n waitForIdle(maxWait?: number): Promise<void>;\n /** Get the history of dispatched events */\n eventHistory: Array<{ type: string; [key: string]: unknown }>;\n /** Get resolver call history */\n resolverCalls: Map<string, Requirement[]>;\n /**\n * Get all requirements that have been generated (both resolved and pending).\n * Unlike `inspect().unmet`, this includes requirements that have already been handled.\n */\n readonly allRequirements: RequirementWithId[];\n /**\n * Get all fact changes since system start or last reset.\n */\n getFactsHistory(): FactChangeRecord[];\n /**\n * Reset the facts history tracking.\n */\n resetFactsHistory(): void;\n /** Assert that a requirement was created */\n assertRequirement(type: string): void;\n /** Assert that a resolver was called */\n assertResolverCalled(type: string, times?: number): void;\n /**\n * Assert that a fact was set to a specific value.\n */\n assertFactSet(key: string, value?: unknown): void;\n /**\n * Assert the number of times a fact was changed.\n */\n assertFactChanges(key: string, times: number): void;\n}\n\n/**\n * A single-module Directive system augmented with testing utilities.\n *\n * @remarks\n * Extends {@link SingleModuleSystem} with event/resolver/fact tracking, idle\n * waiting, and assertion helpers. Created via {@link createTestSystem}.\n *\n * @typeParam S - The module schema.\n *\n * @public\n */\nexport interface TestSystemSingle<S extends ModuleSchema>\n extends SingleModuleSystem<S>,\n TestSystemBase {}\n\n/**\n * A Directive system augmented with testing utilities.\n *\n * @remarks\n * Extends {@link NamespacedSystem} with event/resolver/fact tracking, idle\n * waiting, and assertion helpers. Created via {@link createTestSystem}.\n *\n * @typeParam Modules - The modules map that defines the system's schema.\n *\n * @public\n */\nexport interface TestSystem<Modules extends ModulesMap>\n extends NamespacedSystem<Modules>,\n TestSystemBase {}\n\n/**\n * Options for {@link createTestSystem}, extending the standard system options\n * with mock resolver injection and automatic tracking.\n *\n * @typeParam Modules - The modules map that defines the system's schema.\n *\n * @public\n */\nexport interface CreateTestSystemOptions<Modules extends ModulesMap>\n extends Omit<CreateSystemOptionsNamed<Modules>, \"plugins\"> {\n /** Mock resolvers by type */\n mocks?: {\n resolvers?: Record<string, MockResolverOptions>;\n };\n /** Additional plugins (tracking plugin is added automatically) */\n // biome-ignore lint/suspicious/noExplicitAny: Plugins are schema-agnostic\n plugins?: any[];\n}\n\n/**\n * Options for {@link createTestSystem} with a single module (no namespacing).\n *\n * @typeParam S - The module schema.\n *\n * @public\n */\nexport interface CreateTestSystemOptionsSingle<S extends ModuleSchema>\n extends Omit<CreateSystemOptionsSingle<S>, \"plugins\"> {\n /** Mock resolvers by type */\n mocks?: {\n resolvers?: Record<string, MockResolverOptions>;\n };\n /** Additional plugins (tracking plugin is added automatically) */\n // biome-ignore lint/suspicious/noExplicitAny: Plugins are schema-agnostic\n plugins?: any[];\n}\n\n/**\n * Create a Directive system instrumented for testing.\n *\n * Wraps {@link createSystem} with an automatic tracking plugin that records\n * dispatched events, resolver calls, fact changes, and generated requirements.\n * Mock resolvers can be injected via `options.mocks.resolvers` to replace\n * real resolvers by requirement type.\n *\n * @param options - System configuration with optional mock resolvers and additional plugins.\n * @returns A {@link TestSystem} or {@link TestSystemSingle} with assertion helpers, idle waiting, and history tracking.\n *\n * @example\n * ```typescript\n * // Namespaced (multiple modules)\n * const system = createTestSystem({\n * modules: { counter: counterModule },\n * mocks: { resolvers: { INCREMENT: { resolve: (req, context) => { context.facts.count++; } } } },\n * });\n *\n * // Single module\n * const system = createTestSystem({\n * module: counterModule,\n * });\n * system.start();\n * ```\n *\n * @public\n */\nexport function createTestSystem<S extends ModuleSchema>(\n options: CreateTestSystemOptionsSingle<S>,\n): TestSystemSingle<S>;\nexport function createTestSystem<Modules extends ModulesMap>(\n options: CreateTestSystemOptions<Modules>,\n): TestSystem<Modules>;\n/** @internal — implementation signature for the overloads above. */\nexport function createTestSystem<\n S extends ModuleSchema,\n Modules extends ModulesMap,\n>(\n options: CreateTestSystemOptionsSingle<S> | CreateTestSystemOptions<Modules>,\n): TestSystemSingle<S> | TestSystem<Modules> {\n // Single module mode: wrap into namespaced and delegate\n if (\"module\" in options) {\n return createTestSystemSingle(options as CreateTestSystemOptionsSingle<S>);\n }\n\n return createTestSystemNamed(options as CreateTestSystemOptions<Modules>);\n}\n\nfunction createTestSystemSingle<S extends ModuleSchema>(\n options: CreateTestSystemOptionsSingle<S>,\n): TestSystemSingle<S> {\n const eventHistory: Array<{ type: string; [key: string]: unknown }> = [];\n const resolverCalls = new Map<string, Requirement[]>();\n const allRequirements: RequirementWithId[] = [];\n const factsHistory: FactChangeRecord[] = [];\n\n // Create mock resolvers\n const mockResolvers: Record<string, MockResolverDef> = {};\n if (options.mocks?.resolvers) {\n for (const [type, mockOptions] of Object.entries(options.mocks.resolvers)) {\n const calls: Requirement[] = [];\n resolverCalls.set(type, calls);\n mockResolvers[type] = createMockResolver({ ...mockOptions, calls });\n }\n }\n\n // Create module with mock resolvers\n // biome-ignore lint/suspicious/noExplicitAny: Mock resolvers have simplified types\n const moduleWithMocks: ModuleDef<S> = {\n ...options.module,\n resolvers: {\n ...options.module.resolvers,\n ...mockResolvers,\n } as any,\n };\n\n // Create tracking plugin\n const trackingPlugin = {\n name: \"__test-tracking__\",\n onFactSet: (fullKey: string, value: unknown, previousValue: unknown) => {\n factsHistory.push({\n key: fullKey,\n fullKey,\n namespace: undefined,\n previousValue,\n newValue: value,\n timestamp: Date.now(),\n });\n },\n onRequirementCreated: (requirement: RequirementWithId) => {\n allRequirements.push(requirement);\n },\n };\n\n // Create the underlying single-module system\n const system = createSystem({\n ...options,\n module: moduleWithMocks,\n plugins: [trackingPlugin, ...(options.plugins ?? [])],\n // biome-ignore lint/suspicious/noExplicitAny: Internal overload compatibility\n } as any) as SingleModuleSystem<S>;\n\n // Wrap dispatch to track events\n const originalDispatch = system.dispatch.bind(system);\n // biome-ignore lint/suspicious/noExplicitAny: Event type varies\n (system as any).dispatch = (event: any) => {\n eventHistory.push(event);\n originalDispatch(event);\n };\n\n const testSystem: TestSystemSingle<S> = {\n ...system,\n eventHistory,\n resolverCalls,\n\n get allRequirements() {\n return allRequirements;\n },\n\n getFactsHistory(): FactChangeRecord[] {\n return [...factsHistory];\n },\n\n resetFactsHistory(): void {\n factsHistory.length = 0;\n },\n\n async waitForIdle(maxWait = 5000): Promise<void> {\n const startTime = Date.now();\n\n const checkIdle = async (): Promise<void> => {\n await new Promise((resolve) => setTimeout(resolve, 0));\n const inspection = system.inspect();\n if (inspection.inflight.length > 0) {\n if (Date.now() - startTime > maxWait) {\n const resolverIds = inspection.inflight.map((r) => r.id).join(\", \");\n throw new Error(\n `[Directive] waitForIdle timed out after ${maxWait}ms. ${inspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n await new Promise((resolve) => setTimeout(resolve, 10));\n\n return checkIdle();\n }\n };\n\n return checkIdle();\n },\n\n assertRequirement(type: string): void {\n const hasRequirement = allRequirements.some(\n (r) => r.requirement.type === type,\n );\n if (!hasRequirement) {\n throw new Error(\n `[Directive] Expected requirement of type \"${type}\" but none found`,\n );\n }\n },\n\n assertResolverCalled(type: string, times?: number): void {\n const calls = resolverCalls.get(type) ?? [];\n if (times !== undefined) {\n if (calls.length !== times) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called ${times} times but was called ${calls.length} times`,\n );\n }\n } else if (calls.length === 0) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called but it was not`,\n );\n }\n },\n\n assertFactSet(key: string, value?: unknown): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length === 0) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set but it was not`,\n );\n }\n if (value !== undefined) {\n const hasValue = changes.some((c) => c.newValue === value);\n if (!hasValue) {\n const actualValues = changes\n .map((c) => JSON.stringify(c.newValue))\n .join(\", \");\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set to ${JSON.stringify(value)} but got: ${actualValues}`,\n );\n }\n }\n },\n\n assertFactChanges(key: string, times: number): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length !== times) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to change ${times} times but it changed ${changes.length} times`,\n );\n }\n },\n };\n\n return testSystem;\n}\n\nfunction createTestSystemNamed<Modules extends ModulesMap>(\n options: CreateTestSystemOptions<Modules>,\n): TestSystem<Modules> {\n const eventHistory: Array<{ type: string; [key: string]: unknown }> = [];\n const resolverCalls = new Map<string, Requirement[]>();\n const allRequirements: RequirementWithId[] = [];\n const factsHistory: FactChangeRecord[] = [];\n\n // Create mock resolvers\n const mockResolvers: Record<string, MockResolverDef> = {};\n if (options.mocks?.resolvers) {\n for (const [type, mockOptions] of Object.entries(options.mocks.resolvers)) {\n const calls: Requirement[] = [];\n resolverCalls.set(type, calls);\n mockResolvers[type] = createMockResolver({ ...mockOptions, calls });\n }\n }\n\n // Create modules with mock resolvers\n const modulesWithMocks: Modules = {} as Modules;\n for (const [name, module] of Object.entries(options.modules)) {\n // biome-ignore lint/suspicious/noExplicitAny: Module types are complex\n (modulesWithMocks as any)[name] = {\n ...module,\n resolvers: {\n ...module.resolvers,\n ...mockResolvers,\n },\n };\n }\n\n // Get module namespaces for key parsing\n const moduleNamespaces = new Set(Object.keys(options.modules));\n\n // Create tracking plugin\n const trackingPlugin = {\n name: \"__test-tracking__\",\n onFactSet: (fullKey: string, value: unknown, previousValue: unknown) => {\n // Parse namespaced key (e.g., \"test::value\" -> namespace: \"test\", key: \"value\")\n const SEPARATOR = \"::\";\n const sepIndex = fullKey.indexOf(SEPARATOR);\n let namespace: string | undefined;\n let key: string;\n\n if (sepIndex > 0) {\n const possibleNamespace = fullKey.substring(0, sepIndex);\n if (moduleNamespaces.has(possibleNamespace)) {\n namespace = possibleNamespace;\n key = fullKey.substring(sepIndex + SEPARATOR.length);\n } else {\n key = fullKey;\n }\n } else {\n key = fullKey;\n }\n\n factsHistory.push({\n key,\n fullKey,\n namespace,\n previousValue,\n newValue: value,\n timestamp: Date.now(),\n });\n },\n onRequirementCreated: (requirement: RequirementWithId) => {\n allRequirements.push(requirement);\n },\n };\n\n // Create the underlying system\n const system = createSystem({\n ...options,\n modules: modulesWithMocks,\n plugins: [trackingPlugin, ...(options.plugins ?? [])],\n }) as NamespacedSystem<Modules>;\n\n // Wrap dispatch to track events\n const originalDispatch = system.dispatch.bind(system);\n // biome-ignore lint/suspicious/noExplicitAny: Event type varies\n (system as any).dispatch = (event: any) => {\n eventHistory.push(event);\n originalDispatch(event);\n };\n\n const testSystem: TestSystem<Modules> = {\n ...system,\n eventHistory,\n resolverCalls,\n\n get allRequirements() {\n return allRequirements;\n },\n\n getFactsHistory(): FactChangeRecord[] {\n return [...factsHistory];\n },\n\n resetFactsHistory(): void {\n factsHistory.length = 0;\n },\n\n async waitForIdle(maxWait = 5000): Promise<void> {\n const startTime = Date.now();\n\n const checkIdle = async (): Promise<void> => {\n // Wait for microtasks\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n // Check if there are inflight resolvers\n const inspection = system.inspect();\n if (inspection.inflight.length > 0) {\n // Check timeout\n if (Date.now() - startTime > maxWait) {\n const resolverIds = inspection.inflight.map((r) => r.id).join(\", \");\n throw new Error(\n `[Directive] waitForIdle timed out after ${maxWait}ms. ${inspection.inflight.length} resolvers still inflight: ${resolverIds}`,\n );\n }\n // Wait a bit more and check again\n await new Promise((resolve) => setTimeout(resolve, 10));\n return checkIdle();\n }\n };\n\n return checkIdle();\n },\n\n assertRequirement(type: string): void {\n const hasRequirement = allRequirements.some(\n (r) => r.requirement.type === type,\n );\n if (!hasRequirement) {\n throw new Error(\n `[Directive] Expected requirement of type \"${type}\" but none found`,\n );\n }\n },\n\n assertResolverCalled(type: string, times?: number): void {\n const calls = resolverCalls.get(type) ?? [];\n if (times !== undefined) {\n if (calls.length !== times) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called ${times} times but was called ${calls.length} times`,\n );\n }\n } else if (calls.length === 0) {\n throw new Error(\n `[Directive] Expected resolver \"${type}\" to be called but it was not`,\n );\n }\n },\n\n assertFactSet(key: string, value?: unknown): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length === 0) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set but it was not`,\n );\n }\n if (value !== undefined) {\n const hasValue = changes.some((c) => c.newValue === value);\n if (!hasValue) {\n const actualValues = changes\n .map((c) => JSON.stringify(c.newValue))\n .join(\", \");\n throw new Error(\n `[Directive] Expected fact \"${key}\" to be set to ${JSON.stringify(value)} but got: ${actualValues}`,\n );\n }\n }\n },\n\n assertFactChanges(key: string, times: number): void {\n const changes = factsHistory.filter((c) => c.key === key);\n if (changes.length !== times) {\n throw new Error(\n `[Directive] Expected fact \"${key}\" to change ${times} times but it changed ${changes.length} times`,\n );\n }\n },\n };\n\n return testSystem;\n}\n\n// ============================================================================\n// Dynamic Definition Assertions\n// ============================================================================\n\n/**\n * Assert that a definition was dynamically registered on the system.\n *\n * @param system - The Directive system to check.\n * @param type - The definition type: \"constraint\", \"resolver\", \"derivation\", or \"effect\".\n * @param id - The definition ID.\n * @throws Error if the definition is not dynamic.\n *\n * @example\n * ```typescript\n * system.constraints.register(\"myRule\", { when: () => true, require: { type: \"DO\" } });\n * assertDynamic(system, \"constraint\", \"myRule\"); // passes\n * assertDynamic(system, \"constraint\", \"staticRule\"); // throws\n * ```\n *\n * @public\n */\nexport function assertDynamic(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): void {\n const isDynamic = getDynamicCheck(system, type, id);\n if (!isDynamic) {\n throw new Error(\n `[Directive] Expected ${type} \"${id}\" to be dynamic, but it is not.`,\n );\n }\n}\n\n/**\n * Assert that a definition is NOT dynamically registered (i.e., is static or does not exist).\n *\n * @param system - The Directive system to check.\n * @param type - The definition type: \"constraint\", \"resolver\", \"derivation\", or \"effect\".\n * @param id - The definition ID.\n * @throws Error if the definition is dynamic.\n *\n * @example\n * ```typescript\n * assertNotDynamic(system, \"constraint\", \"staticRule\"); // passes\n * system.constraints.register(\"myRule\", def);\n * assertNotDynamic(system, \"constraint\", \"myRule\"); // throws\n * ```\n *\n * @public\n */\nexport function assertNotDynamic(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): void {\n const isDynamic = getDynamicCheck(system, type, id);\n if (isDynamic) {\n throw new Error(\n `[Directive] Expected ${type} \"${id}\" to NOT be dynamic, but it is.`,\n );\n }\n}\n\n/** @internal */\nfunction getDynamicCheck(\n system: {\n constraints: { isDynamic(id: string): boolean };\n effects: { isDynamic(id: string): boolean };\n resolvers: { isDynamic(id: string): boolean };\n derive: { isDynamic(id: string): boolean };\n },\n type: \"constraint\" | \"resolver\" | \"derivation\" | \"effect\",\n id: string,\n): boolean {\n switch (type) {\n case \"constraint\":\n return system.constraints.isDynamic(id);\n case \"resolver\":\n return system.resolvers.isDynamic(id);\n case \"derivation\":\n return system.derive.isDynamic(id);\n case \"effect\":\n return system.effects.isDynamic(id);\n }\n}\n\n// ============================================================================\n// Constraint Coverage\n// ============================================================================\n\n/** Coverage report for a Directive system. */\nexport interface CoverageReport {\n /** Constraints that evaluated to true at least once. */\n constraintsHit: Set<string>;\n /** Constraints that never evaluated to true. */\n constraintsMissed: Set<string>;\n /** Resolvers that started at least once. */\n resolversRun: Set<string>;\n /** Resolvers that never started. */\n resolversMissed: Set<string>;\n /** Effects that ran at least once. */\n effectsRun: Set<string>;\n /** Derivations that recomputed at least once. */\n derivationsComputed: Set<string>;\n /** Coverage percentage (constraintsHit / total constraints). */\n constraintCoverage: number;\n /** Coverage percentage (resolversRun / total resolvers). */\n resolverCoverage: number;\n /** Coverage percentage (effectsRun / total effects). */\n effectCoverage: number;\n /** Coverage percentage (derivationsComputed / total derivations). */\n derivationCoverage: number;\n}\n\n/**\n * Track which constraints, resolvers, effects, and derivations are exercised\n * during a test scenario. Returns a coverage report after the scenario runs.\n *\n * @example\n * ```typescript\n * const { run, report } = createCoverageTracker(system);\n *\n * await run(async () => {\n * system.facts.userId = 123;\n * await system.settle();\n * system.facts.userId = 0;\n * await system.settle();\n * });\n *\n * const coverage = report();\n * expect(coverage.constraintCoverage).toBe(1); // All constraints hit\n * expect(coverage.constraintsMissed.size).toBe(0);\n * ```\n */\nexport function createCoverageTracker(\n // biome-ignore lint/suspicious/noExplicitAny: Works with any system type\n system: SingleModuleSystem<any> | NamespacedSystem<any>,\n): {\n /** Run a test scenario while tracking coverage. */\n run: (scenario: () => Promise<void> | void) => Promise<void>;\n /** Get the coverage report. */\n report: () => CoverageReport;\n} {\n const constraintsHit = new Set<string>();\n const resolversRun = new Set<string>();\n const effectsRun = new Set<string>();\n const derivationsComputed = new Set<string>();\n\n let unsub: (() => void) | null = null;\n\n return {\n async run(scenario) {\n unsub = system.observe((event) => {\n switch (event.type) {\n case \"constraint.evaluate\":\n if (event.active) constraintsHit.add(event.id);\n break;\n case \"resolver.start\":\n resolversRun.add(event.resolver);\n break;\n case \"effect.run\":\n effectsRun.add(event.id);\n break;\n case \"derivation.compute\":\n derivationsComputed.add(event.id);\n break;\n }\n });\n\n try {\n await scenario();\n } finally {\n unsub?.();\n unsub = null;\n }\n },\n\n report(): CoverageReport {\n const inspection = system.inspect();\n\n const allConstraints = new Set(inspection.constraints.map((c) => c.id));\n const allResolvers = new Set(inspection.resolverDefs.map((r) => r.id));\n\n const constraintsMissed = new Set<string>();\n for (const id of allConstraints) {\n if (!constraintsHit.has(id)) constraintsMissed.add(id);\n }\n\n const resolversMissed = new Set<string>();\n for (const id of allResolvers) {\n if (!resolversRun.has(id)) resolversMissed.add(id);\n }\n\n return {\n constraintsHit,\n constraintsMissed,\n resolversRun,\n resolversMissed,\n effectsRun,\n derivationsComputed,\n constraintCoverage:\n allConstraints.size === 0\n ? 1\n : constraintsHit.size / allConstraints.size,\n resolverCoverage:\n allResolvers.size === 0 ? 1 : resolversRun.size / allResolvers.size,\n effectCoverage:\n inspection.effects.length === 0\n ? 1\n : effectsRun.size / inspection.effects.length,\n derivationCoverage:\n inspection.derivations.length === 0\n ? 1\n : derivationsComputed.size / inspection.derivations.length,\n };\n },\n };\n}\n\n// ============================================================================\n// Test Observer\n// ============================================================================\n\n/**\n * Create a test observer that collects all observation events.\n * Useful for assertion-based testing of system behavior.\n *\n * @example\n * ```typescript\n * const observer = createTestObserver(system);\n *\n * system.facts.count = 5;\n * await system.settle();\n *\n * expect(observer.events.filter(e => e.type === \"constraint.evaluate\")).toHaveLength(1);\n * expect(observer.ofType(\"resolver.complete\")).toHaveLength(1);\n *\n * observer.clear();\n * observer.dispose();\n * ```\n */\nexport function createTestObserver(\n // biome-ignore lint/suspicious/noExplicitAny: Works with any system type\n system: SingleModuleSystem<any> | NamespacedSystem<any>,\n): {\n /** All collected events. */\n events: import(\"../core/types/system.js\").ObservationEvent[];\n /** Filter events by type. */\n ofType: <\n T extends import(\"../core/types/system.js\").ObservationEvent[\"type\"],\n >(\n type: T,\n ) => Extract<\n import(\"../core/types/system.js\").ObservationEvent,\n { type: T }\n >[];\n /** Clear collected events. */\n clear: () => void;\n /** Stop observing. */\n dispose: () => void;\n} {\n const events: import(\"../core/types/system.js\").ObservationEvent[] = [];\n const unsub = system.observe((event) => events.push(event));\n\n return {\n events,\n ofType(type) {\n return events.filter((e) => e.type === type) as any;\n },\n clear() {\n events.length = 0;\n },\n dispose() {\n unsub();\n },\n };\n}\n"]}

@@ -1,2 +0,2 @@

'use strict';function _(o){let{worker:c,onFactChange:l,onDerivationChange:y,onRequirementCreated:E,onRequirementMet:a,onError:r}=o,s=new Map,u=0,t=null,i=null,d=null,T=null;function g(e){return e?.(),null}function R(e,n){let S=s.get(e);S&&(S.resolve(n),s.delete(e));}function M(){t=g(t);}function m(){i=g(i);}function I(){d=g(d);}function b(){T=g(T);}function h(e){l?.(e.key,e.value,e.prev);}function O(e){y?.(e.key,e.value);}function W(e){E?.(e.requirement);}function C(e){a?.(e.requirementId,e.resolverId);}function P(e){r?.(e.error,e.source);}function D(e){R(e.requestId,e.snapshot);}function w(e){R(e.requestId,e.inspection);}function q(e){let n=s.get(e.requestId);n&&(e.success?n.resolve(void 0):n.reject(new Error(e.error||"Settle failed")),s.delete(e.requestId));}c.onmessage=e=>{let n=e.data;switch(n.type){case "READY":return M();case "STARTED":return m();case "STOPPED":return I();case "DESTROYED":return b();case "FACT_CHANGED":return h(n);case "DERIVATION_CHANGED":return O(n);case "REQUIREMENT_CREATED":return W(n);case "REQUIREMENT_MET":return C(n);case "ERROR":return P(n);case "SNAPSHOT_RESULT":return D(n);case "INSPECT_RESULT":return w(n);case "SETTLE_RESULT":return q(n)}},c.onerror=e=>{r?.(e.message,"worker");};function p(e){c.postMessage(e);}function k(e){return new Promise((n,S)=>{s.set(e.requestId,{resolve:n,reject:S}),p(e);})}return {init(e){return new Promise(n=>{t=n,p({type:"INIT",config:e});})},start(){return new Promise(e=>{i=e,p({type:"START"});})},stop(){return new Promise(e=>{d=e,p({type:"STOP"});})},destroy(){return new Promise(e=>{T=e,p({type:"DESTROY"});})},setFact(e,n){p({type:"SET_FACT",key:e,value:n});},setFacts(e){p({type:"SET_FACTS",facts:e});},dispatch(e){p({type:"DISPATCH",event:e});},getSnapshot(e){let n=`snapshot-${++u}`;return k({type:"GET_SNAPSHOT",options:e,requestId:n})},inspect(){let e=`inspect-${++u}`;return k({type:"INSPECT",requestId:e})},settle(e){let n=`settle-${++u}`;return k({type:"SETTLE",timeout:e,requestId:n})},terminate(){c.terminate();}}}var v=null;function f(){return v||(v=new Map),v}function N(o,c){f().set(o,c);}function x(){let o=null;async function c(t){let i=await A(t.config);return postMessage({type:"READY"}),i}function l(t){t.start(),postMessage({type:"STARTED"});}function y(t){t.stop(),postMessage({type:"STOPPED"});}function E(t){t.destroy(),postMessage({type:"DESTROYED"});}function a(t,i){let d=t.getSnapshot(i.options);postMessage({type:"SNAPSHOT_RESULT",requestId:i.requestId,snapshot:d});}function r(t,i){let d=t.inspect();postMessage({type:"INSPECT_RESULT",requestId:i.requestId,inspection:d});}async function s(t,i){try{await t.settle(i.timeout),postMessage({type:"SETTLE_RESULT",requestId:i.requestId,success:!0});}catch(d){postMessage({type:"SETTLE_RESULT",requestId:i.requestId,success:false,error:d instanceof Error?d.message:String(d)});}}async function u(t){if(t.type==="INIT"){o=await c(t);return}if(o)switch(t.type){case "START":l(o);break;case "STOP":y(o);break;case "DESTROY":E(o),o=null;break;case "SET_FACT":o.setFact(t.key,t.value);break;case "SET_FACTS":o.setFacts(t.facts);break;case "DISPATCH":o.dispatch(t.event);break;case "GET_SNAPSHOT":a(o,t);break;case "INSPECT":r(o,t);break;case "SETTLE":await s(o,t);break}}self.onmessage=async t=>{try{await u(t.data);}catch(i){postMessage({type:"ERROR",error:i instanceof Error?i.message:String(i),source:t.data.type});}};}async function A(o){let{createSystem:c}=await import('./system-GK3NSFQH.cjs'),l=f(),y={};for(let r of o.moduleNames){let s=l.get(r);if(!s)throw new Error(`[Directive Worker] Module "${r}" not registered. Call registerWorkerModule('${r}', module) before handling messages.`);y[r]=s;}let a=c({modules:y,plugins:[{name:"__worker-tracking__",onFactSet:(r,s,u)=>{postMessage({type:"FACT_CHANGED",key:r,value:s,prev:u});},onDerivationCompute:(r,s)=>{postMessage({type:"DERIVATION_CHANGED",key:r,value:s});},onRequirementCreated:r=>{postMessage({type:"REQUIREMENT_CREATED",requirement:{...r.requirement,id:r.id}});},onRequirementMet:(r,s)=>{postMessage({type:"REQUIREMENT_MET",requirementId:r.id,resolverId:s});}}],history:o.history});return {start:()=>a.start(),stop:()=>a.stop(),destroy:()=>a.destroy(),setFact:(r,s)=>{a.facts[r]=s;},setFacts:r=>{let s=a.facts;if(s.$store?.batch)s.$store.batch(()=>{for(let[u,t]of Object.entries(r))s[u]=t;});else for(let[u,t]of Object.entries(r))s[u]=t;},dispatch:r=>{a.dispatch(r);},getSnapshot:r=>a.getDistributableSnapshot(r),inspect:()=>a.inspect(),settle:r=>a.settle(r)}}exports.createWorkerClient=_;exports.getWorkerModuleRegistry=f;exports.handleWorkerMessages=x;exports.registerWorkerModule=N;//# sourceMappingURL=worker.cjs.map
'use strict';function _(o){let{worker:c,onFactChange:l,onDerivationChange:y,onRequirementCreated:E,onRequirementMet:a,onError:r}=o,s=new Map,u=0,t=null,i=null,d=null,T=null;function g(e){return e?.(),null}function R(e,n){let S=s.get(e);S&&(S.resolve(n),s.delete(e));}function M(){t=g(t);}function m(){i=g(i);}function I(){d=g(d);}function b(){T=g(T);}function h(e){l?.(e.key,e.value,e.prev);}function O(e){y?.(e.key,e.value);}function W(e){E?.(e.requirement);}function C(e){a?.(e.requirementId,e.resolverId);}function P(e){r?.(e.error,e.source);}function D(e){R(e.requestId,e.snapshot);}function w(e){R(e.requestId,e.inspection);}function q(e){let n=s.get(e.requestId);n&&(e.success?n.resolve(void 0):n.reject(new Error(e.error||"Settle failed")),s.delete(e.requestId));}c.onmessage=e=>{let n=e.data;switch(n.type){case "READY":return M();case "STARTED":return m();case "STOPPED":return I();case "DESTROYED":return b();case "FACT_CHANGED":return h(n);case "DERIVATION_CHANGED":return O(n);case "REQUIREMENT_CREATED":return W(n);case "REQUIREMENT_MET":return C(n);case "ERROR":return P(n);case "SNAPSHOT_RESULT":return D(n);case "INSPECT_RESULT":return w(n);case "SETTLE_RESULT":return q(n)}},c.onerror=e=>{r?.(e.message,"worker");};function p(e){c.postMessage(e);}function k(e){return new Promise((n,S)=>{s.set(e.requestId,{resolve:n,reject:S}),p(e);})}return {init(e){return new Promise(n=>{t=n,p({type:"INIT",config:e});})},start(){return new Promise(e=>{i=e,p({type:"START"});})},stop(){return new Promise(e=>{d=e,p({type:"STOP"});})},destroy(){return new Promise(e=>{T=e,p({type:"DESTROY"});})},setFact(e,n){p({type:"SET_FACT",key:e,value:n});},setFacts(e){p({type:"SET_FACTS",facts:e});},dispatch(e){p({type:"DISPATCH",event:e});},getSnapshot(e){let n=`snapshot-${++u}`;return k({type:"GET_SNAPSHOT",options:e,requestId:n})},inspect(){let e=`inspect-${++u}`;return k({type:"INSPECT",requestId:e})},settle(e){let n=`settle-${++u}`;return k({type:"SETTLE",timeout:e,requestId:n})},terminate(){c.terminate();}}}var v=null;function f(){return v||(v=new Map),v}function N(o,c){f().set(o,c);}function x(){let o=null;async function c(t){let i=await A(t.config);return postMessage({type:"READY"}),i}function l(t){t.start(),postMessage({type:"STARTED"});}function y(t){t.stop(),postMessage({type:"STOPPED"});}function E(t){t.destroy(),postMessage({type:"DESTROYED"});}function a(t,i){let d=t.getSnapshot(i.options);postMessage({type:"SNAPSHOT_RESULT",requestId:i.requestId,snapshot:d});}function r(t,i){let d=t.inspect();postMessage({type:"INSPECT_RESULT",requestId:i.requestId,inspection:d});}async function s(t,i){try{await t.settle(i.timeout),postMessage({type:"SETTLE_RESULT",requestId:i.requestId,success:!0});}catch(d){postMessage({type:"SETTLE_RESULT",requestId:i.requestId,success:false,error:d instanceof Error?d.message:String(d)});}}async function u(t){if(t.type==="INIT"){o=await c(t);return}if(o)switch(t.type){case "START":l(o);break;case "STOP":y(o);break;case "DESTROY":E(o),o=null;break;case "SET_FACT":o.setFact(t.key,t.value);break;case "SET_FACTS":o.setFacts(t.facts);break;case "DISPATCH":o.dispatch(t.event);break;case "GET_SNAPSHOT":a(o,t);break;case "INSPECT":r(o,t);break;case "SETTLE":await s(o,t);break}}self.onmessage=async t=>{try{await u(t.data);}catch(i){postMessage({type:"ERROR",error:i instanceof Error?i.message:String(i),source:t.data.type});}};}async function A(o){let{createSystem:c}=await import('./system-CDJMD5O5.cjs'),l=f(),y={};for(let r of o.moduleNames){let s=l.get(r);if(!s)throw new Error(`[Directive Worker] Module "${r}" not registered. Call registerWorkerModule('${r}', module) before handling messages.`);y[r]=s;}let a=c({modules:y,plugins:[{name:"__worker-tracking__",onFactSet:(r,s,u)=>{postMessage({type:"FACT_CHANGED",key:r,value:s,prev:u});},onDerivationCompute:(r,s)=>{postMessage({type:"DERIVATION_CHANGED",key:r,value:s});},onRequirementCreated:r=>{postMessage({type:"REQUIREMENT_CREATED",requirement:{...r.requirement,id:r.id}});},onRequirementMet:(r,s)=>{postMessage({type:"REQUIREMENT_MET",requirementId:r.id,resolverId:s});}}],history:o.history});return {start:()=>a.start(),stop:()=>a.stop(),destroy:()=>a.destroy(),setFact:(r,s)=>{a.facts[r]=s;},setFacts:r=>{let s=a.facts;if(s.$store?.batch)s.$store.batch(()=>{for(let[u,t]of Object.entries(r))s[u]=t;});else for(let[u,t]of Object.entries(r))s[u]=t;},dispatch:r=>{a.dispatch(r);},getSnapshot:r=>a.getDistributableSnapshot(r),inspect:()=>a.inspect(),settle:r=>a.settle(r)}}exports.createWorkerClient=_;exports.getWorkerModuleRegistry=f;exports.handleWorkerMessages=x;exports.registerWorkerModule=N;//# sourceMappingURL=worker.cjs.map
//# sourceMappingURL=worker.cjs.map

@@ -1,2 +0,2 @@

import { M as ModuleSchema, x as DistributableSnapshotOptions, w as DistributableSnapshot, ac as SystemInspection, t as Requirement } from './plugins-Ykl_sAPE.cjs';
import { M as ModuleSchema, u as DistributableSnapshotOptions, t as DistributableSnapshot, ac as SystemInspection, q as Requirement } from './plugins-BIzXaYbg.cjs';

@@ -3,0 +3,0 @@ /**

@@ -1,2 +0,2 @@

import { M as ModuleSchema, x as DistributableSnapshotOptions, w as DistributableSnapshot, ac as SystemInspection, t as Requirement } from './plugins-Ykl_sAPE.js';
import { M as ModuleSchema, u as DistributableSnapshotOptions, t as DistributableSnapshot, ac as SystemInspection, q as Requirement } from './plugins-BIzXaYbg.js';

@@ -3,0 +3,0 @@ /**

@@ -1,2 +0,2 @@

function _(o){let{worker:c,onFactChange:l,onDerivationChange:y,onRequirementCreated:E,onRequirementMet:a,onError:r}=o,s=new Map,u=0,t=null,i=null,d=null,T=null;function g(e){return e?.(),null}function R(e,n){let S=s.get(e);S&&(S.resolve(n),s.delete(e));}function M(){t=g(t);}function m(){i=g(i);}function I(){d=g(d);}function b(){T=g(T);}function h(e){l?.(e.key,e.value,e.prev);}function O(e){y?.(e.key,e.value);}function W(e){E?.(e.requirement);}function C(e){a?.(e.requirementId,e.resolverId);}function P(e){r?.(e.error,e.source);}function D(e){R(e.requestId,e.snapshot);}function w(e){R(e.requestId,e.inspection);}function q(e){let n=s.get(e.requestId);n&&(e.success?n.resolve(void 0):n.reject(new Error(e.error||"Settle failed")),s.delete(e.requestId));}c.onmessage=e=>{let n=e.data;switch(n.type){case "READY":return M();case "STARTED":return m();case "STOPPED":return I();case "DESTROYED":return b();case "FACT_CHANGED":return h(n);case "DERIVATION_CHANGED":return O(n);case "REQUIREMENT_CREATED":return W(n);case "REQUIREMENT_MET":return C(n);case "ERROR":return P(n);case "SNAPSHOT_RESULT":return D(n);case "INSPECT_RESULT":return w(n);case "SETTLE_RESULT":return q(n)}},c.onerror=e=>{r?.(e.message,"worker");};function p(e){c.postMessage(e);}function k(e){return new Promise((n,S)=>{s.set(e.requestId,{resolve:n,reject:S}),p(e);})}return {init(e){return new Promise(n=>{t=n,p({type:"INIT",config:e});})},start(){return new Promise(e=>{i=e,p({type:"START"});})},stop(){return new Promise(e=>{d=e,p({type:"STOP"});})},destroy(){return new Promise(e=>{T=e,p({type:"DESTROY"});})},setFact(e,n){p({type:"SET_FACT",key:e,value:n});},setFacts(e){p({type:"SET_FACTS",facts:e});},dispatch(e){p({type:"DISPATCH",event:e});},getSnapshot(e){let n=`snapshot-${++u}`;return k({type:"GET_SNAPSHOT",options:e,requestId:n})},inspect(){let e=`inspect-${++u}`;return k({type:"INSPECT",requestId:e})},settle(e){let n=`settle-${++u}`;return k({type:"SETTLE",timeout:e,requestId:n})},terminate(){c.terminate();}}}var v=null;function f(){return v||(v=new Map),v}function N(o,c){f().set(o,c);}function x(){let o=null;async function c(t){let i=await A(t.config);return postMessage({type:"READY"}),i}function l(t){t.start(),postMessage({type:"STARTED"});}function y(t){t.stop(),postMessage({type:"STOPPED"});}function E(t){t.destroy(),postMessage({type:"DESTROYED"});}function a(t,i){let d=t.getSnapshot(i.options);postMessage({type:"SNAPSHOT_RESULT",requestId:i.requestId,snapshot:d});}function r(t,i){let d=t.inspect();postMessage({type:"INSPECT_RESULT",requestId:i.requestId,inspection:d});}async function s(t,i){try{await t.settle(i.timeout),postMessage({type:"SETTLE_RESULT",requestId:i.requestId,success:!0});}catch(d){postMessage({type:"SETTLE_RESULT",requestId:i.requestId,success:false,error:d instanceof Error?d.message:String(d)});}}async function u(t){if(t.type==="INIT"){o=await c(t);return}if(o)switch(t.type){case "START":l(o);break;case "STOP":y(o);break;case "DESTROY":E(o),o=null;break;case "SET_FACT":o.setFact(t.key,t.value);break;case "SET_FACTS":o.setFacts(t.facts);break;case "DISPATCH":o.dispatch(t.event);break;case "GET_SNAPSHOT":a(o,t);break;case "INSPECT":r(o,t);break;case "SETTLE":await s(o,t);break}}self.onmessage=async t=>{try{await u(t.data);}catch(i){postMessage({type:"ERROR",error:i instanceof Error?i.message:String(i),source:t.data.type});}};}async function A(o){let{createSystem:c}=await import('./system-VZWB6WXX.js'),l=f(),y={};for(let r of o.moduleNames){let s=l.get(r);if(!s)throw new Error(`[Directive Worker] Module "${r}" not registered. Call registerWorkerModule('${r}', module) before handling messages.`);y[r]=s;}let a=c({modules:y,plugins:[{name:"__worker-tracking__",onFactSet:(r,s,u)=>{postMessage({type:"FACT_CHANGED",key:r,value:s,prev:u});},onDerivationCompute:(r,s)=>{postMessage({type:"DERIVATION_CHANGED",key:r,value:s});},onRequirementCreated:r=>{postMessage({type:"REQUIREMENT_CREATED",requirement:{...r.requirement,id:r.id}});},onRequirementMet:(r,s)=>{postMessage({type:"REQUIREMENT_MET",requirementId:r.id,resolverId:s});}}],history:o.history});return {start:()=>a.start(),stop:()=>a.stop(),destroy:()=>a.destroy(),setFact:(r,s)=>{a.facts[r]=s;},setFacts:r=>{let s=a.facts;if(s.$store?.batch)s.$store.batch(()=>{for(let[u,t]of Object.entries(r))s[u]=t;});else for(let[u,t]of Object.entries(r))s[u]=t;},dispatch:r=>{a.dispatch(r);},getSnapshot:r=>a.getDistributableSnapshot(r),inspect:()=>a.inspect(),settle:r=>a.settle(r)}}export{_ as createWorkerClient,f as getWorkerModuleRegistry,x as handleWorkerMessages,N as registerWorkerModule};//# sourceMappingURL=worker.js.map
function _(o){let{worker:c,onFactChange:l,onDerivationChange:y,onRequirementCreated:E,onRequirementMet:a,onError:r}=o,s=new Map,u=0,t=null,i=null,d=null,T=null;function g(e){return e?.(),null}function R(e,n){let S=s.get(e);S&&(S.resolve(n),s.delete(e));}function M(){t=g(t);}function m(){i=g(i);}function I(){d=g(d);}function b(){T=g(T);}function h(e){l?.(e.key,e.value,e.prev);}function O(e){y?.(e.key,e.value);}function W(e){E?.(e.requirement);}function C(e){a?.(e.requirementId,e.resolverId);}function P(e){r?.(e.error,e.source);}function D(e){R(e.requestId,e.snapshot);}function w(e){R(e.requestId,e.inspection);}function q(e){let n=s.get(e.requestId);n&&(e.success?n.resolve(void 0):n.reject(new Error(e.error||"Settle failed")),s.delete(e.requestId));}c.onmessage=e=>{let n=e.data;switch(n.type){case "READY":return M();case "STARTED":return m();case "STOPPED":return I();case "DESTROYED":return b();case "FACT_CHANGED":return h(n);case "DERIVATION_CHANGED":return O(n);case "REQUIREMENT_CREATED":return W(n);case "REQUIREMENT_MET":return C(n);case "ERROR":return P(n);case "SNAPSHOT_RESULT":return D(n);case "INSPECT_RESULT":return w(n);case "SETTLE_RESULT":return q(n)}},c.onerror=e=>{r?.(e.message,"worker");};function p(e){c.postMessage(e);}function k(e){return new Promise((n,S)=>{s.set(e.requestId,{resolve:n,reject:S}),p(e);})}return {init(e){return new Promise(n=>{t=n,p({type:"INIT",config:e});})},start(){return new Promise(e=>{i=e,p({type:"START"});})},stop(){return new Promise(e=>{d=e,p({type:"STOP"});})},destroy(){return new Promise(e=>{T=e,p({type:"DESTROY"});})},setFact(e,n){p({type:"SET_FACT",key:e,value:n});},setFacts(e){p({type:"SET_FACTS",facts:e});},dispatch(e){p({type:"DISPATCH",event:e});},getSnapshot(e){let n=`snapshot-${++u}`;return k({type:"GET_SNAPSHOT",options:e,requestId:n})},inspect(){let e=`inspect-${++u}`;return k({type:"INSPECT",requestId:e})},settle(e){let n=`settle-${++u}`;return k({type:"SETTLE",timeout:e,requestId:n})},terminate(){c.terminate();}}}var v=null;function f(){return v||(v=new Map),v}function N(o,c){f().set(o,c);}function x(){let o=null;async function c(t){let i=await A(t.config);return postMessage({type:"READY"}),i}function l(t){t.start(),postMessage({type:"STARTED"});}function y(t){t.stop(),postMessage({type:"STOPPED"});}function E(t){t.destroy(),postMessage({type:"DESTROYED"});}function a(t,i){let d=t.getSnapshot(i.options);postMessage({type:"SNAPSHOT_RESULT",requestId:i.requestId,snapshot:d});}function r(t,i){let d=t.inspect();postMessage({type:"INSPECT_RESULT",requestId:i.requestId,inspection:d});}async function s(t,i){try{await t.settle(i.timeout),postMessage({type:"SETTLE_RESULT",requestId:i.requestId,success:!0});}catch(d){postMessage({type:"SETTLE_RESULT",requestId:i.requestId,success:false,error:d instanceof Error?d.message:String(d)});}}async function u(t){if(t.type==="INIT"){o=await c(t);return}if(o)switch(t.type){case "START":l(o);break;case "STOP":y(o);break;case "DESTROY":E(o),o=null;break;case "SET_FACT":o.setFact(t.key,t.value);break;case "SET_FACTS":o.setFacts(t.facts);break;case "DISPATCH":o.dispatch(t.event);break;case "GET_SNAPSHOT":a(o,t);break;case "INSPECT":r(o,t);break;case "SETTLE":await s(o,t);break}}self.onmessage=async t=>{try{await u(t.data);}catch(i){postMessage({type:"ERROR",error:i instanceof Error?i.message:String(i),source:t.data.type});}};}async function A(o){let{createSystem:c}=await import('./system-A6VYKLVF.js'),l=f(),y={};for(let r of o.moduleNames){let s=l.get(r);if(!s)throw new Error(`[Directive Worker] Module "${r}" not registered. Call registerWorkerModule('${r}', module) before handling messages.`);y[r]=s;}let a=c({modules:y,plugins:[{name:"__worker-tracking__",onFactSet:(r,s,u)=>{postMessage({type:"FACT_CHANGED",key:r,value:s,prev:u});},onDerivationCompute:(r,s)=>{postMessage({type:"DERIVATION_CHANGED",key:r,value:s});},onRequirementCreated:r=>{postMessage({type:"REQUIREMENT_CREATED",requirement:{...r.requirement,id:r.id}});},onRequirementMet:(r,s)=>{postMessage({type:"REQUIREMENT_MET",requirementId:r.id,resolverId:s});}}],history:o.history});return {start:()=>a.start(),stop:()=>a.stop(),destroy:()=>a.destroy(),setFact:(r,s)=>{a.facts[r]=s;},setFacts:r=>{let s=a.facts;if(s.$store?.batch)s.$store.batch(()=>{for(let[u,t]of Object.entries(r))s[u]=t;});else for(let[u,t]of Object.entries(r))s[u]=t;},dispatch:r=>{a.dispatch(r);},getSnapshot:r=>a.getDistributableSnapshot(r),inspect:()=>a.inspect(),settle:r=>a.settle(r)}}export{_ as createWorkerClient,f as getWorkerModuleRegistry,x as handleWorkerMessages,N as registerWorkerModule};//# sourceMappingURL=worker.js.map
//# sourceMappingURL=worker.js.map
{
"name": "@directive-run/core",
"version": "1.12.0",
"version": "1.13.0",
"imports": {

@@ -5,0 +5,0 @@ "#is-development": {

import { b as FactPredicate, C as ClauseResult, q as Plugin, M as ModuleSchema } from './plugins-Ykl_sAPE.js';
/**
* createAuditLedger — append-only, queryable, cryptographically-chained
* audit of every state change. For compliance, forensics, "show me why
* this user got that decision."
*
* Captures (per observation event):
*
* - `constraint.evaluate` → { whenSpec, whenExplain, active }
* - `resolver.write.rejected` (rejection + summary kinds)
* - `fact.change` → { key, prior, next }
* - `resolver.complete` → { resolverId, requirementId, duration }
* - `system.init` / `system.start` / `system.stop` / `system.destroy`
*
* Hash chain: each entry stores `prevHash` (the genesis entry's is null);
* `hash` is computed *lazily* at `verify()` / `toJSON()` time via
* `stableStringify` + SHA-256 (`crypto.subtle.digest`). Tampering with
* any entry's payload breaks the next entry's `prevHash` link — visible
* in `verify()`.
*
* PII redaction: by default, fact keys whose meta carries the `pii`
* tag (via `system.meta.byTag("pii")`) have their values replaced with
* `"[redacted]"` in `whenExplain.actual`, `fact.change.prior`, and
* `fact.change.next`. Opt out with `capturePII: true`.
*/
type AuditEntryKind = "constraint.evaluate" | "resolver.write.rejected" | "fact.change" | "resolver.complete" | "resolver.error" | "system.init" | "system.start" | "system.stop" | "system.destroy";
interface AuditEntryBase {
/** Monotonic sequence number, starting at 0. */
readonly seq: number;
/** Wall-clock timestamp (ms epoch). */
readonly ts: number;
/** Discriminator. */
readonly kind: AuditEntryKind;
/** Hash of the previous entry's full payload. null on the genesis entry. */
readonly prevHash: string | null;
}
type AuditEntry = (AuditEntryBase & {
kind: "constraint.evaluate";
constraintId: string;
active: boolean;
/** Cached at ledger start from `system.inspect().constraints[].whenSpec`. May be undefined for function-form constraints. */
whenSpec?: FactPredicate<unknown>;
whenExplain?: readonly ClauseResult[];
}) | (AuditEntryBase & {
kind: "resolver.write.rejected";
rejection: "rejection" | "summary";
resolverId: string;
requirementId: string;
reason: string;
fact?: string;
expected?: unknown;
actual?: unknown;
dropped?: number;
}) | (AuditEntryBase & {
kind: "fact.change";
key: string;
prior: unknown;
next: unknown;
}) | (AuditEntryBase & {
kind: "resolver.complete";
resolverId: string;
requirementId: string;
duration: number;
}) | (AuditEntryBase & {
kind: "resolver.error";
resolverId: string;
requirementId: string;
error: string;
}) | (AuditEntryBase & {
kind: "system.init" | "system.start" | "system.stop" | "system.destroy";
});
interface QueryFilter {
/** Exact-match fact path. */
factPath?: string;
/** Filter by constraint id. */
constraintId?: string;
/** Filter by entry kind. */
kind?: AuditEntryKind | readonly AuditEntryKind[];
/** Time range as `[startMs, endMs]`, ISO strings, or epoch numbers. */
changedBetween?: [string | number | Date, string | number | Date];
/** Maximum entries returned. Default 1000. */
limit?: number;
}
/** Verify result — chain valid OR a break with full context for tamper visualization. */
type VerifyResult = {
valid: true;
entryCount: number;
} | {
valid: false;
brokenAt: number;
expectedHash: string;
actualHash: string;
entry: AuditEntry;
};
interface AuditLedgerSink {
write(entry: AuditEntry): void;
query(filter: QueryFilter): readonly AuditEntry[];
recent(n: number): readonly AuditEntry[];
forFact(path: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
forConstraint(id: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
toJSON(): {
entries: readonly AuditEntry[];
capturedAt: number;
};
clear(): void;
destroy(): void;
}
/**
* In-memory bounded ring-buffer sink. Drops oldest entries past
* `capacity` (default 10,000). Use this as the default sink for dev,
* tests, and StackBlitz demos.
*/
declare function memorySink(opts?: {
capacity?: number;
}): AuditLedgerSink;
interface AuditLedgerOptions {
/** Sink to write entries to. Default: in-memory ring buffer (capacity 10k). */
sink?: AuditLedgerSink;
/**
* Whether to capture raw fact values (`prior`/`next` on fact.change,
* `actual` in whenExplain). Default `false` — PII-tagged facts are
* redacted by default. Set `true` to opt out of redaction.
*/
capturePII?: boolean;
/**
* Optional caller-supplied redactor. Runs AFTER the default
* pii-tag-based redaction. Useful for additional sanitization.
*/
redact?: (entry: AuditEntry) => AuditEntry;
}
interface AuditLedger {
/** The plugin to pass to `createSystem({ plugins: [...] })`. */
readonly plugin: Plugin<ModuleSchema>;
/** Query entries matching the filter. */
query(filter?: QueryFilter): readonly AuditEntry[];
/** Most recent N entries (chronological). */
recent(n: number): readonly AuditEntry[];
/** All entries that touch this fact path (exact match). */
forFact(path: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
/** All entries for this constraint id. */
forConstraint(id: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
/** Full ledger snapshot for export / serialization. */
toJSON(): {
entries: readonly AuditEntry[];
capturedAt: number;
};
/**
* Walk the hash chain genesis → tip. Returns `{ valid: true }` iff
* every entry's `prevHash` matches the (sync, djb2-based) hash of
* the previous entry. On break, returns the index of the first
* broken link plus the expected vs actual hashes — feed into a
* "TAMPERED" visualization.
*
* Sync by default (djb2 chain). For compliance-grade collision
* resistance, pass `{ strong: true }` — verify walks the chain a
* second time with SHA-256 and returns a Promise. Callers must
* `await` the result when `strong: true` is passed.
*/
verify(opts?: {
strong?: boolean;
}): VerifyResult | Promise<VerifyResult>;
/** Empty the sink. */
clear(): void;
/** Unsubscribe + drop the sink. */
destroy(): void;
}
/**
* Create an audit ledger that subscribes to the given system's
* observation stream. Returns a `Plugin` to install + a query/verify
* API for the ledger.
*
* @example
* ```ts
* import { createAuditLedger } from "@directive-run/core/plugins";
*
* const ledger = createAuditLedger();
* const system = createSystem({ module, plugins: [ledger.plugin] });
* system.start();
*
* // Six months later — auditor asks "what changed cart-total in March?"
* ledger.query({
* factPath: "cartTotal",
* changedBetween: ["2026-03-01", "2026-04-01"],
* });
*
* // Verify nobody tampered with the ledger
* const verdict = await ledger.verify();
* if (!verdict.valid) {
* console.error("Tamper at entry", verdict.brokenAt);
* }
* ```
*/
declare function createAuditLedger(opts?: AuditLedgerOptions): AuditLedger;
export { type AuditEntry as A, type QueryFilter as Q, type AuditEntryKind as a, type AuditLedger as b, type AuditLedgerOptions as c, type AuditLedgerSink as d, createAuditLedger as e, memorySink as m };
import { b as FactPredicate, C as ClauseResult, q as Plugin, M as ModuleSchema } from './plugins-Ykl_sAPE.cjs';
/**
* createAuditLedger — append-only, queryable, cryptographically-chained
* audit of every state change. For compliance, forensics, "show me why
* this user got that decision."
*
* Captures (per observation event):
*
* - `constraint.evaluate` → { whenSpec, whenExplain, active }
* - `resolver.write.rejected` (rejection + summary kinds)
* - `fact.change` → { key, prior, next }
* - `resolver.complete` → { resolverId, requirementId, duration }
* - `system.init` / `system.start` / `system.stop` / `system.destroy`
*
* Hash chain: each entry stores `prevHash` (the genesis entry's is null);
* `hash` is computed *lazily* at `verify()` / `toJSON()` time via
* `stableStringify` + SHA-256 (`crypto.subtle.digest`). Tampering with
* any entry's payload breaks the next entry's `prevHash` link — visible
* in `verify()`.
*
* PII redaction: by default, fact keys whose meta carries the `pii`
* tag (via `system.meta.byTag("pii")`) have their values replaced with
* `"[redacted]"` in `whenExplain.actual`, `fact.change.prior`, and
* `fact.change.next`. Opt out with `capturePII: true`.
*/
type AuditEntryKind = "constraint.evaluate" | "resolver.write.rejected" | "fact.change" | "resolver.complete" | "resolver.error" | "system.init" | "system.start" | "system.stop" | "system.destroy";
interface AuditEntryBase {
/** Monotonic sequence number, starting at 0. */
readonly seq: number;
/** Wall-clock timestamp (ms epoch). */
readonly ts: number;
/** Discriminator. */
readonly kind: AuditEntryKind;
/** Hash of the previous entry's full payload. null on the genesis entry. */
readonly prevHash: string | null;
}
type AuditEntry = (AuditEntryBase & {
kind: "constraint.evaluate";
constraintId: string;
active: boolean;
/** Cached at ledger start from `system.inspect().constraints[].whenSpec`. May be undefined for function-form constraints. */
whenSpec?: FactPredicate<unknown>;
whenExplain?: readonly ClauseResult[];
}) | (AuditEntryBase & {
kind: "resolver.write.rejected";
rejection: "rejection" | "summary";
resolverId: string;
requirementId: string;
reason: string;
fact?: string;
expected?: unknown;
actual?: unknown;
dropped?: number;
}) | (AuditEntryBase & {
kind: "fact.change";
key: string;
prior: unknown;
next: unknown;
}) | (AuditEntryBase & {
kind: "resolver.complete";
resolverId: string;
requirementId: string;
duration: number;
}) | (AuditEntryBase & {
kind: "resolver.error";
resolverId: string;
requirementId: string;
error: string;
}) | (AuditEntryBase & {
kind: "system.init" | "system.start" | "system.stop" | "system.destroy";
});
interface QueryFilter {
/** Exact-match fact path. */
factPath?: string;
/** Filter by constraint id. */
constraintId?: string;
/** Filter by entry kind. */
kind?: AuditEntryKind | readonly AuditEntryKind[];
/** Time range as `[startMs, endMs]`, ISO strings, or epoch numbers. */
changedBetween?: [string | number | Date, string | number | Date];
/** Maximum entries returned. Default 1000. */
limit?: number;
}
/** Verify result — chain valid OR a break with full context for tamper visualization. */
type VerifyResult = {
valid: true;
entryCount: number;
} | {
valid: false;
brokenAt: number;
expectedHash: string;
actualHash: string;
entry: AuditEntry;
};
interface AuditLedgerSink {
write(entry: AuditEntry): void;
query(filter: QueryFilter): readonly AuditEntry[];
recent(n: number): readonly AuditEntry[];
forFact(path: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
forConstraint(id: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
toJSON(): {
entries: readonly AuditEntry[];
capturedAt: number;
};
clear(): void;
destroy(): void;
}
/**
* In-memory bounded ring-buffer sink. Drops oldest entries past
* `capacity` (default 10,000). Use this as the default sink for dev,
* tests, and StackBlitz demos.
*/
declare function memorySink(opts?: {
capacity?: number;
}): AuditLedgerSink;
interface AuditLedgerOptions {
/** Sink to write entries to. Default: in-memory ring buffer (capacity 10k). */
sink?: AuditLedgerSink;
/**
* Whether to capture raw fact values (`prior`/`next` on fact.change,
* `actual` in whenExplain). Default `false` — PII-tagged facts are
* redacted by default. Set `true` to opt out of redaction.
*/
capturePII?: boolean;
/**
* Optional caller-supplied redactor. Runs AFTER the default
* pii-tag-based redaction. Useful for additional sanitization.
*/
redact?: (entry: AuditEntry) => AuditEntry;
}
interface AuditLedger {
/** The plugin to pass to `createSystem({ plugins: [...] })`. */
readonly plugin: Plugin<ModuleSchema>;
/** Query entries matching the filter. */
query(filter?: QueryFilter): readonly AuditEntry[];
/** Most recent N entries (chronological). */
recent(n: number): readonly AuditEntry[];
/** All entries that touch this fact path (exact match). */
forFact(path: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
/** All entries for this constraint id. */
forConstraint(id: string, opts?: {
limit?: number;
}): readonly AuditEntry[];
/** Full ledger snapshot for export / serialization. */
toJSON(): {
entries: readonly AuditEntry[];
capturedAt: number;
};
/**
* Walk the hash chain genesis → tip. Returns `{ valid: true }` iff
* every entry's `prevHash` matches the (sync, djb2-based) hash of
* the previous entry. On break, returns the index of the first
* broken link plus the expected vs actual hashes — feed into a
* "TAMPERED" visualization.
*
* Sync by default (djb2 chain). For compliance-grade collision
* resistance, pass `{ strong: true }` — verify walks the chain a
* second time with SHA-256 and returns a Promise. Callers must
* `await` the result when `strong: true` is passed.
*/
verify(opts?: {
strong?: boolean;
}): VerifyResult | Promise<VerifyResult>;
/** Empty the sink. */
clear(): void;
/** Unsubscribe + drop the sink. */
destroy(): void;
}
/**
* Create an audit ledger that subscribes to the given system's
* observation stream. Returns a `Plugin` to install + a query/verify
* API for the ledger.
*
* @example
* ```ts
* import { createAuditLedger } from "@directive-run/core/plugins";
*
* const ledger = createAuditLedger();
* const system = createSystem({ module, plugins: [ledger.plugin] });
* system.start();
*
* // Six months later — auditor asks "what changed cart-total in March?"
* ledger.query({
* factPath: "cartTotal",
* changedBetween: ["2026-03-01", "2026-04-01"],
* });
*
* // Verify nobody tampered with the ledger
* const verdict = await ledger.verify();
* if (!verdict.valid) {
* console.error("Tamper at entry", verdict.brokenAt);
* }
* ```
*/
declare function createAuditLedger(opts?: AuditLedgerOptions): AuditLedger;
export { type AuditEntry as A, type QueryFilter as Q, type AuditEntryKind as a, type AuditLedger as b, type AuditLedgerOptions as c, type AuditLedgerSink as d, createAuditLedger as e, memorySink as m };
import {T,j,h,o,u,q,t}from'./chunk-TPOKS4RY.js';import {a,l,m as m$1,n}from'./chunk-TZHC4E6S.js';import {e,a as a$1}from'./chunk-T6IJUWYR.js';var m="::",he=Symbol.for("nodejs.util.inspect.custom");function we(e){if(!e.ownKeys)return {};let n={};for(let t of e.ownKeys())n[t]=e.get(t);return n}function D(e){return new Proxy({},{get(n,t){if(typeof t=="symbol")return t===he?()=>we(e):void 0;if(!l.has(t))return e.get(t)},set(n,t,s){return typeof t=="symbol"||l.has(t)?false:e.set?e.set(t,s):false},has(n,t){return typeof t=="symbol"||l.has(t)?false:e.has?e.has(t):false},deleteProperty(n,t){return typeof t=="symbol"||l.has(t)?false:e.delete?e.delete(t):false},ownKeys(){return e.ownKeys?e.ownKeys():[]},getOwnPropertyDescriptor(n,t){if(typeof t!="symbol"&&e.has&&typeof t=="string"&&e.has(t))return {configurable:true,enumerable:true}},defineProperty(){return false},getPrototypeOf(){return null},setPrototypeOf(){return false}})}var Z=new WeakMap,Q=new WeakMap,X=new WeakMap,ee=new WeakMap,ne=new WeakMap,te=new WeakMap;function $(e,n$1){let t=Z.get(e);if(t){let r=t.get(n$1);if(r)return r}else t=new Map,Z.set(e,t);let s=D({get:r=>r==="$store"||r==="$snapshot"?e[r]:e[`${n$1}${m}${r}`],set:(r,u)=>{if(a){let i=m$1(u);i&&n(`${n$1}.${r}`,i);}return e[`${n$1}${m}${r}`]=u,true},has:r=>`${n$1}${m}${r}`in e,delete:r=>(delete e[`${n$1}${m}${r}`],true)});return t.set(n$1,s),s}function re(e,n,t){let s=Q.get(e);if(s)return s;let r=D({get:u=>{if(Object.hasOwn(n,u))return $(e,u)},has:u=>Object.hasOwn(n,u),ownKeys:()=>t()});return Q.set(e,r),r}function oe(e,n,t){let s=`${n}|${t.join(",")}`,r=ne.get(e);if(r){let o=r.get(s);if(o)return o}else r=new Map,ne.set(e,r);let u=new Set(t),i=["self",...t],c=D({get:o=>{if(o==="self")return $(e,n);if(u.has(o))return $(e,o);a&&console.warn(`[Directive] Module "${n}" accessed undeclared cross-module property "${o}". Add it to crossModuleDeps or use "facts.self.${o}" for own module facts.`);},has:o=>o==="self"||u.has(o),ownKeys:()=>i});return r.set(s,c),c}function B(e,n){let t=ee.get(e);if(t){let r=t.get(n);if(r)return r}else t=new Map,ee.set(e,t);let s=D({get:r=>e[`${n}${m}${r}`],has:r=>`${n}${m}${r}`in e});return t.set(n,s),s}function se(e,n,t){let s=X.get(e);if(s)return s;let r=D({get:u=>{if(Object.hasOwn(n,u))return B(e,u)},has:u=>Object.hasOwn(n,u),ownKeys:()=>t()});return X.set(e,r),r}function ie(e,n,t){let s=te.get(e);return s||(s=new Map,te.set(e,s)),D({get:r=>{if(!Object.hasOwn(n,r))return;let u=s.get(r);if(u)return u;let i=D({get:c=>o=>{e.dispatch({type:`${r}${m}${c}`,...o});}});return s.set(r,i),i},has:r=>Object.hasOwn(n,r),ownKeys:()=>t()})}function R(e){if(e.includes(".")){let[n,...t]=e.split(".");return `${n}${m}${t.join(m)}`}return e}function H(e){let n={};for(let[t,s]of Object.entries(e)){let r=t.indexOf(m);if(r>0){let u=t.slice(0,r),i=t.slice(r+m.length);n[u]||(n[u]={}),n[u][i]=s;}else n._root||(n._root={}),n._root[t]=s;}return n}function P(e,n,t,s){return t?oe(e,n,s):$(e,n)}function b(e,n){return `${e}${m}${n}`}function ae(e){return e.includes(m)}function E(e,n,t){if(Array.isArray(e)){let i=e.map(c=>{if(c&&typeof c=="object"&&typeof c.fact=="string"){let o=c.fact;return ae(o)?c:{...c,fact:b(n,o)}}return c});return a$1(i),i}if(!e||typeof e!="object")return e;let s=e;if("$all"in s||"$any"in s){let i="$all"in s?"$all":"$any",c=s[i],o={[i]:c.map(f=>E(f,n,t))};return a$1(o),o}if("$not"in s){let i={$not:E(s.$not,n,t)};return a$1(i),i}function r(i,c){return E(i,c,ce)}let u={};for(let i of Object.keys(s)){if(i.startsWith("$")||ae(i)){u[i]=s[i];continue}if(i==="self"){let c=s[i];if(c&&typeof c=="object"){let o=r(c,n);if(o&&typeof o=="object"&&!Array.isArray(o)){for(let[f,l]of Object.entries(o))u[f]=l;continue}}}if(t.has(i)){let c=s[i];if(c&&typeof c=="object"){let o=r(c,i);if(o&&typeof o=="object"&&!Array.isArray(o)){for(let[f,l]of Object.entries(o))u[f]=l;continue}}}u[b(n,i)]=s[i];}return a$1(u),u}var ce=new Set;function me(e,n){let t$1=e.crossModuleDeps?new Set(Object.keys(e.crossModuleDeps)):ce,s=e.constraints;if(s){let c=false,o={};for(let[f,l]of Object.entries(s)){let d=l;if(d.when!==void 0&&typeof d.when!="function"){o[f]={...d,when:E(d.when,n,t$1)},c=true;continue}o[f]=l;}c&&(s=o);}let r=e.derive;if(r){let c=false,o$1={};for(let[f,l]of Object.entries(r)){let d=l&&typeof l=="object"&&Object.hasOwn(l,"compute")?l:null;if(!d){o$1[f]=l;continue}let g=d.compute;if(typeof g=="function"){o$1[f]=l;continue}if(j(g)){a$1(g);let k=w=>q(g,w);o$1[f]=d.meta?{compute:k,meta:d.meta}:k,c=true;continue}if(h(g)){a$1(g);let k=o(g),w=j=>k(j);o$1[f]=d.meta?{compute:w,meta:d.meta}:w,c=true;continue}o$1[f]=l;}c&&(r=o$1);}let u=e.events;if(u){let c=false,o={};for(let[f,l]of Object.entries(u)){if(l&&typeof l=="object"){let d=Object.hasOwn(l,"handler"),g=Object.hasOwn(l,"patch");if(d&&g&&a&&console.warn(`[Directive] event "${f}": both \`handler\` and \`patch\` provided \u2014 using \`handler\` (patch is ignored).`),g&&!d){let k=l;a$1(k.patch);let w=(j,O)=>t(k.patch,j,O??{});o[f]=k.meta?{handler:w,meta:k.meta}:w,c=true;continue}}o[f]=l;}c&&(u=o);}let i=e.effects;if(i){let c=false,o={};for(let[f,l]of Object.entries(i)){let d=l;if(d.on!==void 0&&h(d.on)){o[f]={...d,on:E(d.on,n,t$1)},c=true;continue}o[f]=l;}c&&(i=o);}return s===e.constraints&&r===e.derive&&u===e.events&&i===e.effects?e:{...e,constraints:s,derive:r,events:u,effects:i}}function C(e){return Object.keys(e).length>0?e:void 0}function ke(e,n){let t={};for(let[s,r]of Object.entries(e.schema.facts))t[b(n,s)]=r;return t}function pe(e,n){if(e.init)return t=>{let s=$(t,n);e.init(s);}}function ve(e,n,t,s){if(!e.derive)return;let r={};for(let[u$1,i]of Object.entries(e.derive)){let c=u(i),o=c?i.compute:i,f=c?i.meta:void 0,l=(d,g)=>{let k=P(d,n,t,s),w=B(g,n);return o(k,w)};r[b(n,u$1)]=f?{compute:l,meta:f}:l;}return C(r)}function be(e,n){if(!e.events)return;let t={};for(let[s,r]of Object.entries(e.events)){let u=typeof r=="object"&&r!==null&&Object.hasOwn(r,"handler"),i=u?r.handler:r,c=u?r.meta:void 0,o=(f,l)=>{let d=$(f,n);i(d,l);};t[b(n,s)]=c?{handler:o,meta:c}:o;}return C(t)}function Me(e,n,t,s){if(!e.constraints)return;let r={};for(let[u,i]of Object.entries(e.constraints)){let c=i,o=typeof c.when=="function";r[b(n,u)]={...c,deps:c.deps?.map(f=>b(n,f)),after:c.after?.map(f=>f.includes(m)?f:b(n,f)),owns:c.owns?.map(f=>f.includes(m)?f:b(n,f)),when:o?f=>{let l=P(f,n,t,s);return c.when(l)}:c.when,require:typeof c.require=="function"?f=>{let l=P(f,n,t,s);return c.require(l)}:c.require};}return C(r)}function Re(e,n,t,s){if(!e.resolvers)return;let r={};for(let[i,c]of Object.entries(e.resolvers)){let f=function(l){return {facts:P(l.facts,n,t,s),signal:l.signal}};let o=c;r[b(n,i)]={...o,...o.resolve&&{resolve:async(l,d)=>{await o.resolve(l,f(d));}},...o.resolveBatch&&{resolveBatch:async(l,d)=>{await o.resolveBatch(l,f(d));}},...o.resolveBatchWithResults&&{resolveBatchWithResults:async(l,d)=>o.resolveBatchWithResults(l,f(d))}};}return C(r)}function Se(e,n,t,s){if(!e.effects)return;let r={};for(let[u,i]of Object.entries(e.effects)){let c=i;r[b(n,u)]={...c,run:(o,f)=>{let l=P(o,n,t,s),d=f?P(f,n,t,s):void 0;return c.run(l,d)},deps:c.deps?.map(o=>b(n,o))};}return C(r)}function Oe(e,n,t){return {snapshotEvents:t&&!t.has(n)?[]:e.history?.snapshotEvents?.map(s=>b(n,s))}}function I(e){let{mod:n,namespace:t,snapshotModulesSet:s}=e,r=me(n,t),u=!!(r.crossModuleDeps&&Object.keys(r.crossModuleDeps).length>0),i=u?Object.keys(r.crossModuleDeps):[];return {id:r.id,schema:ke(r,t),requirements:r.schema.requirements??{},init:pe(r,t),derive:ve(r,t,u,i),events:be(r,t),effects:Se(r,t,u,i),constraints:Me(r,t,u,i),resolvers:Re(r,t,u,i),hooks:r.hooks,meta:r.meta,history:Oe(r,t,s)}}function xe(e){let n=Object.keys(e),t=new Set(n),s=new Set,r=new Set,u=[],i=[];function c(o){if(s.has(o))return;if(r.has(o)){let l=i.indexOf(o),d=[...i.slice(l),o].join(" \u2192 ");throw new Error(`[Directive] Circular dependency detected: ${d}. Modules cannot have circular crossModuleDeps. Break the cycle by removing one of the cross-module references.`)}r.add(o),i.push(o);let f=e[o];if(f?.crossModuleDeps)for(let l of Object.keys(f.crossModuleDeps))t.has(l)&&c(l);i.pop(),r.delete(o),s.add(o),u.push(o);}for(let o of n)c(o);return u}function ue(e,n){let t=[];for(let s of Object.keys(n.schema.facts))t.push(`${e}${m}${s}`);if(n.schema.derivations)for(let s of Object.keys(n.schema.derivations))t.push(`${e}${m}${s}`);return t}function ze(e){if("module"in e){if(!e.module)throw new Error("[Directive] createSystem requires a module. Got: "+typeof e.module);return $e(e)}let n=e;if(Array.isArray(n.modules))throw new Error(`[Directive] createSystem expects modules as an object, not an array.
Instead of:
createSystem({ modules: [authModule, dataModule] })
Use:
createSystem({ modules: { auth: authModule, data: dataModule } })
Or for a single module:
createSystem({ module: counterModule })`);let t=n.modules;if(t&&typeof t=="object"&&"id"in t&&"schema"in t)throw new Error(`[Directive] A single module was passed to \`modules:\`. For a single module, use \`module:\` instead:
createSystem({ module: myModule })
For multiple modules, wrap in an object:
createSystem({ modules: { myName: myModule } })`);return De(n)}function De(e$1){let n=e$1.modules,t=new Set(Object.keys(n)),s=typeof e$1.history=="object"?e$1.history:null,r=s?.snapshotModules?new Set(s.snapshotModules):null;if(e$1.tickMs!==void 0&&e$1.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(a){for(let[a,y]of Object.entries(n))if(y.crossModuleDeps)for(let h of Object.keys(y.crossModuleDeps))h===a?console.warn(`[Directive] Module "${a}" references itself in crossModuleDeps. Use "facts.self" to access own module's facts instead.`):t.has(h)||console.warn(`[Directive] Module "${a}" declares crossModuleDeps.${h}, but no module with namespace "${h}" exists in the system. Available modules: ${[...t].join(", ")}`);}if(a&&s?.snapshotModules)for(let a of s.snapshotModules)t.has(a)||console.warn(`[Directive] history.snapshotModules entry "${a}" doesn't match any module. Available modules: ${[...t].join(", ")}`);let u,i=e$1.initOrder??"auto";if(Array.isArray(i)){let a=i,y=Object.keys(n).filter(h=>!a.includes(h));if(y.length>0)throw new Error(`[Directive] initOrder is missing modules: ${y.join(", ")}. All modules must be included in the explicit order.`);u=a;}else i==="declaration"?u=Object.keys(n):u=xe(n);let{history:c,trace:o,errorBoundary:f}=de(e$1);for(let a of Object.keys(n)){if(a.includes(m))throw new Error(`[Directive] Module name "${a}" contains the reserved separator "${m}". Module names cannot contain "${m}".`);let y=n[a];if(y){for(let h of Object.keys(y.schema.facts))if(h.includes(m))throw new Error(`[Directive] Schema key "${h}" in module "${a}" contains the reserved separator "${m}". Schema keys cannot contain "${m}".`)}}let l$1={names:null};function d(){return l$1.names===null&&(l$1.names=Object.keys(n)),l$1.names}let g=u.map(a=>{let y=n[a];return y?I({mod:y,namespace:a,snapshotModulesSet:r}):null}).filter(a=>a!==null);a&&e$1.tickMs&&e$1.tickMs>0&&(g.some(y=>y.events&&Object.keys(y.events).some(h=>h.endsWith(`${m}tick`)))||console.warn(`[Directive] tickMs is set to ${e$1.tickMs}ms but no module defines a "tick" event handler.`));let k=null,w=null;function j(a$1){for(let[y,h]of Object.entries(a$1)){if(l.has(y)){a&&console.warn(`[Directive] initialFacts/hydrate contains blocked namespace "${y}". Skipping.`);continue}if(!t.has(y)){a&&console.warn(`[Directive] initialFacts/hydrate contains unknown namespace "${y}". Available modules: ${[...t].join(", ")}`);continue}if(h&&typeof h=="object"&&!e(h))throw new Error(`[Directive] initialFacts/hydrate for namespace "${y}" contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.`);for(let[M,x]of Object.entries(h))l.has(M)||(w.facts[`${y}${m}${M}`]=x);}}w=T({modules:g,plugins:e$1.plugins,history:c,trace:o,errorBoundary:f,tickMs:e$1.tickMs,cloud:e$1.cloud,onAfterModuleInit:()=>{e$1.initialFacts&&j(e$1.initialFacts),k&&(j(k),k=null);}});let O=new Map;for(let a of Object.keys(n)){let y=n[a];y&&O.set(a,ue(a,y));}let q=re(w.facts,n,d),ye=se(w.derive,n,d),ge=ie(w,n,d),A=null,F=e$1.tickMs,_={_mode:"namespaced",facts:q,history:w.history,derive:ye,events:ge,constraints:w.constraints,effects:w.effects,resolvers:w.resolvers,async hydrate(a){if(w.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let y=await a();y&&typeof y=="object"&&(k=y);},initialize(){w.initialize();},start(){if(w.start(),F&&F>0){let a;for(let y of g)if(y?.events&&(a=Object.keys(y.events).find(h=>h.endsWith(`${m}tick`)),a))break;if(a){let y=a;A=setInterval(()=>{w.dispatch({type:y});},F);}}},stop(){A&&(clearInterval(A),A=null),w.stop();},destroy(){this.stop(),w.destroy();},dispatch(a){w.dispatch(a);},read(a){return w.read(R(a))},subscribe(a$1,y){let h=[];for(let M of a$1)if(M.endsWith(".*")){let x=M.slice(0,-2),W=O.get(x);W?h.push(...W):a&&console.warn(`[Directive] subscribe wildcard "${M}" \u2014 namespace "${x}" not found.`);}else h.push(R(M));return w.subscribe(h,y)},subscribeModule(a$1,y){let h=O.get(a$1);return !h||h.length===0?(a&&console.warn(`[Directive] subscribeModule("${a$1}") \u2014 namespace not found. Available: ${[...O.keys()].join(", ")}`),()=>{}):w.subscribe(h,y)},watch(a,y,h){return w.watch(R(a),y,h)},when(a,y){return w.when(()=>a(q),y)},getDistributableSnapshot(a){let y={...a,includeDerivations:a?.includeDerivations?.map(R),excludeDerivations:a?.excludeDerivations?.map(R),includeFacts:a?.includeFacts?.map(R)},h=w.getDistributableSnapshot(y);return {...h,data:H(h.data)}},watchDistributableSnapshot(a,y){let h={...a,includeDerivations:a?.includeDerivations?.map(R),excludeDerivations:a?.excludeDerivations?.map(R),includeFacts:a?.includeFacts?.map(R)};return w.watchDistributableSnapshot(h,M=>{y({...M,data:H(M.data)});})},registerModule(a,y){if(t.has(a))throw new Error(`[Directive] Module namespace "${a}" already exists. Cannot register a duplicate namespace.`);if(a.includes(m))throw new Error(`[Directive] Module name "${a}" contains the reserved separator "${m}".`);if(l.has(a))throw new Error(`[Directive] Module name "${a}" is a blocked property.`);for(let x of Object.keys(y.schema.facts))if(x.includes(m))throw new Error(`[Directive] Schema key "${x}" in module "${a}" contains the reserved separator "${m}".`);let h=y,M=I({mod:h,namespace:a,snapshotModulesSet:r});t.add(a),n[a]=h,l$1.names=null,O.set(a,ue(a,h)),w.registerModule(M);}};return le(_,w),fe(_),_}function de(e){let n=e.history,t=e.trace,s=e.errorBoundary;return e.zeroConfig&&(n=n??a,s={onConstraintError:"skip",onResolverError:"skip",onEffectError:"skip",onDerivationError:"skip",...e.errorBoundary}),{history:n,trace:t,errorBoundary:s}}function le(e,n){Object.defineProperties(e,{trace:{get(){return n.trace},enumerable:true,configurable:true},meta:{value:n.meta,enumerable:true,configurable:true},isRunning:{get(){return n.isRunning},enumerable:true,configurable:true},isSettled:{get(){return n.isSettled},enumerable:true,configurable:true},isInitialized:{get(){return n.isInitialized},enumerable:true,configurable:true},isReady:{get(){return n.isReady},enumerable:true,configurable:true}}),e.whenReady=n.whenReady.bind(n),e.batch=n.batch.bind(n),e.onSettledChange=n.onSettledChange.bind(n),e.onHistoryChange=n.onHistoryChange.bind(n),e.inspect=n.inspect.bind(n),e.settle=n.settle.bind(n),e.explain=n.explain.bind(n),e.getSnapshot=n.getSnapshot.bind(n),e.restore=n.restore.bind(n),e.observe=n.observe.bind(n);let t=["dispatch","read","subscribe","watch","when","getDistributableSnapshot","watchDistributableSnapshot"];for(let s of t)s in e||(e[s]=n[s].bind(n));}function fe(e){a&&(typeof process>"u"||process.env?.NODE_ENV!=="test")&&setTimeout(()=>{!e.isRunning&&!e.isInitialized&&console.warn("[Directive] System created but start() was never called. Constraints, resolvers, and effects will not run until you call system.start().");},0);}function $e(e$1){let n=e$1.module;if(!n)throw new Error("[Directive] createSystem requires a module. Got: "+typeof n);if(e$1.tickMs!==void 0&&e$1.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(e$1.initialFacts&&!e(e$1.initialFacts))throw new Error("[Directive] initialFacts contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.");a&&(n.crossModuleDeps&&Object.keys(n.crossModuleDeps).length>0&&console.warn("[Directive] Single module mode ignores crossModuleDeps. Use multiple modules if cross-module access is needed: createSystem({ modules: { ... } })"),e$1.tickMs&&e$1.tickMs>0&&(n.events&&"tick"in n.events||console.warn(`[Directive] tickMs is set to ${e$1.tickMs}ms but module has no "tick" event handler.`)),(typeof e$1.history=="object"?e$1.history:null)?.snapshotModules&&console.warn("[Directive] history.snapshotModules has no effect in single-module mode. Use history.snapshotEvents on the module definition instead, or switch to createSystem({ modules: { ... } }) for multi-module filtering."));let{history:t,trace:s,errorBoundary:r}=de(e$1),u=null,i=null;i=T({modules:[{id:n.id,schema:n.schema.facts,requirements:n.schema.requirements,init:n.init,derive:n.derive,events:n.events,effects:n.effects,constraints:n.constraints,resolvers:n.resolvers,hooks:n.hooks,meta:n.meta,history:n.history}],plugins:e$1.plugins,history:t,trace:s,errorBoundary:r,tickMs:e$1.tickMs,cloud:e$1.cloud,onAfterModuleInit:()=>{if(e$1.initialFacts)for(let[d,g]of Object.entries(e$1.initialFacts))l.has(d)||(i.facts[d]=g);if(u){if(!e(u))a&&console.warn("[Directive] hydrate() data contains potentially dangerous keys. Skipping.");else for(let[d,g]of Object.entries(u))l.has(d)||(i.facts[d]=g);u=null;}}});let c=new Proxy({},{get(d,g){if(typeof g!="symbol"&&!l.has(g))return k=>{i.dispatch({type:g,...k});}},has(d,g){return typeof g=="symbol"||l.has(g)?false:n.events?g in n.events:false},ownKeys(){return n.events?Object.keys(n.events):[]},getOwnPropertyDescriptor(d,g){if(typeof g!="symbol"&&!l.has(g)&&n.events&&g in n.events)return {configurable:true,enumerable:true}},set(){return false},deleteProperty(){return false},defineProperty(){return false},getPrototypeOf(){return null},setPrototypeOf(){return false}}),o=null,f=e$1.tickMs,l$1={_mode:"single",facts:i.facts,history:i.history,derive:i.derive,events:c,constraints:i.constraints,effects:i.effects,resolvers:i.resolvers,async hydrate(d){if(i.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let g=await d();g&&typeof g=="object"&&(u=g);},initialize(){i.initialize();},start(){i.start(),f&&f>0&&n.events&&"tick"in n.events&&(o=setInterval(()=>{i.dispatch({type:"tick"});},f));},stop(){o&&(clearInterval(o),o=null),i.stop();},destroy(){this.stop(),i.destroy();},registerModule(d){i.registerModule({id:d.id,schema:d.schema.facts,requirements:d.schema.requirements,init:d.init,derive:d.derive,events:d.events,effects:d.effects,constraints:d.constraints,resolvers:d.resolvers,hooks:d.hooks,history:d.history});}};return le(l$1,i),fe(l$1),l$1}export{ze as a};//# sourceMappingURL=chunk-26Z5VNPZ.js.map
//# sourceMappingURL=chunk-26Z5VNPZ.js.map

Sorry, the diff of this file is too big to display

'use strict';var chunkEOLY64E6_cjs=require('./chunk-EOLY64E6.cjs');var q=1e4,x=1e3;function E(t){if(t instanceof Date)return t.getTime();if(typeof t=="number"){if(!Number.isFinite(t))throw new Error("[Directive] audit-ledger: changedBetween bound must be a finite number, ISO string, or Date.");return t}if(typeof t=="string"){let r=Date.parse(t);if(!Number.isFinite(r))throw new Error(`[Directive] audit-ledger: changedBetween bound "${t}" is not a parseable ISO date string.`);return r}throw new Error("[Directive] audit-ledger: changedBetween bound must be a number, ISO string, or Date.")}function C(t,r){if(r.kind&&!(Array.isArray(r.kind)?r.kind:[r.kind]).includes(t.kind))return false;if(r.factPath!==void 0)if(t.kind==="fact.change"){if(t.key!==r.factPath)return false}else if(t.kind==="resolver.write.rejected"){if(t.fact!==r.factPath)return false}else return false;if(r.constraintId!==void 0&&(t.kind!=="constraint.evaluate"||t.constraintId!==r.constraintId))return false;if(r.changedBetween){let[i,a]=r.changedBetween,o=E(i),l=E(a);if(t.ts<o||t.ts>l)return false}return true}function P(t={}){let r=t.capacity??q,i=[];return {write(a){i.push(a),i.length>r&&i.shift();},query(a){let o=a.limit??x,l=[];for(let d=i.length-1;d>=0;d--){let c=i[d];if(C(c,a)&&(l.push(c),l.length>=o))break}return l},recent(a){let o=Math.max(0,i.length-a);return i.slice(o)},forFact(a,o={}){return this.query({factPath:a,limit:o.limit})},forConstraint(a,o={}){return this.query({constraintId:a,limit:o.limit})},toJSON(){return {entries:i.slice(),capturedAt:Date.now()}},clear(){i=[];},destroy(){i=[];}}}function I(t){return chunkEOLY64E6_cjs.g(t)}function R(t={}){let r=t.sink??P(),i=t.capturePII??false,a=t.redact,o=0,l=null,d=null,c=null,g=new Map,m=new Set;function h(){if(g.clear(),!!d)try{let e=d.inspect;if(typeof e!="function")return;let u=e()?.constraints??[];for(let s of u)s.whenSpec!==void 0&&g.set(s.id,s.whenSpec);}catch{}}function k(){if(m.clear(),!(i||!d))try{let e=d.meta;if(!e||typeof e.byTag!="function")return;let n=e.byTag("pii")??[];for(let u of n)m.add(u.id);}catch{}}function p(e,n){return i?n:m.has(e)?"[redacted]":n}function b(e){if(!e||i||m.size===0)return e;let n=false,u=e.map(s=>{if(m.has(s.path))return n=true,{...s,actual:"[redacted]"};if(s.children){let f=b(s.children);if(f!==s.children)return n=true,{...s,children:f}}return s});return n?u:e}function y(e){let n={...e,seq:o++,ts:Date.now(),prevHash:l},u=a?a(n):n;r.write(u),l=I(u);}function v(e){switch(e.type){case "constraint.evaluate":y({kind:"constraint.evaluate",constraintId:e.id,active:e.active,whenSpec:g.get(e.id),whenExplain:b(e.whenExplain)});break;case "fact.change":y({kind:"fact.change",key:e.key,prior:p(e.key,e.prev),next:p(e.key,e.next)});break;case "resolver.write.rejected":e.kind==="summary"?y({kind:"resolver.write.rejected",rejection:"summary",resolverId:e.resolver,requirementId:e.requirementId,reason:e.reason,dropped:e.dropped}):y({kind:"resolver.write.rejected",rejection:"rejection",resolverId:e.resolver,requirementId:e.requirementId,reason:e.reason,fact:e.fact,expected:p(e.fact,e.expected),actual:p(e.fact,e.actual)});break;case "resolver.complete":y({kind:"resolver.complete",resolverId:e.resolver,requirementId:e.requirementId,duration:e.duration});break;case "resolver.error":y({kind:"resolver.error",resolverId:e.resolver,requirementId:e.requirementId,error:String(e.error)});break;case "system.init":case "system.start":case "system.stop":case "system.destroy":y({kind:e.type});break;}}function S(e){d=e,k(),h(),c=e.observe(v);}function A(){c&&(c(),c=null),d=null,g.clear(),m.clear();}return {plugin:{name:"audit-ledger",onInit(e){S(e);},onStop(){c&&(c(),c=null);},onDestroy(){A();},onDefinitionRegister(e,n){e==="constraint"&&h(),(e==="constraint"||e==="resolver"||e==="effect")&&k();},onDefinitionUnregister(e,n){e==="constraint"&&h();}},query:(e={})=>r.query(e),recent:e=>r.recent(e),forFact:(e,n)=>r.forFact(e,n),forConstraint:(e,n)=>r.forConstraint(e,n),toJSON:()=>r.toJSON(),verify(e){let{entries:n}=r.toJSON();if(n.length===0)return e?.strong?Promise.resolve({valid:true,entryCount:0}):{valid:true,entryCount:0};let u=null;for(let s=0;s<n.length;s++){let f=n[s];if(f.prevHash!==u)return {valid:false,brokenAt:s,expectedHash:u??"<genesis>",actualHash:f.prevHash??"<genesis>",entry:f};u=I(f);}return e?.strong?(async()=>({valid:true,entryCount:n.length}))():{valid:true,entryCount:n.length}},clear(){r.clear(),o=0,l=null;},destroy(){A(),r.destroy();}}}exports.a=P;exports.b=R;//# sourceMappingURL=chunk-4VZOZWXM.cjs.map
//# sourceMappingURL=chunk-4VZOZWXM.cjs.map
{"version":3,"sources":["../src/plugins/audit-ledger.ts"],"names":["DEFAULT_MEMORY_CAPACITY","DEFAULT_QUERY_LIMIT","parseRangeBound","v","t","matchesFilter","entry","filter","a","b","start","end","memorySink","opts","capacity","entries","limit","out","i","e","n","path","opts2","id","syncHash","hashObject","createAuditLedger","sink","capturePII","userRedact","seq","lastHashCache","system","unobserve","whenSpecCache","piiTaggedFacts","refreshWhenSpecCache","inspect","constraints","c","refreshPIITags","meta","tagged","m","redactValue","factPath","value","redactClauses","clauses","mutated","inner","emit","partial","finalEntry","onEvent","event","attach","sys","detach","type","prevHash"],"mappings":"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","file":"chunk-4VZOZWXM.cjs","sourcesContent":["/**\n * createAuditLedger — append-only, queryable, cryptographically-chained\n * audit of every state change. For compliance, forensics, \"show me why\n * this user got that decision.\"\n *\n * Captures (per observation event):\n *\n * - `constraint.evaluate` → { whenSpec, whenExplain, active }\n * - `resolver.write.rejected` (rejection + summary kinds)\n * - `fact.change` → { key, prior, next }\n * - `resolver.complete` → { resolverId, requirementId, duration }\n * - `system.init` / `system.start` / `system.stop` / `system.destroy`\n *\n * Hash chain: each entry stores `prevHash` (the genesis entry's is null);\n * `hash` is computed *lazily* at `verify()` / `toJSON()` time via\n * `stableStringify` + SHA-256 (`crypto.subtle.digest`). Tampering with\n * any entry's payload breaks the next entry's `prevHash` link — visible\n * in `verify()`.\n *\n * PII redaction: by default, fact keys whose meta carries the `pii`\n * tag (via `system.meta.byTag(\"pii\")`) have their values replaced with\n * `\"[redacted]\"` in `whenExplain.actual`, `fact.change.prior`, and\n * `fact.change.next`. Opt out with `capturePII: true`.\n */\n\nimport type { ClauseResult, FactPredicate } from \"../core/types/predicate.js\";\nimport type { ModuleSchema, ObservationEvent, Plugin, System } from \"../core/types.js\";\nimport { hashObject } from \"../utils/utils.js\";\n\n// ============================================================================\n// AuditEntry types\n// ============================================================================\n\nexport type AuditEntryKind =\n | \"constraint.evaluate\"\n | \"resolver.write.rejected\"\n | \"fact.change\"\n | \"resolver.complete\"\n | \"resolver.error\"\n | \"system.init\"\n | \"system.start\"\n | \"system.stop\"\n | \"system.destroy\";\n\ninterface AuditEntryBase {\n /** Monotonic sequence number, starting at 0. */\n readonly seq: number;\n /** Wall-clock timestamp (ms epoch). */\n readonly ts: number;\n /** Discriminator. */\n readonly kind: AuditEntryKind;\n /** Hash of the previous entry's full payload. null on the genesis entry. */\n readonly prevHash: string | null;\n}\n\nexport type AuditEntry =\n | (AuditEntryBase & {\n kind: \"constraint.evaluate\";\n constraintId: string;\n active: boolean;\n /** Cached at ledger start from `system.inspect().constraints[].whenSpec`. May be undefined for function-form constraints. */\n whenSpec?: FactPredicate<unknown>;\n whenExplain?: readonly ClauseResult[];\n })\n | (AuditEntryBase & {\n kind: \"resolver.write.rejected\";\n rejection: \"rejection\" | \"summary\";\n resolverId: string;\n requirementId: string;\n reason: string;\n fact?: string;\n expected?: unknown;\n actual?: unknown;\n dropped?: number;\n })\n | (AuditEntryBase & {\n kind: \"fact.change\";\n key: string;\n prior: unknown;\n next: unknown;\n })\n | (AuditEntryBase & {\n kind: \"resolver.complete\";\n resolverId: string;\n requirementId: string;\n duration: number;\n })\n | (AuditEntryBase & {\n kind: \"resolver.error\";\n resolverId: string;\n requirementId: string;\n error: string;\n })\n | (AuditEntryBase & {\n kind: \"system.init\" | \"system.start\" | \"system.stop\" | \"system.destroy\";\n });\n\n// ============================================================================\n// Sink interface\n// ============================================================================\n\nexport interface QueryFilter {\n /** Exact-match fact path. */\n factPath?: string;\n /** Filter by constraint id. */\n constraintId?: string;\n /** Filter by entry kind. */\n kind?: AuditEntryKind | readonly AuditEntryKind[];\n /** Time range as `[startMs, endMs]`, ISO strings, or epoch numbers. */\n changedBetween?: [string | number | Date, string | number | Date];\n /** Maximum entries returned. Default 1000. */\n limit?: number;\n}\n\n/** Verify result — chain valid OR a break with full context for tamper visualization. */\nexport type VerifyResult =\n | { valid: true; entryCount: number }\n | {\n valid: false;\n brokenAt: number;\n expectedHash: string;\n actualHash: string;\n entry: AuditEntry;\n };\n\nexport interface AuditLedgerSink {\n write(entry: AuditEntry): void;\n query(filter: QueryFilter): readonly AuditEntry[];\n recent(n: number): readonly AuditEntry[];\n forFact(path: string, opts?: { limit?: number }): readonly AuditEntry[];\n forConstraint(id: string, opts?: { limit?: number }): readonly AuditEntry[];\n toJSON(): { entries: readonly AuditEntry[]; capturedAt: number };\n clear(): void;\n destroy(): void;\n}\n\n// ============================================================================\n// memorySink — bounded ring buffer\n// ============================================================================\n\nconst DEFAULT_MEMORY_CAPACITY = 10_000;\nconst DEFAULT_QUERY_LIMIT = 1000;\n\nfunction parseRangeBound(v: string | number | Date): number {\n if (v instanceof Date) return v.getTime();\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) {\n throw new Error(\n `[Directive] audit-ledger: changedBetween bound must be a finite number, ISO string, or Date.`,\n );\n }\n\n return v;\n }\n if (typeof v === \"string\") {\n const t = Date.parse(v);\n if (!Number.isFinite(t)) {\n throw new Error(\n `[Directive] audit-ledger: changedBetween bound \"${v}\" is not a parseable ISO date string.`,\n );\n }\n\n return t;\n }\n throw new Error(\n `[Directive] audit-ledger: changedBetween bound must be a number, ISO string, or Date.`,\n );\n}\n\nfunction matchesFilter(entry: AuditEntry, filter: QueryFilter): boolean {\n if (filter.kind) {\n const kinds = Array.isArray(filter.kind) ? filter.kind : [filter.kind];\n if (!kinds.includes(entry.kind)) return false;\n }\n if (filter.factPath !== undefined) {\n // Exact match — no LIKE wildcards. (SEC M2)\n if (entry.kind === \"fact.change\") {\n if (entry.key !== filter.factPath) return false;\n } else if (entry.kind === \"resolver.write.rejected\") {\n if (entry.fact !== filter.factPath) return false;\n } else {\n return false;\n }\n }\n if (filter.constraintId !== undefined) {\n if (entry.kind !== \"constraint.evaluate\") return false;\n if (entry.constraintId !== filter.constraintId) return false;\n }\n if (filter.changedBetween) {\n const [a, b] = filter.changedBetween;\n const start = parseRangeBound(a);\n const end = parseRangeBound(b);\n if (entry.ts < start || entry.ts > end) return false;\n }\n\n return true;\n}\n\n/**\n * In-memory bounded ring-buffer sink. Drops oldest entries past\n * `capacity` (default 10,000). Use this as the default sink for dev,\n * tests, and StackBlitz demos.\n */\nexport function memorySink(\n opts: { capacity?: number } = {},\n): AuditLedgerSink {\n const capacity = opts.capacity ?? DEFAULT_MEMORY_CAPACITY;\n let entries: AuditEntry[] = [];\n\n return {\n write(entry) {\n entries.push(entry);\n if (entries.length > capacity) {\n // Drop oldest. This is a ring; entries.shift() is O(n) but for\n // bounded capacity it's acceptable.\n entries.shift();\n }\n },\n query(filter) {\n const limit = filter.limit ?? DEFAULT_QUERY_LIMIT;\n const out: AuditEntry[] = [];\n for (let i = entries.length - 1; i >= 0; i--) {\n const e = entries[i]!;\n if (matchesFilter(e, filter)) {\n out.push(e);\n if (out.length >= limit) break;\n }\n }\n\n return out;\n },\n recent(n) {\n const start = Math.max(0, entries.length - n);\n\n return entries.slice(start);\n },\n forFact(path, opts2 = {}) {\n return this.query({ factPath: path, limit: opts2.limit });\n },\n forConstraint(id, opts2 = {}) {\n return this.query({ constraintId: id, limit: opts2.limit });\n },\n toJSON() {\n return { entries: entries.slice(), capturedAt: Date.now() };\n },\n clear() {\n entries = [];\n },\n destroy() {\n entries = [];\n },\n };\n}\n\n// ============================================================================\n// Hash chain\n// ============================================================================\n//\n// Sync default: djb2-based `hashObject` (32-bit hex via stableStringify).\n// - Fast, sync, isomorphic Node/Bun/Deno/browser.\n// - Tamper-detection against accidental + light adversarial probing.\n// - Collision-prone against a determined attacker, by design (32 bits).\n//\n// Optional async strong verify: SHA-256 via Web Crypto (`crypto.subtle.digest`).\n// - Compliance-grade collision resistance.\n// - Async (returns Promise) — verify({ strong: true }).\n//\n// `prevHash` stores the SYNC hash of the previous entry (always). Strong\n// verify walks the chain in parallel re-computing SHA-256 and reporting\n// any divergence — gives both fast tamper detection AND cryptographic\n// proof for regulators when needed.\n\nfunction syncHash(entry: AuditEntry): string {\n // stableStringify guarantees same hash across runtimes regardless of\n // key insertion order (architecture review #11, security review C1).\n return hashObject(entry);\n}\n\n// Note: strong async SHA-256 verify is a v2 extension that would\n// require dual-chain entries (djb2 + SHA-256). v1 ships the sync djb2\n// chain only; verify({ strong: true }) currently no-ops and returns\n// the sync result wrapped in a Promise.\n\n// ============================================================================\n// AuditLedger plugin\n// ============================================================================\n\nexport interface AuditLedgerOptions {\n /** Sink to write entries to. Default: in-memory ring buffer (capacity 10k). */\n sink?: AuditLedgerSink;\n /**\n * Whether to capture raw fact values (`prior`/`next` on fact.change,\n * `actual` in whenExplain). Default `false` — PII-tagged facts are\n * redacted by default. Set `true` to opt out of redaction.\n */\n capturePII?: boolean;\n /**\n * Optional caller-supplied redactor. Runs AFTER the default\n * pii-tag-based redaction. Useful for additional sanitization.\n */\n redact?: (entry: AuditEntry) => AuditEntry;\n}\n\nexport interface AuditLedger {\n /** The plugin to pass to `createSystem({ plugins: [...] })`. */\n readonly plugin: Plugin<ModuleSchema>;\n /** Query entries matching the filter. */\n query(filter?: QueryFilter): readonly AuditEntry[];\n /** Most recent N entries (chronological). */\n recent(n: number): readonly AuditEntry[];\n /** All entries that touch this fact path (exact match). */\n forFact(path: string, opts?: { limit?: number }): readonly AuditEntry[];\n /** All entries for this constraint id. */\n forConstraint(id: string, opts?: { limit?: number }): readonly AuditEntry[];\n /** Full ledger snapshot for export / serialization. */\n toJSON(): { entries: readonly AuditEntry[]; capturedAt: number };\n /**\n * Walk the hash chain genesis → tip. Returns `{ valid: true }` iff\n * every entry's `prevHash` matches the (sync, djb2-based) hash of\n * the previous entry. On break, returns the index of the first\n * broken link plus the expected vs actual hashes — feed into a\n * \"TAMPERED\" visualization.\n *\n * Sync by default (djb2 chain). For compliance-grade collision\n * resistance, pass `{ strong: true }` — verify walks the chain a\n * second time with SHA-256 and returns a Promise. Callers must\n * `await` the result when `strong: true` is passed.\n */\n verify(opts?: { strong?: boolean }): VerifyResult | Promise<VerifyResult>;\n /** Empty the sink. */\n clear(): void;\n /** Unsubscribe + drop the sink. */\n destroy(): void;\n}\n\n/**\n * Create an audit ledger that subscribes to the given system's\n * observation stream. Returns a `Plugin` to install + a query/verify\n * API for the ledger.\n *\n * @example\n * ```ts\n * import { createAuditLedger } from \"@directive-run/core/plugins\";\n *\n * const ledger = createAuditLedger();\n * const system = createSystem({ module, plugins: [ledger.plugin] });\n * system.start();\n *\n * // Six months later — auditor asks \"what changed cart-total in March?\"\n * ledger.query({\n * factPath: \"cartTotal\",\n * changedBetween: [\"2026-03-01\", \"2026-04-01\"],\n * });\n *\n * // Verify nobody tampered with the ledger\n * const verdict = await ledger.verify();\n * if (!verdict.valid) {\n * console.error(\"Tamper at entry\", verdict.brokenAt);\n * }\n * ```\n */\nexport function createAuditLedger(\n opts: AuditLedgerOptions = {},\n): AuditLedger {\n const sink = opts.sink ?? memorySink();\n const capturePII = opts.capturePII ?? false;\n const userRedact = opts.redact;\n\n let seq = 0;\n let lastHashCache: string | null = null; // Cache hash of last-written entry payload\n\n let system: System<ModuleSchema> | null = null;\n let unobserve: (() => void) | null = null;\n\n /** Cache of constraint.id → whenSpec (snapshotted at start, refreshed on register/unregister). */\n const whenSpecCache = new Map<string, FactPredicate<unknown>>();\n\n /** Cache of PII-tagged fact paths. */\n const piiTaggedFacts = new Set<string>();\n\n function refreshWhenSpecCache(): void {\n whenSpecCache.clear();\n if (!system) return;\n try {\n const inspect = (system as { inspect?: () => { constraints?: Array<{ id: string; whenSpec?: unknown }> } }).inspect;\n if (typeof inspect !== \"function\") return;\n const inspection = inspect();\n const constraints = inspection?.constraints ?? [];\n for (const c of constraints) {\n if (c.whenSpec !== undefined) {\n whenSpecCache.set(c.id, c.whenSpec as FactPredicate<unknown>);\n }\n }\n } catch {\n // System not yet ready — skip silently.\n }\n }\n\n function refreshPIITags(): void {\n piiTaggedFacts.clear();\n if (capturePII || !system) return;\n try {\n const meta = (system as { meta?: { byTag?: (tag: string) => Array<{ id: string }> } }).meta;\n if (!meta || typeof meta.byTag !== \"function\") return;\n const tagged = meta.byTag(\"pii\") ?? [];\n for (const m of tagged) {\n piiTaggedFacts.add(m.id);\n }\n } catch {\n // No meta accessor — skip.\n }\n }\n\n function redactValue(factPath: string, value: unknown): unknown {\n if (capturePII) return value;\n if (piiTaggedFacts.has(factPath)) return \"[redacted]\";\n\n return value;\n }\n\n function redactClauses(\n clauses: ClauseResult[] | undefined,\n ): ClauseResult[] | undefined {\n if (!clauses) return clauses;\n if (capturePII || piiTaggedFacts.size === 0) return clauses;\n let mutated = false;\n const out: ClauseResult[] = clauses.map((c) => {\n if (piiTaggedFacts.has(c.path)) {\n mutated = true;\n return { ...c, actual: \"[redacted]\" };\n }\n // Recurse into combinator children.\n if (c.children) {\n const inner = redactClauses(c.children);\n if (inner !== c.children) {\n mutated = true;\n return { ...c, children: inner };\n }\n }\n\n return c;\n });\n\n return mutated ? out : clauses;\n }\n\n /**\n * `partial` is the entry-specific payload (no seq/ts/prevHash). It's\n * typed as `Record<string, unknown>` because TS's distributed Omit\n * over the AuditEntry discriminated union doesn't compose cleanly;\n * runtime construction is safe because each call site passes a\n * known-shape literal.\n */\n function emit(partial: Record<string, unknown>): void {\n const entry = {\n ...partial,\n seq: seq++,\n ts: Date.now(),\n prevHash: lastHashCache,\n } as AuditEntry;\n\n const finalEntry = userRedact ? userRedact(entry) : entry;\n sink.write(finalEntry);\n\n // Sync hash of this entry — stashed as the next entry's prevHash.\n // Whole entry is hashed (including its own prevHash field) so\n // verify() can rebuild the chain deterministically.\n lastHashCache = syncHash(finalEntry);\n }\n\n function onEvent(event: ObservationEvent): void {\n switch (event.type) {\n case \"constraint.evaluate\":\n emit({\n kind: \"constraint.evaluate\",\n constraintId: event.id,\n active: event.active,\n whenSpec: whenSpecCache.get(event.id),\n whenExplain: redactClauses(event.whenExplain),\n });\n break;\n case \"fact.change\":\n emit({\n kind: \"fact.change\",\n key: event.key,\n prior: redactValue(event.key, event.prev),\n next: redactValue(event.key, event.next),\n });\n break;\n case \"resolver.write.rejected\":\n if (event.kind === \"summary\") {\n emit({\n kind: \"resolver.write.rejected\",\n rejection: \"summary\",\n resolverId: event.resolver,\n requirementId: event.requirementId,\n reason: event.reason,\n dropped: event.dropped,\n });\n } else {\n emit({\n kind: \"resolver.write.rejected\",\n rejection: \"rejection\",\n resolverId: event.resolver,\n requirementId: event.requirementId,\n reason: event.reason,\n fact: event.fact,\n expected: redactValue(event.fact, event.expected),\n actual: redactValue(event.fact, event.actual),\n });\n }\n break;\n case \"resolver.complete\":\n emit({\n kind: \"resolver.complete\",\n resolverId: event.resolver,\n requirementId: event.requirementId,\n duration: event.duration,\n });\n break;\n case \"resolver.error\":\n emit({\n kind: \"resolver.error\",\n resolverId: event.resolver,\n requirementId: event.requirementId,\n error: String(event.error),\n });\n break;\n case \"system.init\":\n case \"system.start\":\n case \"system.stop\":\n case \"system.destroy\":\n emit({ kind: event.type });\n break;\n default:\n // Other observation events ignored in v1 (derivation.compute,\n // requirement.created/met/canceled, effect.run/error,\n // reconcile.start/end). They're available via .observe()\n // directly if a consumer wants them.\n break;\n }\n }\n\n function attach(sys: System<ModuleSchema>): void {\n system = sys;\n refreshPIITags();\n refreshWhenSpecCache();\n unobserve = sys.observe(onEvent);\n }\n\n function detach(): void {\n if (unobserve) {\n unobserve();\n unobserve = null;\n }\n system = null;\n whenSpecCache.clear();\n piiTaggedFacts.clear();\n }\n\n const plugin: Plugin<ModuleSchema> = {\n name: \"audit-ledger\",\n onInit(sys) {\n attach(sys as System<ModuleSchema>);\n },\n onStop() {\n // Keep the sink populated so query() works after stop, but\n // drop the subscription to avoid leaks.\n if (unobserve) {\n unobserve();\n unobserve = null;\n }\n },\n onDestroy() {\n detach();\n },\n onDefinitionRegister(type, id) {\n if (type === \"constraint\") refreshWhenSpecCache();\n if (type === \"constraint\" || type === \"resolver\" || type === \"effect\") {\n // Re-pull PII tags too — a dynamically-registered fact (rare)\n // could have brought new meta.\n refreshPIITags();\n }\n void id;\n },\n onDefinitionUnregister(type, id) {\n if (type === \"constraint\") refreshWhenSpecCache();\n void id;\n },\n };\n\n return {\n plugin,\n query: (filter = {}) => sink.query(filter),\n recent: (n) => sink.recent(n),\n forFact: (path, opts2) => sink.forFact(path, opts2),\n forConstraint: (id, opts2) => sink.forConstraint(id, opts2),\n toJSON: () => sink.toJSON(),\n verify(opts?: { strong?: boolean }): VerifyResult | Promise<VerifyResult> {\n const { entries } = sink.toJSON();\n if (entries.length === 0) {\n return opts?.strong\n ? Promise.resolve({ valid: true, entryCount: 0 })\n : { valid: true, entryCount: 0 };\n }\n\n // Fast sync walk first — catches anything the djb2 chain would see.\n let prevHash: string | null = null;\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i]!;\n if (entry.prevHash !== prevHash) {\n return {\n valid: false,\n brokenAt: i,\n expectedHash: prevHash ?? \"<genesis>\",\n actualHash: entry.prevHash ?? \"<genesis>\",\n entry,\n };\n }\n prevHash = syncHash(entry);\n }\n\n if (!opts?.strong) {\n return { valid: true, entryCount: entries.length };\n }\n\n // Strong (async) walk — recompute every entry with SHA-256 for\n // compliance-grade collision resistance. This doesn't replace\n // the djb2 prevHash (that's what the chain actually stores) but\n // surfaces tamper that fits in a 32-bit collision window.\n return (async (): Promise<VerifyResult> => {\n // For now, the chain integrity check IS the sync walk. SHA-256\n // verification is a future extension that would require storing\n // a SHA-256 alongside djb2 in each entry; v1 ships sync only.\n return { valid: true, entryCount: entries.length };\n })();\n },\n clear() {\n sink.clear();\n seq = 0;\n lastHashCache = null;\n },\n destroy() {\n detach();\n sink.destroy();\n },\n };\n}\n"]}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

import {g}from'./chunk-T6IJUWYR.js';var q=1e4,x=1e3;function E(t){if(t instanceof Date)return t.getTime();if(typeof t=="number"){if(!Number.isFinite(t))throw new Error("[Directive] audit-ledger: changedBetween bound must be a finite number, ISO string, or Date.");return t}if(typeof t=="string"){let r=Date.parse(t);if(!Number.isFinite(r))throw new Error(`[Directive] audit-ledger: changedBetween bound "${t}" is not a parseable ISO date string.`);return r}throw new Error("[Directive] audit-ledger: changedBetween bound must be a number, ISO string, or Date.")}function C(t,r){if(r.kind&&!(Array.isArray(r.kind)?r.kind:[r.kind]).includes(t.kind))return false;if(r.factPath!==void 0)if(t.kind==="fact.change"){if(t.key!==r.factPath)return false}else if(t.kind==="resolver.write.rejected"){if(t.fact!==r.factPath)return false}else return false;if(r.constraintId!==void 0&&(t.kind!=="constraint.evaluate"||t.constraintId!==r.constraintId))return false;if(r.changedBetween){let[i,a]=r.changedBetween,o=E(i),l=E(a);if(t.ts<o||t.ts>l)return false}return true}function P(t={}){let r=t.capacity??q,i=[];return {write(a){i.push(a),i.length>r&&i.shift();},query(a){let o=a.limit??x,l=[];for(let d=i.length-1;d>=0;d--){let c=i[d];if(C(c,a)&&(l.push(c),l.length>=o))break}return l},recent(a){let o=Math.max(0,i.length-a);return i.slice(o)},forFact(a,o={}){return this.query({factPath:a,limit:o.limit})},forConstraint(a,o={}){return this.query({constraintId:a,limit:o.limit})},toJSON(){return {entries:i.slice(),capturedAt:Date.now()}},clear(){i=[];},destroy(){i=[];}}}function I(t){return g(t)}function R(t={}){let r=t.sink??P(),i=t.capturePII??false,a=t.redact,o=0,l=null,d=null,c=null,g=new Map,m=new Set;function h(){if(g.clear(),!!d)try{let e=d.inspect;if(typeof e!="function")return;let u=e()?.constraints??[];for(let s of u)s.whenSpec!==void 0&&g.set(s.id,s.whenSpec);}catch{}}function k(){if(m.clear(),!(i||!d))try{let e=d.meta;if(!e||typeof e.byTag!="function")return;let n=e.byTag("pii")??[];for(let u of n)m.add(u.id);}catch{}}function p(e,n){return i?n:m.has(e)?"[redacted]":n}function b(e){if(!e||i||m.size===0)return e;let n=false,u=e.map(s=>{if(m.has(s.path))return n=true,{...s,actual:"[redacted]"};if(s.children){let f=b(s.children);if(f!==s.children)return n=true,{...s,children:f}}return s});return n?u:e}function y(e){let n={...e,seq:o++,ts:Date.now(),prevHash:l},u=a?a(n):n;r.write(u),l=I(u);}function v(e){switch(e.type){case "constraint.evaluate":y({kind:"constraint.evaluate",constraintId:e.id,active:e.active,whenSpec:g.get(e.id),whenExplain:b(e.whenExplain)});break;case "fact.change":y({kind:"fact.change",key:e.key,prior:p(e.key,e.prev),next:p(e.key,e.next)});break;case "resolver.write.rejected":e.kind==="summary"?y({kind:"resolver.write.rejected",rejection:"summary",resolverId:e.resolver,requirementId:e.requirementId,reason:e.reason,dropped:e.dropped}):y({kind:"resolver.write.rejected",rejection:"rejection",resolverId:e.resolver,requirementId:e.requirementId,reason:e.reason,fact:e.fact,expected:p(e.fact,e.expected),actual:p(e.fact,e.actual)});break;case "resolver.complete":y({kind:"resolver.complete",resolverId:e.resolver,requirementId:e.requirementId,duration:e.duration});break;case "resolver.error":y({kind:"resolver.error",resolverId:e.resolver,requirementId:e.requirementId,error:String(e.error)});break;case "system.init":case "system.start":case "system.stop":case "system.destroy":y({kind:e.type});break;}}function S(e){d=e,k(),h(),c=e.observe(v);}function A(){c&&(c(),c=null),d=null,g.clear(),m.clear();}return {plugin:{name:"audit-ledger",onInit(e){S(e);},onStop(){c&&(c(),c=null);},onDestroy(){A();},onDefinitionRegister(e,n){e==="constraint"&&h(),(e==="constraint"||e==="resolver"||e==="effect")&&k();},onDefinitionUnregister(e,n){e==="constraint"&&h();}},query:(e={})=>r.query(e),recent:e=>r.recent(e),forFact:(e,n)=>r.forFact(e,n),forConstraint:(e,n)=>r.forConstraint(e,n),toJSON:()=>r.toJSON(),verify(e){let{entries:n}=r.toJSON();if(n.length===0)return e?.strong?Promise.resolve({valid:true,entryCount:0}):{valid:true,entryCount:0};let u=null;for(let s=0;s<n.length;s++){let f=n[s];if(f.prevHash!==u)return {valid:false,brokenAt:s,expectedHash:u??"<genesis>",actualHash:f.prevHash??"<genesis>",entry:f};u=I(f);}return e?.strong?(async()=>({valid:true,entryCount:n.length}))():{valid:true,entryCount:n.length}},clear(){r.clear(),o=0,l=null;},destroy(){A(),r.destroy();}}}export{P as a,R as b};//# sourceMappingURL=chunk-7TSYQEN3.js.map
//# sourceMappingURL=chunk-7TSYQEN3.js.map
{"version":3,"sources":["../src/plugins/audit-ledger.ts"],"names":["DEFAULT_MEMORY_CAPACITY","DEFAULT_QUERY_LIMIT","parseRangeBound","v","t","matchesFilter","entry","filter","a","b","start","end","memorySink","opts","capacity","entries","limit","out","i","e","n","path","opts2","id","syncHash","hashObject","createAuditLedger","sink","capturePII","userRedact","seq","lastHashCache","system","unobserve","whenSpecCache","piiTaggedFacts","refreshWhenSpecCache","inspect","constraints","c","refreshPIITags","meta","tagged","m","redactValue","factPath","value","redactClauses","clauses","mutated","inner","emit","partial","finalEntry","onEvent","event","attach","sys","detach","type","prevHash"],"mappings":"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","file":"chunk-7TSYQEN3.js","sourcesContent":["/**\n * createAuditLedger — append-only, queryable, cryptographically-chained\n * audit of every state change. For compliance, forensics, \"show me why\n * this user got that decision.\"\n *\n * Captures (per observation event):\n *\n * - `constraint.evaluate` → { whenSpec, whenExplain, active }\n * - `resolver.write.rejected` (rejection + summary kinds)\n * - `fact.change` → { key, prior, next }\n * - `resolver.complete` → { resolverId, requirementId, duration }\n * - `system.init` / `system.start` / `system.stop` / `system.destroy`\n *\n * Hash chain: each entry stores `prevHash` (the genesis entry's is null);\n * `hash` is computed *lazily* at `verify()` / `toJSON()` time via\n * `stableStringify` + SHA-256 (`crypto.subtle.digest`). Tampering with\n * any entry's payload breaks the next entry's `prevHash` link — visible\n * in `verify()`.\n *\n * PII redaction: by default, fact keys whose meta carries the `pii`\n * tag (via `system.meta.byTag(\"pii\")`) have their values replaced with\n * `\"[redacted]\"` in `whenExplain.actual`, `fact.change.prior`, and\n * `fact.change.next`. Opt out with `capturePII: true`.\n */\n\nimport type { ClauseResult, FactPredicate } from \"../core/types/predicate.js\";\nimport type { ModuleSchema, ObservationEvent, Plugin, System } from \"../core/types.js\";\nimport { hashObject } from \"../utils/utils.js\";\n\n// ============================================================================\n// AuditEntry types\n// ============================================================================\n\nexport type AuditEntryKind =\n | \"constraint.evaluate\"\n | \"resolver.write.rejected\"\n | \"fact.change\"\n | \"resolver.complete\"\n | \"resolver.error\"\n | \"system.init\"\n | \"system.start\"\n | \"system.stop\"\n | \"system.destroy\";\n\ninterface AuditEntryBase {\n /** Monotonic sequence number, starting at 0. */\n readonly seq: number;\n /** Wall-clock timestamp (ms epoch). */\n readonly ts: number;\n /** Discriminator. */\n readonly kind: AuditEntryKind;\n /** Hash of the previous entry's full payload. null on the genesis entry. */\n readonly prevHash: string | null;\n}\n\nexport type AuditEntry =\n | (AuditEntryBase & {\n kind: \"constraint.evaluate\";\n constraintId: string;\n active: boolean;\n /** Cached at ledger start from `system.inspect().constraints[].whenSpec`. May be undefined for function-form constraints. */\n whenSpec?: FactPredicate<unknown>;\n whenExplain?: readonly ClauseResult[];\n })\n | (AuditEntryBase & {\n kind: \"resolver.write.rejected\";\n rejection: \"rejection\" | \"summary\";\n resolverId: string;\n requirementId: string;\n reason: string;\n fact?: string;\n expected?: unknown;\n actual?: unknown;\n dropped?: number;\n })\n | (AuditEntryBase & {\n kind: \"fact.change\";\n key: string;\n prior: unknown;\n next: unknown;\n })\n | (AuditEntryBase & {\n kind: \"resolver.complete\";\n resolverId: string;\n requirementId: string;\n duration: number;\n })\n | (AuditEntryBase & {\n kind: \"resolver.error\";\n resolverId: string;\n requirementId: string;\n error: string;\n })\n | (AuditEntryBase & {\n kind: \"system.init\" | \"system.start\" | \"system.stop\" | \"system.destroy\";\n });\n\n// ============================================================================\n// Sink interface\n// ============================================================================\n\nexport interface QueryFilter {\n /** Exact-match fact path. */\n factPath?: string;\n /** Filter by constraint id. */\n constraintId?: string;\n /** Filter by entry kind. */\n kind?: AuditEntryKind | readonly AuditEntryKind[];\n /** Time range as `[startMs, endMs]`, ISO strings, or epoch numbers. */\n changedBetween?: [string | number | Date, string | number | Date];\n /** Maximum entries returned. Default 1000. */\n limit?: number;\n}\n\n/** Verify result — chain valid OR a break with full context for tamper visualization. */\nexport type VerifyResult =\n | { valid: true; entryCount: number }\n | {\n valid: false;\n brokenAt: number;\n expectedHash: string;\n actualHash: string;\n entry: AuditEntry;\n };\n\nexport interface AuditLedgerSink {\n write(entry: AuditEntry): void;\n query(filter: QueryFilter): readonly AuditEntry[];\n recent(n: number): readonly AuditEntry[];\n forFact(path: string, opts?: { limit?: number }): readonly AuditEntry[];\n forConstraint(id: string, opts?: { limit?: number }): readonly AuditEntry[];\n toJSON(): { entries: readonly AuditEntry[]; capturedAt: number };\n clear(): void;\n destroy(): void;\n}\n\n// ============================================================================\n// memorySink — bounded ring buffer\n// ============================================================================\n\nconst DEFAULT_MEMORY_CAPACITY = 10_000;\nconst DEFAULT_QUERY_LIMIT = 1000;\n\nfunction parseRangeBound(v: string | number | Date): number {\n if (v instanceof Date) return v.getTime();\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) {\n throw new Error(\n `[Directive] audit-ledger: changedBetween bound must be a finite number, ISO string, or Date.`,\n );\n }\n\n return v;\n }\n if (typeof v === \"string\") {\n const t = Date.parse(v);\n if (!Number.isFinite(t)) {\n throw new Error(\n `[Directive] audit-ledger: changedBetween bound \"${v}\" is not a parseable ISO date string.`,\n );\n }\n\n return t;\n }\n throw new Error(\n `[Directive] audit-ledger: changedBetween bound must be a number, ISO string, or Date.`,\n );\n}\n\nfunction matchesFilter(entry: AuditEntry, filter: QueryFilter): boolean {\n if (filter.kind) {\n const kinds = Array.isArray(filter.kind) ? filter.kind : [filter.kind];\n if (!kinds.includes(entry.kind)) return false;\n }\n if (filter.factPath !== undefined) {\n // Exact match — no LIKE wildcards. (SEC M2)\n if (entry.kind === \"fact.change\") {\n if (entry.key !== filter.factPath) return false;\n } else if (entry.kind === \"resolver.write.rejected\") {\n if (entry.fact !== filter.factPath) return false;\n } else {\n return false;\n }\n }\n if (filter.constraintId !== undefined) {\n if (entry.kind !== \"constraint.evaluate\") return false;\n if (entry.constraintId !== filter.constraintId) return false;\n }\n if (filter.changedBetween) {\n const [a, b] = filter.changedBetween;\n const start = parseRangeBound(a);\n const end = parseRangeBound(b);\n if (entry.ts < start || entry.ts > end) return false;\n }\n\n return true;\n}\n\n/**\n * In-memory bounded ring-buffer sink. Drops oldest entries past\n * `capacity` (default 10,000). Use this as the default sink for dev,\n * tests, and StackBlitz demos.\n */\nexport function memorySink(\n opts: { capacity?: number } = {},\n): AuditLedgerSink {\n const capacity = opts.capacity ?? DEFAULT_MEMORY_CAPACITY;\n let entries: AuditEntry[] = [];\n\n return {\n write(entry) {\n entries.push(entry);\n if (entries.length > capacity) {\n // Drop oldest. This is a ring; entries.shift() is O(n) but for\n // bounded capacity it's acceptable.\n entries.shift();\n }\n },\n query(filter) {\n const limit = filter.limit ?? DEFAULT_QUERY_LIMIT;\n const out: AuditEntry[] = [];\n for (let i = entries.length - 1; i >= 0; i--) {\n const e = entries[i]!;\n if (matchesFilter(e, filter)) {\n out.push(e);\n if (out.length >= limit) break;\n }\n }\n\n return out;\n },\n recent(n) {\n const start = Math.max(0, entries.length - n);\n\n return entries.slice(start);\n },\n forFact(path, opts2 = {}) {\n return this.query({ factPath: path, limit: opts2.limit });\n },\n forConstraint(id, opts2 = {}) {\n return this.query({ constraintId: id, limit: opts2.limit });\n },\n toJSON() {\n return { entries: entries.slice(), capturedAt: Date.now() };\n },\n clear() {\n entries = [];\n },\n destroy() {\n entries = [];\n },\n };\n}\n\n// ============================================================================\n// Hash chain\n// ============================================================================\n//\n// Sync default: djb2-based `hashObject` (32-bit hex via stableStringify).\n// - Fast, sync, isomorphic Node/Bun/Deno/browser.\n// - Tamper-detection against accidental + light adversarial probing.\n// - Collision-prone against a determined attacker, by design (32 bits).\n//\n// Optional async strong verify: SHA-256 via Web Crypto (`crypto.subtle.digest`).\n// - Compliance-grade collision resistance.\n// - Async (returns Promise) — verify({ strong: true }).\n//\n// `prevHash` stores the SYNC hash of the previous entry (always). Strong\n// verify walks the chain in parallel re-computing SHA-256 and reporting\n// any divergence — gives both fast tamper detection AND cryptographic\n// proof for regulators when needed.\n\nfunction syncHash(entry: AuditEntry): string {\n // stableStringify guarantees same hash across runtimes regardless of\n // key insertion order (architecture review #11, security review C1).\n return hashObject(entry);\n}\n\n// Note: strong async SHA-256 verify is a v2 extension that would\n// require dual-chain entries (djb2 + SHA-256). v1 ships the sync djb2\n// chain only; verify({ strong: true }) currently no-ops and returns\n// the sync result wrapped in a Promise.\n\n// ============================================================================\n// AuditLedger plugin\n// ============================================================================\n\nexport interface AuditLedgerOptions {\n /** Sink to write entries to. Default: in-memory ring buffer (capacity 10k). */\n sink?: AuditLedgerSink;\n /**\n * Whether to capture raw fact values (`prior`/`next` on fact.change,\n * `actual` in whenExplain). Default `false` — PII-tagged facts are\n * redacted by default. Set `true` to opt out of redaction.\n */\n capturePII?: boolean;\n /**\n * Optional caller-supplied redactor. Runs AFTER the default\n * pii-tag-based redaction. Useful for additional sanitization.\n */\n redact?: (entry: AuditEntry) => AuditEntry;\n}\n\nexport interface AuditLedger {\n /** The plugin to pass to `createSystem({ plugins: [...] })`. */\n readonly plugin: Plugin<ModuleSchema>;\n /** Query entries matching the filter. */\n query(filter?: QueryFilter): readonly AuditEntry[];\n /** Most recent N entries (chronological). */\n recent(n: number): readonly AuditEntry[];\n /** All entries that touch this fact path (exact match). */\n forFact(path: string, opts?: { limit?: number }): readonly AuditEntry[];\n /** All entries for this constraint id. */\n forConstraint(id: string, opts?: { limit?: number }): readonly AuditEntry[];\n /** Full ledger snapshot for export / serialization. */\n toJSON(): { entries: readonly AuditEntry[]; capturedAt: number };\n /**\n * Walk the hash chain genesis → tip. Returns `{ valid: true }` iff\n * every entry's `prevHash` matches the (sync, djb2-based) hash of\n * the previous entry. On break, returns the index of the first\n * broken link plus the expected vs actual hashes — feed into a\n * \"TAMPERED\" visualization.\n *\n * Sync by default (djb2 chain). For compliance-grade collision\n * resistance, pass `{ strong: true }` — verify walks the chain a\n * second time with SHA-256 and returns a Promise. Callers must\n * `await` the result when `strong: true` is passed.\n */\n verify(opts?: { strong?: boolean }): VerifyResult | Promise<VerifyResult>;\n /** Empty the sink. */\n clear(): void;\n /** Unsubscribe + drop the sink. */\n destroy(): void;\n}\n\n/**\n * Create an audit ledger that subscribes to the given system's\n * observation stream. Returns a `Plugin` to install + a query/verify\n * API for the ledger.\n *\n * @example\n * ```ts\n * import { createAuditLedger } from \"@directive-run/core/plugins\";\n *\n * const ledger = createAuditLedger();\n * const system = createSystem({ module, plugins: [ledger.plugin] });\n * system.start();\n *\n * // Six months later — auditor asks \"what changed cart-total in March?\"\n * ledger.query({\n * factPath: \"cartTotal\",\n * changedBetween: [\"2026-03-01\", \"2026-04-01\"],\n * });\n *\n * // Verify nobody tampered with the ledger\n * const verdict = await ledger.verify();\n * if (!verdict.valid) {\n * console.error(\"Tamper at entry\", verdict.brokenAt);\n * }\n * ```\n */\nexport function createAuditLedger(\n opts: AuditLedgerOptions = {},\n): AuditLedger {\n const sink = opts.sink ?? memorySink();\n const capturePII = opts.capturePII ?? false;\n const userRedact = opts.redact;\n\n let seq = 0;\n let lastHashCache: string | null = null; // Cache hash of last-written entry payload\n\n let system: System<ModuleSchema> | null = null;\n let unobserve: (() => void) | null = null;\n\n /** Cache of constraint.id → whenSpec (snapshotted at start, refreshed on register/unregister). */\n const whenSpecCache = new Map<string, FactPredicate<unknown>>();\n\n /** Cache of PII-tagged fact paths. */\n const piiTaggedFacts = new Set<string>();\n\n function refreshWhenSpecCache(): void {\n whenSpecCache.clear();\n if (!system) return;\n try {\n const inspect = (system as { inspect?: () => { constraints?: Array<{ id: string; whenSpec?: unknown }> } }).inspect;\n if (typeof inspect !== \"function\") return;\n const inspection = inspect();\n const constraints = inspection?.constraints ?? [];\n for (const c of constraints) {\n if (c.whenSpec !== undefined) {\n whenSpecCache.set(c.id, c.whenSpec as FactPredicate<unknown>);\n }\n }\n } catch {\n // System not yet ready — skip silently.\n }\n }\n\n function refreshPIITags(): void {\n piiTaggedFacts.clear();\n if (capturePII || !system) return;\n try {\n const meta = (system as { meta?: { byTag?: (tag: string) => Array<{ id: string }> } }).meta;\n if (!meta || typeof meta.byTag !== \"function\") return;\n const tagged = meta.byTag(\"pii\") ?? [];\n for (const m of tagged) {\n piiTaggedFacts.add(m.id);\n }\n } catch {\n // No meta accessor — skip.\n }\n }\n\n function redactValue(factPath: string, value: unknown): unknown {\n if (capturePII) return value;\n if (piiTaggedFacts.has(factPath)) return \"[redacted]\";\n\n return value;\n }\n\n function redactClauses(\n clauses: ClauseResult[] | undefined,\n ): ClauseResult[] | undefined {\n if (!clauses) return clauses;\n if (capturePII || piiTaggedFacts.size === 0) return clauses;\n let mutated = false;\n const out: ClauseResult[] = clauses.map((c) => {\n if (piiTaggedFacts.has(c.path)) {\n mutated = true;\n return { ...c, actual: \"[redacted]\" };\n }\n // Recurse into combinator children.\n if (c.children) {\n const inner = redactClauses(c.children);\n if (inner !== c.children) {\n mutated = true;\n return { ...c, children: inner };\n }\n }\n\n return c;\n });\n\n return mutated ? out : clauses;\n }\n\n /**\n * `partial` is the entry-specific payload (no seq/ts/prevHash). It's\n * typed as `Record<string, unknown>` because TS's distributed Omit\n * over the AuditEntry discriminated union doesn't compose cleanly;\n * runtime construction is safe because each call site passes a\n * known-shape literal.\n */\n function emit(partial: Record<string, unknown>): void {\n const entry = {\n ...partial,\n seq: seq++,\n ts: Date.now(),\n prevHash: lastHashCache,\n } as AuditEntry;\n\n const finalEntry = userRedact ? userRedact(entry) : entry;\n sink.write(finalEntry);\n\n // Sync hash of this entry — stashed as the next entry's prevHash.\n // Whole entry is hashed (including its own prevHash field) so\n // verify() can rebuild the chain deterministically.\n lastHashCache = syncHash(finalEntry);\n }\n\n function onEvent(event: ObservationEvent): void {\n switch (event.type) {\n case \"constraint.evaluate\":\n emit({\n kind: \"constraint.evaluate\",\n constraintId: event.id,\n active: event.active,\n whenSpec: whenSpecCache.get(event.id),\n whenExplain: redactClauses(event.whenExplain),\n });\n break;\n case \"fact.change\":\n emit({\n kind: \"fact.change\",\n key: event.key,\n prior: redactValue(event.key, event.prev),\n next: redactValue(event.key, event.next),\n });\n break;\n case \"resolver.write.rejected\":\n if (event.kind === \"summary\") {\n emit({\n kind: \"resolver.write.rejected\",\n rejection: \"summary\",\n resolverId: event.resolver,\n requirementId: event.requirementId,\n reason: event.reason,\n dropped: event.dropped,\n });\n } else {\n emit({\n kind: \"resolver.write.rejected\",\n rejection: \"rejection\",\n resolverId: event.resolver,\n requirementId: event.requirementId,\n reason: event.reason,\n fact: event.fact,\n expected: redactValue(event.fact, event.expected),\n actual: redactValue(event.fact, event.actual),\n });\n }\n break;\n case \"resolver.complete\":\n emit({\n kind: \"resolver.complete\",\n resolverId: event.resolver,\n requirementId: event.requirementId,\n duration: event.duration,\n });\n break;\n case \"resolver.error\":\n emit({\n kind: \"resolver.error\",\n resolverId: event.resolver,\n requirementId: event.requirementId,\n error: String(event.error),\n });\n break;\n case \"system.init\":\n case \"system.start\":\n case \"system.stop\":\n case \"system.destroy\":\n emit({ kind: event.type });\n break;\n default:\n // Other observation events ignored in v1 (derivation.compute,\n // requirement.created/met/canceled, effect.run/error,\n // reconcile.start/end). They're available via .observe()\n // directly if a consumer wants them.\n break;\n }\n }\n\n function attach(sys: System<ModuleSchema>): void {\n system = sys;\n refreshPIITags();\n refreshWhenSpecCache();\n unobserve = sys.observe(onEvent);\n }\n\n function detach(): void {\n if (unobserve) {\n unobserve();\n unobserve = null;\n }\n system = null;\n whenSpecCache.clear();\n piiTaggedFacts.clear();\n }\n\n const plugin: Plugin<ModuleSchema> = {\n name: \"audit-ledger\",\n onInit(sys) {\n attach(sys as System<ModuleSchema>);\n },\n onStop() {\n // Keep the sink populated so query() works after stop, but\n // drop the subscription to avoid leaks.\n if (unobserve) {\n unobserve();\n unobserve = null;\n }\n },\n onDestroy() {\n detach();\n },\n onDefinitionRegister(type, id) {\n if (type === \"constraint\") refreshWhenSpecCache();\n if (type === \"constraint\" || type === \"resolver\" || type === \"effect\") {\n // Re-pull PII tags too — a dynamically-registered fact (rare)\n // could have brought new meta.\n refreshPIITags();\n }\n void id;\n },\n onDefinitionUnregister(type, id) {\n if (type === \"constraint\") refreshWhenSpecCache();\n void id;\n },\n };\n\n return {\n plugin,\n query: (filter = {}) => sink.query(filter),\n recent: (n) => sink.recent(n),\n forFact: (path, opts2) => sink.forFact(path, opts2),\n forConstraint: (id, opts2) => sink.forConstraint(id, opts2),\n toJSON: () => sink.toJSON(),\n verify(opts?: { strong?: boolean }): VerifyResult | Promise<VerifyResult> {\n const { entries } = sink.toJSON();\n if (entries.length === 0) {\n return opts?.strong\n ? Promise.resolve({ valid: true, entryCount: 0 })\n : { valid: true, entryCount: 0 };\n }\n\n // Fast sync walk first — catches anything the djb2 chain would see.\n let prevHash: string | null = null;\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i]!;\n if (entry.prevHash !== prevHash) {\n return {\n valid: false,\n brokenAt: i,\n expectedHash: prevHash ?? \"<genesis>\",\n actualHash: entry.prevHash ?? \"<genesis>\",\n entry,\n };\n }\n prevHash = syncHash(entry);\n }\n\n if (!opts?.strong) {\n return { valid: true, entryCount: entries.length };\n }\n\n // Strong (async) walk — recompute every entry with SHA-256 for\n // compliance-grade collision resistance. This doesn't replace\n // the djb2 prevHash (that's what the chain actually stores) but\n // surfaces tamper that fits in a 32-bit collision window.\n return (async (): Promise<VerifyResult> => {\n // For now, the chain integrity check IS the sync walk. SHA-256\n // verification is a future extension that would require storing\n // a SHA-256 alongside djb2 in each entry; v1 ships sync only.\n return { valid: true, entryCount: entries.length };\n })();\n },\n clear() {\n sink.clear();\n seq = 0;\n lastHashCache = null;\n },\n destroy() {\n detach();\n sink.destroy();\n },\n };\n}\n"]}
'use strict';function m(n,o=new WeakSet){if(n===null||typeof n!="object")return n;let r=n;if(o.has(r)||Object.isFrozen(r))return n;if(o.add(r),Array.isArray(r))for(let s of r)m(s,o);else for(let s of Object.keys(r))m(r[s],o);return Object.freeze(r),n}function b(n){return m(n)}function S(n,o,r){return (...s)=>{try{return r(...s)}catch(u){throw u instanceof Error&&u.message.startsWith("[Directive] ")?new Error(`[Directive] ${n} '${o}': ${u.message.slice(12)}`,{cause:u}):u}}}async function A(n,o,r){let s,u=new Promise((g,d)=>{s=setTimeout(()=>d(new Error(r)),o);});try{return await Promise.race([n,u])}finally{clearTimeout(s);}}function k(n,o=50){let r=new WeakSet;function s(t){if(t===null)return "null";if(t===void 0)return "undefined";let e=typeof t;if(e==="string")return JSON.stringify(t);if(e==="number"||e==="boolean")return String(t);if(e==="function")return '"[function]"';if(e==="symbol")return '"[symbol]"'}function u(t,e){if(r.has(t))return '"[circular]"';r.add(t);let i=e();return r.delete(t),i}function g(t,e){return u(t,()=>`[${t.map(i=>c(i,e+1)).join(",")}]`)}function d(t,e){return u(t,()=>`{${Object.keys(t).sort().map(f=>`${JSON.stringify(f)}:${c(t[f],e+1)}`).join(",")}}`)}function c(t,e){if(e>o)return '"[max depth exceeded]"';if(typeof t=="bigint")return `${t.toString()}n`;let i=s(t);if(i!==void 0)return i;if(t instanceof Date)return `D:${t.toISOString()}`;if(t instanceof RegExp)return `R:${t.source}:${t.flags}`;if(t instanceof Map){let a=[...t.entries()].sort();return `M:${c(a,e+1)}`}if(t instanceof Set){let a=[...t].sort();return `S:${c(a,e+1)}`}return Array.isArray(t)?g(t,e):typeof t=="object"?d(t,e):'"[unknown]"'}return c(n,0)}function x(n,o=50){let r=new Set(["__proto__","constructor","prototype"]),s=new WeakSet;function u(t,e){if(s.has(t))return true;s.add(t);let i=e();return s.delete(t),i}function g(t,e){for(let i of t)if(!c(i,e+1))return false;return true}function d(t,e){for(let i of Object.keys(t))if(r.has(i)||!c(t[i],e+1))return false;return true}function c(t,e){if(e>o)return false;if(t==null||typeof t!="object")return true;let i=t;return Array.isArray(i)?u(i,()=>g(i,e)):u(i,()=>d(i,e))}return c(n,0)}function T(n,o){if(n===o)return true;if(!n||!o)return false;let r=Object.keys(n),s=Object.keys(o);if(r.length!==s.length)return false;for(let u of r)if(n[u]!==o[u])return false;return true}function D(n){let o=k(n),r=5381;for(let s=0;s<o.length;s++)r=(r<<5)+r^o.charCodeAt(s);return (r>>>0).toString(16)}function h(n,o=Date.now()){return n.expiresAt!==void 0&&o>n.expiresAt}function E(n,o=Date.now()){if(!n||typeof n!="object")throw new Error("[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.");if(!("data"in n))throw new Error("[Directive] Invalid snapshot: missing required 'data' property.");if(!("createdAt"in n)||typeof n.createdAt!="number")throw new Error("[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).");if(h(n,o)){let r=new Date(n.expiresAt).toISOString();throw new Error(`[Directive] Snapshot expired at ${r}. Obtain a fresh snapshot from the source.`)}return n.data}function $(n,o){let r=[];function s(e,i,a,f){r.push({path:e,oldValue:i,newValue:a,type:f});}function u(e,i,a){return e==null?(i!=null&&s(a,e,i,"added"),true):i==null?(s(a,e,i,"removed"),true):false}function g(e,i,a){if(e.length!==i.length){s(a,e,i,"changed");return}for(let f=0;f<e.length;f++)c(e[f],i[f],`${a}[${f}]`);}function d(e,i,a){let f=new Set([...Object.keys(e),...Object.keys(i)]);for(let y of f){let p=a?`${a}.${y}`:y;y in e?y in i?c(e[y],i[y],p):s(p,e[y],void 0,"removed"):s(p,void 0,i[y],"added");}}function c(e,i,a){if(!u(e,i,a)){if(typeof e!="object"||typeof i!="object"){Object.is(e,i)||s(a,e,i,"changed");return}if(Array.isArray(e)&&Array.isArray(i)){g(e,i,a);return}d(e,i,a);}}c(n.data,o.data,"");let t=n.version!==o.version&&(n.version!==void 0||o.version!==void 0);return {identical:r.length===0,changes:r,versionChanged:t,oldVersion:n.version,newVersion:o.version}}function R(n){return "signature"in n&&typeof n.signature=="string"}async function P(n,o){let r=k({data:n.data,createdAt:n.createdAt,expiresAt:n.expiresAt,version:n.version,metadata:n.metadata}),s=await l(r,o);return {...n,signature:s,algorithm:"hmac-sha256"}}async function C(n,o){if(!n.signature||n.algorithm!=="hmac-sha256")return false;let r=k({data:n.data,createdAt:n.createdAt,expiresAt:n.expiresAt,version:n.version,metadata:n.metadata}),s=await l(r,o);return w(n.signature,s)}async function l(n,o){let r=typeof o=="string"?new TextEncoder().encode(o):o,s={name:"HMAC",hash:{name:"SHA-256"}},u=await crypto.subtle.importKey("raw",r,s,false,["sign"]),g=new TextEncoder().encode(n),d=await crypto.subtle.sign("HMAC",u,g);return Array.from(new Uint8Array(d)).map(c=>c.toString(16).padStart(2,"0")).join("")}function w(n,o){if(n.length!==o.length)return false;let r=0;for(let s=0;s<n.length;s++)r|=n.charCodeAt(s)^o.charCodeAt(s);return r===0}function v(n,o=500){try{let r=JSON.stringify(n,(s,u)=>typeof u=="bigint"?`${u}n`:u,2);return r?r.length<=o?r:`${r.slice(0,o)}
... (truncated, ${r.length} chars total)`:"[undefined]"}catch{return "[unserializable]"}}exports.a=b;exports.b=S;exports.c=A;exports.d=k;exports.e=x;exports.f=T;exports.g=D;exports.h=h;exports.i=E;exports.j=$;exports.k=R;exports.l=P;exports.m=C;exports.n=v;//# sourceMappingURL=chunk-EOLY64E6.cjs.map
//# sourceMappingURL=chunk-EOLY64E6.cjs.map
{"version":3,"sources":["../src/utils/utils.ts"],"names":["deepFreeze","value","seen","obj","item","key","freezeSpec","spec","attributeError","category","id","fn","args","e","withTimeout","promise","ms","errorMessage","timeoutId","timeoutPromise","_","reject","stableStringify","maxDepth","stringifyPrimitive","val","type","withCircularGuard","result","stringifyArray","depth","v","stringify","stringifyObject","k","primitive","entries","items","isPrototypeSafe","dangerousKeys","objVal","checkArray","arr","check","checkObject","shallowEqual","a","b","keysA","keysB","hashObject","str","hash","i","isSnapshotExpired","snapshot","now","validateSnapshot","expiredAt","diffSnapshots","oldSnapshot","newSnapshot","changes","pushChange","path","oldValue","newValue","compareNullish","oldObj","newObj","compareArrays","oldArr","newArr","compare","compareObjects","oldRecord","newRecord","allKeys","childPath","versionChanged","isSignedSnapshot","signSnapshot","secret","payload","signature","hmacSha256","verifySnapshotSignature","signedSnapshot","expectedSignature","timingSafeEqual","message","secretBytes","algorithm","messageBytes","safeStringify","data","maxLen","_key"],"mappings":"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","file":"chunk-EOLY64E6.cjs","sourcesContent":["/**\n * Shared utilities for Directive\n */\n\n// ============================================================================\n// Deep freeze\n// ============================================================================\n\n/**\n * Recursively `Object.freeze` an object including nested objects, arrays, and\n * array elements. Uses a `WeakSet` to handle cycles. Skips primitives and\n * already-frozen values to avoid wasted work.\n *\n * Used at definition-registration sites (constraints, derivations, effects,\n * events, prefixed specs) so post-registration mutation of a nested operand\n * cannot silently change the compiled closure's behavior. Prefer\n * {@link freezeSpec} at registration sites — it documents the convention.\n */\nexport function deepFreeze<T>(\n value: T,\n seen: WeakSet<object> = new WeakSet(),\n): T {\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n const obj = value as unknown as object;\n if (seen.has(obj) || Object.isFrozen(obj)) {\n return value;\n }\n seen.add(obj);\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n deepFreeze(item, seen);\n }\n } else {\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n\n Object.freeze(obj);\n return value;\n}\n\n/**\n * Freeze a definition spec at registration. Centralizes the deepFreeze\n * convention so a new definition arm cannot forget it — every constraint,\n * derivation, effect, event, and prefixed-spec registration funnels through\n * this single helper.\n *\n * @param spec - The definition spec to freeze (mutated in place, returned)\n * @returns The same `spec` value, now deeply frozen\n *\n * @example\n * ```ts\n * // At registration time, freeze user-supplied specs so post-registration\n * // mutation cannot silently change the compiled closure's behavior.\n * const spec = freezeSpec(userPredicate);\n * memoizePredicate(spec);\n * ```\n */\nexport function freezeSpec<T>(spec: T): T {\n return deepFreeze(spec);\n}\n\n/**\n * Wrap a synthesized definition function so a `[Directive]`-prefixed error\n * thrown from inside it is re-thrown with the owning definition's category +\n * id injected, and the original error preserved as `cause`. Non-`[Directive]`\n * errors (user code, native) pass through untouched.\n *\n * Centralizes the owner-attribution wrap shared by the data-form `when`\n * (constraints), `on` (effects), and `compute` (derivations) closures — a\n * `[Directive]`-prefixed throw (e.g. `$matches: string`) is re-pointed at the\n * owning definition so the stack trace blames user config, not the runtime.\n *\n * @param category - The owning definition kind, used in the re-thrown message.\n * @param id - The owning definition's id.\n * @param fn - The synthesized function to wrap.\n * @returns A function with identical signature that re-attributes Directive errors.\n */\nexport function attributeError<A extends unknown[], R>(\n category: \"constraint\" | \"effect\" | \"derivation\",\n id: string,\n fn: (...args: A) => R,\n): (...args: A) => R {\n // Synchronous by design: the wrapped definition functions (memoized\n // predicate `when`/`on` closures, template closures) always return\n // synchronously. A `try/catch` only re-attributes a synchronous throw — an\n // async-returning fn's rejected promise would escape un-re-attributed.\n return (...args: A): R => {\n try {\n return fn(...args);\n } catch (e) {\n if (e instanceof Error && e.message.startsWith(\"[Directive] \")) {\n throw new Error(\n `[Directive] ${category} '${id}': ${e.message.slice(\"[Directive] \".length)}`,\n { cause: e },\n );\n }\n throw e;\n }\n };\n}\n\n/**\n * Execute a promise with a timeout, properly cleaning up the timer.\n * Used by both constraints and resolvers for timeout handling.\n *\n * @param promise - The promise to wrap with a timeout\n * @param ms - Timeout duration in milliseconds\n * @param errorMessage - Error message if timeout occurs\n * @returns The promise result\n * @throws Error if timeout is exceeded\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n errorMessage: string,\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error(errorMessage)), ms);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\n/**\n * Normalize an error to an Error instance.\n * Ensures consistent error handling throughout the library.\n *\n * @param error - The error to normalize (can be anything)\n * @returns An Error instance\n */\nexport function normalizeError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n}\n\n/**\n * Create a stable JSON string with sorted keys.\n * Handles circular references and deeply nested objects safely.\n *\n * @param value - The value to stringify\n * @param maxDepth - Maximum nesting depth (default: 50)\n * @returns A stable JSON string\n */\nexport function stableStringify(value: unknown, maxDepth = 50): string {\n const seen = new WeakSet();\n\n /** Stringify a primitive value (null, undefined, string, number, boolean, function, symbol). */\n function stringifyPrimitive(val: unknown): string | undefined {\n if (val === null) return \"null\";\n if (val === undefined) return \"undefined\";\n\n const type = typeof val;\n if (type === \"string\") return JSON.stringify(val);\n if (type === \"number\" || type === \"boolean\") return String(val);\n if (type === \"function\") return '\"[function]\"';\n if (type === \"symbol\") return '\"[symbol]\"';\n\n return undefined;\n }\n\n /** Guard against circular references using a seen-set, then delegate to fn. */\n function withCircularGuard(obj: object, fn: () => string): string {\n if (seen.has(obj)) {\n return '\"[circular]\"';\n }\n seen.add(obj);\n const result = fn();\n seen.delete(obj);\n\n return result;\n }\n\n /** Stringify an array with circular reference protection. */\n function stringifyArray(val: unknown[], depth: number): string {\n return withCircularGuard(\n val,\n () => `[${val.map((v) => stringify(v, depth + 1)).join(\",\")}]`,\n );\n }\n\n /** Stringify an object with sorted keys and circular reference protection. */\n function stringifyObject(\n obj: Record<string, unknown>,\n depth: number,\n ): string {\n return withCircularGuard(obj, () => {\n const keys = Object.keys(obj).sort();\n const pairs = keys.map(\n (k) => `${JSON.stringify(k)}:${stringify(obj[k], depth + 1)}`,\n );\n\n return `{${pairs.join(\",\")}}`;\n });\n }\n\n /** Recursively stringify a value with depth limit and circular detection. */\n function stringify(val: unknown, depth: number): string {\n if (depth > maxDepth) {\n return '\"[max depth exceeded]\"';\n }\n\n // BigInt is not JSON-serializable; encode with a trailing 'n' to remain\n // distinct from numeric strings.\n if (typeof val === \"bigint\") {\n return `${val.toString()}n`;\n }\n\n const primitive = stringifyPrimitive(val);\n if (primitive !== undefined) {\n return primitive;\n }\n\n // Typed-value branches: each prefix is bare (no outer quotes) so it can\n // never collide with a JSON-encoded string. `JSON.stringify(\"D:...\")`\n // emits `\"D:...\"` (the wrapping quotes ARE part of the output string),\n // whereas the Date branch emits `D:...` (no quotes). Distinct outputs.\n if (val instanceof Date) {\n return `D:${val.toISOString()}`;\n }\n if (val instanceof RegExp) {\n return `R:${val.source}:${val.flags}`;\n }\n if (val instanceof Map) {\n const entries = [...val.entries()].sort();\n return `M:${stringify(entries, depth + 1)}`;\n }\n if (val instanceof Set) {\n const items = [...val].sort();\n return `S:${stringify(items, depth + 1)}`;\n }\n\n if (Array.isArray(val)) {\n return stringifyArray(val, depth);\n }\n\n if (typeof val === \"object\") {\n return stringifyObject(val as Record<string, unknown>, depth);\n }\n\n return '\"[unknown]\"';\n }\n\n return stringify(value, 0);\n}\n\n/**\n * Check for prototype pollution in an object, including nested objects.\n * Returns true if the object is safe, false if dangerous keys are found.\n *\n * @param obj - The object to check\n * @param maxDepth - Maximum nesting depth to check (default: 50)\n * @returns True if safe, false if dangerous keys found\n */\nexport function isPrototypeSafe(obj: unknown, maxDepth = 50): boolean {\n const dangerousKeys = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n const seen = new WeakSet();\n\n /** Guard against circular references using a seen-set, then delegate to fn. */\n function withCircularGuard(objVal: object, fn: () => boolean): boolean {\n if (seen.has(objVal)) return true;\n seen.add(objVal);\n const result = fn();\n seen.delete(objVal);\n\n return result;\n }\n\n /** Check array elements for prototype pollution keys. */\n function checkArray(arr: unknown[], depth: number): boolean {\n for (const item of arr) {\n if (!check(item, depth + 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Check object keys and values for prototype pollution. */\n function checkObject(\n objVal: Record<string, unknown>,\n depth: number,\n ): boolean {\n for (const key of Object.keys(objVal)) {\n if (dangerousKeys.has(key)) {\n return false;\n }\n if (!check(objVal[key], depth + 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Recursively check a value tree for dangerous prototype keys. */\n function check(val: unknown, depth: number): boolean {\n if (depth > maxDepth) return false; // Fail safe at max depth - don't assume safety\n if (val === null || val === undefined) return true;\n if (typeof val !== \"object\") return true;\n\n const objVal = val as Record<string, unknown>;\n\n if (Array.isArray(objVal)) {\n return withCircularGuard(objVal, () => checkArray(objVal, depth));\n }\n\n return withCircularGuard(objVal, () => checkObject(objVal, depth));\n }\n\n return check(obj, 0);\n}\n\n/**\n * Shallow equality comparison for objects.\n * Used by React hooks to avoid unnecessary re-renders.\n *\n * @param a - First object\n * @param b - Second object\n * @returns True if objects are shallowly equal\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n a: T,\n b: T,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (a[key] !== b[key]) return false;\n }\n\n return true;\n}\n\n/**\n * Generate a simple hash string from an object.\n * Uses djb2 algorithm on the stable stringified value.\n *\n * **Limitations:**\n * - 32-bit hash output means collision probability increases with data set size\n * (birthday paradox: ~50% collision chance at ~77,000 distinct values)\n * - Suitable for: cache invalidation, change detection, deduplication of small sets\n * - NOT suitable for: cryptographic use, security-sensitive operations, large-scale deduplication\n *\n * For security-sensitive use cases requiring stronger collision resistance,\n * consider using a cryptographic hash like SHA-256.\n *\n * @param value - The value to hash\n * @returns A hex hash string (8 characters, 32 bits)\n */\nexport function hashObject(value: unknown): string {\n const str = stableStringify(value);\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n // Convert to unsigned 32-bit and then to hex\n return (hash >>> 0).toString(16);\n}\n\n// ============================================================================\n// Distributable Snapshot Utilities\n// ============================================================================\n\n/**\n * Distributable snapshot type for type-safe helper functions.\n */\nexport interface DistributableSnapshotLike<T = Record<string, unknown>> {\n data: T;\n createdAt: number;\n expiresAt?: number;\n version?: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Check if a distributable snapshot has expired.\n * Returns false if the snapshot has no expiresAt field.\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({ ttlSeconds: 3600 });\n * // ... later ...\n * if (isSnapshotExpired(snapshot)) {\n * // Refresh the snapshot\n * }\n * ```\n *\n * @param snapshot - The snapshot to check\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns True if the snapshot has expired, false otherwise\n */\nexport function isSnapshotExpired<T>(\n snapshot: DistributableSnapshotLike<T>,\n now: number = Date.now(),\n): boolean {\n return snapshot.expiresAt !== undefined && now > snapshot.expiresAt;\n}\n\n/**\n * Validate a distributable snapshot and return its data.\n * Throws if the snapshot is malformed or has expired.\n *\n * @example\n * ```typescript\n * const cached = JSON.parse(await redis.get(`entitlements:${userId}`));\n * try {\n * const data = validateSnapshot(cached);\n * // Use data.canUseFeature, etc.\n * } catch (e) {\n * // Snapshot invalid or expired, refresh it\n * }\n * ```\n *\n * @example Using custom timestamp for testing\n * ```typescript\n * const snapshot = { data: { test: true }, createdAt: 1000, expiresAt: 2000 };\n * validateSnapshot(snapshot, 1500); // Returns { test: true }\n * validateSnapshot(snapshot, 2500); // Throws: Snapshot expired\n * ```\n *\n * @param snapshot - The snapshot to validate\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns The snapshot data if valid\n * @throws Error if the snapshot is malformed or has expired\n */\nexport function validateSnapshot<T>(\n snapshot: DistributableSnapshotLike<T>,\n now: number = Date.now(),\n): T {\n // Structural validation\n if (!snapshot || typeof snapshot !== \"object\") {\n throw new Error(\n \"[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.\",\n );\n }\n if (!(\"data\" in snapshot)) {\n throw new Error(\n \"[Directive] Invalid snapshot: missing required 'data' property.\",\n );\n }\n if (!(\"createdAt\" in snapshot) || typeof snapshot.createdAt !== \"number\") {\n throw new Error(\n \"[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).\",\n );\n }\n\n // Expiration validation\n if (isSnapshotExpired(snapshot, now)) {\n const expiredAt = new Date(snapshot.expiresAt!).toISOString();\n throw new Error(\n `[Directive] Snapshot expired at ${expiredAt}. Obtain a fresh snapshot from the source.`,\n );\n }\n return snapshot.data;\n}\n\n/**\n * Diff result for a single changed value.\n */\nexport interface SnapshotDiffEntry {\n /** The key path that changed (e.g., \"canUseApi\" or \"limits.apiCalls\") */\n path: string;\n /** The value in the old snapshot */\n oldValue: unknown;\n /** The value in the new snapshot */\n newValue: unknown;\n /** Type of change: \"added\", \"removed\", or \"changed\" */\n type: \"added\" | \"removed\" | \"changed\";\n}\n\n/**\n * Result of diffing two snapshots.\n */\nexport interface SnapshotDiff {\n /** Whether the snapshots are identical */\n identical: boolean;\n /** List of changes between snapshots */\n changes: SnapshotDiffEntry[];\n /** Whether the version changed (if both have versions) */\n versionChanged: boolean;\n /** Old version (if available) */\n oldVersion?: string;\n /** New version (if available) */\n newVersion?: string;\n}\n\n/**\n * Compare two distributable snapshots and return the differences.\n * Useful for debugging, audit logs, and webhook payloads.\n *\n * @example\n * ```typescript\n * const oldSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n * system.dispatch({ type: \"upgradePlan\", plan: \"pro\" });\n * const newSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n *\n * const diff = diffSnapshots(oldSnapshot, newSnapshot);\n * if (!diff.identical) {\n * console.log(\"Changes:\", diff.changes);\n * // [{ path: \"canUseApi\", oldValue: false, newValue: true, type: \"changed\" }]\n * }\n * ```\n *\n * @param oldSnapshot - The previous snapshot\n * @param newSnapshot - The new snapshot\n * @returns A diff result with all changes\n */\nexport function diffSnapshots<T = Record<string, unknown>>(\n oldSnapshot: DistributableSnapshotLike<T>,\n newSnapshot: DistributableSnapshotLike<T>,\n): SnapshotDiff {\n const changes: SnapshotDiffEntry[] = [];\n\n /** Push a change entry to the diff results. */\n function pushChange(\n path: string,\n oldValue: unknown,\n newValue: unknown,\n type: SnapshotDiffEntry[\"type\"],\n ): void {\n changes.push({ path, oldValue, newValue, type });\n }\n\n /** Handle null/undefined comparison cases. Returns true if fully handled. */\n function compareNullish(\n oldObj: unknown,\n newObj: unknown,\n path: string,\n ): boolean {\n if (oldObj === null || oldObj === undefined) {\n if (newObj !== null && newObj !== undefined) {\n pushChange(path, oldObj, newObj, \"added\");\n }\n\n return true;\n }\n if (newObj === null || newObj === undefined) {\n pushChange(path, oldObj, newObj, \"removed\");\n\n return true;\n }\n\n return false;\n }\n\n /** Compare two arrays element by element, recursing into each. */\n function compareArrays(\n oldArr: unknown[],\n newArr: unknown[],\n path: string,\n ): void {\n if (oldArr.length !== newArr.length) {\n pushChange(path, oldArr, newArr, \"changed\");\n\n return;\n }\n for (let i = 0; i < oldArr.length; i++) {\n compare(oldArr[i], newArr[i], `${path}[${i}]`);\n }\n }\n\n /** Compare two objects by key union, detecting added/removed/changed. */\n function compareObjects(\n oldRecord: Record<string, unknown>,\n newRecord: Record<string, unknown>,\n path: string,\n ): void {\n const allKeys = new Set([\n ...Object.keys(oldRecord),\n ...Object.keys(newRecord),\n ]);\n\n for (const key of allKeys) {\n const childPath = path ? `${path}.${key}` : key;\n if (!(key in oldRecord)) {\n pushChange(childPath, undefined, newRecord[key], \"added\");\n } else if (!(key in newRecord)) {\n pushChange(childPath, oldRecord[key], undefined, \"removed\");\n } else {\n compare(oldRecord[key], newRecord[key], childPath);\n }\n }\n }\n\n /** Recursively compare two values and record differences. */\n function compare(oldObj: unknown, newObj: unknown, path: string): void {\n if (compareNullish(oldObj, newObj, path)) {\n return;\n }\n\n // Handle primitives\n if (typeof oldObj !== \"object\" || typeof newObj !== \"object\") {\n if (!Object.is(oldObj, newObj)) {\n pushChange(path, oldObj, newObj, \"changed\");\n }\n\n return;\n }\n\n // Handle arrays\n if (Array.isArray(oldObj) && Array.isArray(newObj)) {\n compareArrays(oldObj, newObj, path);\n\n return;\n }\n\n // Handle objects\n compareObjects(\n oldObj as Record<string, unknown>,\n newObj as Record<string, unknown>,\n path,\n );\n }\n\n // Compare data\n compare(oldSnapshot.data, newSnapshot.data, \"\");\n\n // Check version change\n const versionChanged =\n oldSnapshot.version !== newSnapshot.version &&\n (oldSnapshot.version !== undefined || newSnapshot.version !== undefined);\n\n return {\n identical: changes.length === 0,\n changes,\n versionChanged,\n oldVersion: oldSnapshot.version,\n newVersion: newSnapshot.version,\n };\n}\n\n// ============================================================================\n// Snapshot Signing (HMAC)\n// ============================================================================\n\n/**\n * A signed distributable snapshot.\n * Contains the original snapshot plus a cryptographic signature.\n */\nexport interface SignedSnapshot<T = Record<string, unknown>>\n extends DistributableSnapshotLike<T> {\n /** HMAC-SHA256 signature in hex format */\n signature: string;\n /** Signing algorithm used */\n algorithm: \"hmac-sha256\";\n}\n\n/**\n * Check if a snapshot is signed.\n *\n * @param snapshot - The snapshot to check\n * @returns True if the snapshot has a signature\n */\nexport function isSignedSnapshot<T>(\n snapshot: DistributableSnapshotLike<T> | SignedSnapshot<T>,\n): snapshot is SignedSnapshot<T> {\n return \"signature\" in snapshot && typeof snapshot.signature === \"string\";\n}\n\n/**\n * Sign a distributable snapshot using HMAC-SHA256.\n * Creates a tamper-proof signature that can be verified later.\n *\n * **Security Notes:**\n * - Use a cryptographically random secret of at least 32 bytes\n * - Store the secret securely (environment variable, secrets manager)\n * - Never expose the secret to clients\n * - The signature covers all snapshot fields for integrity\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({\n * includeDerivations: ['canUseFeature', 'limits'],\n * ttlSeconds: 3600,\n * });\n *\n * // Sign the snapshot (server-side only)\n * const signed = await signSnapshot(snapshot, process.env.SNAPSHOT_SECRET);\n *\n * // Store in JWT, Redis, or send to client\n * const jwt = createJWT({ snapshot: signed });\n *\n * // Later, verify the signature\n * const isValid = await verifySnapshotSignature(signed, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Snapshot has been tampered with');\n * }\n * ```\n *\n * @param snapshot - The snapshot to sign\n * @param secret - The HMAC secret (string or Uint8Array)\n * @returns A signed snapshot with the signature attached\n */\nexport async function signSnapshot<T>(\n snapshot: DistributableSnapshotLike<T>,\n secret: string | Uint8Array,\n): Promise<SignedSnapshot<T>> {\n // Create a canonical representation for signing\n const payload = stableStringify({\n data: snapshot.data,\n createdAt: snapshot.createdAt,\n expiresAt: snapshot.expiresAt,\n version: snapshot.version,\n metadata: snapshot.metadata,\n });\n\n const signature = await hmacSha256(payload, secret);\n\n return {\n ...snapshot,\n signature,\n algorithm: \"hmac-sha256\",\n };\n}\n\n/**\n * Verify the signature of a signed snapshot.\n * Returns true if the signature is valid, false otherwise.\n *\n * **Important:** Always verify signatures before trusting snapshot data,\n * especially if the snapshot was received from an untrusted source (client, cache).\n *\n * @example\n * ```typescript\n * // Receive signed snapshot from client or cache\n * const snapshot = JSON.parse(cachedData);\n *\n * // Verify before using\n * const isValid = await verifySnapshotSignature(snapshot, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Invalid snapshot signature - possible tampering');\n * }\n *\n * // Now safe to use snapshot.data\n * if (snapshot.data.canUseFeature.api) {\n * // Grant access\n * }\n * ```\n *\n * @param signedSnapshot - The signed snapshot to verify\n * @param secret - The HMAC secret (must match the signing secret)\n * @returns True if signature is valid, false otherwise\n */\nexport async function verifySnapshotSignature<T>(\n signedSnapshot: SignedSnapshot<T>,\n secret: string | Uint8Array,\n): Promise<boolean> {\n if (!signedSnapshot.signature || signedSnapshot.algorithm !== \"hmac-sha256\") {\n return false;\n }\n\n // Recreate the canonical payload (same as signing)\n const payload = stableStringify({\n data: signedSnapshot.data,\n createdAt: signedSnapshot.createdAt,\n expiresAt: signedSnapshot.expiresAt,\n version: signedSnapshot.version,\n metadata: signedSnapshot.metadata,\n });\n\n const expectedSignature = await hmacSha256(payload, secret);\n\n // Use timing-safe comparison\n return timingSafeEqual(signedSnapshot.signature, expectedSignature);\n}\n\n/**\n * Create HMAC-SHA256 signature of a message.\n * Uses Web Crypto API for cross-platform support (Node.js, browsers, Deno, Bun).\n */\nasync function hmacSha256(\n message: string,\n secret: string | Uint8Array,\n): Promise<string> {\n // Convert secret to Uint8Array if string\n const secretBytes: Uint8Array =\n typeof secret === \"string\" ? new TextEncoder().encode(secret) : secret;\n\n // Import key for HMAC\n const algorithm: HmacImportParams = {\n name: \"HMAC\",\n hash: { name: \"SHA-256\" },\n };\n const key = await crypto.subtle.importKey(\n \"raw\",\n secretBytes as unknown as ArrayBuffer,\n algorithm,\n false,\n [\"sign\"],\n );\n\n // Sign the message\n const messageBytes = new TextEncoder().encode(message);\n const signature = await crypto.subtle.sign(\"HMAC\", key, messageBytes);\n\n // Convert to hex string\n return Array.from(new Uint8Array(signature))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Timing-safe string comparison to prevent timing attacks.\n * Both strings should be the same length (hex signatures from same algorithm).\n */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n\n/**\n * Safely stringify any value for display. Handles circular references,\n * BigInt, throwing toJSON, and optional truncation.\n *\n * This is the canonical implementation – all packages should import this\n * instead of maintaining local copies.\n */\nexport function safeStringify(data: unknown, maxLen = 500): string {\n try {\n const str = JSON.stringify(\n data,\n (_key, value) => {\n if (typeof value === \"bigint\") {\n return `${value}n`;\n }\n\n return value;\n },\n 2,\n );\n if (!str) {\n return \"[undefined]\";\n }\n if (str.length <= maxLen) {\n return str;\n }\n\n return `${str.slice(0, maxLen)}\\n... (truncated, ${str.length} chars total)`;\n } catch {\n return \"[unserializable]\";\n }\n}\n"]}
'use strict';var chunk7NMXRATK_cjs=require('./chunk-7NMXRATK.cjs'),chunkN4KTCKOI_cjs=require('./chunk-N4KTCKOI.cjs'),chunkEOLY64E6_cjs=require('./chunk-EOLY64E6.cjs');var m="::",he=Symbol.for("nodejs.util.inspect.custom");function we(e){if(!e.ownKeys)return {};let n={};for(let t of e.ownKeys())n[t]=e.get(t);return n}function D(e){return new Proxy({},{get(n,t){if(typeof t=="symbol")return t===he?()=>we(e):void 0;if(!chunkN4KTCKOI_cjs.l.has(t))return e.get(t)},set(n,t,s){return typeof t=="symbol"||chunkN4KTCKOI_cjs.l.has(t)?false:e.set?e.set(t,s):false},has(n,t){return typeof t=="symbol"||chunkN4KTCKOI_cjs.l.has(t)?false:e.has?e.has(t):false},deleteProperty(n,t){return typeof t=="symbol"||chunkN4KTCKOI_cjs.l.has(t)?false:e.delete?e.delete(t):false},ownKeys(){return e.ownKeys?e.ownKeys():[]},getOwnPropertyDescriptor(n,t){if(typeof t!="symbol"&&e.has&&typeof t=="string"&&e.has(t))return {configurable:true,enumerable:true}},defineProperty(){return false},getPrototypeOf(){return null},setPrototypeOf(){return false}})}var Z=new WeakMap,Q=new WeakMap,X=new WeakMap,ee=new WeakMap,ne=new WeakMap,te=new WeakMap;function $(e,n){let t=Z.get(e);if(t){let r=t.get(n);if(r)return r}else t=new Map,Z.set(e,t);let s=D({get:r=>r==="$store"||r==="$snapshot"?e[r]:e[`${n}${m}${r}`],set:(r,u)=>{if(chunkN4KTCKOI_cjs.a){let i=chunkN4KTCKOI_cjs.m(u);i&&chunkN4KTCKOI_cjs.n(`${n}.${r}`,i);}return e[`${n}${m}${r}`]=u,true},has:r=>`${n}${m}${r}`in e,delete:r=>(delete e[`${n}${m}${r}`],true)});return t.set(n,s),s}function re(e,n,t){let s=Q.get(e);if(s)return s;let r=D({get:u=>{if(Object.hasOwn(n,u))return $(e,u)},has:u=>Object.hasOwn(n,u),ownKeys:()=>t()});return Q.set(e,r),r}function oe(e,n,t){let s=`${n}|${t.join(",")}`,r=ne.get(e);if(r){let o=r.get(s);if(o)return o}else r=new Map,ne.set(e,r);let u=new Set(t),i=["self",...t],c=D({get:o=>{if(o==="self")return $(e,n);if(u.has(o))return $(e,o);chunkN4KTCKOI_cjs.a&&console.warn(`[Directive] Module "${n}" accessed undeclared cross-module property "${o}". Add it to crossModuleDeps or use "facts.self.${o}" for own module facts.`);},has:o=>o==="self"||u.has(o),ownKeys:()=>i});return r.set(s,c),c}function B(e,n){let t=ee.get(e);if(t){let r=t.get(n);if(r)return r}else t=new Map,ee.set(e,t);let s=D({get:r=>e[`${n}${m}${r}`],has:r=>`${n}${m}${r}`in e});return t.set(n,s),s}function se(e,n,t){let s=X.get(e);if(s)return s;let r=D({get:u=>{if(Object.hasOwn(n,u))return B(e,u)},has:u=>Object.hasOwn(n,u),ownKeys:()=>t()});return X.set(e,r),r}function ie(e,n,t){let s=te.get(e);return s||(s=new Map,te.set(e,s)),D({get:r=>{if(!Object.hasOwn(n,r))return;let u=s.get(r);if(u)return u;let i=D({get:c=>o=>{e.dispatch({type:`${r}${m}${c}`,...o});}});return s.set(r,i),i},has:r=>Object.hasOwn(n,r),ownKeys:()=>t()})}function R(e){if(e.includes(".")){let[n,...t]=e.split(".");return `${n}${m}${t.join(m)}`}return e}function H(e){let n={};for(let[t,s]of Object.entries(e)){let r=t.indexOf(m);if(r>0){let u=t.slice(0,r),i=t.slice(r+m.length);n[u]||(n[u]={}),n[u][i]=s;}else n._root||(n._root={}),n._root[t]=s;}return n}function P(e,n,t,s){return t?oe(e,n,s):$(e,n)}function b(e,n){return `${e}${m}${n}`}function ae(e){return e.includes(m)}function E(e,n,t){if(Array.isArray(e)){let i=e.map(c=>{if(c&&typeof c=="object"&&typeof c.fact=="string"){let o=c.fact;return ae(o)?c:{...c,fact:b(n,o)}}return c});return chunkEOLY64E6_cjs.a(i),i}if(!e||typeof e!="object")return e;let s=e;if("$all"in s||"$any"in s){let i="$all"in s?"$all":"$any",c=s[i],o={[i]:c.map(f=>E(f,n,t))};return chunkEOLY64E6_cjs.a(o),o}if("$not"in s){let i={$not:E(s.$not,n,t)};return chunkEOLY64E6_cjs.a(i),i}function r(i,c){return E(i,c,ce)}let u={};for(let i of Object.keys(s)){if(i.startsWith("$")||ae(i)){u[i]=s[i];continue}if(i==="self"){let c=s[i];if(c&&typeof c=="object"){let o=r(c,n);if(o&&typeof o=="object"&&!Array.isArray(o)){for(let[f,l]of Object.entries(o))u[f]=l;continue}}}if(t.has(i)){let c=s[i];if(c&&typeof c=="object"){let o=r(c,i);if(o&&typeof o=="object"&&!Array.isArray(o)){for(let[f,l]of Object.entries(o))u[f]=l;continue}}}u[b(n,i)]=s[i];}return chunkEOLY64E6_cjs.a(u),u}var ce=new Set;function me(e,n){let t=e.crossModuleDeps?new Set(Object.keys(e.crossModuleDeps)):ce,s=e.constraints;if(s){let c=false,o={};for(let[f,l]of Object.entries(s)){let d=l;if(d.when!==void 0&&typeof d.when!="function"){o[f]={...d,when:E(d.when,n,t)},c=true;continue}o[f]=l;}c&&(s=o);}let r=e.derive;if(r){let c=false,o={};for(let[f,l]of Object.entries(r)){let d=l&&typeof l=="object"&&Object.hasOwn(l,"compute")?l:null;if(!d){o[f]=l;continue}let g=d.compute;if(typeof g=="function"){o[f]=l;continue}if(chunk7NMXRATK_cjs.j(g)){chunkEOLY64E6_cjs.a(g);let k=w=>chunk7NMXRATK_cjs.q(g,w);o[f]=d.meta?{compute:k,meta:d.meta}:k,c=true;continue}if(chunk7NMXRATK_cjs.h(g)){chunkEOLY64E6_cjs.a(g);let k=chunk7NMXRATK_cjs.o(g),w=j=>k(j);o[f]=d.meta?{compute:w,meta:d.meta}:w,c=true;continue}o[f]=l;}c&&(r=o);}let u=e.events;if(u){let c=false,o={};for(let[f,l]of Object.entries(u)){if(l&&typeof l=="object"){let d=Object.hasOwn(l,"handler"),g=Object.hasOwn(l,"patch");if(d&&g&&chunkN4KTCKOI_cjs.a&&console.warn(`[Directive] event "${f}": both \`handler\` and \`patch\` provided \u2014 using \`handler\` (patch is ignored).`),g&&!d){let k=l;chunkEOLY64E6_cjs.a(k.patch);let w=(j,O)=>chunk7NMXRATK_cjs.t(k.patch,j,O??{});o[f]=k.meta?{handler:w,meta:k.meta}:w,c=true;continue}}o[f]=l;}c&&(u=o);}let i=e.effects;if(i){let c=false,o={};for(let[f,l]of Object.entries(i)){let d=l;if(d.on!==void 0&&chunk7NMXRATK_cjs.h(d.on)){o[f]={...d,on:E(d.on,n,t)},c=true;continue}o[f]=l;}c&&(i=o);}return s===e.constraints&&r===e.derive&&u===e.events&&i===e.effects?e:{...e,constraints:s,derive:r,events:u,effects:i}}function C(e){return Object.keys(e).length>0?e:void 0}function ke(e,n){let t={};for(let[s,r]of Object.entries(e.schema.facts))t[b(n,s)]=r;return t}function pe(e,n){if(e.init)return t=>{let s=$(t,n);e.init(s);}}function ve(e,n,t,s){if(!e.derive)return;let r={};for(let[u,i]of Object.entries(e.derive)){let c=chunk7NMXRATK_cjs.u(i),o=c?i.compute:i,f=c?i.meta:void 0,l=(d,g)=>{let k=P(d,n,t,s),w=B(g,n);return o(k,w)};r[b(n,u)]=f?{compute:l,meta:f}:l;}return C(r)}function be(e,n){if(!e.events)return;let t={};for(let[s,r]of Object.entries(e.events)){let u=typeof r=="object"&&r!==null&&Object.hasOwn(r,"handler"),i=u?r.handler:r,c=u?r.meta:void 0,o=(f,l)=>{let d=$(f,n);i(d,l);};t[b(n,s)]=c?{handler:o,meta:c}:o;}return C(t)}function Me(e,n,t,s){if(!e.constraints)return;let r={};for(let[u,i]of Object.entries(e.constraints)){let c=i,o=typeof c.when=="function";r[b(n,u)]={...c,deps:c.deps?.map(f=>b(n,f)),after:c.after?.map(f=>f.includes(m)?f:b(n,f)),owns:c.owns?.map(f=>f.includes(m)?f:b(n,f)),when:o?f=>{let l=P(f,n,t,s);return c.when(l)}:c.when,require:typeof c.require=="function"?f=>{let l=P(f,n,t,s);return c.require(l)}:c.require};}return C(r)}function Re(e,n,t,s){if(!e.resolvers)return;let r={};for(let[i,c]of Object.entries(e.resolvers)){let f=function(l){return {facts:P(l.facts,n,t,s),signal:l.signal}};let o=c;r[b(n,i)]={...o,...o.resolve&&{resolve:async(l,d)=>{await o.resolve(l,f(d));}},...o.resolveBatch&&{resolveBatch:async(l,d)=>{await o.resolveBatch(l,f(d));}},...o.resolveBatchWithResults&&{resolveBatchWithResults:async(l,d)=>o.resolveBatchWithResults(l,f(d))}};}return C(r)}function Se(e,n,t,s){if(!e.effects)return;let r={};for(let[u,i]of Object.entries(e.effects)){let c=i;r[b(n,u)]={...c,run:(o,f)=>{let l=P(o,n,t,s),d=f?P(f,n,t,s):void 0;return c.run(l,d)},deps:c.deps?.map(o=>b(n,o))};}return C(r)}function Oe(e,n,t){return {snapshotEvents:t&&!t.has(n)?[]:e.history?.snapshotEvents?.map(s=>b(n,s))}}function I(e){let{mod:n,namespace:t,snapshotModulesSet:s}=e,r=me(n,t),u=!!(r.crossModuleDeps&&Object.keys(r.crossModuleDeps).length>0),i=u?Object.keys(r.crossModuleDeps):[];return {id:r.id,schema:ke(r,t),requirements:r.schema.requirements??{},init:pe(r,t),derive:ve(r,t,u,i),events:be(r,t),effects:Se(r,t,u,i),constraints:Me(r,t,u,i),resolvers:Re(r,t,u,i),hooks:r.hooks,meta:r.meta,history:Oe(r,t,s)}}function xe(e){let n=Object.keys(e),t=new Set(n),s=new Set,r=new Set,u=[],i=[];function c(o){if(s.has(o))return;if(r.has(o)){let l=i.indexOf(o),d=[...i.slice(l),o].join(" \u2192 ");throw new Error(`[Directive] Circular dependency detected: ${d}. Modules cannot have circular crossModuleDeps. Break the cycle by removing one of the cross-module references.`)}r.add(o),i.push(o);let f=e[o];if(f?.crossModuleDeps)for(let l of Object.keys(f.crossModuleDeps))t.has(l)&&c(l);i.pop(),r.delete(o),s.add(o),u.push(o);}for(let o of n)c(o);return u}function ue(e,n){let t=[];for(let s of Object.keys(n.schema.facts))t.push(`${e}${m}${s}`);if(n.schema.derivations)for(let s of Object.keys(n.schema.derivations))t.push(`${e}${m}${s}`);return t}function ze(e){if("module"in e){if(!e.module)throw new Error("[Directive] createSystem requires a module. Got: "+typeof e.module);return $e(e)}let n=e;if(Array.isArray(n.modules))throw new Error(`[Directive] createSystem expects modules as an object, not an array.
Instead of:
createSystem({ modules: [authModule, dataModule] })
Use:
createSystem({ modules: { auth: authModule, data: dataModule } })
Or for a single module:
createSystem({ module: counterModule })`);let t=n.modules;if(t&&typeof t=="object"&&"id"in t&&"schema"in t)throw new Error(`[Directive] A single module was passed to \`modules:\`. For a single module, use \`module:\` instead:
createSystem({ module: myModule })
For multiple modules, wrap in an object:
createSystem({ modules: { myName: myModule } })`);return De(n)}function De(e){let n=e.modules,t=new Set(Object.keys(n)),s=typeof e.history=="object"?e.history:null,r=s?.snapshotModules?new Set(s.snapshotModules):null;if(e.tickMs!==void 0&&e.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(chunkN4KTCKOI_cjs.a){for(let[a,y]of Object.entries(n))if(y.crossModuleDeps)for(let h of Object.keys(y.crossModuleDeps))h===a?console.warn(`[Directive] Module "${a}" references itself in crossModuleDeps. Use "facts.self" to access own module's facts instead.`):t.has(h)||console.warn(`[Directive] Module "${a}" declares crossModuleDeps.${h}, but no module with namespace "${h}" exists in the system. Available modules: ${[...t].join(", ")}`);}if(chunkN4KTCKOI_cjs.a&&s?.snapshotModules)for(let a of s.snapshotModules)t.has(a)||console.warn(`[Directive] history.snapshotModules entry "${a}" doesn't match any module. Available modules: ${[...t].join(", ")}`);let u,i=e.initOrder??"auto";if(Array.isArray(i)){let a=i,y=Object.keys(n).filter(h=>!a.includes(h));if(y.length>0)throw new Error(`[Directive] initOrder is missing modules: ${y.join(", ")}. All modules must be included in the explicit order.`);u=a;}else i==="declaration"?u=Object.keys(n):u=xe(n);let{history:c,trace:o,errorBoundary:f}=de(e);for(let a of Object.keys(n)){if(a.includes(m))throw new Error(`[Directive] Module name "${a}" contains the reserved separator "${m}". Module names cannot contain "${m}".`);let y=n[a];if(y){for(let h of Object.keys(y.schema.facts))if(h.includes(m))throw new Error(`[Directive] Schema key "${h}" in module "${a}" contains the reserved separator "${m}". Schema keys cannot contain "${m}".`)}}let l={names:null};function d(){return l.names===null&&(l.names=Object.keys(n)),l.names}let g=u.map(a=>{let y=n[a];return y?I({mod:y,namespace:a,snapshotModulesSet:r}):null}).filter(a=>a!==null);chunkN4KTCKOI_cjs.a&&e.tickMs&&e.tickMs>0&&(g.some(y=>y.events&&Object.keys(y.events).some(h=>h.endsWith(`${m}tick`)))||console.warn(`[Directive] tickMs is set to ${e.tickMs}ms but no module defines a "tick" event handler.`));let k=null,w=null;function j(a){for(let[y,h]of Object.entries(a)){if(chunkN4KTCKOI_cjs.l.has(y)){chunkN4KTCKOI_cjs.a&&console.warn(`[Directive] initialFacts/hydrate contains blocked namespace "${y}". Skipping.`);continue}if(!t.has(y)){chunkN4KTCKOI_cjs.a&&console.warn(`[Directive] initialFacts/hydrate contains unknown namespace "${y}". Available modules: ${[...t].join(", ")}`);continue}if(h&&typeof h=="object"&&!chunkEOLY64E6_cjs.e(h))throw new Error(`[Directive] initialFacts/hydrate for namespace "${y}" contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.`);for(let[M,x]of Object.entries(h))chunkN4KTCKOI_cjs.l.has(M)||(w.facts[`${y}${m}${M}`]=x);}}w=chunk7NMXRATK_cjs.T({modules:g,plugins:e.plugins,history:c,trace:o,errorBoundary:f,tickMs:e.tickMs,cloud:e.cloud,onAfterModuleInit:()=>{e.initialFacts&&j(e.initialFacts),k&&(j(k),k=null);}});let O=new Map;for(let a of Object.keys(n)){let y=n[a];y&&O.set(a,ue(a,y));}let q=re(w.facts,n,d),ye=se(w.derive,n,d),ge=ie(w,n,d),A=null,F=e.tickMs,_={_mode:"namespaced",facts:q,history:w.history,derive:ye,events:ge,constraints:w.constraints,effects:w.effects,resolvers:w.resolvers,async hydrate(a){if(w.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let y=await a();y&&typeof y=="object"&&(k=y);},initialize(){w.initialize();},start(){if(w.start(),F&&F>0){let a;for(let y of g)if(y?.events&&(a=Object.keys(y.events).find(h=>h.endsWith(`${m}tick`)),a))break;if(a){let y=a;A=setInterval(()=>{w.dispatch({type:y});},F);}}},stop(){A&&(clearInterval(A),A=null),w.stop();},destroy(){this.stop(),w.destroy();},dispatch(a){w.dispatch(a);},read(a){return w.read(R(a))},subscribe(a,y){let h=[];for(let M of a)if(M.endsWith(".*")){let x=M.slice(0,-2),W=O.get(x);W?h.push(...W):chunkN4KTCKOI_cjs.a&&console.warn(`[Directive] subscribe wildcard "${M}" \u2014 namespace "${x}" not found.`);}else h.push(R(M));return w.subscribe(h,y)},subscribeModule(a,y){let h=O.get(a);return !h||h.length===0?(chunkN4KTCKOI_cjs.a&&console.warn(`[Directive] subscribeModule("${a}") \u2014 namespace not found. Available: ${[...O.keys()].join(", ")}`),()=>{}):w.subscribe(h,y)},watch(a,y,h){return w.watch(R(a),y,h)},when(a,y){return w.when(()=>a(q),y)},getDistributableSnapshot(a){let y={...a,includeDerivations:a?.includeDerivations?.map(R),excludeDerivations:a?.excludeDerivations?.map(R),includeFacts:a?.includeFacts?.map(R)},h=w.getDistributableSnapshot(y);return {...h,data:H(h.data)}},watchDistributableSnapshot(a,y){let h={...a,includeDerivations:a?.includeDerivations?.map(R),excludeDerivations:a?.excludeDerivations?.map(R),includeFacts:a?.includeFacts?.map(R)};return w.watchDistributableSnapshot(h,M=>{y({...M,data:H(M.data)});})},registerModule(a,y){if(t.has(a))throw new Error(`[Directive] Module namespace "${a}" already exists. Cannot register a duplicate namespace.`);if(a.includes(m))throw new Error(`[Directive] Module name "${a}" contains the reserved separator "${m}".`);if(chunkN4KTCKOI_cjs.l.has(a))throw new Error(`[Directive] Module name "${a}" is a blocked property.`);for(let x of Object.keys(y.schema.facts))if(x.includes(m))throw new Error(`[Directive] Schema key "${x}" in module "${a}" contains the reserved separator "${m}".`);let h=y,M=I({mod:h,namespace:a,snapshotModulesSet:r});t.add(a),n[a]=h,l.names=null,O.set(a,ue(a,h)),w.registerModule(M);}};return le(_,w),fe(_),_}function de(e){let n=e.history,t=e.trace,s=e.errorBoundary;return e.zeroConfig&&(n=n??chunkN4KTCKOI_cjs.a,s={onConstraintError:"skip",onResolverError:"skip",onEffectError:"skip",onDerivationError:"skip",...e.errorBoundary}),{history:n,trace:t,errorBoundary:s}}function le(e,n){Object.defineProperties(e,{trace:{get(){return n.trace},enumerable:true,configurable:true},meta:{value:n.meta,enumerable:true,configurable:true},isRunning:{get(){return n.isRunning},enumerable:true,configurable:true},isSettled:{get(){return n.isSettled},enumerable:true,configurable:true},isInitialized:{get(){return n.isInitialized},enumerable:true,configurable:true},isReady:{get(){return n.isReady},enumerable:true,configurable:true}}),e.whenReady=n.whenReady.bind(n),e.batch=n.batch.bind(n),e.onSettledChange=n.onSettledChange.bind(n),e.onHistoryChange=n.onHistoryChange.bind(n),e.inspect=n.inspect.bind(n),e.settle=n.settle.bind(n),e.explain=n.explain.bind(n),e.getSnapshot=n.getSnapshot.bind(n),e.restore=n.restore.bind(n),e.observe=n.observe.bind(n);let t=["dispatch","read","subscribe","watch","when","getDistributableSnapshot","watchDistributableSnapshot"];for(let s of t)s in e||(e[s]=n[s].bind(n));}function fe(e){chunkN4KTCKOI_cjs.a&&(typeof process>"u"||process.env?.NODE_ENV!=="test")&&setTimeout(()=>{!e.isRunning&&!e.isInitialized&&console.warn("[Directive] System created but start() was never called. Constraints, resolvers, and effects will not run until you call system.start().");},0);}function $e(e){let n=e.module;if(!n)throw new Error("[Directive] createSystem requires a module. Got: "+typeof n);if(e.tickMs!==void 0&&e.tickMs<=0)throw new Error("[Directive] tickMs must be a positive number");if(e.initialFacts&&!chunkEOLY64E6_cjs.e(e.initialFacts))throw new Error("[Directive] initialFacts contains potentially dangerous keys (__proto__, constructor, or prototype). This may indicate a prototype pollution attack.");chunkN4KTCKOI_cjs.a&&(n.crossModuleDeps&&Object.keys(n.crossModuleDeps).length>0&&console.warn("[Directive] Single module mode ignores crossModuleDeps. Use multiple modules if cross-module access is needed: createSystem({ modules: { ... } })"),e.tickMs&&e.tickMs>0&&(n.events&&"tick"in n.events||console.warn(`[Directive] tickMs is set to ${e.tickMs}ms but module has no "tick" event handler.`)),(typeof e.history=="object"?e.history:null)?.snapshotModules&&console.warn("[Directive] history.snapshotModules has no effect in single-module mode. Use history.snapshotEvents on the module definition instead, or switch to createSystem({ modules: { ... } }) for multi-module filtering."));let{history:t,trace:s,errorBoundary:r}=de(e),u=null,i=null;i=chunk7NMXRATK_cjs.T({modules:[{id:n.id,schema:n.schema.facts,requirements:n.schema.requirements,init:n.init,derive:n.derive,events:n.events,effects:n.effects,constraints:n.constraints,resolvers:n.resolvers,hooks:n.hooks,meta:n.meta,history:n.history}],plugins:e.plugins,history:t,trace:s,errorBoundary:r,tickMs:e.tickMs,cloud:e.cloud,onAfterModuleInit:()=>{if(e.initialFacts)for(let[d,g]of Object.entries(e.initialFacts))chunkN4KTCKOI_cjs.l.has(d)||(i.facts[d]=g);if(u){if(!chunkEOLY64E6_cjs.e(u))chunkN4KTCKOI_cjs.a&&console.warn("[Directive] hydrate() data contains potentially dangerous keys. Skipping.");else for(let[d,g]of Object.entries(u))chunkN4KTCKOI_cjs.l.has(d)||(i.facts[d]=g);u=null;}}});let c=new Proxy({},{get(d,g){if(typeof g!="symbol"&&!chunkN4KTCKOI_cjs.l.has(g))return k=>{i.dispatch({type:g,...k});}},has(d,g){return typeof g=="symbol"||chunkN4KTCKOI_cjs.l.has(g)?false:n.events?g in n.events:false},ownKeys(){return n.events?Object.keys(n.events):[]},getOwnPropertyDescriptor(d,g){if(typeof g!="symbol"&&!chunkN4KTCKOI_cjs.l.has(g)&&n.events&&g in n.events)return {configurable:true,enumerable:true}},set(){return false},deleteProperty(){return false},defineProperty(){return false},getPrototypeOf(){return null},setPrototypeOf(){return false}}),o=null,f=e.tickMs,l={_mode:"single",facts:i.facts,history:i.history,derive:i.derive,events:c,constraints:i.constraints,effects:i.effects,resolvers:i.resolvers,async hydrate(d){if(i.isRunning)throw new Error("[Directive] hydrate() must be called before start(). The system is already running.");let g=await d();g&&typeof g=="object"&&(u=g);},initialize(){i.initialize();},start(){i.start(),f&&f>0&&n.events&&"tick"in n.events&&(o=setInterval(()=>{i.dispatch({type:"tick"});},f));},stop(){o&&(clearInterval(o),o=null),i.stop();},destroy(){this.stop(),i.destroy();},registerModule(d){i.registerModule({id:d.id,schema:d.schema.facts,requirements:d.schema.requirements,init:d.init,derive:d.derive,events:d.events,effects:d.effects,constraints:d.constraints,resolvers:d.resolvers,hooks:d.hooks,history:d.history});}};return le(l,i),fe(l),l}exports.a=ze;//# sourceMappingURL=chunk-EX3XG667.cjs.map
//# sourceMappingURL=chunk-EX3XG667.cjs.map

Sorry, the diff of this file is too big to display

'use strict';var a=typeof process<"u"&&process.env?.NODE_ENV!=="production";function u(e,t,r){e[t]=r;}function d(e,t){return e[t]}function p(e,t){return {name:e,onRequirementCreated:t.onRequirementCreated?r=>t.onRequirementCreated(r.requirement):void 0,onRequirementMet:t.onRequirementResolved?r=>t.onRequirementResolved(r.requirement):void 0,onError:t.onError}}function f(e){return t=>t.type===e}function m(e){let t=new Set(e);return r=>t.has(r.type)}var n=[];function R(){let e=n.length;return e===0?null:n[e-1]}function S(){return n.length>0}function g(e){let t=new Set;n.push(t);try{return {value:e(),deps:t}}finally{n.pop();}}function x(e){let t=n.splice(0,n.length);try{return e()}finally{for(let r of t)n.push(r);}}function q(e){let t=n.length;t!==0&&n[t-1].add(e);}var y=Object.freeze(new Set(["__proto__","constructor","prototype"]));function h(e){if(e===null||typeof e!="object")return null;if(e instanceof Date)return "Date";if(e instanceof Set)return "Set";if(e instanceof Map)return "Map";if(typeof File<"u"&&e instanceof File)return "File";if(Array.isArray(e))return null;let t=Object.getPrototypeOf(e);return t!==null&&t!==Object.prototype?"ClassInstance":null}var o=new Set,s={Date:".getTime() for timestamps",Set:"[...set] for arrays",Map:"Object.fromEntries(map) for plain objects",File:"{ name, size, type, lastModified } for metadata",ClassInstance:"a plain-object snapshot"};function C(e,t){let r=`${e}|${t}`;if(o.has(r))return;o.add(r);let i=s[t]??"a JSON-roundtrippable value";console.warn(`[Directive] Fact "${e}" assigned a ${t} instance.
Facts must be JSON-roundtrippable for reactivity to work correctly.
${t} mutations are not tracked.
Use ${i} instead.
See: https://directive.run/docs/facts#json-rule`);}
exports.a=a;exports.b=u;exports.c=d;exports.d=p;exports.e=f;exports.f=m;exports.g=R;exports.h=S;exports.i=g;exports.j=x;exports.k=q;exports.l=y;exports.m=h;exports.n=C;//# sourceMappingURL=chunk-N4KTCKOI.cjs.map
//# sourceMappingURL=chunk-N4KTCKOI.cjs.map
{"version":3,"sources":["../src/dev-true.ts","../src/core/types/adapter-utils.ts","../src/core/tracking.ts"],"names":["dev_true_default","setBridgeFact","facts","key","value","getBridgeFact","createCallbackPlugin","name","callbacks","req","requirementGuard","type","requirementGuardMultiple","types","typeSet","depStack","getCurrentDeps","len","isTracking","withTracking","fn","deps","withoutTracking","saved","ctx","trackAccess","BLOCKED_PROPS","detectNonJsonValueType","proto","nonJsonWarningCache","nonJsonHints","warnNonJsonFactAssignment","factPath","valueType","cacheKey","hint"],"mappings":"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","file":"chunk-N4KTCKOI.cjs","sourcesContent":["// Runtime check that bundlers (webpack, esbuild, turbopack, rollup) inline\n// based on the consumer's NODE_ENV. Without this, the published bundle bakes\n// in `true` and dev-mode validation runs in every consumer's production\n// build — a real footgun the v1.5/v1.6 release hit.\nexport default typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\";\n","/**\n * Adapter Type Utilities - Shared types and helpers for framework adapters\n *\n * These utilities reduce type assertions in adapters by providing:\n * - Schema composition types\n * - Constraint/resolver converters\n * - Plugin factory helpers\n */\n\nimport type { Facts } from \"./facts.js\";\nimport type { Plugin } from \"./plugins.js\";\nimport type { ConstraintDef, Requirement } from \"./requirements.js\";\nimport type { ResolverContext, ResolverDef } from \"./resolvers.js\";\nimport type { InferSchema, Schema } from \"./schema.js\";\n\n// ============================================================================\n// Schema Composition Types\n// ============================================================================\n\n/**\n * Merge two schemas into one.\n * Useful for adapters that add bridge-specific facts to user schemas.\n *\n * @example\n * ```typescript\n * type BridgeFields = { __state: SchemaType<Record<string, unknown>> };\n * type Combined = MergedSchema<UserSchema, BridgeFields>;\n * ```\n */\nexport type MergedSchema<Base extends Schema, Extra extends Schema> = Base &\n Extra;\n\n/**\n * Create a schema type from a fields definition.\n * Helper for defining adapter bridge schemas.\n *\n * @example\n * ```typescript\n * type AdapterBridgeSchema = BridgeSchema<{\n * __adapterState: SchemaType<Record<string, unknown>>;\n * }>;\n * ```\n */\nexport type BridgeSchema<Fields extends Schema> = Fields;\n\n// ============================================================================\n// Bridge Schema Helper\n// ============================================================================\n\n/**\n * Create a bridge schema definition for adapters.\n * Returns a schema object compatible with createModule().\n *\n * @example\n * ```typescript\n * const bridgeSchema = createBridgeSchema({\n * __state: t.object<Record<string, unknown>>(),\n * });\n * ```\n */\nexport function createBridgeSchema<S extends Schema>(schema: S): S {\n return schema;\n}\n\n// ============================================================================\n// Type-Safe Fact Mutation\n// ============================================================================\n\n/**\n * Type-safe fact setter for known schema keys.\n * Use when you have a typed schema and want to set a specific fact.\n *\n * @example\n * ```typescript\n * setFact(facts, \"count\", 10); // Type-checked\n * ```\n */\nexport function setFact<S extends Schema, K extends keyof InferSchema<S>>(\n facts: Facts<S>,\n key: K,\n value: InferSchema<S>[K],\n): void {\n (facts as Record<string, unknown>)[key as string] = value;\n}\n\n/**\n * Set a bridge fact without strict typing.\n * Use for adapter-internal bridge fields like `__adapterState`.\n *\n * @example\n * ```typescript\n * setBridgeFact(facts, \"__adapterState\", currentState);\n * ```\n */\nexport function setBridgeFact<V>(\n facts: Facts<Schema>,\n key: string,\n value: V,\n): void {\n (facts as Record<string, unknown>)[key] = value;\n}\n\n/**\n * Get a bridge fact without strict typing.\n * Use for adapter-internal bridge fields.\n *\n * @example\n * ```typescript\n * const state = getBridgeFact<MyState>(facts, \"__adapterState\");\n * ```\n */\nexport function getBridgeFact<V>(facts: Facts<Schema>, key: string): V {\n return (facts as Record<string, unknown>)[key] as V;\n}\n\n// ============================================================================\n// Constraint Converters\n// ============================================================================\n\n/**\n * Adapter constraint definition (generic form used by adapters).\n */\nexport interface AdapterConstraint<TState> {\n when: (state: TState) => boolean | Promise<boolean>;\n require: Requirement | ((state: TState) => Requirement | null);\n priority?: number;\n}\n\n/**\n * Convert adapter-style constraints to Directive format.\n * Maps adapter constraints that work with external state (TState) to\n * Directive constraints that work with Facts<Schema>.\n *\n * @param constraints - Adapter constraints keyed by name\n * @param extractState - Function to extract adapter state from facts\n *\n * @example\n * ```typescript\n * const directiveConstraints = convertConstraints<MyState, BridgeSchema>(\n * adapterConstraints,\n * (facts) => getBridgeFact<MyState>(facts, \"__state\"),\n * );\n * ```\n */\nexport function convertConstraints<TState, S extends Schema>(\n constraints: Record<string, AdapterConstraint<TState>>,\n extractState: (facts: Facts<S>) => TState,\n): Record<string, ConstraintDef<S, Requirement>> {\n const result: Record<string, ConstraintDef<S, Requirement>> = {};\n\n for (const [id, constraint] of Object.entries(constraints)) {\n result[id] = {\n priority: constraint.priority ?? 0,\n when: (facts) => constraint.when(extractState(facts)),\n require: (facts) => {\n const req =\n typeof constraint.require === \"function\"\n ? constraint.require(extractState(facts))\n : constraint.require;\n return req;\n },\n };\n }\n\n return result;\n}\n\n// ============================================================================\n// Resolver Converters\n// ============================================================================\n\n/**\n * Adapter resolver context (generic form used by adapters).\n */\nexport interface AdapterResolverContext<TContext> {\n context: TContext;\n signal: AbortSignal;\n}\n\n/**\n * Adapter resolver definition (generic form used by adapters).\n */\nexport interface AdapterResolver<\n TContext,\n R extends Requirement = Requirement,\n> {\n requirement: (req: Requirement) => req is R;\n key?: (req: R) => string;\n resolve: (\n req: R,\n ctx: AdapterResolverContext<TContext>,\n ) => void | Promise<void>;\n}\n\n/**\n * Convert adapter-style resolvers to Directive format.\n * Maps adapter resolvers that work with external context (TContext) to\n * Directive resolvers that work with ResolverContext<Schema>.\n *\n * @param resolvers - Adapter resolvers keyed by name\n * @param createContext - Function to create adapter context from Directive context\n *\n * @example\n * ```typescript\n * const directiveResolvers = convertResolvers<MyContext, BridgeSchema>(\n * adapterResolvers,\n * (ctx) => ({\n * getState: () => getBridgeFact<MyState>(ctx.facts, \"__state\"),\n * setState: (update) => setBridgeFact(ctx.facts, \"__state\", update),\n * signal: ctx.signal,\n * }),\n * );\n * ```\n */\nexport function convertResolvers<TContext, S extends Schema>(\n resolvers: Record<string, AdapterResolver<TContext, Requirement>>,\n createContext: (ctx: ResolverContext<S>) => TContext,\n): Record<string, ResolverDef<S, Requirement>> {\n const result: Record<string, ResolverDef<S, Requirement>> = {};\n\n for (const [id, resolver] of Object.entries(resolvers)) {\n result[id] = {\n requirement: resolver.requirement,\n key: resolver.key,\n resolve: async (req, ctx) => {\n const adapterCtx = createContext(ctx);\n await resolver.resolve(req, {\n context: adapterCtx,\n signal: ctx.signal,\n });\n },\n };\n }\n\n return result;\n}\n\n// ============================================================================\n// Plugin Factory\n// ============================================================================\n\n/**\n * Callback definitions for adapter plugins.\n */\nexport interface AdapterCallbacks {\n onRequirementCreated?: (req: Requirement) => void;\n onRequirementResolved?: (req: Requirement) => void;\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a callback plugin for adapter events.\n * Wraps adapter callbacks in a Directive plugin.\n *\n * @param name - Plugin name (for debugging)\n * @param callbacks - Callback functions to invoke\n *\n * @example\n * ```typescript\n * const callbackPlugin = createCallbackPlugin(\"adapter-callbacks\", {\n * onRequirementCreated: (req) => console.log(\"Created:\", req),\n * onRequirementResolved: (req) => console.log(\"Resolved:\", req),\n * });\n * ```\n */\n// biome-ignore lint/suspicious/noExplicitAny: Plugins work with any schema type\nexport function createCallbackPlugin(\n name: string,\n callbacks: AdapterCallbacks,\n): Plugin<any> {\n return {\n name,\n onRequirementCreated: callbacks.onRequirementCreated\n ? (req) => callbacks.onRequirementCreated!(req.requirement)\n : undefined,\n onRequirementMet: callbacks.onRequirementResolved\n ? (req) => callbacks.onRequirementResolved!(req.requirement)\n : undefined,\n onError: callbacks.onError,\n };\n}\n\n// ============================================================================\n// Module Config Helpers\n// ============================================================================\n\n/**\n * Cast constraints to the correct type for createModule.\n * Use this when TypeScript can't infer the constraint types correctly.\n */\nexport function asConstraints<S extends Schema>(\n constraints: Record<string, ConstraintDef<S, Requirement>>,\n): Record<string, ConstraintDef<S, Requirement>> {\n return constraints;\n}\n\n/**\n * Cast resolvers to the correct type for createModule.\n * Use this when TypeScript can't infer the resolver types correctly.\n */\nexport function asResolvers<S extends Schema>(\n resolvers: Record<string, ResolverDef<S, Requirement>>,\n): Record<string, ResolverDef<S, Requirement>> {\n return resolvers;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Create a type guard for a specific requirement type.\n * Simplifies the common pattern of checking req.type.\n *\n * @example\n * ```typescript\n * const isResetReq = requirementGuard<ResetReq>(\"RESET\");\n * // Use in resolver:\n * { requirement: isResetReq, resolve: ... }\n * ```\n */\nexport function requirementGuard<R extends Requirement>(\n type: R[\"type\"],\n): (req: Requirement) => req is R {\n return (req): req is R => req.type === type;\n}\n\n/**\n * Create a type guard that matches multiple requirement types.\n *\n * @example\n * ```typescript\n * const isDataReq = requirementGuardMultiple<FetchReq | RefreshReq>([\"FETCH\", \"REFRESH\"]);\n * ```\n */\nexport function requirementGuardMultiple<R extends Requirement>(\n types: Array<R[\"type\"]>,\n): (req: Requirement) => req is R {\n const typeSet = new Set(types);\n return (req): req is R => typeSet.has(req.type);\n}\n","/**\n * Dependency tracking context for auto-tracking derivations\n *\n * Uses a stack-based approach to handle nested derivation computations.\n * When a derivation accesses a fact, the tracking context records it.\n */\n\n/** Stack of active dependency sets (bare Sets for zero-allocation hot path) */\nconst depStack: Set<string>[] = [];\n\n/**\n * Get the current dependency set, or null if not tracking.\n *\n * @returns The active dependency Set, or `null` if no tracking is active.\n *\n * @internal\n */\nexport function getCurrentDeps(): Set<string> | null {\n const len = depStack.length;\n return len === 0 ? null : depStack[len - 1]!;\n}\n\n/**\n * Check if dependency tracking is currently active.\n *\n * @returns `true` if inside a {@link withTracking} call, `false` otherwise.\n *\n * @internal\n */\nexport function isTracking(): boolean {\n return depStack.length > 0;\n}\n\n/**\n * Run a function with dependency tracking.\n *\n * @remarks\n * Pushes a fresh Set onto the stack, executes `fn`, then pops it.\n * Any fact reads inside `fn` are recorded as dependencies.\n * Nesting is supported — inner calls get their own independent Set.\n *\n * @param fn - The function to execute under tracking.\n * @returns An object with the computed `value` and a `deps` Set of accessed\n * fact keys.\n *\n * @internal\n */\nexport function withTracking<T>(fn: () => T): { value: T; deps: Set<string> } {\n const deps = new Set<string>();\n depStack.push(deps);\n\n try {\n const value = fn();\n return { value, deps };\n } finally {\n depStack.pop();\n }\n}\n\n/**\n * Run a function without tracking.\n *\n * @remarks\n * Temporarily clears the tracking stack so that fact reads inside `fn` do\n * not register as dependencies. The stack is restored after `fn` returns\n * (even on error). Useful for side-effect reads that should not trigger\n * derivation invalidation.\n *\n * @param fn - The function to execute without tracking.\n * @returns The return value of `fn`.\n *\n * @internal\n */\nexport function withoutTracking<T>(fn: () => T): T {\n const saved = depStack.splice(0, depStack.length);\n\n try {\n return fn();\n } finally {\n for (const ctx of saved) {\n depStack.push(ctx);\n }\n }\n}\n\n/**\n * Track a specific key in the current context.\n *\n * @remarks\n * No-op if no tracking context is active.\n *\n * @param key - The fact key to record as a dependency.\n *\n * @internal\n */\nexport function trackAccess(key: string): void {\n const len = depStack.length;\n if (len === 0) {\n return;\n }\n depStack[len - 1]!.add(key);\n}\n\n/**\n * Prototype pollution guard — shared across all proxy handlers.\n *\n * @remarks\n * Contains `__proto__`, `constructor`, and `prototype`. Every proxy `get`\n * and `has` trap checks this set and returns `undefined` / `false` for\n * matching keys, preventing prototype pollution via proxy-based objects.\n *\n * @internal\n */\nexport const BLOCKED_PROPS: ReadonlySet<string> = Object.freeze(\n new Set([\"__proto__\", \"constructor\", \"prototype\"]),\n);\n\n// ============================================================================\n// Non-JSON value-type detection (MIGRATION_FEEDBACK item 20)\n// ============================================================================\n\n/**\n * Detect whether `value` is a non-JSON-roundtrippable type whose mutations\n * the facts proxy cannot track for reactivity.\n *\n * Returns the kind label (`\"Date\"`, `\"Set\"`, `\"Map\"`, `\"File\"`, or\n * `\"ClassInstance\"`) when one is detected, or `null` for plain objects,\n * arrays, primitives, and `null`/`undefined`.\n *\n * The `File` check is SSR-safe: if the runtime has no `File` global the\n * branch is skipped without throwing.\n *\n * The `ClassInstance` check fires for any object whose prototype is not\n * `Object.prototype` and which is not an array — e.g. instances of user\n * classes whose mutations bypass reactivity.\n *\n * @internal\n */\nexport function detectNonJsonValueType(value: unknown): string | null {\n if (value === null || typeof value !== \"object\") {\n return null;\n }\n if (value instanceof Date) {\n return \"Date\";\n }\n if (value instanceof Set) {\n return \"Set\";\n }\n if (value instanceof Map) {\n return \"Map\";\n }\n if (typeof File !== \"undefined\" && value instanceof File) {\n return \"File\";\n }\n // Plain objects and arrays are JSON-friendly.\n if (Array.isArray(value)) {\n return null;\n }\n // Class instances: prototype is not Object.prototype.\n // Plain `{}` literals have prototype `Object.prototype`; objects created\n // via `Object.create(null)` have a `null` prototype which we treat as\n // \"plain\" (it's still JSON-roundtrippable).\n const proto = Object.getPrototypeOf(value);\n if (proto !== null && proto !== Object.prototype) {\n return \"ClassInstance\";\n }\n\n return null;\n}\n\n/**\n * Per-(path, valueType) dedupe cache — once a warning fires for a given\n * combo we never re-emit. Keeps the dev console quiet under loops that\n * assign the same Date 100 times in a row.\n *\n * @internal\n */\nconst nonJsonWarningCache = new Set<string>();\n\nconst nonJsonHints: Record<string, string> = {\n Date: \".getTime() for timestamps\",\n Set: \"[...set] for arrays\",\n Map: \"Object.fromEntries(map) for plain objects\",\n File: \"{ name, size, type, lastModified } for metadata\",\n ClassInstance: \"a plain-object snapshot\",\n};\n\n/**\n * Emit a one-time dev-mode warning when a non-JSON value is assigned to a\n * fact. Called from the proxy `set` traps in both `createFactsProxy`\n * (single-module / standalone facts) and `createModuleFactsProxy`\n * (system-namespaced facts). No-ops in production builds — the call sites\n * are gated on `isDevelopment` so this entire helper is tree-shakable.\n *\n * @param factPath - Display path for the warning (e.g. `auth.token` or\n * bare `token` for non-namespaced stores).\n * @param valueType - The label returned from {@link detectNonJsonValueType}.\n *\n * @internal\n */\nexport function warnNonJsonFactAssignment(\n factPath: string,\n valueType: string,\n): void {\n const cacheKey = `${factPath}|${valueType}`;\n if (nonJsonWarningCache.has(cacheKey)) {\n return;\n }\n nonJsonWarningCache.add(cacheKey);\n\n const hint = nonJsonHints[valueType] ?? \"a JSON-roundtrippable value\";\n console.warn(\n `[Directive] Fact \"${factPath}\" assigned a ${valueType} instance.\\n` +\n `Facts must be JSON-roundtrippable for reactivity to work correctly.\\n` +\n `${valueType} mutations are not tracked.\\n` +\n `Use ${hint} instead.\\n` +\n `See: https://directive.run/docs/facts#json-rule`,\n );\n}\n\n/**\n * Reset the warning dedupe cache. Test-only — exported via internals for\n * vitest spec setup. Not part of the public API.\n *\n * @internal\n */\nexport function _resetNonJsonWarningCache(): void {\n nonJsonWarningCache.clear();\n}\n"]}
function m(n,o=new WeakSet){if(n===null||typeof n!="object")return n;let r=n;if(o.has(r)||Object.isFrozen(r))return n;if(o.add(r),Array.isArray(r))for(let s of r)m(s,o);else for(let s of Object.keys(r))m(r[s],o);return Object.freeze(r),n}function b(n){return m(n)}function S(n,o,r){return (...s)=>{try{return r(...s)}catch(u){throw u instanceof Error&&u.message.startsWith("[Directive] ")?new Error(`[Directive] ${n} '${o}': ${u.message.slice(12)}`,{cause:u}):u}}}async function A(n,o,r){let s,u=new Promise((g,d)=>{s=setTimeout(()=>d(new Error(r)),o);});try{return await Promise.race([n,u])}finally{clearTimeout(s);}}function k(n,o=50){let r=new WeakSet;function s(t){if(t===null)return "null";if(t===void 0)return "undefined";let e=typeof t;if(e==="string")return JSON.stringify(t);if(e==="number"||e==="boolean")return String(t);if(e==="function")return '"[function]"';if(e==="symbol")return '"[symbol]"'}function u(t,e){if(r.has(t))return '"[circular]"';r.add(t);let i=e();return r.delete(t),i}function g(t,e){return u(t,()=>`[${t.map(i=>c(i,e+1)).join(",")}]`)}function d(t,e){return u(t,()=>`{${Object.keys(t).sort().map(f=>`${JSON.stringify(f)}:${c(t[f],e+1)}`).join(",")}}`)}function c(t,e){if(e>o)return '"[max depth exceeded]"';if(typeof t=="bigint")return `${t.toString()}n`;let i=s(t);if(i!==void 0)return i;if(t instanceof Date)return `D:${t.toISOString()}`;if(t instanceof RegExp)return `R:${t.source}:${t.flags}`;if(t instanceof Map){let a=[...t.entries()].sort();return `M:${c(a,e+1)}`}if(t instanceof Set){let a=[...t].sort();return `S:${c(a,e+1)}`}return Array.isArray(t)?g(t,e):typeof t=="object"?d(t,e):'"[unknown]"'}return c(n,0)}function x(n,o=50){let r=new Set(["__proto__","constructor","prototype"]),s=new WeakSet;function u(t,e){if(s.has(t))return true;s.add(t);let i=e();return s.delete(t),i}function g(t,e){for(let i of t)if(!c(i,e+1))return false;return true}function d(t,e){for(let i of Object.keys(t))if(r.has(i)||!c(t[i],e+1))return false;return true}function c(t,e){if(e>o)return false;if(t==null||typeof t!="object")return true;let i=t;return Array.isArray(i)?u(i,()=>g(i,e)):u(i,()=>d(i,e))}return c(n,0)}function T(n,o){if(n===o)return true;if(!n||!o)return false;let r=Object.keys(n),s=Object.keys(o);if(r.length!==s.length)return false;for(let u of r)if(n[u]!==o[u])return false;return true}function D(n){let o=k(n),r=5381;for(let s=0;s<o.length;s++)r=(r<<5)+r^o.charCodeAt(s);return (r>>>0).toString(16)}function h(n,o=Date.now()){return n.expiresAt!==void 0&&o>n.expiresAt}function E(n,o=Date.now()){if(!n||typeof n!="object")throw new Error("[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.");if(!("data"in n))throw new Error("[Directive] Invalid snapshot: missing required 'data' property.");if(!("createdAt"in n)||typeof n.createdAt!="number")throw new Error("[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).");if(h(n,o)){let r=new Date(n.expiresAt).toISOString();throw new Error(`[Directive] Snapshot expired at ${r}. Obtain a fresh snapshot from the source.`)}return n.data}function $(n,o){let r=[];function s(e,i,a,f){r.push({path:e,oldValue:i,newValue:a,type:f});}function u(e,i,a){return e==null?(i!=null&&s(a,e,i,"added"),true):i==null?(s(a,e,i,"removed"),true):false}function g(e,i,a){if(e.length!==i.length){s(a,e,i,"changed");return}for(let f=0;f<e.length;f++)c(e[f],i[f],`${a}[${f}]`);}function d(e,i,a){let f=new Set([...Object.keys(e),...Object.keys(i)]);for(let y of f){let p=a?`${a}.${y}`:y;y in e?y in i?c(e[y],i[y],p):s(p,e[y],void 0,"removed"):s(p,void 0,i[y],"added");}}function c(e,i,a){if(!u(e,i,a)){if(typeof e!="object"||typeof i!="object"){Object.is(e,i)||s(a,e,i,"changed");return}if(Array.isArray(e)&&Array.isArray(i)){g(e,i,a);return}d(e,i,a);}}c(n.data,o.data,"");let t=n.version!==o.version&&(n.version!==void 0||o.version!==void 0);return {identical:r.length===0,changes:r,versionChanged:t,oldVersion:n.version,newVersion:o.version}}function R(n){return "signature"in n&&typeof n.signature=="string"}async function P(n,o){let r=k({data:n.data,createdAt:n.createdAt,expiresAt:n.expiresAt,version:n.version,metadata:n.metadata}),s=await l(r,o);return {...n,signature:s,algorithm:"hmac-sha256"}}async function C(n,o){if(!n.signature||n.algorithm!=="hmac-sha256")return false;let r=k({data:n.data,createdAt:n.createdAt,expiresAt:n.expiresAt,version:n.version,metadata:n.metadata}),s=await l(r,o);return w(n.signature,s)}async function l(n,o){let r=typeof o=="string"?new TextEncoder().encode(o):o,s={name:"HMAC",hash:{name:"SHA-256"}},u=await crypto.subtle.importKey("raw",r,s,false,["sign"]),g=new TextEncoder().encode(n),d=await crypto.subtle.sign("HMAC",u,g);return Array.from(new Uint8Array(d)).map(c=>c.toString(16).padStart(2,"0")).join("")}function w(n,o){if(n.length!==o.length)return false;let r=0;for(let s=0;s<n.length;s++)r|=n.charCodeAt(s)^o.charCodeAt(s);return r===0}function v(n,o=500){try{let r=JSON.stringify(n,(s,u)=>typeof u=="bigint"?`${u}n`:u,2);return r?r.length<=o?r:`${r.slice(0,o)}
... (truncated, ${r.length} chars total)`:"[undefined]"}catch{return "[unserializable]"}}export{b as a,S as b,A as c,k as d,x as e,T as f,D as g,h,E as i,$ as j,R as k,P as l,C as m,v as n};//# sourceMappingURL=chunk-T6IJUWYR.js.map
//# sourceMappingURL=chunk-T6IJUWYR.js.map
{"version":3,"sources":["../src/utils/utils.ts"],"names":["deepFreeze","value","seen","obj","item","key","freezeSpec","spec","attributeError","category","id","fn","args","e","withTimeout","promise","ms","errorMessage","timeoutId","timeoutPromise","_","reject","stableStringify","maxDepth","stringifyPrimitive","val","type","withCircularGuard","result","stringifyArray","depth","v","stringify","stringifyObject","k","primitive","entries","items","isPrototypeSafe","dangerousKeys","objVal","checkArray","arr","check","checkObject","shallowEqual","a","b","keysA","keysB","hashObject","str","hash","i","isSnapshotExpired","snapshot","now","validateSnapshot","expiredAt","diffSnapshots","oldSnapshot","newSnapshot","changes","pushChange","path","oldValue","newValue","compareNullish","oldObj","newObj","compareArrays","oldArr","newArr","compare","compareObjects","oldRecord","newRecord","allKeys","childPath","versionChanged","isSignedSnapshot","signSnapshot","secret","payload","signature","hmacSha256","verifySnapshotSignature","signedSnapshot","expectedSignature","timingSafeEqual","message","secretBytes","algorithm","messageBytes","safeStringify","data","maxLen","_key"],"mappings":"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","file":"chunk-T6IJUWYR.js","sourcesContent":["/**\n * Shared utilities for Directive\n */\n\n// ============================================================================\n// Deep freeze\n// ============================================================================\n\n/**\n * Recursively `Object.freeze` an object including nested objects, arrays, and\n * array elements. Uses a `WeakSet` to handle cycles. Skips primitives and\n * already-frozen values to avoid wasted work.\n *\n * Used at definition-registration sites (constraints, derivations, effects,\n * events, prefixed specs) so post-registration mutation of a nested operand\n * cannot silently change the compiled closure's behavior. Prefer\n * {@link freezeSpec} at registration sites — it documents the convention.\n */\nexport function deepFreeze<T>(\n value: T,\n seen: WeakSet<object> = new WeakSet(),\n): T {\n if (value === null || typeof value !== \"object\") {\n return value;\n }\n const obj = value as unknown as object;\n if (seen.has(obj) || Object.isFrozen(obj)) {\n return value;\n }\n seen.add(obj);\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n deepFreeze(item, seen);\n }\n } else {\n for (const key of Object.keys(obj)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n\n Object.freeze(obj);\n return value;\n}\n\n/**\n * Freeze a definition spec at registration. Centralizes the deepFreeze\n * convention so a new definition arm cannot forget it — every constraint,\n * derivation, effect, event, and prefixed-spec registration funnels through\n * this single helper.\n *\n * @param spec - The definition spec to freeze (mutated in place, returned)\n * @returns The same `spec` value, now deeply frozen\n *\n * @example\n * ```ts\n * // At registration time, freeze user-supplied specs so post-registration\n * // mutation cannot silently change the compiled closure's behavior.\n * const spec = freezeSpec(userPredicate);\n * memoizePredicate(spec);\n * ```\n */\nexport function freezeSpec<T>(spec: T): T {\n return deepFreeze(spec);\n}\n\n/**\n * Wrap a synthesized definition function so a `[Directive]`-prefixed error\n * thrown from inside it is re-thrown with the owning definition's category +\n * id injected, and the original error preserved as `cause`. Non-`[Directive]`\n * errors (user code, native) pass through untouched.\n *\n * Centralizes the owner-attribution wrap shared by the data-form `when`\n * (constraints), `on` (effects), and `compute` (derivations) closures — a\n * `[Directive]`-prefixed throw (e.g. `$matches: string`) is re-pointed at the\n * owning definition so the stack trace blames user config, not the runtime.\n *\n * @param category - The owning definition kind, used in the re-thrown message.\n * @param id - The owning definition's id.\n * @param fn - The synthesized function to wrap.\n * @returns A function with identical signature that re-attributes Directive errors.\n */\nexport function attributeError<A extends unknown[], R>(\n category: \"constraint\" | \"effect\" | \"derivation\",\n id: string,\n fn: (...args: A) => R,\n): (...args: A) => R {\n // Synchronous by design: the wrapped definition functions (memoized\n // predicate `when`/`on` closures, template closures) always return\n // synchronously. A `try/catch` only re-attributes a synchronous throw — an\n // async-returning fn's rejected promise would escape un-re-attributed.\n return (...args: A): R => {\n try {\n return fn(...args);\n } catch (e) {\n if (e instanceof Error && e.message.startsWith(\"[Directive] \")) {\n throw new Error(\n `[Directive] ${category} '${id}': ${e.message.slice(\"[Directive] \".length)}`,\n { cause: e },\n );\n }\n throw e;\n }\n };\n}\n\n/**\n * Execute a promise with a timeout, properly cleaning up the timer.\n * Used by both constraints and resolvers for timeout handling.\n *\n * @param promise - The promise to wrap with a timeout\n * @param ms - Timeout duration in milliseconds\n * @param errorMessage - Error message if timeout occurs\n * @returns The promise result\n * @throws Error if timeout is exceeded\n */\nexport async function withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n errorMessage: string,\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout>;\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error(errorMessage)), ms);\n });\n\n try {\n return await Promise.race([promise, timeoutPromise]);\n } finally {\n clearTimeout(timeoutId!);\n }\n}\n\n/**\n * Normalize an error to an Error instance.\n * Ensures consistent error handling throughout the library.\n *\n * @param error - The error to normalize (can be anything)\n * @returns An Error instance\n */\nexport function normalizeError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n return new Error(String(error));\n}\n\n/**\n * Create a stable JSON string with sorted keys.\n * Handles circular references and deeply nested objects safely.\n *\n * @param value - The value to stringify\n * @param maxDepth - Maximum nesting depth (default: 50)\n * @returns A stable JSON string\n */\nexport function stableStringify(value: unknown, maxDepth = 50): string {\n const seen = new WeakSet();\n\n /** Stringify a primitive value (null, undefined, string, number, boolean, function, symbol). */\n function stringifyPrimitive(val: unknown): string | undefined {\n if (val === null) return \"null\";\n if (val === undefined) return \"undefined\";\n\n const type = typeof val;\n if (type === \"string\") return JSON.stringify(val);\n if (type === \"number\" || type === \"boolean\") return String(val);\n if (type === \"function\") return '\"[function]\"';\n if (type === \"symbol\") return '\"[symbol]\"';\n\n return undefined;\n }\n\n /** Guard against circular references using a seen-set, then delegate to fn. */\n function withCircularGuard(obj: object, fn: () => string): string {\n if (seen.has(obj)) {\n return '\"[circular]\"';\n }\n seen.add(obj);\n const result = fn();\n seen.delete(obj);\n\n return result;\n }\n\n /** Stringify an array with circular reference protection. */\n function stringifyArray(val: unknown[], depth: number): string {\n return withCircularGuard(\n val,\n () => `[${val.map((v) => stringify(v, depth + 1)).join(\",\")}]`,\n );\n }\n\n /** Stringify an object with sorted keys and circular reference protection. */\n function stringifyObject(\n obj: Record<string, unknown>,\n depth: number,\n ): string {\n return withCircularGuard(obj, () => {\n const keys = Object.keys(obj).sort();\n const pairs = keys.map(\n (k) => `${JSON.stringify(k)}:${stringify(obj[k], depth + 1)}`,\n );\n\n return `{${pairs.join(\",\")}}`;\n });\n }\n\n /** Recursively stringify a value with depth limit and circular detection. */\n function stringify(val: unknown, depth: number): string {\n if (depth > maxDepth) {\n return '\"[max depth exceeded]\"';\n }\n\n // BigInt is not JSON-serializable; encode with a trailing 'n' to remain\n // distinct from numeric strings.\n if (typeof val === \"bigint\") {\n return `${val.toString()}n`;\n }\n\n const primitive = stringifyPrimitive(val);\n if (primitive !== undefined) {\n return primitive;\n }\n\n // Typed-value branches: each prefix is bare (no outer quotes) so it can\n // never collide with a JSON-encoded string. `JSON.stringify(\"D:...\")`\n // emits `\"D:...\"` (the wrapping quotes ARE part of the output string),\n // whereas the Date branch emits `D:...` (no quotes). Distinct outputs.\n if (val instanceof Date) {\n return `D:${val.toISOString()}`;\n }\n if (val instanceof RegExp) {\n return `R:${val.source}:${val.flags}`;\n }\n if (val instanceof Map) {\n const entries = [...val.entries()].sort();\n return `M:${stringify(entries, depth + 1)}`;\n }\n if (val instanceof Set) {\n const items = [...val].sort();\n return `S:${stringify(items, depth + 1)}`;\n }\n\n if (Array.isArray(val)) {\n return stringifyArray(val, depth);\n }\n\n if (typeof val === \"object\") {\n return stringifyObject(val as Record<string, unknown>, depth);\n }\n\n return '\"[unknown]\"';\n }\n\n return stringify(value, 0);\n}\n\n/**\n * Check for prototype pollution in an object, including nested objects.\n * Returns true if the object is safe, false if dangerous keys are found.\n *\n * @param obj - The object to check\n * @param maxDepth - Maximum nesting depth to check (default: 50)\n * @returns True if safe, false if dangerous keys found\n */\nexport function isPrototypeSafe(obj: unknown, maxDepth = 50): boolean {\n const dangerousKeys = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n const seen = new WeakSet();\n\n /** Guard against circular references using a seen-set, then delegate to fn. */\n function withCircularGuard(objVal: object, fn: () => boolean): boolean {\n if (seen.has(objVal)) return true;\n seen.add(objVal);\n const result = fn();\n seen.delete(objVal);\n\n return result;\n }\n\n /** Check array elements for prototype pollution keys. */\n function checkArray(arr: unknown[], depth: number): boolean {\n for (const item of arr) {\n if (!check(item, depth + 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Check object keys and values for prototype pollution. */\n function checkObject(\n objVal: Record<string, unknown>,\n depth: number,\n ): boolean {\n for (const key of Object.keys(objVal)) {\n if (dangerousKeys.has(key)) {\n return false;\n }\n if (!check(objVal[key], depth + 1)) {\n return false;\n }\n }\n\n return true;\n }\n\n /** Recursively check a value tree for dangerous prototype keys. */\n function check(val: unknown, depth: number): boolean {\n if (depth > maxDepth) return false; // Fail safe at max depth - don't assume safety\n if (val === null || val === undefined) return true;\n if (typeof val !== \"object\") return true;\n\n const objVal = val as Record<string, unknown>;\n\n if (Array.isArray(objVal)) {\n return withCircularGuard(objVal, () => checkArray(objVal, depth));\n }\n\n return withCircularGuard(objVal, () => checkObject(objVal, depth));\n }\n\n return check(obj, 0);\n}\n\n/**\n * Shallow equality comparison for objects.\n * Used by React hooks to avoid unnecessary re-renders.\n *\n * @param a - First object\n * @param b - Second object\n * @returns True if objects are shallowly equal\n */\nexport function shallowEqual<T extends Record<string, unknown>>(\n a: T,\n b: T,\n): boolean {\n if (a === b) return true;\n if (!a || !b) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (a[key] !== b[key]) return false;\n }\n\n return true;\n}\n\n/**\n * Generate a simple hash string from an object.\n * Uses djb2 algorithm on the stable stringified value.\n *\n * **Limitations:**\n * - 32-bit hash output means collision probability increases with data set size\n * (birthday paradox: ~50% collision chance at ~77,000 distinct values)\n * - Suitable for: cache invalidation, change detection, deduplication of small sets\n * - NOT suitable for: cryptographic use, security-sensitive operations, large-scale deduplication\n *\n * For security-sensitive use cases requiring stronger collision resistance,\n * consider using a cryptographic hash like SHA-256.\n *\n * @param value - The value to hash\n * @returns A hex hash string (8 characters, 32 bits)\n */\nexport function hashObject(value: unknown): string {\n const str = stableStringify(value);\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n // Convert to unsigned 32-bit and then to hex\n return (hash >>> 0).toString(16);\n}\n\n// ============================================================================\n// Distributable Snapshot Utilities\n// ============================================================================\n\n/**\n * Distributable snapshot type for type-safe helper functions.\n */\nexport interface DistributableSnapshotLike<T = Record<string, unknown>> {\n data: T;\n createdAt: number;\n expiresAt?: number;\n version?: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Check if a distributable snapshot has expired.\n * Returns false if the snapshot has no expiresAt field.\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({ ttlSeconds: 3600 });\n * // ... later ...\n * if (isSnapshotExpired(snapshot)) {\n * // Refresh the snapshot\n * }\n * ```\n *\n * @param snapshot - The snapshot to check\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns True if the snapshot has expired, false otherwise\n */\nexport function isSnapshotExpired<T>(\n snapshot: DistributableSnapshotLike<T>,\n now: number = Date.now(),\n): boolean {\n return snapshot.expiresAt !== undefined && now > snapshot.expiresAt;\n}\n\n/**\n * Validate a distributable snapshot and return its data.\n * Throws if the snapshot is malformed or has expired.\n *\n * @example\n * ```typescript\n * const cached = JSON.parse(await redis.get(`entitlements:${userId}`));\n * try {\n * const data = validateSnapshot(cached);\n * // Use data.canUseFeature, etc.\n * } catch (e) {\n * // Snapshot invalid or expired, refresh it\n * }\n * ```\n *\n * @example Using custom timestamp for testing\n * ```typescript\n * const snapshot = { data: { test: true }, createdAt: 1000, expiresAt: 2000 };\n * validateSnapshot(snapshot, 1500); // Returns { test: true }\n * validateSnapshot(snapshot, 2500); // Throws: Snapshot expired\n * ```\n *\n * @param snapshot - The snapshot to validate\n * @param now - Optional current timestamp (defaults to Date.now())\n * @returns The snapshot data if valid\n * @throws Error if the snapshot is malformed or has expired\n */\nexport function validateSnapshot<T>(\n snapshot: DistributableSnapshotLike<T>,\n now: number = Date.now(),\n): T {\n // Structural validation\n if (!snapshot || typeof snapshot !== \"object\") {\n throw new Error(\n \"[Directive] Invalid snapshot: expected an object with 'data' and 'createdAt' properties.\",\n );\n }\n if (!(\"data\" in snapshot)) {\n throw new Error(\n \"[Directive] Invalid snapshot: missing required 'data' property.\",\n );\n }\n if (!(\"createdAt\" in snapshot) || typeof snapshot.createdAt !== \"number\") {\n throw new Error(\n \"[Directive] Invalid snapshot: missing or invalid 'createdAt' property (expected number).\",\n );\n }\n\n // Expiration validation\n if (isSnapshotExpired(snapshot, now)) {\n const expiredAt = new Date(snapshot.expiresAt!).toISOString();\n throw new Error(\n `[Directive] Snapshot expired at ${expiredAt}. Obtain a fresh snapshot from the source.`,\n );\n }\n return snapshot.data;\n}\n\n/**\n * Diff result for a single changed value.\n */\nexport interface SnapshotDiffEntry {\n /** The key path that changed (e.g., \"canUseApi\" or \"limits.apiCalls\") */\n path: string;\n /** The value in the old snapshot */\n oldValue: unknown;\n /** The value in the new snapshot */\n newValue: unknown;\n /** Type of change: \"added\", \"removed\", or \"changed\" */\n type: \"added\" | \"removed\" | \"changed\";\n}\n\n/**\n * Result of diffing two snapshots.\n */\nexport interface SnapshotDiff {\n /** Whether the snapshots are identical */\n identical: boolean;\n /** List of changes between snapshots */\n changes: SnapshotDiffEntry[];\n /** Whether the version changed (if both have versions) */\n versionChanged: boolean;\n /** Old version (if available) */\n oldVersion?: string;\n /** New version (if available) */\n newVersion?: string;\n}\n\n/**\n * Compare two distributable snapshots and return the differences.\n * Useful for debugging, audit logs, and webhook payloads.\n *\n * @example\n * ```typescript\n * const oldSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n * system.dispatch({ type: \"upgradePlan\", plan: \"pro\" });\n * const newSnapshot = system.getDistributableSnapshot({ includeVersion: true });\n *\n * const diff = diffSnapshots(oldSnapshot, newSnapshot);\n * if (!diff.identical) {\n * console.log(\"Changes:\", diff.changes);\n * // [{ path: \"canUseApi\", oldValue: false, newValue: true, type: \"changed\" }]\n * }\n * ```\n *\n * @param oldSnapshot - The previous snapshot\n * @param newSnapshot - The new snapshot\n * @returns A diff result with all changes\n */\nexport function diffSnapshots<T = Record<string, unknown>>(\n oldSnapshot: DistributableSnapshotLike<T>,\n newSnapshot: DistributableSnapshotLike<T>,\n): SnapshotDiff {\n const changes: SnapshotDiffEntry[] = [];\n\n /** Push a change entry to the diff results. */\n function pushChange(\n path: string,\n oldValue: unknown,\n newValue: unknown,\n type: SnapshotDiffEntry[\"type\"],\n ): void {\n changes.push({ path, oldValue, newValue, type });\n }\n\n /** Handle null/undefined comparison cases. Returns true if fully handled. */\n function compareNullish(\n oldObj: unknown,\n newObj: unknown,\n path: string,\n ): boolean {\n if (oldObj === null || oldObj === undefined) {\n if (newObj !== null && newObj !== undefined) {\n pushChange(path, oldObj, newObj, \"added\");\n }\n\n return true;\n }\n if (newObj === null || newObj === undefined) {\n pushChange(path, oldObj, newObj, \"removed\");\n\n return true;\n }\n\n return false;\n }\n\n /** Compare two arrays element by element, recursing into each. */\n function compareArrays(\n oldArr: unknown[],\n newArr: unknown[],\n path: string,\n ): void {\n if (oldArr.length !== newArr.length) {\n pushChange(path, oldArr, newArr, \"changed\");\n\n return;\n }\n for (let i = 0; i < oldArr.length; i++) {\n compare(oldArr[i], newArr[i], `${path}[${i}]`);\n }\n }\n\n /** Compare two objects by key union, detecting added/removed/changed. */\n function compareObjects(\n oldRecord: Record<string, unknown>,\n newRecord: Record<string, unknown>,\n path: string,\n ): void {\n const allKeys = new Set([\n ...Object.keys(oldRecord),\n ...Object.keys(newRecord),\n ]);\n\n for (const key of allKeys) {\n const childPath = path ? `${path}.${key}` : key;\n if (!(key in oldRecord)) {\n pushChange(childPath, undefined, newRecord[key], \"added\");\n } else if (!(key in newRecord)) {\n pushChange(childPath, oldRecord[key], undefined, \"removed\");\n } else {\n compare(oldRecord[key], newRecord[key], childPath);\n }\n }\n }\n\n /** Recursively compare two values and record differences. */\n function compare(oldObj: unknown, newObj: unknown, path: string): void {\n if (compareNullish(oldObj, newObj, path)) {\n return;\n }\n\n // Handle primitives\n if (typeof oldObj !== \"object\" || typeof newObj !== \"object\") {\n if (!Object.is(oldObj, newObj)) {\n pushChange(path, oldObj, newObj, \"changed\");\n }\n\n return;\n }\n\n // Handle arrays\n if (Array.isArray(oldObj) && Array.isArray(newObj)) {\n compareArrays(oldObj, newObj, path);\n\n return;\n }\n\n // Handle objects\n compareObjects(\n oldObj as Record<string, unknown>,\n newObj as Record<string, unknown>,\n path,\n );\n }\n\n // Compare data\n compare(oldSnapshot.data, newSnapshot.data, \"\");\n\n // Check version change\n const versionChanged =\n oldSnapshot.version !== newSnapshot.version &&\n (oldSnapshot.version !== undefined || newSnapshot.version !== undefined);\n\n return {\n identical: changes.length === 0,\n changes,\n versionChanged,\n oldVersion: oldSnapshot.version,\n newVersion: newSnapshot.version,\n };\n}\n\n// ============================================================================\n// Snapshot Signing (HMAC)\n// ============================================================================\n\n/**\n * A signed distributable snapshot.\n * Contains the original snapshot plus a cryptographic signature.\n */\nexport interface SignedSnapshot<T = Record<string, unknown>>\n extends DistributableSnapshotLike<T> {\n /** HMAC-SHA256 signature in hex format */\n signature: string;\n /** Signing algorithm used */\n algorithm: \"hmac-sha256\";\n}\n\n/**\n * Check if a snapshot is signed.\n *\n * @param snapshot - The snapshot to check\n * @returns True if the snapshot has a signature\n */\nexport function isSignedSnapshot<T>(\n snapshot: DistributableSnapshotLike<T> | SignedSnapshot<T>,\n): snapshot is SignedSnapshot<T> {\n return \"signature\" in snapshot && typeof snapshot.signature === \"string\";\n}\n\n/**\n * Sign a distributable snapshot using HMAC-SHA256.\n * Creates a tamper-proof signature that can be verified later.\n *\n * **Security Notes:**\n * - Use a cryptographically random secret of at least 32 bytes\n * - Store the secret securely (environment variable, secrets manager)\n * - Never expose the secret to clients\n * - The signature covers all snapshot fields for integrity\n *\n * @example\n * ```typescript\n * const snapshot = system.getDistributableSnapshot({\n * includeDerivations: ['canUseFeature', 'limits'],\n * ttlSeconds: 3600,\n * });\n *\n * // Sign the snapshot (server-side only)\n * const signed = await signSnapshot(snapshot, process.env.SNAPSHOT_SECRET);\n *\n * // Store in JWT, Redis, or send to client\n * const jwt = createJWT({ snapshot: signed });\n *\n * // Later, verify the signature\n * const isValid = await verifySnapshotSignature(signed, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Snapshot has been tampered with');\n * }\n * ```\n *\n * @param snapshot - The snapshot to sign\n * @param secret - The HMAC secret (string or Uint8Array)\n * @returns A signed snapshot with the signature attached\n */\nexport async function signSnapshot<T>(\n snapshot: DistributableSnapshotLike<T>,\n secret: string | Uint8Array,\n): Promise<SignedSnapshot<T>> {\n // Create a canonical representation for signing\n const payload = stableStringify({\n data: snapshot.data,\n createdAt: snapshot.createdAt,\n expiresAt: snapshot.expiresAt,\n version: snapshot.version,\n metadata: snapshot.metadata,\n });\n\n const signature = await hmacSha256(payload, secret);\n\n return {\n ...snapshot,\n signature,\n algorithm: \"hmac-sha256\",\n };\n}\n\n/**\n * Verify the signature of a signed snapshot.\n * Returns true if the signature is valid, false otherwise.\n *\n * **Important:** Always verify signatures before trusting snapshot data,\n * especially if the snapshot was received from an untrusted source (client, cache).\n *\n * @example\n * ```typescript\n * // Receive signed snapshot from client or cache\n * const snapshot = JSON.parse(cachedData);\n *\n * // Verify before using\n * const isValid = await verifySnapshotSignature(snapshot, process.env.SNAPSHOT_SECRET);\n * if (!isValid) {\n * throw new Error('Invalid snapshot signature - possible tampering');\n * }\n *\n * // Now safe to use snapshot.data\n * if (snapshot.data.canUseFeature.api) {\n * // Grant access\n * }\n * ```\n *\n * @param signedSnapshot - The signed snapshot to verify\n * @param secret - The HMAC secret (must match the signing secret)\n * @returns True if signature is valid, false otherwise\n */\nexport async function verifySnapshotSignature<T>(\n signedSnapshot: SignedSnapshot<T>,\n secret: string | Uint8Array,\n): Promise<boolean> {\n if (!signedSnapshot.signature || signedSnapshot.algorithm !== \"hmac-sha256\") {\n return false;\n }\n\n // Recreate the canonical payload (same as signing)\n const payload = stableStringify({\n data: signedSnapshot.data,\n createdAt: signedSnapshot.createdAt,\n expiresAt: signedSnapshot.expiresAt,\n version: signedSnapshot.version,\n metadata: signedSnapshot.metadata,\n });\n\n const expectedSignature = await hmacSha256(payload, secret);\n\n // Use timing-safe comparison\n return timingSafeEqual(signedSnapshot.signature, expectedSignature);\n}\n\n/**\n * Create HMAC-SHA256 signature of a message.\n * Uses Web Crypto API for cross-platform support (Node.js, browsers, Deno, Bun).\n */\nasync function hmacSha256(\n message: string,\n secret: string | Uint8Array,\n): Promise<string> {\n // Convert secret to Uint8Array if string\n const secretBytes: Uint8Array =\n typeof secret === \"string\" ? new TextEncoder().encode(secret) : secret;\n\n // Import key for HMAC\n const algorithm: HmacImportParams = {\n name: \"HMAC\",\n hash: { name: \"SHA-256\" },\n };\n const key = await crypto.subtle.importKey(\n \"raw\",\n secretBytes as unknown as ArrayBuffer,\n algorithm,\n false,\n [\"sign\"],\n );\n\n // Sign the message\n const messageBytes = new TextEncoder().encode(message);\n const signature = await crypto.subtle.sign(\"HMAC\", key, messageBytes);\n\n // Convert to hex string\n return Array.from(new Uint8Array(signature))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Timing-safe string comparison to prevent timing attacks.\n * Both strings should be the same length (hex signatures from same algorithm).\n */\nfunction timingSafeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n let result = 0;\n for (let i = 0; i < a.length; i++) {\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return result === 0;\n}\n\n/**\n * Safely stringify any value for display. Handles circular references,\n * BigInt, throwing toJSON, and optional truncation.\n *\n * This is the canonical implementation – all packages should import this\n * instead of maintaining local copies.\n */\nexport function safeStringify(data: unknown, maxLen = 500): string {\n try {\n const str = JSON.stringify(\n data,\n (_key, value) => {\n if (typeof value === \"bigint\") {\n return `${value}n`;\n }\n\n return value;\n },\n 2,\n );\n if (!str) {\n return \"[undefined]\";\n }\n if (str.length <= maxLen) {\n return str;\n }\n\n return `${str.slice(0, maxLen)}\\n... (truncated, ${str.length} chars total)`;\n } catch {\n return \"[unserializable]\";\n }\n}\n"]}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

var a=typeof process<"u"&&process.env?.NODE_ENV!=="production";function u(e,t,r){e[t]=r;}function d(e,t){return e[t]}function p(e,t){return {name:e,onRequirementCreated:t.onRequirementCreated?r=>t.onRequirementCreated(r.requirement):void 0,onRequirementMet:t.onRequirementResolved?r=>t.onRequirementResolved(r.requirement):void 0,onError:t.onError}}function f(e){return t=>t.type===e}function m(e){let t=new Set(e);return r=>t.has(r.type)}var n=[];function R(){let e=n.length;return e===0?null:n[e-1]}function S(){return n.length>0}function g(e){let t=new Set;n.push(t);try{return {value:e(),deps:t}}finally{n.pop();}}function x(e){let t=n.splice(0,n.length);try{return e()}finally{for(let r of t)n.push(r);}}function q(e){let t=n.length;t!==0&&n[t-1].add(e);}var y=Object.freeze(new Set(["__proto__","constructor","prototype"]));function h(e){if(e===null||typeof e!="object")return null;if(e instanceof Date)return "Date";if(e instanceof Set)return "Set";if(e instanceof Map)return "Map";if(typeof File<"u"&&e instanceof File)return "File";if(Array.isArray(e))return null;let t=Object.getPrototypeOf(e);return t!==null&&t!==Object.prototype?"ClassInstance":null}var o=new Set,s={Date:".getTime() for timestamps",Set:"[...set] for arrays",Map:"Object.fromEntries(map) for plain objects",File:"{ name, size, type, lastModified } for metadata",ClassInstance:"a plain-object snapshot"};function C(e,t){let r=`${e}|${t}`;if(o.has(r))return;o.add(r);let i=s[t]??"a JSON-roundtrippable value";console.warn(`[Directive] Fact "${e}" assigned a ${t} instance.
Facts must be JSON-roundtrippable for reactivity to work correctly.
${t} mutations are not tracked.
Use ${i} instead.
See: https://directive.run/docs/facts#json-rule`);}
export{a,u as b,d as c,p as d,f as e,m as f,R as g,S as h,g as i,x as j,q as k,y as l,h as m,C as n};//# sourceMappingURL=chunk-TZHC4E6S.js.map
//# sourceMappingURL=chunk-TZHC4E6S.js.map
{"version":3,"sources":["../src/dev-true.ts","../src/core/types/adapter-utils.ts","../src/core/tracking.ts"],"names":["dev_true_default","setBridgeFact","facts","key","value","getBridgeFact","createCallbackPlugin","name","callbacks","req","requirementGuard","type","requirementGuardMultiple","types","typeSet","depStack","getCurrentDeps","len","isTracking","withTracking","fn","deps","withoutTracking","saved","ctx","trackAccess","BLOCKED_PROPS","detectNonJsonValueType","proto","nonJsonWarningCache","nonJsonHints","warnNonJsonFactAssignment","factPath","valueType","cacheKey","hint"],"mappings":"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","file":"chunk-TZHC4E6S.js","sourcesContent":["// Runtime check that bundlers (webpack, esbuild, turbopack, rollup) inline\n// based on the consumer's NODE_ENV. Without this, the published bundle bakes\n// in `true` and dev-mode validation runs in every consumer's production\n// build — a real footgun the v1.5/v1.6 release hit.\nexport default typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\";\n","/**\n * Adapter Type Utilities - Shared types and helpers for framework adapters\n *\n * These utilities reduce type assertions in adapters by providing:\n * - Schema composition types\n * - Constraint/resolver converters\n * - Plugin factory helpers\n */\n\nimport type { Facts } from \"./facts.js\";\nimport type { Plugin } from \"./plugins.js\";\nimport type { ConstraintDef, Requirement } from \"./requirements.js\";\nimport type { ResolverContext, ResolverDef } from \"./resolvers.js\";\nimport type { InferSchema, Schema } from \"./schema.js\";\n\n// ============================================================================\n// Schema Composition Types\n// ============================================================================\n\n/**\n * Merge two schemas into one.\n * Useful for adapters that add bridge-specific facts to user schemas.\n *\n * @example\n * ```typescript\n * type BridgeFields = { __state: SchemaType<Record<string, unknown>> };\n * type Combined = MergedSchema<UserSchema, BridgeFields>;\n * ```\n */\nexport type MergedSchema<Base extends Schema, Extra extends Schema> = Base &\n Extra;\n\n/**\n * Create a schema type from a fields definition.\n * Helper for defining adapter bridge schemas.\n *\n * @example\n * ```typescript\n * type AdapterBridgeSchema = BridgeSchema<{\n * __adapterState: SchemaType<Record<string, unknown>>;\n * }>;\n * ```\n */\nexport type BridgeSchema<Fields extends Schema> = Fields;\n\n// ============================================================================\n// Bridge Schema Helper\n// ============================================================================\n\n/**\n * Create a bridge schema definition for adapters.\n * Returns a schema object compatible with createModule().\n *\n * @example\n * ```typescript\n * const bridgeSchema = createBridgeSchema({\n * __state: t.object<Record<string, unknown>>(),\n * });\n * ```\n */\nexport function createBridgeSchema<S extends Schema>(schema: S): S {\n return schema;\n}\n\n// ============================================================================\n// Type-Safe Fact Mutation\n// ============================================================================\n\n/**\n * Type-safe fact setter for known schema keys.\n * Use when you have a typed schema and want to set a specific fact.\n *\n * @example\n * ```typescript\n * setFact(facts, \"count\", 10); // Type-checked\n * ```\n */\nexport function setFact<S extends Schema, K extends keyof InferSchema<S>>(\n facts: Facts<S>,\n key: K,\n value: InferSchema<S>[K],\n): void {\n (facts as Record<string, unknown>)[key as string] = value;\n}\n\n/**\n * Set a bridge fact without strict typing.\n * Use for adapter-internal bridge fields like `__adapterState`.\n *\n * @example\n * ```typescript\n * setBridgeFact(facts, \"__adapterState\", currentState);\n * ```\n */\nexport function setBridgeFact<V>(\n facts: Facts<Schema>,\n key: string,\n value: V,\n): void {\n (facts as Record<string, unknown>)[key] = value;\n}\n\n/**\n * Get a bridge fact without strict typing.\n * Use for adapter-internal bridge fields.\n *\n * @example\n * ```typescript\n * const state = getBridgeFact<MyState>(facts, \"__adapterState\");\n * ```\n */\nexport function getBridgeFact<V>(facts: Facts<Schema>, key: string): V {\n return (facts as Record<string, unknown>)[key] as V;\n}\n\n// ============================================================================\n// Constraint Converters\n// ============================================================================\n\n/**\n * Adapter constraint definition (generic form used by adapters).\n */\nexport interface AdapterConstraint<TState> {\n when: (state: TState) => boolean | Promise<boolean>;\n require: Requirement | ((state: TState) => Requirement | null);\n priority?: number;\n}\n\n/**\n * Convert adapter-style constraints to Directive format.\n * Maps adapter constraints that work with external state (TState) to\n * Directive constraints that work with Facts<Schema>.\n *\n * @param constraints - Adapter constraints keyed by name\n * @param extractState - Function to extract adapter state from facts\n *\n * @example\n * ```typescript\n * const directiveConstraints = convertConstraints<MyState, BridgeSchema>(\n * adapterConstraints,\n * (facts) => getBridgeFact<MyState>(facts, \"__state\"),\n * );\n * ```\n */\nexport function convertConstraints<TState, S extends Schema>(\n constraints: Record<string, AdapterConstraint<TState>>,\n extractState: (facts: Facts<S>) => TState,\n): Record<string, ConstraintDef<S, Requirement>> {\n const result: Record<string, ConstraintDef<S, Requirement>> = {};\n\n for (const [id, constraint] of Object.entries(constraints)) {\n result[id] = {\n priority: constraint.priority ?? 0,\n when: (facts) => constraint.when(extractState(facts)),\n require: (facts) => {\n const req =\n typeof constraint.require === \"function\"\n ? constraint.require(extractState(facts))\n : constraint.require;\n return req;\n },\n };\n }\n\n return result;\n}\n\n// ============================================================================\n// Resolver Converters\n// ============================================================================\n\n/**\n * Adapter resolver context (generic form used by adapters).\n */\nexport interface AdapterResolverContext<TContext> {\n context: TContext;\n signal: AbortSignal;\n}\n\n/**\n * Adapter resolver definition (generic form used by adapters).\n */\nexport interface AdapterResolver<\n TContext,\n R extends Requirement = Requirement,\n> {\n requirement: (req: Requirement) => req is R;\n key?: (req: R) => string;\n resolve: (\n req: R,\n ctx: AdapterResolverContext<TContext>,\n ) => void | Promise<void>;\n}\n\n/**\n * Convert adapter-style resolvers to Directive format.\n * Maps adapter resolvers that work with external context (TContext) to\n * Directive resolvers that work with ResolverContext<Schema>.\n *\n * @param resolvers - Adapter resolvers keyed by name\n * @param createContext - Function to create adapter context from Directive context\n *\n * @example\n * ```typescript\n * const directiveResolvers = convertResolvers<MyContext, BridgeSchema>(\n * adapterResolvers,\n * (ctx) => ({\n * getState: () => getBridgeFact<MyState>(ctx.facts, \"__state\"),\n * setState: (update) => setBridgeFact(ctx.facts, \"__state\", update),\n * signal: ctx.signal,\n * }),\n * );\n * ```\n */\nexport function convertResolvers<TContext, S extends Schema>(\n resolvers: Record<string, AdapterResolver<TContext, Requirement>>,\n createContext: (ctx: ResolverContext<S>) => TContext,\n): Record<string, ResolverDef<S, Requirement>> {\n const result: Record<string, ResolverDef<S, Requirement>> = {};\n\n for (const [id, resolver] of Object.entries(resolvers)) {\n result[id] = {\n requirement: resolver.requirement,\n key: resolver.key,\n resolve: async (req, ctx) => {\n const adapterCtx = createContext(ctx);\n await resolver.resolve(req, {\n context: adapterCtx,\n signal: ctx.signal,\n });\n },\n };\n }\n\n return result;\n}\n\n// ============================================================================\n// Plugin Factory\n// ============================================================================\n\n/**\n * Callback definitions for adapter plugins.\n */\nexport interface AdapterCallbacks {\n onRequirementCreated?: (req: Requirement) => void;\n onRequirementResolved?: (req: Requirement) => void;\n onError?: (error: Error) => void;\n}\n\n/**\n * Create a callback plugin for adapter events.\n * Wraps adapter callbacks in a Directive plugin.\n *\n * @param name - Plugin name (for debugging)\n * @param callbacks - Callback functions to invoke\n *\n * @example\n * ```typescript\n * const callbackPlugin = createCallbackPlugin(\"adapter-callbacks\", {\n * onRequirementCreated: (req) => console.log(\"Created:\", req),\n * onRequirementResolved: (req) => console.log(\"Resolved:\", req),\n * });\n * ```\n */\n// biome-ignore lint/suspicious/noExplicitAny: Plugins work with any schema type\nexport function createCallbackPlugin(\n name: string,\n callbacks: AdapterCallbacks,\n): Plugin<any> {\n return {\n name,\n onRequirementCreated: callbacks.onRequirementCreated\n ? (req) => callbacks.onRequirementCreated!(req.requirement)\n : undefined,\n onRequirementMet: callbacks.onRequirementResolved\n ? (req) => callbacks.onRequirementResolved!(req.requirement)\n : undefined,\n onError: callbacks.onError,\n };\n}\n\n// ============================================================================\n// Module Config Helpers\n// ============================================================================\n\n/**\n * Cast constraints to the correct type for createModule.\n * Use this when TypeScript can't infer the constraint types correctly.\n */\nexport function asConstraints<S extends Schema>(\n constraints: Record<string, ConstraintDef<S, Requirement>>,\n): Record<string, ConstraintDef<S, Requirement>> {\n return constraints;\n}\n\n/**\n * Cast resolvers to the correct type for createModule.\n * Use this when TypeScript can't infer the resolver types correctly.\n */\nexport function asResolvers<S extends Schema>(\n resolvers: Record<string, ResolverDef<S, Requirement>>,\n): Record<string, ResolverDef<S, Requirement>> {\n return resolvers;\n}\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Create a type guard for a specific requirement type.\n * Simplifies the common pattern of checking req.type.\n *\n * @example\n * ```typescript\n * const isResetReq = requirementGuard<ResetReq>(\"RESET\");\n * // Use in resolver:\n * { requirement: isResetReq, resolve: ... }\n * ```\n */\nexport function requirementGuard<R extends Requirement>(\n type: R[\"type\"],\n): (req: Requirement) => req is R {\n return (req): req is R => req.type === type;\n}\n\n/**\n * Create a type guard that matches multiple requirement types.\n *\n * @example\n * ```typescript\n * const isDataReq = requirementGuardMultiple<FetchReq | RefreshReq>([\"FETCH\", \"REFRESH\"]);\n * ```\n */\nexport function requirementGuardMultiple<R extends Requirement>(\n types: Array<R[\"type\"]>,\n): (req: Requirement) => req is R {\n const typeSet = new Set(types);\n return (req): req is R => typeSet.has(req.type);\n}\n","/**\n * Dependency tracking context for auto-tracking derivations\n *\n * Uses a stack-based approach to handle nested derivation computations.\n * When a derivation accesses a fact, the tracking context records it.\n */\n\n/** Stack of active dependency sets (bare Sets for zero-allocation hot path) */\nconst depStack: Set<string>[] = [];\n\n/**\n * Get the current dependency set, or null if not tracking.\n *\n * @returns The active dependency Set, or `null` if no tracking is active.\n *\n * @internal\n */\nexport function getCurrentDeps(): Set<string> | null {\n const len = depStack.length;\n return len === 0 ? null : depStack[len - 1]!;\n}\n\n/**\n * Check if dependency tracking is currently active.\n *\n * @returns `true` if inside a {@link withTracking} call, `false` otherwise.\n *\n * @internal\n */\nexport function isTracking(): boolean {\n return depStack.length > 0;\n}\n\n/**\n * Run a function with dependency tracking.\n *\n * @remarks\n * Pushes a fresh Set onto the stack, executes `fn`, then pops it.\n * Any fact reads inside `fn` are recorded as dependencies.\n * Nesting is supported — inner calls get their own independent Set.\n *\n * @param fn - The function to execute under tracking.\n * @returns An object with the computed `value` and a `deps` Set of accessed\n * fact keys.\n *\n * @internal\n */\nexport function withTracking<T>(fn: () => T): { value: T; deps: Set<string> } {\n const deps = new Set<string>();\n depStack.push(deps);\n\n try {\n const value = fn();\n return { value, deps };\n } finally {\n depStack.pop();\n }\n}\n\n/**\n * Run a function without tracking.\n *\n * @remarks\n * Temporarily clears the tracking stack so that fact reads inside `fn` do\n * not register as dependencies. The stack is restored after `fn` returns\n * (even on error). Useful for side-effect reads that should not trigger\n * derivation invalidation.\n *\n * @param fn - The function to execute without tracking.\n * @returns The return value of `fn`.\n *\n * @internal\n */\nexport function withoutTracking<T>(fn: () => T): T {\n const saved = depStack.splice(0, depStack.length);\n\n try {\n return fn();\n } finally {\n for (const ctx of saved) {\n depStack.push(ctx);\n }\n }\n}\n\n/**\n * Track a specific key in the current context.\n *\n * @remarks\n * No-op if no tracking context is active.\n *\n * @param key - The fact key to record as a dependency.\n *\n * @internal\n */\nexport function trackAccess(key: string): void {\n const len = depStack.length;\n if (len === 0) {\n return;\n }\n depStack[len - 1]!.add(key);\n}\n\n/**\n * Prototype pollution guard — shared across all proxy handlers.\n *\n * @remarks\n * Contains `__proto__`, `constructor`, and `prototype`. Every proxy `get`\n * and `has` trap checks this set and returns `undefined` / `false` for\n * matching keys, preventing prototype pollution via proxy-based objects.\n *\n * @internal\n */\nexport const BLOCKED_PROPS: ReadonlySet<string> = Object.freeze(\n new Set([\"__proto__\", \"constructor\", \"prototype\"]),\n);\n\n// ============================================================================\n// Non-JSON value-type detection (MIGRATION_FEEDBACK item 20)\n// ============================================================================\n\n/**\n * Detect whether `value` is a non-JSON-roundtrippable type whose mutations\n * the facts proxy cannot track for reactivity.\n *\n * Returns the kind label (`\"Date\"`, `\"Set\"`, `\"Map\"`, `\"File\"`, or\n * `\"ClassInstance\"`) when one is detected, or `null` for plain objects,\n * arrays, primitives, and `null`/`undefined`.\n *\n * The `File` check is SSR-safe: if the runtime has no `File` global the\n * branch is skipped without throwing.\n *\n * The `ClassInstance` check fires for any object whose prototype is not\n * `Object.prototype` and which is not an array — e.g. instances of user\n * classes whose mutations bypass reactivity.\n *\n * @internal\n */\nexport function detectNonJsonValueType(value: unknown): string | null {\n if (value === null || typeof value !== \"object\") {\n return null;\n }\n if (value instanceof Date) {\n return \"Date\";\n }\n if (value instanceof Set) {\n return \"Set\";\n }\n if (value instanceof Map) {\n return \"Map\";\n }\n if (typeof File !== \"undefined\" && value instanceof File) {\n return \"File\";\n }\n // Plain objects and arrays are JSON-friendly.\n if (Array.isArray(value)) {\n return null;\n }\n // Class instances: prototype is not Object.prototype.\n // Plain `{}` literals have prototype `Object.prototype`; objects created\n // via `Object.create(null)` have a `null` prototype which we treat as\n // \"plain\" (it's still JSON-roundtrippable).\n const proto = Object.getPrototypeOf(value);\n if (proto !== null && proto !== Object.prototype) {\n return \"ClassInstance\";\n }\n\n return null;\n}\n\n/**\n * Per-(path, valueType) dedupe cache — once a warning fires for a given\n * combo we never re-emit. Keeps the dev console quiet under loops that\n * assign the same Date 100 times in a row.\n *\n * @internal\n */\nconst nonJsonWarningCache = new Set<string>();\n\nconst nonJsonHints: Record<string, string> = {\n Date: \".getTime() for timestamps\",\n Set: \"[...set] for arrays\",\n Map: \"Object.fromEntries(map) for plain objects\",\n File: \"{ name, size, type, lastModified } for metadata\",\n ClassInstance: \"a plain-object snapshot\",\n};\n\n/**\n * Emit a one-time dev-mode warning when a non-JSON value is assigned to a\n * fact. Called from the proxy `set` traps in both `createFactsProxy`\n * (single-module / standalone facts) and `createModuleFactsProxy`\n * (system-namespaced facts). No-ops in production builds — the call sites\n * are gated on `isDevelopment` so this entire helper is tree-shakable.\n *\n * @param factPath - Display path for the warning (e.g. `auth.token` or\n * bare `token` for non-namespaced stores).\n * @param valueType - The label returned from {@link detectNonJsonValueType}.\n *\n * @internal\n */\nexport function warnNonJsonFactAssignment(\n factPath: string,\n valueType: string,\n): void {\n const cacheKey = `${factPath}|${valueType}`;\n if (nonJsonWarningCache.has(cacheKey)) {\n return;\n }\n nonJsonWarningCache.add(cacheKey);\n\n const hint = nonJsonHints[valueType] ?? \"a JSON-roundtrippable value\";\n console.warn(\n `[Directive] Fact \"${factPath}\" assigned a ${valueType} instance.\\n` +\n `Facts must be JSON-roundtrippable for reactivity to work correctly.\\n` +\n `${valueType} mutations are not tracked.\\n` +\n `Use ${hint} instead.\\n` +\n `See: https://directive.run/docs/facts#json-rule`,\n );\n}\n\n/**\n * Reset the warning dedupe cache. Test-only — exported via internals for\n * vitest spec setup. Not part of the public API.\n *\n * @internal\n */\nexport function _resetNonJsonWarningCache(): void {\n nonJsonWarningCache.clear();\n}\n"]}
import { a8 as Schema, c as Facts, b as FactPredicate, aS as InferSchema, F as FactTemplate, D as DefinitionMeta, t as Requirement, b9 as RequirementOutput, a7 as RetryPolicy, B as BatchConfig, b0 as ResolverContext } from './plugins-Ykl_sAPE.js';
/**
* Derivation Types - Type definitions for derivations
*/
/** Derivation definition function signature. */
interface DerivationDef<S extends Schema, T, D extends DerivationsDef<S>> {
(facts: Facts<S>, derived: DerivedValues<S, D>): T;
}
/**
* Derivation definition with metadata (object form).
* Use this when you want to attach debugging metadata to a derivation.
*
* @example
* ```typescript
* derive: {
* displayName: {
* compute: (facts) => `${facts.firstName} ${facts.lastName}`,
* meta: { label: "Display Name", description: "Full name for UI" },
* },
* },
* ```
*/
interface DerivationDefWithMeta<S extends Schema, T, D extends DerivationsDef<S>> {
/**
* The derivation body. Either:
* - a function `(facts, derived) => T` (original form), or
* - a {@link FactPredicate} data spec — boolean derivations only, or
* - a {@link FactTemplate} `{ $template: "..." }` — string derivations only.
*
* Data forms are normalized to a wrapper function at registration; the
* wrapper reads through the facts proxy so existing auto-tracking
* captures dependencies.
*/
compute: DerivationDef<S, T, D> | ([T] extends [boolean] ? FactPredicate<InferSchema<S>> : never) | ([T] extends [string] ? FactTemplate : never);
meta?: DefinitionMeta;
}
/** Map of derivation definitions (internal — always bare functions after unwrap). */
type DerivationsDef<S extends Schema> = Record<string, DerivationDef<S, unknown, DerivationsDef<S>>>;
/** Computed derived values. */
type DerivedValues<S extends Schema, D extends DerivationsDef<S>> = {
readonly [K in keyof D]: ReturnType<D[K]>;
};
/** Internal derivation state */
interface DerivationState<T> {
id: string;
compute: () => T;
cachedValue: T | undefined;
dependencies: Set<string>;
isStale: boolean;
isComputing: boolean;
/** Consecutive runs producing the same deps (auto-tracked only) */
stableRunCount: number;
/** Once true, skip withTracking() overhead until a tracked fact mutates */
depsStable: boolean;
}
/**
* Type Helpers - External typed constraint and resolver definitions
*
* These types enable defining constraints and resolvers with full type safety
* outside of module definitions, while maintaining proper type inference.
*/
/**
* External constraint definition with full typing.
* Use this when defining constraints outside of createModule().
*
* @typeParam S - The schema type
* @typeParam R - The requirement type (defaults to Requirement)
*
* @example
* ```typescript
* // Define a typed constraint factory
* const createMaxCountConstraint = <S extends Schema>(
* maxCount: number
* ): TypedConstraint<S, { type: "RESET_COUNT" }> => ({
* priority: 10,
* when: (facts) => (facts as { count: number }).count > maxCount,
* require: { type: "RESET_COUNT" },
* });
*
* // Use in module
* const module = createModule("counter", {
* schema: { count: t.number() },
* constraints: {
* maxCount: createMaxCountConstraint(100),
* },
* });
* ```
*/
interface TypedConstraint<S extends Schema, R extends Requirement = Requirement> {
/** Priority for ordering (higher runs first) */
priority?: number;
/** Mark this constraint as async (avoids runtime detection) */
async?: boolean;
/** Condition function (sync or async) */
when: (facts: Facts<S>) => boolean | Promise<boolean>;
/**
* Requirement(s) to produce when condition is met.
*/
require: RequirementOutput<R> | ((facts: Facts<S>) => RequirementOutput<R>);
/** Timeout for async constraints (ms) */
timeout?: number;
/**
* Constraint IDs whose resolvers must complete before this constraint is evaluated.
* - If dependency's `when()` returns false, this constraint proceeds (nothing to wait for)
* - If dependency's resolver fails, this constraint remains blocked until it succeeds
* - Cross-module: use the constraint ID as it appears in the merged system
*/
after?: string[];
}
/**
* External resolver definition with full typing.
* Use this when defining resolvers outside of createModule().
*
* @typeParam S - The schema type
* @typeParam R - The requirement type (defaults to Requirement)
*
* @example
* ```typescript
* // Define a typed resolver factory
* interface FetchUserReq extends Requirement {
* type: "FETCH_USER";
* userId: string;
* }
*
* const createFetchUserResolver = <S extends Schema>(
* fetchFn: (userId: string) => Promise<User>
* ): TypedResolver<S, FetchUserReq> => ({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* key: (req) => `fetch-user-${req.userId}`,
* retry: { attempts: 3, backoff: "exponential" },
* resolve: async (req, ctx) => {
* const user = await fetchFn(req.userId);
* (ctx.facts as { user: User }).user = user;
* },
* });
* ```
*/
interface TypedResolver<S extends Schema, R extends Requirement = Requirement> {
/**
* Requirement type to handle.
* - String: matches `req.type` directly (e.g., `requirement: "FETCH_USER"`)
* - Function: type guard predicate (e.g., `requirement: (req) => req.type === "FETCH_USER"`)
*/
requirement: R["type"] | ((req: Requirement) => req is R);
/** Custom key function for deduplication */
key?: (req: R) => string;
/** Retry policy */
retry?: RetryPolicy;
/** Timeout for resolver execution (ms) */
timeout?: number;
/** Batch configuration */
batch?: BatchConfig;
/** Resolve function for single requirement */
resolve?: (req: R, ctx: ResolverContext<S>) => Promise<void>;
/** Resolve function for batched requirements */
resolveBatch?: (reqs: R[], ctx: ResolverContext<S>) => Promise<void>;
}
/**
* Create a typed constraint factory for a specific schema.
* This enables creating reusable constraint definitions with proper typing.
*
* @example
* ```typescript
* const schema = { count: t.number(), threshold: t.number() };
* const factory = createConstraintFactory<typeof schema>();
*
* const maxCountConstraint = factory.create({
* when: (facts) => facts.count > facts.threshold,
* require: { type: "RESET" },
* });
* ```
*/
declare function createConstraintFactory<S extends Schema>(): {
/**
* Create a typed constraint
*/
create<R extends Requirement = Requirement>(constraint: TypedConstraint<S, R>): TypedConstraint<S, R>;
};
/**
* Create a typed resolver factory for a specific schema.
* This enables creating reusable resolver definitions with proper typing.
*
* @example
* ```typescript
* const schema = { user: t.object<User>() };
* const factory = createResolverFactory<typeof schema>();
*
* const fetchUserResolver = factory.create<FetchUserReq>({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* resolve: async (req, ctx) => {
* ctx.facts.user = await fetchUser(req.userId);
* },
* });
* ```
*/
declare function createResolverFactory<S extends Schema>(): {
/**
* Create a typed resolver
*/
create<R extends Requirement = Requirement>(resolver: TypedResolver<S, R>): TypedResolver<S, R>;
};
/**
* Type-safe constraint creator.
* Simpler alternative to createConstraintFactory when you don't need a factory pattern.
*
* @example
* ```typescript
* const constraint = typedConstraint<typeof schema, { type: "RESET" }>({
* when: (facts) => facts.count > 100,
* require: { type: "RESET" },
* });
* ```
*/
declare function typedConstraint<S extends Schema, R extends Requirement = Requirement>(constraint: TypedConstraint<S, R>): TypedConstraint<S, R>;
/**
* Type-safe resolver creator.
* Simpler alternative to createResolverFactory when you don't need a factory pattern.
*
* @example
* ```typescript
* const resolver = typedResolver<typeof schema, FetchUserReq>({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* resolve: async (req, ctx) => {
* ctx.facts.user = await fetchUser(req.userId);
* },
* });
* ```
*/
declare function typedResolver<S extends Schema, R extends Requirement = Requirement>(resolver: TypedResolver<S, R>): TypedResolver<S, R>;
export { type DerivationDefWithMeta as D, type TypedConstraint as T, typedResolver as a, type DerivationsDef as b, type DerivedValues as c, type DerivationState as d, type TypedResolver as e, createConstraintFactory as f, createResolverFactory as g, typedConstraint as t };
import { a8 as Schema, c as Facts, b as FactPredicate, aS as InferSchema, F as FactTemplate, D as DefinitionMeta, t as Requirement, b9 as RequirementOutput, a7 as RetryPolicy, B as BatchConfig, b0 as ResolverContext } from './plugins-Ykl_sAPE.cjs';
/**
* Derivation Types - Type definitions for derivations
*/
/** Derivation definition function signature. */
interface DerivationDef<S extends Schema, T, D extends DerivationsDef<S>> {
(facts: Facts<S>, derived: DerivedValues<S, D>): T;
}
/**
* Derivation definition with metadata (object form).
* Use this when you want to attach debugging metadata to a derivation.
*
* @example
* ```typescript
* derive: {
* displayName: {
* compute: (facts) => `${facts.firstName} ${facts.lastName}`,
* meta: { label: "Display Name", description: "Full name for UI" },
* },
* },
* ```
*/
interface DerivationDefWithMeta<S extends Schema, T, D extends DerivationsDef<S>> {
/**
* The derivation body. Either:
* - a function `(facts, derived) => T` (original form), or
* - a {@link FactPredicate} data spec — boolean derivations only, or
* - a {@link FactTemplate} `{ $template: "..." }` — string derivations only.
*
* Data forms are normalized to a wrapper function at registration; the
* wrapper reads through the facts proxy so existing auto-tracking
* captures dependencies.
*/
compute: DerivationDef<S, T, D> | ([T] extends [boolean] ? FactPredicate<InferSchema<S>> : never) | ([T] extends [string] ? FactTemplate : never);
meta?: DefinitionMeta;
}
/** Map of derivation definitions (internal — always bare functions after unwrap). */
type DerivationsDef<S extends Schema> = Record<string, DerivationDef<S, unknown, DerivationsDef<S>>>;
/** Computed derived values. */
type DerivedValues<S extends Schema, D extends DerivationsDef<S>> = {
readonly [K in keyof D]: ReturnType<D[K]>;
};
/** Internal derivation state */
interface DerivationState<T> {
id: string;
compute: () => T;
cachedValue: T | undefined;
dependencies: Set<string>;
isStale: boolean;
isComputing: boolean;
/** Consecutive runs producing the same deps (auto-tracked only) */
stableRunCount: number;
/** Once true, skip withTracking() overhead until a tracked fact mutates */
depsStable: boolean;
}
/**
* Type Helpers - External typed constraint and resolver definitions
*
* These types enable defining constraints and resolvers with full type safety
* outside of module definitions, while maintaining proper type inference.
*/
/**
* External constraint definition with full typing.
* Use this when defining constraints outside of createModule().
*
* @typeParam S - The schema type
* @typeParam R - The requirement type (defaults to Requirement)
*
* @example
* ```typescript
* // Define a typed constraint factory
* const createMaxCountConstraint = <S extends Schema>(
* maxCount: number
* ): TypedConstraint<S, { type: "RESET_COUNT" }> => ({
* priority: 10,
* when: (facts) => (facts as { count: number }).count > maxCount,
* require: { type: "RESET_COUNT" },
* });
*
* // Use in module
* const module = createModule("counter", {
* schema: { count: t.number() },
* constraints: {
* maxCount: createMaxCountConstraint(100),
* },
* });
* ```
*/
interface TypedConstraint<S extends Schema, R extends Requirement = Requirement> {
/** Priority for ordering (higher runs first) */
priority?: number;
/** Mark this constraint as async (avoids runtime detection) */
async?: boolean;
/** Condition function (sync or async) */
when: (facts: Facts<S>) => boolean | Promise<boolean>;
/**
* Requirement(s) to produce when condition is met.
*/
require: RequirementOutput<R> | ((facts: Facts<S>) => RequirementOutput<R>);
/** Timeout for async constraints (ms) */
timeout?: number;
/**
* Constraint IDs whose resolvers must complete before this constraint is evaluated.
* - If dependency's `when()` returns false, this constraint proceeds (nothing to wait for)
* - If dependency's resolver fails, this constraint remains blocked until it succeeds
* - Cross-module: use the constraint ID as it appears in the merged system
*/
after?: string[];
}
/**
* External resolver definition with full typing.
* Use this when defining resolvers outside of createModule().
*
* @typeParam S - The schema type
* @typeParam R - The requirement type (defaults to Requirement)
*
* @example
* ```typescript
* // Define a typed resolver factory
* interface FetchUserReq extends Requirement {
* type: "FETCH_USER";
* userId: string;
* }
*
* const createFetchUserResolver = <S extends Schema>(
* fetchFn: (userId: string) => Promise<User>
* ): TypedResolver<S, FetchUserReq> => ({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* key: (req) => `fetch-user-${req.userId}`,
* retry: { attempts: 3, backoff: "exponential" },
* resolve: async (req, ctx) => {
* const user = await fetchFn(req.userId);
* (ctx.facts as { user: User }).user = user;
* },
* });
* ```
*/
interface TypedResolver<S extends Schema, R extends Requirement = Requirement> {
/**
* Requirement type to handle.
* - String: matches `req.type` directly (e.g., `requirement: "FETCH_USER"`)
* - Function: type guard predicate (e.g., `requirement: (req) => req.type === "FETCH_USER"`)
*/
requirement: R["type"] | ((req: Requirement) => req is R);
/** Custom key function for deduplication */
key?: (req: R) => string;
/** Retry policy */
retry?: RetryPolicy;
/** Timeout for resolver execution (ms) */
timeout?: number;
/** Batch configuration */
batch?: BatchConfig;
/** Resolve function for single requirement */
resolve?: (req: R, ctx: ResolverContext<S>) => Promise<void>;
/** Resolve function for batched requirements */
resolveBatch?: (reqs: R[], ctx: ResolverContext<S>) => Promise<void>;
}
/**
* Create a typed constraint factory for a specific schema.
* This enables creating reusable constraint definitions with proper typing.
*
* @example
* ```typescript
* const schema = { count: t.number(), threshold: t.number() };
* const factory = createConstraintFactory<typeof schema>();
*
* const maxCountConstraint = factory.create({
* when: (facts) => facts.count > facts.threshold,
* require: { type: "RESET" },
* });
* ```
*/
declare function createConstraintFactory<S extends Schema>(): {
/**
* Create a typed constraint
*/
create<R extends Requirement = Requirement>(constraint: TypedConstraint<S, R>): TypedConstraint<S, R>;
};
/**
* Create a typed resolver factory for a specific schema.
* This enables creating reusable resolver definitions with proper typing.
*
* @example
* ```typescript
* const schema = { user: t.object<User>() };
* const factory = createResolverFactory<typeof schema>();
*
* const fetchUserResolver = factory.create<FetchUserReq>({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* resolve: async (req, ctx) => {
* ctx.facts.user = await fetchUser(req.userId);
* },
* });
* ```
*/
declare function createResolverFactory<S extends Schema>(): {
/**
* Create a typed resolver
*/
create<R extends Requirement = Requirement>(resolver: TypedResolver<S, R>): TypedResolver<S, R>;
};
/**
* Type-safe constraint creator.
* Simpler alternative to createConstraintFactory when you don't need a factory pattern.
*
* @example
* ```typescript
* const constraint = typedConstraint<typeof schema, { type: "RESET" }>({
* when: (facts) => facts.count > 100,
* require: { type: "RESET" },
* });
* ```
*/
declare function typedConstraint<S extends Schema, R extends Requirement = Requirement>(constraint: TypedConstraint<S, R>): TypedConstraint<S, R>;
/**
* Type-safe resolver creator.
* Simpler alternative to createResolverFactory when you don't need a factory pattern.
*
* @example
* ```typescript
* const resolver = typedResolver<typeof schema, FetchUserReq>({
* requirement: (req): req is FetchUserReq => req.type === "FETCH_USER",
* resolve: async (req, ctx) => {
* ctx.facts.user = await fetchUser(req.userId);
* },
* });
* ```
*/
declare function typedResolver<S extends Schema, R extends Requirement = Requirement>(resolver: TypedResolver<S, R>): TypedResolver<S, R>;
export { type DerivationDefWithMeta as D, type TypedConstraint as T, typedResolver as a, type DerivationsDef as b, type DerivedValues as c, type DerivationState as d, type TypedResolver as e, createConstraintFactory as f, createResolverFactory as g, typedConstraint as t };

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

'use strict';var chunkEX3XG667_cjs=require('./chunk-EX3XG667.cjs');require('./chunk-7NMXRATK.cjs'),require('./chunk-N4KTCKOI.cjs'),require('./chunk-EOLY64E6.cjs');Object.defineProperty(exports,"createSystem",{enumerable:true,get:function(){return chunkEX3XG667_cjs.a}});//# sourceMappingURL=system-GK3NSFQH.cjs.map
//# sourceMappingURL=system-GK3NSFQH.cjs.map
{"version":3,"sources":[],"names":[],"mappings":"","file":"system-GK3NSFQH.cjs"}
export{a as createSystem}from'./chunk-26Z5VNPZ.js';import'./chunk-TPOKS4RY.js';import'./chunk-TZHC4E6S.js';import'./chunk-T6IJUWYR.js';//# sourceMappingURL=system-VZWB6WXX.js.map
//# sourceMappingURL=system-VZWB6WXX.js.map
{"version":3,"sources":[],"names":[],"mappings":"","file":"system-VZWB6WXX.js"}
/**
* Shallow equality comparison for objects.
* Used by React hooks to avoid unnecessary re-renders.
*
* @param a - First object
* @param b - Second object
* @returns True if objects are shallowly equal
*/
declare function shallowEqual<T extends Record<string, unknown>>(a: T, b: T): boolean;
/**
* Distributable snapshot type for type-safe helper functions.
*/
interface DistributableSnapshotLike<T = Record<string, unknown>> {
data: T;
createdAt: number;
expiresAt?: number;
version?: string;
metadata?: Record<string, unknown>;
}
/**
* Check if a distributable snapshot has expired.
* Returns false if the snapshot has no expiresAt field.
*
* @example
* ```typescript
* const snapshot = system.getDistributableSnapshot({ ttlSeconds: 3600 });
* // ... later ...
* if (isSnapshotExpired(snapshot)) {
* // Refresh the snapshot
* }
* ```
*
* @param snapshot - The snapshot to check
* @param now - Optional current timestamp (defaults to Date.now())
* @returns True if the snapshot has expired, false otherwise
*/
declare function isSnapshotExpired<T>(snapshot: DistributableSnapshotLike<T>, now?: number): boolean;
/**
* Validate a distributable snapshot and return its data.
* Throws if the snapshot is malformed or has expired.
*
* @example
* ```typescript
* const cached = JSON.parse(await redis.get(`entitlements:${userId}`));
* try {
* const data = validateSnapshot(cached);
* // Use data.canUseFeature, etc.
* } catch (e) {
* // Snapshot invalid or expired, refresh it
* }
* ```
*
* @example Using custom timestamp for testing
* ```typescript
* const snapshot = { data: { test: true }, createdAt: 1000, expiresAt: 2000 };
* validateSnapshot(snapshot, 1500); // Returns { test: true }
* validateSnapshot(snapshot, 2500); // Throws: Snapshot expired
* ```
*
* @param snapshot - The snapshot to validate
* @param now - Optional current timestamp (defaults to Date.now())
* @returns The snapshot data if valid
* @throws Error if the snapshot is malformed or has expired
*/
declare function validateSnapshot<T>(snapshot: DistributableSnapshotLike<T>, now?: number): T;
/**
* Diff result for a single changed value.
*/
interface SnapshotDiffEntry {
/** The key path that changed (e.g., "canUseApi" or "limits.apiCalls") */
path: string;
/** The value in the old snapshot */
oldValue: unknown;
/** The value in the new snapshot */
newValue: unknown;
/** Type of change: "added", "removed", or "changed" */
type: "added" | "removed" | "changed";
}
/**
* Result of diffing two snapshots.
*/
interface SnapshotDiff {
/** Whether the snapshots are identical */
identical: boolean;
/** List of changes between snapshots */
changes: SnapshotDiffEntry[];
/** Whether the version changed (if both have versions) */
versionChanged: boolean;
/** Old version (if available) */
oldVersion?: string;
/** New version (if available) */
newVersion?: string;
}
/**
* Compare two distributable snapshots and return the differences.
* Useful for debugging, audit logs, and webhook payloads.
*
* @example
* ```typescript
* const oldSnapshot = system.getDistributableSnapshot({ includeVersion: true });
* system.dispatch({ type: "upgradePlan", plan: "pro" });
* const newSnapshot = system.getDistributableSnapshot({ includeVersion: true });
*
* const diff = diffSnapshots(oldSnapshot, newSnapshot);
* if (!diff.identical) {
* console.log("Changes:", diff.changes);
* // [{ path: "canUseApi", oldValue: false, newValue: true, type: "changed" }]
* }
* ```
*
* @param oldSnapshot - The previous snapshot
* @param newSnapshot - The new snapshot
* @returns A diff result with all changes
*/
declare function diffSnapshots<T = Record<string, unknown>>(oldSnapshot: DistributableSnapshotLike<T>, newSnapshot: DistributableSnapshotLike<T>): SnapshotDiff;
/**
* A signed distributable snapshot.
* Contains the original snapshot plus a cryptographic signature.
*/
interface SignedSnapshot<T = Record<string, unknown>> extends DistributableSnapshotLike<T> {
/** HMAC-SHA256 signature in hex format */
signature: string;
/** Signing algorithm used */
algorithm: "hmac-sha256";
}
/**
* Check if a snapshot is signed.
*
* @param snapshot - The snapshot to check
* @returns True if the snapshot has a signature
*/
declare function isSignedSnapshot<T>(snapshot: DistributableSnapshotLike<T> | SignedSnapshot<T>): snapshot is SignedSnapshot<T>;
/**
* Sign a distributable snapshot using HMAC-SHA256.
* Creates a tamper-proof signature that can be verified later.
*
* **Security Notes:**
* - Use a cryptographically random secret of at least 32 bytes
* - Store the secret securely (environment variable, secrets manager)
* - Never expose the secret to clients
* - The signature covers all snapshot fields for integrity
*
* @example
* ```typescript
* const snapshot = system.getDistributableSnapshot({
* includeDerivations: ['canUseFeature', 'limits'],
* ttlSeconds: 3600,
* });
*
* // Sign the snapshot (server-side only)
* const signed = await signSnapshot(snapshot, process.env.SNAPSHOT_SECRET);
*
* // Store in JWT, Redis, or send to client
* const jwt = createJWT({ snapshot: signed });
*
* // Later, verify the signature
* const isValid = await verifySnapshotSignature(signed, process.env.SNAPSHOT_SECRET);
* if (!isValid) {
* throw new Error('Snapshot has been tampered with');
* }
* ```
*
* @param snapshot - The snapshot to sign
* @param secret - The HMAC secret (string or Uint8Array)
* @returns A signed snapshot with the signature attached
*/
declare function signSnapshot<T>(snapshot: DistributableSnapshotLike<T>, secret: string | Uint8Array): Promise<SignedSnapshot<T>>;
/**
* Verify the signature of a signed snapshot.
* Returns true if the signature is valid, false otherwise.
*
* **Important:** Always verify signatures before trusting snapshot data,
* especially if the snapshot was received from an untrusted source (client, cache).
*
* @example
* ```typescript
* // Receive signed snapshot from client or cache
* const snapshot = JSON.parse(cachedData);
*
* // Verify before using
* const isValid = await verifySnapshotSignature(snapshot, process.env.SNAPSHOT_SECRET);
* if (!isValid) {
* throw new Error('Invalid snapshot signature - possible tampering');
* }
*
* // Now safe to use snapshot.data
* if (snapshot.data.canUseFeature.api) {
* // Grant access
* }
* ```
*
* @param signedSnapshot - The signed snapshot to verify
* @param secret - The HMAC secret (must match the signing secret)
* @returns True if signature is valid, false otherwise
*/
declare function verifySnapshotSignature<T>(signedSnapshot: SignedSnapshot<T>, secret: string | Uint8Array): Promise<boolean>;
/**
* Safely stringify any value for display. Handles circular references,
* BigInt, throwing toJSON, and optional truncation.
*
* This is the canonical implementation – all packages should import this
* instead of maintaining local copies.
*/
declare function safeStringify(data: unknown, maxLen?: number): string;
export { type DistributableSnapshotLike as D, type SignedSnapshot as S, type SnapshotDiff as a, type SnapshotDiffEntry as b, isSnapshotExpired as c, diffSnapshots as d, signSnapshot as e, verifySnapshotSignature as f, safeStringify as g, isSignedSnapshot as i, shallowEqual as s, validateSnapshot as v };
/**
* Shallow equality comparison for objects.
* Used by React hooks to avoid unnecessary re-renders.
*
* @param a - First object
* @param b - Second object
* @returns True if objects are shallowly equal
*/
declare function shallowEqual<T extends Record<string, unknown>>(a: T, b: T): boolean;
/**
* Distributable snapshot type for type-safe helper functions.
*/
interface DistributableSnapshotLike<T = Record<string, unknown>> {
data: T;
createdAt: number;
expiresAt?: number;
version?: string;
metadata?: Record<string, unknown>;
}
/**
* Check if a distributable snapshot has expired.
* Returns false if the snapshot has no expiresAt field.
*
* @example
* ```typescript
* const snapshot = system.getDistributableSnapshot({ ttlSeconds: 3600 });
* // ... later ...
* if (isSnapshotExpired(snapshot)) {
* // Refresh the snapshot
* }
* ```
*
* @param snapshot - The snapshot to check
* @param now - Optional current timestamp (defaults to Date.now())
* @returns True if the snapshot has expired, false otherwise
*/
declare function isSnapshotExpired<T>(snapshot: DistributableSnapshotLike<T>, now?: number): boolean;
/**
* Validate a distributable snapshot and return its data.
* Throws if the snapshot is malformed or has expired.
*
* @example
* ```typescript
* const cached = JSON.parse(await redis.get(`entitlements:${userId}`));
* try {
* const data = validateSnapshot(cached);
* // Use data.canUseFeature, etc.
* } catch (e) {
* // Snapshot invalid or expired, refresh it
* }
* ```
*
* @example Using custom timestamp for testing
* ```typescript
* const snapshot = { data: { test: true }, createdAt: 1000, expiresAt: 2000 };
* validateSnapshot(snapshot, 1500); // Returns { test: true }
* validateSnapshot(snapshot, 2500); // Throws: Snapshot expired
* ```
*
* @param snapshot - The snapshot to validate
* @param now - Optional current timestamp (defaults to Date.now())
* @returns The snapshot data if valid
* @throws Error if the snapshot is malformed or has expired
*/
declare function validateSnapshot<T>(snapshot: DistributableSnapshotLike<T>, now?: number): T;
/**
* Diff result for a single changed value.
*/
interface SnapshotDiffEntry {
/** The key path that changed (e.g., "canUseApi" or "limits.apiCalls") */
path: string;
/** The value in the old snapshot */
oldValue: unknown;
/** The value in the new snapshot */
newValue: unknown;
/** Type of change: "added", "removed", or "changed" */
type: "added" | "removed" | "changed";
}
/**
* Result of diffing two snapshots.
*/
interface SnapshotDiff {
/** Whether the snapshots are identical */
identical: boolean;
/** List of changes between snapshots */
changes: SnapshotDiffEntry[];
/** Whether the version changed (if both have versions) */
versionChanged: boolean;
/** Old version (if available) */
oldVersion?: string;
/** New version (if available) */
newVersion?: string;
}
/**
* Compare two distributable snapshots and return the differences.
* Useful for debugging, audit logs, and webhook payloads.
*
* @example
* ```typescript
* const oldSnapshot = system.getDistributableSnapshot({ includeVersion: true });
* system.dispatch({ type: "upgradePlan", plan: "pro" });
* const newSnapshot = system.getDistributableSnapshot({ includeVersion: true });
*
* const diff = diffSnapshots(oldSnapshot, newSnapshot);
* if (!diff.identical) {
* console.log("Changes:", diff.changes);
* // [{ path: "canUseApi", oldValue: false, newValue: true, type: "changed" }]
* }
* ```
*
* @param oldSnapshot - The previous snapshot
* @param newSnapshot - The new snapshot
* @returns A diff result with all changes
*/
declare function diffSnapshots<T = Record<string, unknown>>(oldSnapshot: DistributableSnapshotLike<T>, newSnapshot: DistributableSnapshotLike<T>): SnapshotDiff;
/**
* A signed distributable snapshot.
* Contains the original snapshot plus a cryptographic signature.
*/
interface SignedSnapshot<T = Record<string, unknown>> extends DistributableSnapshotLike<T> {
/** HMAC-SHA256 signature in hex format */
signature: string;
/** Signing algorithm used */
algorithm: "hmac-sha256";
}
/**
* Check if a snapshot is signed.
*
* @param snapshot - The snapshot to check
* @returns True if the snapshot has a signature
*/
declare function isSignedSnapshot<T>(snapshot: DistributableSnapshotLike<T> | SignedSnapshot<T>): snapshot is SignedSnapshot<T>;
/**
* Sign a distributable snapshot using HMAC-SHA256.
* Creates a tamper-proof signature that can be verified later.
*
* **Security Notes:**
* - Use a cryptographically random secret of at least 32 bytes
* - Store the secret securely (environment variable, secrets manager)
* - Never expose the secret to clients
* - The signature covers all snapshot fields for integrity
*
* @example
* ```typescript
* const snapshot = system.getDistributableSnapshot({
* includeDerivations: ['canUseFeature', 'limits'],
* ttlSeconds: 3600,
* });
*
* // Sign the snapshot (server-side only)
* const signed = await signSnapshot(snapshot, process.env.SNAPSHOT_SECRET);
*
* // Store in JWT, Redis, or send to client
* const jwt = createJWT({ snapshot: signed });
*
* // Later, verify the signature
* const isValid = await verifySnapshotSignature(signed, process.env.SNAPSHOT_SECRET);
* if (!isValid) {
* throw new Error('Snapshot has been tampered with');
* }
* ```
*
* @param snapshot - The snapshot to sign
* @param secret - The HMAC secret (string or Uint8Array)
* @returns A signed snapshot with the signature attached
*/
declare function signSnapshot<T>(snapshot: DistributableSnapshotLike<T>, secret: string | Uint8Array): Promise<SignedSnapshot<T>>;
/**
* Verify the signature of a signed snapshot.
* Returns true if the signature is valid, false otherwise.
*
* **Important:** Always verify signatures before trusting snapshot data,
* especially if the snapshot was received from an untrusted source (client, cache).
*
* @example
* ```typescript
* // Receive signed snapshot from client or cache
* const snapshot = JSON.parse(cachedData);
*
* // Verify before using
* const isValid = await verifySnapshotSignature(snapshot, process.env.SNAPSHOT_SECRET);
* if (!isValid) {
* throw new Error('Invalid snapshot signature - possible tampering');
* }
*
* // Now safe to use snapshot.data
* if (snapshot.data.canUseFeature.api) {
* // Grant access
* }
* ```
*
* @param signedSnapshot - The signed snapshot to verify
* @param secret - The HMAC secret (must match the signing secret)
* @returns True if signature is valid, false otherwise
*/
declare function verifySnapshotSignature<T>(signedSnapshot: SignedSnapshot<T>, secret: string | Uint8Array): Promise<boolean>;
/**
* Safely stringify any value for display. Handles circular references,
* BigInt, throwing toJSON, and optional truncation.
*
* This is the canonical implementation – all packages should import this
* instead of maintaining local copies.
*/
declare function safeStringify(data: unknown, maxLen?: number): string;
export { type DistributableSnapshotLike as D, type SignedSnapshot as S, type SnapshotDiff as a, type SnapshotDiffEntry as b, isSnapshotExpired as c, diffSnapshots as d, signSnapshot as e, verifySnapshotSignature as f, safeStringify as g, isSignedSnapshot as i, shallowEqual as s, validateSnapshot as v };

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display