@lssm/example.personalization 0.0.0-canary-20251217080011 → 0.0.0-canary-20251219202229

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.turbo/turbo-build$colon$bundle.log +143 -96
  2. package/.turbo/turbo-build.log +144 -20
  3. package/CHANGELOG.md +7 -7
  4. package/LICENSE +21 -0
  5. package/dist/behavior-tracking.d.ts +2 -1
  6. package/dist/behavior-tracking.d.ts.map +1 -0
  7. package/dist/behavior-tracking.js +2 -1
  8. package/dist/behavior-tracking.js.map +1 -0
  9. package/dist/docs/personalization.docblock.js +2 -1
  10. package/dist/docs/personalization.docblock.js.map +1 -0
  11. package/dist/example.d.ts +2 -1
  12. package/dist/example.d.ts.map +1 -0
  13. package/dist/example.js +2 -1
  14. package/dist/example.js.map +1 -0
  15. package/dist/libs/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js +2 -1
  16. package/dist/libs/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js.map +1 -0
  17. package/dist/libs/contracts/dist/docs/index.js +2 -6
  18. package/dist/libs/contracts/dist/docs/meta.docs.js +30 -0
  19. package/dist/libs/contracts/dist/docs/meta.docs.js.map +1 -0
  20. package/dist/libs/contracts/dist/docs/presentations.js +2 -1
  21. package/dist/libs/contracts/dist/docs/presentations.js.map +1 -0
  22. package/dist/libs/contracts/dist/docs/registry.js +2 -1
  23. package/dist/libs/contracts/dist/docs/registry.js.map +1 -0
  24. package/dist/libs/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js +2 -1
  25. package/dist/libs/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js.map +1 -0
  26. package/dist/libs/contracts/dist/docs/tech/contracts/openapi-export.docblock.js +2 -1
  27. package/dist/libs/contracts/dist/docs/tech/contracts/openapi-export.docblock.js.map +1 -0
  28. package/dist/libs/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js +2 -1
  29. package/dist/libs/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js.map +1 -0
  30. package/dist/libs/contracts/dist/docs/tech/llm/llm-integration.docblock.js +2 -1
  31. package/dist/libs/contracts/dist/docs/tech/llm/llm-integration.docblock.js.map +1 -0
  32. package/dist/libs/contracts/dist/docs/tech/mcp-endpoints.docblock.js +2 -1
  33. package/dist/libs/contracts/dist/docs/tech/mcp-endpoints.docblock.js.map +1 -0
  34. package/dist/libs/contracts/dist/docs/tech/presentation-runtime.docblock.js +2 -1
  35. package/dist/libs/contracts/dist/docs/tech/presentation-runtime.docblock.js.map +1 -0
  36. package/dist/libs/contracts/dist/docs/tech/schema/README.docblock.js +2 -1
  37. package/dist/libs/contracts/dist/docs/tech/schema/README.docblock.js.map +1 -0
  38. package/dist/libs/contracts/dist/docs/tech/studio/learning-events.docblock.js +2 -1
  39. package/dist/libs/contracts/dist/docs/tech/studio/learning-events.docblock.js.map +1 -0
  40. package/dist/libs/contracts/dist/docs/tech/studio/learning-journeys.docblock.js +2 -1
  41. package/dist/libs/contracts/dist/docs/tech/studio/learning-journeys.docblock.js.map +1 -0
  42. package/dist/libs/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js +2 -1
  43. package/dist/libs/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js.map +1 -0
  44. package/dist/libs/contracts/dist/docs/tech/studio/project-access-teams.docblock.js +2 -1
  45. package/dist/libs/contracts/dist/docs/tech/studio/project-access-teams.docblock.js.map +1 -0
  46. package/dist/libs/contracts/dist/docs/tech/studio/project-routing.docblock.js +2 -1
  47. package/dist/libs/contracts/dist/docs/tech/studio/project-routing.docblock.js.map +1 -0
  48. package/dist/libs/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js +2 -1
  49. package/dist/libs/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js.map +1 -0
  50. package/dist/libs/contracts/dist/docs/tech/studio/team-invitations.docblock.js +2 -1
  51. package/dist/libs/contracts/dist/docs/tech/studio/team-invitations.docblock.js.map +1 -0
  52. package/dist/libs/contracts/dist/docs/tech/studio/workspace-ops.docblock.js +2 -1
  53. package/dist/libs/contracts/dist/docs/tech/studio/workspace-ops.docblock.js.map +1 -0
  54. package/dist/libs/contracts/dist/docs/tech/studio/workspaces.docblock.js +2 -1
  55. package/dist/libs/contracts/dist/docs/tech/studio/workspaces.docblock.js.map +1 -0
  56. package/dist/libs/contracts/dist/docs/tech/telemetry-ingest.docblock.js +2 -1
  57. package/dist/libs/contracts/dist/docs/tech/telemetry-ingest.docblock.js.map +1 -0
  58. package/dist/libs/contracts/dist/docs/tech/templates/runtime.docblock.js +2 -1
  59. package/dist/libs/contracts/dist/docs/tech/templates/runtime.docblock.js.map +1 -0
  60. package/dist/libs/contracts/dist/docs/tech/vscode-extension.docblock.js +2 -1
  61. package/dist/libs/contracts/dist/docs/tech/vscode-extension.docblock.js.map +1 -0
  62. package/dist/libs/contracts/dist/docs/tech/workflows/overview.docblock.js +2 -1
  63. package/dist/libs/contracts/dist/docs/tech/workflows/overview.docblock.js.map +1 -0
  64. package/dist/libs/contracts/dist/docs/tech-contracts.docs.js +97 -0
  65. package/dist/libs/contracts/dist/docs/tech-contracts.docs.js.map +1 -0
  66. package/dist/libs/logger/dist/context.node.js +2 -1
  67. package/dist/libs/logger/dist/context.node.js.map +1 -0
  68. package/dist/libs/logger/dist/formatters.js +2 -1
  69. package/dist/libs/logger/dist/formatters.js.map +1 -0
  70. package/dist/libs/logger/dist/logger.node.js +2 -1
  71. package/dist/libs/logger/dist/logger.node.js.map +1 -0
  72. package/dist/libs/logger/dist/timer.js +2 -1
  73. package/dist/libs/logger/dist/timer.js.map +1 -0
  74. package/dist/libs/logger/dist/tracer.node.js +2 -1
  75. package/dist/libs/logger/dist/tracer.node.js.map +1 -0
  76. package/dist/libs/logger/dist/types.js +2 -1
  77. package/dist/libs/logger/dist/types.js.map +1 -0
  78. package/dist/libs/overlay-engine/dist/merger.js +2 -1
  79. package/dist/libs/overlay-engine/dist/merger.js.map +1 -0
  80. package/dist/libs/overlay-engine/dist/registry.js +2 -1
  81. package/dist/libs/overlay-engine/dist/registry.js.map +1 -0
  82. package/dist/libs/overlay-engine/dist/runtime.js +2 -1
  83. package/dist/libs/overlay-engine/dist/runtime.js.map +1 -0
  84. package/dist/libs/overlay-engine/dist/signer.js +2 -1
  85. package/dist/libs/overlay-engine/dist/signer.js.map +1 -0
  86. package/dist/libs/overlay-engine/dist/spec.js +2 -1
  87. package/dist/libs/overlay-engine/dist/spec.js.map +1 -0
  88. package/dist/libs/overlay-engine/dist/validator.js +2 -1
  89. package/dist/libs/overlay-engine/dist/validator.js.map +1 -0
  90. package/dist/libs/personalization/dist/analyzer.js +2 -1
  91. package/dist/libs/personalization/dist/analyzer.js.map +1 -0
  92. package/dist/libs/personalization/dist/store.js +2 -1
  93. package/dist/libs/personalization/dist/store.js.map +1 -0
  94. package/dist/libs/personalization/dist/tracker.js +2 -1
  95. package/dist/libs/personalization/dist/tracker.js.map +1 -0
  96. package/dist/libs/workflow-composer/dist/composer.js +2 -1
  97. package/dist/libs/workflow-composer/dist/composer.js.map +1 -0
  98. package/dist/libs/workflow-composer/dist/injector.js +2 -1
  99. package/dist/libs/workflow-composer/dist/injector.js.map +1 -0
  100. package/dist/libs/workflow-composer/dist/validator.js +2 -1
  101. package/dist/libs/workflow-composer/dist/validator.js.map +1 -0
  102. package/dist/overlay-customization.d.ts +2 -1
  103. package/dist/overlay-customization.d.ts.map +1 -0
  104. package/dist/overlay-customization.js +2 -1
  105. package/dist/overlay-customization.js.map +1 -0
  106. package/dist/workflow-extension.d.ts +2 -1
  107. package/dist/workflow-extension.d.ts.map +1 -0
  108. package/dist/workflow-extension.js +2 -1
  109. package/dist/workflow-extension.js.map +1 -0
  110. package/package.json +12 -11
  111. package/tsconfig.tsbuildinfo +1 -1
  112. package/dist/libs/contracts/dist/docs/PUBLISHING.docblock.js +0 -16
  113. package/dist/libs/contracts/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js +0 -16
  114. package/dist/libs/contracts/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +0 -16
  115. package/dist/libs/contracts/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +0 -16
  116. package/dist/libs/contracts/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +0 -16
  117. package/dist/libs/contracts/dist/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +0 -16
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vscode-extension.docblock.js","names":[],"sources":["../../../../../../../../libs/contracts/dist/docs/tech/vscode-extension.docblock.js"],"sourcesContent":["import { registerDocBlocks } from \"../registry.js\";\n\n//#region src/docs/tech/vscode-extension.docblock.ts\nconst tech_vscode_extension_DocBlocks = [{\n\tid: \"docs.tech.vscode.extension\",\n\ttitle: \"ContractSpec VS Code Extension\",\n\tsummary: \"VS Code extension for spec-first development with validation, scaffolding, and MCP integration.\",\n\tkind: \"reference\",\n\tvisibility: \"public\",\n\troute: \"/docs/tech/vscode/extension\",\n\ttags: [\n\t\t\"vscode\",\n\t\t\"extension\",\n\t\t\"tooling\",\n\t\t\"dx\"\n\t],\n\tbody: `# ContractSpec VS Code Extension\n\nThe ContractSpec VS Code extension provides spec-first development tooling directly in your editor.\n\n## Features\n\n- **Real-time Validation**: Get instant feedback on spec errors and warnings as you save files\n- **Build/Scaffold**: Generate handler and component skeletons from specs (no AI required)\n- **Spec Explorer**: List and navigate all specs in your workspace\n- **Dependency Analysis**: Visualize spec dependencies and detect cycles\n- **MCP Integration**: Search ContractSpec documentation via Model Context Protocol\n- **Snippets**: Code snippets for common ContractSpec patterns\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| \\`ContractSpec: Validate Current Spec\\` | Validate the currently open spec file |\n| \\`ContractSpec: Validate All Specs\\` | Validate all spec files in the workspace |\n| \\`ContractSpec: Build/Scaffold\\` | Generate handler/component from the current spec |\n| \\`ContractSpec: List All Specs\\` | Show all specs in the workspace |\n| \\`ContractSpec: Analyze Dependencies\\` | Analyze and visualize spec dependencies |\n| \\`ContractSpec: Search Docs (MCP)\\` | Search documentation via MCP |\n\n## Configuration\n\n| Setting | Description | Default |\n|---------|-------------|---------|\n| \\`contractspec.api.baseUrl\\` | Base URL for ContractSpec API (enables MCP + remote telemetry) | \\`\"\"\\` |\n| \\`contractspec.telemetry.posthogHost\\` | PostHog host URL for direct telemetry | \\`\"https://eu.posthog.com\"\\` |\n| \\`contractspec.telemetry.posthogProjectKey\\` | PostHog project key for direct telemetry | \\`\"\"\\` |\n| \\`contractspec.validation.onSave\\` | Run validation on save | \\`true\\` |\n| \\`contractspec.validation.onOpen\\` | Run validation on open | \\`true\\` |\n\n## Architecture\n\nThe extension uses:\n- \\`@lssm/module.contractspec-workspace\\` for pure analysis + templates\n- \\`@lssm/bundle.contractspec-workspace\\` for workspace services + adapters\n\nThis allows the extension to work without requiring the CLI to be installed.\n\n## Telemetry\n\nThe extension uses a hybrid telemetry approach:\n1. If \\`contractspec.api.baseUrl\\` is configured → send to API \\`/api/telemetry/ingest\\`\n2. Otherwise → send directly to PostHog (if project key configured)\n\nTelemetry respects VS Code's telemetry settings. No file paths, source code, or PII is collected.\n`\n}, {\n\tid: \"docs.tech.vscode.snippets\",\n\ttitle: \"ContractSpec Snippets\",\n\tsummary: \"Code snippets for common ContractSpec patterns in VS Code.\",\n\tkind: \"reference\",\n\tvisibility: \"public\",\n\troute: \"/docs/tech/vscode/snippets\",\n\ttags: [\n\t\t\"vscode\",\n\t\t\"snippets\",\n\t\t\"dx\"\n\t],\n\tbody: `# ContractSpec Snippets\n\nThe VS Code extension includes snippets for common ContractSpec patterns.\n\n## Available Snippets\n\n| Prefix | Description |\n|--------|-------------|\n| \\`contractspec-command\\` | Create a new command (write operation) |\n| \\`contractspec-query\\` | Create a new query (read-only operation) |\n| \\`contractspec-event\\` | Create a new event |\n| \\`contractspec-docblock\\` | Create a new DocBlock |\n| \\`contractspec-telemetry\\` | Create a new TelemetrySpec |\n| \\`contractspec-presentation\\` | Create a new Presentation |\n\n## Usage\n\nType the prefix in a TypeScript file and press Tab to expand the snippet. Tab through the placeholders to fill in your values.\n`\n}];\nregisterDocBlocks(tech_vscode_extension_DocBlocks);\n\n//#endregion\nexport { tech_vscode_extension_DocBlocks };\n//# sourceMappingURL=vscode-extension.docblock.js.map"],"mappings":";;;AAGA,MAAM,kCAAkC,CAAC;CACxC,IAAI;CACJ,OAAO;CACP,SAAS;CACT,MAAM;CACN,YAAY;CACZ,OAAO;CACP,MAAM;EACL;EACA;EACA;EACA;EACA;CACD,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDN,EAAE;CACF,IAAI;CACJ,OAAO;CACP,SAAS;CACT,MAAM;CACN,YAAY;CACZ,OAAO;CACP,MAAM;EACL;EACA;EACA;EACA;CACD,MAAM;;;;;;;;;;;;;;;;;;;CAmBN,CAAC;AACF,kBAAkB,gCAAgC"}
@@ -17,4 +17,5 @@ const tech_workflows_overview_DocBlocks = [{
17
17
  }];
18
18
  registerDocBlocks(tech_workflows_overview_DocBlocks);
19
19
 
20
- //#endregion
20
+ //#endregion
21
+ //# sourceMappingURL=overview.docblock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overview.docblock.js","names":[],"sources":["../../../../../../../../../libs/contracts/dist/docs/tech/workflows/overview.docblock.js"],"sourcesContent":["import { registerDocBlocks } from \"../../registry.js\";\n\n//#region src/docs/tech/workflows/overview.docblock.ts\nconst tech_workflows_overview_DocBlocks = [{\n\tid: \"docs.tech.workflows.overview\",\n\ttitle: \"WorkflowSpec Overview\",\n\tsummary: \"WorkflowSpec provides a declarative, versioned format for long-running flows that mix automation and human review. Specs stay inside `@lssm/lib.contracts` (`src/workflow/spec.ts`) so the same definition powers runtime execution, documentation, and future generation.\",\n\tkind: \"reference\",\n\tvisibility: \"public\",\n\troute: \"/docs/tech/workflows/overview\",\n\ttags: [\n\t\t\"tech\",\n\t\t\"workflows\",\n\t\t\"overview\"\n\t],\n\tbody: \"# WorkflowSpec Overview\\n\\n## Purpose\\n\\nWorkflowSpec provides a declarative, versioned format for long-running flows that mix automation and human review. Specs stay inside `@lssm/lib.contracts` (`src/workflow/spec.ts`) so the same definition powers runtime execution, documentation, and future generation.\\n\\n## Core Types\\n\\n- `WorkflowMeta`: ownership metadata (`title`, `domain`, `owners`, `tags`, `stability`) plus `name` and `version`.\\n- `WorkflowDefinition`:\\n - `entryStepId?`: optional explicit entry point (defaults to first step).\\n - `steps[]`: ordered list of `Step` descriptors.\\n - `transitions[]`: directed edges between steps with optional expressions.\\n - `sla?`: aggregated timing hints for the overall flow or per-step budgets.\\n - `compensation?`: fallback operations executed when a workflow is rolled back or fails.\\n- `Step`:\\n - `type`: `human`, `automation`, or `decision`.\\n - `action`: references either a `ContractSpec` (`operation`) or `FormSpec` (`form`).\\n - Optional `guard`, `timeoutMs`, and retry policy (`maxAttempts`, `backoff`, `delayMs`, `maxDelayMs?`).\\n - `requiredIntegrations?`: integration slot ids that must be bound before the step may execute.\\n - `requiredCapabilities?`: `CapabilityRef[]` that must be enabled in the resolved app config.\\n- `Transition`: `from` → `to` with optional `condition` string (simple data expressions).\\n\\n## Registry & Validation\\n\\n- `WorkflowRegistry` (`src/workflow/spec.ts`) stores specs by key `<name>.v<version>` and exposes `register`, `list`, and `get`.\\n- `validateWorkflowSpec()` (`src/workflow/validation.ts`) checks:\\n - Duplicate step IDs.\\n - Unknown `from`/`to` transitions.\\n - Empty guards/conditions.\\n - Reachability from the entry step.\\n - Cycles in the graph.\\n - Operation/Form references against provided registries.\\n- `assertWorkflowSpecValid()` wraps validation and throws `WorkflowValidationError` when errors remain.\\n\\n## Runtime\\n\\n- `WorkflowRunner` (`src/workflow/runner.ts`) executes workflows and coordinates steps.\\n - `start(name, version?, initialData?)` returns a `workflowId`.\\n - `executeStep(workflowId, input?)` runs the current step (automation or human).\\n - `getState(workflowId)` retrieves the latest state snapshot.\\n - `cancel(workflowId)` marks the workflow as cancelled.\\n - `preFlightCheck(name, version?, resolvedConfig?)` evaluates integration/capability requirements before the workflow starts.\\n - Throws `WorkflowPreFlightError` if required integration slots are unbound or required capabilities are disabled.\\n- `StateStore` (`src/workflow/state.ts`) abstracts persistence. V1 ships with:\\n - `InMemoryStateStore` (`src/workflow/adapters/memory-store.ts`) for tests/dev.\\n - Placeholder factories for file/database adapters (`adapters/file-adapter.ts`, `adapters/db-adapter.ts`).\\n- Guard evaluation: expression guards run through `evaluateExpression()` (`src/workflow/expression.ts`); custom policy guards can be provided via `guardEvaluator`.\\n- Events: the runner emits `workflow.started`, `workflow.step_completed`, `workflow.step_failed`, and `workflow.cancelled` through the optional `eventEmitter`.\\n- React bindings (`@lssm/lib.presentation-runtime-react`):\\n - `useWorkflow` hook (polls state, exposes `executeStep`, `cancel`, `refresh`).\\n - `WorkflowStepper` progress indicator using design-system Stepper.\\n - `WorkflowStepRenderer` helper to render human/automation/decision steps with sensible fallbacks.\\n\\n## Authoring Checklist\\n\\n1. Reuse existing operations/forms; create new specs when missing.\\n2. Prefer explicit `entryStepId` for clarity (especially with decision branches).\\n3. Give automation steps an `operation` and human steps a `form` (warnings surface otherwise).\\n4. Use short, meaningful step IDs (`submit`, `review`, `finalize`) to simplify analytics.\\n5. Keep guard expressions deterministic; complex policy logic should move to PolicySpec (Phase 2).\\n\\n## Testing\\n\\n- Add unit tests for new workflows via `assertWorkflowSpecValid`.\\n- Use the new Vitest suites (`validation.test.ts`, `expression.test.ts`, `runner.test.ts`) as examples.\\n- CLI support will arrive in Phase 1 PR 3 (`contractspec create --type workflow`).\\n\\n## Tooling\\n\\n- `contractspec create --type workflow` scaffolds a WorkflowSpec with interactive prompts.\\n- `contractspec build <spec.workflow.ts>` generates a runner scaffold (`.runner.ts`) wired to `WorkflowRunner` and the in-memory store.\\n- `contractspec validate` understands `.workflow.ts` files and checks core structure (meta, steps, transitions).\\n\\n## Next Steps (Non-MVP)\\n\\n- Persistence adapters (database/file) for workflow state (Phase 2).\\n- React bindings (`useWorkflow`, `WorkflowStepper`) and presentation-runtime integration (PR 3).\\n- Policy engine integration (`guard.type === 'policy'` validated against PolicySpec).\\n- Telemetry hooks for step execution metrics.\\n\\n\"\n}];\nregisterDocBlocks(tech_workflows_overview_DocBlocks);\n\n//#endregion\nexport { tech_workflows_overview_DocBlocks };\n//# sourceMappingURL=overview.docblock.js.map"],"mappings":";;;AAGA,MAAM,oCAAoC,CAAC;CAC1C,IAAI;CACJ,OAAO;CACP,SAAS;CACT,MAAM;CACN,YAAY;CACZ,OAAO;CACP,MAAM;EACL;EACA;EACA;EACA;CACD,MAAM;CACN,CAAC;AACF,kBAAkB,kCAAkC"}
@@ -0,0 +1,97 @@
1
+ import { registerDocBlocks } from "./registry.js";
2
+
3
+ //#region ../../libs/contracts/dist/docs/tech-contracts.docs.js
4
+ const techContractsDocs = [{
5
+ id: "docs.tech.contracts.presentations-v2",
6
+ title: "Presentations V2 — Unified Descriptor & Transform Engine",
7
+ summary: "How PresentationDescriptorV2 and TransformEngine keep docs/renderers consistent.",
8
+ visibility: "public",
9
+ route: "/docs/tech/contracts/presentations-v2",
10
+ kind: "reference",
11
+ tags: [
12
+ "presentations",
13
+ "docs",
14
+ "mcp"
15
+ ],
16
+ body: `## Presentations V2 — Unified Descriptor & Transform Engine
17
+
18
+ ### Purpose
19
+
20
+ Unify presentations into one descriptor (\`PresentationDescriptorV2\`) that declares a single source (React component key or BlockNote doc) and a list of output targets (react, markdown, application/json, application/xml). A pluggable \`TransformEngine\` renders any target and applies PII redaction.
21
+
22
+ ### Types
23
+
24
+ \`\`\`ts
25
+ type PresentationTarget =
26
+ | 'react'
27
+ | 'markdown'
28
+ | 'application/json'
29
+ | 'application/xml';
30
+
31
+ type PresentationSource =
32
+ | {
33
+ type: 'component';
34
+ framework: 'react';
35
+ componentKey: string;
36
+ props?: AnySchemaModel;
37
+ }
38
+ | { type: 'blocknotejs'; docJson: unknown; blockConfig?: unknown };
39
+
40
+ interface PresentationDescriptorV2 {
41
+ meta: PresentationV2Meta; // includes partial OwnerShipMeta + description
42
+ policy?: { flags?: string[]; pii?: string[] };
43
+ source: PresentationSource;
44
+ targets: PresentationTarget[];
45
+ }
46
+
47
+ // Shared ownership schema (source of truth in @lssm/lib.contracts/src/ownership.ts)
48
+ interface OwnerShipMeta {
49
+ title: string;
50
+ description: string;
51
+ domain: string;
52
+ owners: Owner[];
53
+ tags: Tag[];
54
+ stability: Stability;
55
+ }
56
+
57
+ type Stability = 'experimental' | 'beta' | 'stable' | 'deprecated';
58
+ type Owner = string; // curated list available in code (e.g., '@sigil-team', 'team-strit')
59
+ type Tag = string; // curated list available in code (e.g., 'auth', 'spots')
60
+
61
+ // For V2 presentations, meta is a Partial<OwnerShipMeta> plus description, name, version
62
+ interface PresentationV2Meta extends Partial<OwnerShipMeta> {
63
+ name: string;
64
+ version: number;
65
+ description?: string;
66
+ }
67
+ \`\`\`
68
+
69
+ ### Engine
70
+
71
+ Use \`createDefaultTransformEngine()\` and register custom renderers as needed (e.g., high-fidelity BlockNote → Markdown). The default engine supports markdown/json/xml; a React renderer returns a serializable descriptor the host app renders via a \`componentMap\` or a BlockNote renderer. The canonical source type string is \`blocknotejs\` (not \`blocknote\`).
72
+
73
+ PII paths (JSON-like) are redacted from rendered outputs.
74
+
75
+ ### MCP Integration
76
+
77
+ \`createMcpServer\` accepts \`presentationsV2\`. Each descriptor is exposed under \`presentation://<name>/v<version>\` and negotiated variants (\`.md/.json/.xml\`) are rendered by the engine.
78
+
79
+ ### Migration
80
+
81
+ - V1 \`PresentationSpec\` remains supported; a back-compat helper converts V1 → V2 when convenient.
82
+ - Prefer V2 for new work.
83
+
84
+ ### Examples (Sigil)
85
+
86
+ - \`sigil.auth.webauth_tabs_v2\`: component source (\`componentKey: 'sigil.webauth.tabs'\`), targets \`react/json/xml\`.
87
+ - \`sigil.signup.guide_v2\`: BlockNote doc source, targets \`react/markdown/json/xml\`.
88
+
89
+ ### React Rendering
90
+
91
+ Host apps use a \`componentMap\` (e.g., \`'sigil.webauth.tabs' → WebAuthTabs\`) and a BlockNote renderer to turn the React render descriptor into elements.`
92
+ }];
93
+ registerDocBlocks(techContractsDocs);
94
+
95
+ //#endregion
96
+ export { techContractsDocs };
97
+ //# sourceMappingURL=tech-contracts.docs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tech-contracts.docs.js","names":[],"sources":["../../../../../../../libs/contracts/dist/docs/tech-contracts.docs.js"],"sourcesContent":["import { registerDocBlocks } from \"./registry.js\";\n\n//#region src/docs/tech-contracts.docs.ts\nconst techContractsDocs = [{\n\tid: \"docs.tech.contracts.presentations-v2\",\n\ttitle: \"Presentations V2 — Unified Descriptor & Transform Engine\",\n\tsummary: \"How PresentationDescriptorV2 and TransformEngine keep docs/renderers consistent.\",\n\tvisibility: \"public\",\n\troute: \"/docs/tech/contracts/presentations-v2\",\n\tkind: \"reference\",\n\ttags: [\n\t\t\"presentations\",\n\t\t\"docs\",\n\t\t\"mcp\"\n\t],\n\tbody: `## Presentations V2 — Unified Descriptor & Transform Engine\n\n### Purpose\n\nUnify presentations into one descriptor (\\`PresentationDescriptorV2\\`) that declares a single source (React component key or BlockNote doc) and a list of output targets (react, markdown, application/json, application/xml). A pluggable \\`TransformEngine\\` renders any target and applies PII redaction.\n\n### Types\n\n\\`\\`\\`ts\ntype PresentationTarget =\n | 'react'\n | 'markdown'\n | 'application/json'\n | 'application/xml';\n\ntype PresentationSource =\n | {\n type: 'component';\n framework: 'react';\n componentKey: string;\n props?: AnySchemaModel;\n }\n | { type: 'blocknotejs'; docJson: unknown; blockConfig?: unknown };\n\ninterface PresentationDescriptorV2 {\n meta: PresentationV2Meta; // includes partial OwnerShipMeta + description\n policy?: { flags?: string[]; pii?: string[] };\n source: PresentationSource;\n targets: PresentationTarget[];\n}\n\n// Shared ownership schema (source of truth in @lssm/lib.contracts/src/ownership.ts)\ninterface OwnerShipMeta {\n title: string;\n description: string;\n domain: string;\n owners: Owner[];\n tags: Tag[];\n stability: Stability;\n}\n\ntype Stability = 'experimental' | 'beta' | 'stable' | 'deprecated';\ntype Owner = string; // curated list available in code (e.g., '@sigil-team', 'team-strit')\ntype Tag = string; // curated list available in code (e.g., 'auth', 'spots')\n\n// For V2 presentations, meta is a Partial<OwnerShipMeta> plus description, name, version\ninterface PresentationV2Meta extends Partial<OwnerShipMeta> {\n name: string;\n version: number;\n description?: string;\n}\n\\`\\`\\`\n\n### Engine\n\nUse \\`createDefaultTransformEngine()\\` and register custom renderers as needed (e.g., high-fidelity BlockNote → Markdown). The default engine supports markdown/json/xml; a React renderer returns a serializable descriptor the host app renders via a \\`componentMap\\` or a BlockNote renderer. The canonical source type string is \\`blocknotejs\\` (not \\`blocknote\\`).\n\nPII paths (JSON-like) are redacted from rendered outputs.\n\n### MCP Integration\n\n\\`createMcpServer\\` accepts \\`presentationsV2\\`. Each descriptor is exposed under \\`presentation://<name>/v<version>\\` and negotiated variants (\\`.md/.json/.xml\\`) are rendered by the engine.\n\n### Migration\n\n- V1 \\`PresentationSpec\\` remains supported; a back-compat helper converts V1 → V2 when convenient.\n- Prefer V2 for new work.\n\n### Examples (Sigil)\n\n- \\`sigil.auth.webauth_tabs_v2\\`: component source (\\`componentKey: 'sigil.webauth.tabs'\\`), targets \\`react/json/xml\\`.\n- \\`sigil.signup.guide_v2\\`: BlockNote doc source, targets \\`react/markdown/json/xml\\`.\n\n### React Rendering\n\nHost apps use a \\`componentMap\\` (e.g., \\`'sigil.webauth.tabs' → WebAuthTabs\\`) and a BlockNote renderer to turn the React render descriptor into elements.`\n}];\nregisterDocBlocks(techContractsDocs);\n\n//#endregion\nexport { techContractsDocs };\n//# sourceMappingURL=tech-contracts.docs.js.map"],"mappings":";;;AAGA,MAAM,oBAAoB,CAAC;CAC1B,IAAI;CACJ,OAAO;CACP,SAAS;CACT,YAAY;CACZ,OAAO;CACP,MAAM;CACN,MAAM;EACL;EACA;EACA;EACA;CACD,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4EN,CAAC;AACF,kBAAkB,kBAAkB"}
@@ -75,4 +75,5 @@ var LogContext = class LogContext$1 {
75
75
  };
76
76
 
77
77
  //#endregion
78
- export { LogContext };
78
+ export { LogContext };
79
+ //# sourceMappingURL=context.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.node.js","names":["LogContext"],"sources":["../../../../../../libs/logger/dist/context.node.mjs"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\n//#region src/context.node.ts\n/**\n* Node.js implementation of LogContext using AsyncLocalStorage.\n*/\nvar LogContext = class LogContext {\n\tstatic instance;\n\tstorage;\n\tconstructor() {\n\t\tthis.storage = new AsyncLocalStorage();\n\t}\n\tstatic getInstance() {\n\t\tif (!LogContext.instance) LogContext.instance = new LogContext();\n\t\treturn LogContext.instance;\n\t}\n\t/**\n\t* Run a function with a new context\n\t*/\n\trun(context, fn) {\n\t\tconst contextData = {\n\t\t\tcontext: { ...context },\n\t\t\ttrace: this.getCurrentTrace()\n\t\t};\n\t\treturn this.storage.run(contextData, fn);\n\t}\n\t/**\n\t* Run a function with an extended context (merges with current)\n\t*/\n\textend(additionalContext, fn) {\n\t\tconst mergedContext = {\n\t\t\t...this.getContext(),\n\t\t\t...additionalContext\n\t\t};\n\t\treturn this.run(mergedContext, fn);\n\t}\n\t/**\n\t* Set context data for the current execution context\n\t*/\n\tset(key, value) {\n\t\tconst current = this.storage.getStore();\n\t\tif (current) current.context[key] = value;\n\t}\n\t/**\n\t* Get a specific context value\n\t*/\n\tget(key) {\n\t\treturn this.storage.getStore()?.context?.[key];\n\t}\n\t/**\n\t* Get all context data\n\t*/\n\tgetContext() {\n\t\treturn this.storage.getStore()?.context || {};\n\t}\n\t/**\n\t* Set trace context\n\t*/\n\tsetTrace(trace) {\n\t\tconst current = this.storage.getStore();\n\t\tif (current) current.trace = trace;\n\t}\n\t/**\n\t* Get current trace context\n\t*/\n\tgetCurrentTrace() {\n\t\treturn this.storage.getStore()?.trace;\n\t}\n\t/**\n\t* Generate a unique ID for requests/operations\n\t*/\n\tgenerateId() {\n\t\treturn crypto.randomUUID();\n\t}\n};\n\n//#endregion\nexport { LogContext };\n//# sourceMappingURL=context.node.mjs.map"],"mappings":";;;;;;AAMA,IAAI,aAAa,MAAMA,aAAW;CACjC,OAAO;CACP;CACA,cAAc;AACb,OAAK,UAAU,IAAI,mBAAmB;;CAEvC,OAAO,cAAc;AACpB,MAAI,CAACA,aAAW,SAAU,cAAW,WAAW,IAAIA,cAAY;AAChE,SAAOA,aAAW;;;;;CAKnB,IAAI,SAAS,IAAI;EAChB,MAAM,cAAc;GACnB,SAAS,EAAE,GAAG,SAAS;GACvB,OAAO,KAAK,iBAAiB;GAC7B;AACD,SAAO,KAAK,QAAQ,IAAI,aAAa,GAAG;;;;;CAKzC,OAAO,mBAAmB,IAAI;EAC7B,MAAM,gBAAgB;GACrB,GAAG,KAAK,YAAY;GACpB,GAAG;GACH;AACD,SAAO,KAAK,IAAI,eAAe,GAAG;;;;;CAKnC,IAAI,KAAK,OAAO;EACf,MAAM,UAAU,KAAK,QAAQ,UAAU;AACvC,MAAI,QAAS,SAAQ,QAAQ,OAAO;;;;;CAKrC,IAAI,KAAK;AACR,SAAO,KAAK,QAAQ,UAAU,EAAE,UAAU;;;;;CAK3C,aAAa;AACZ,SAAO,KAAK,QAAQ,UAAU,EAAE,WAAW,EAAE;;;;;CAK9C,SAAS,OAAO;EACf,MAAM,UAAU,KAAK,QAAQ,UAAU;AACvC,MAAI,QAAS,SAAQ,QAAQ;;;;;CAK9B,kBAAkB;AACjB,SAAO,KAAK,QAAQ,UAAU,EAAE;;;;;CAKjC,aAAa;AACZ,SAAO,OAAO,YAAY"}
@@ -160,4 +160,5 @@ var ProductionFormatter = class {
160
160
  };
161
161
 
162
162
  //#endregion
163
- export { DevFormatter, ProductionFormatter };
163
+ export { DevFormatter, ProductionFormatter };
164
+ //# sourceMappingURL=formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.js","names":[],"sources":["../../../../../../libs/logger/dist/formatters.mjs"],"sourcesContent":["import { LogLevel } from \"./types.mjs\";\n\n//#region src/formatters.ts\nconst colors = {\n\treset: \"\\x1B[0m\",\n\tbright: \"\\x1B[1m\",\n\tdim: \"\\x1B[2m\",\n\tred: \"\\x1B[31m\",\n\tgreen: \"\\x1B[32m\",\n\tyellow: \"\\x1B[33m\",\n\tblue: \"\\x1B[34m\",\n\tmagenta: \"\\x1B[35m\",\n\tcyan: \"\\x1B[36m\",\n\twhite: \"\\x1B[37m\",\n\tgray: \"\\x1B[90m\",\n\tbgRed: \"\\x1B[41m\",\n\tbgYellow: \"\\x1B[43m\"\n};\nconst levelConfig = {\n\t[LogLevel.TRACE]: {\n\t\tcolor: colors.gray,\n\t\tsymbol: \"○\",\n\t\tname: \"TRACE\"\n\t},\n\t[LogLevel.DEBUG]: {\n\t\tcolor: colors.blue,\n\t\tsymbol: \"●\",\n\t\tname: \"DEBUG\"\n\t},\n\t[LogLevel.INFO]: {\n\t\tcolor: colors.green,\n\t\tsymbol: \"●\",\n\t\tname: \"INFO \"\n\t},\n\t[LogLevel.WARN]: {\n\t\tcolor: colors.yellow,\n\t\tsymbol: \"▲\",\n\t\tname: \"WARN \"\n\t},\n\t[LogLevel.ERROR]: {\n\t\tcolor: colors.red,\n\t\tsymbol: \"✖\",\n\t\tname: \"ERROR\"\n\t},\n\t[LogLevel.FATAL]: {\n\t\tcolor: colors.bgRed + colors.white,\n\t\tsymbol: \"💀\",\n\t\tname: \"FATAL\"\n\t}\n};\nvar DevFormatter = class {\n\tenableColors;\n\tconstructor(enableColors = true) {\n\t\tthis.enableColors = enableColors;\n\t}\n\tformat(entry) {\n\t\tconst parts = [];\n\t\tconst config = levelConfig[entry.level];\n\t\tconst timestamp = this.formatTimestamp(entry.timestamp);\n\t\tparts.push(this.colorize(timestamp, colors.gray));\n\t\tconst levelText = `${config.symbol} ${config.name}`;\n\t\tparts.push(this.colorize(levelText, config.color));\n\t\tif (entry.traceId) {\n\t\t\tconst traceInfo = this.formatTraceInfo(entry);\n\t\t\tparts.push(this.colorize(traceInfo, colors.cyan));\n\t\t}\n\t\tparts.push(this.colorize(entry.message, colors.white));\n\t\tif (entry.duration !== void 0) {\n\t\t\tconst durationText = `(${this.formatDuration(entry.duration)})`;\n\t\t\tparts.push(this.colorize(durationText, colors.magenta));\n\t\t}\n\t\tlet output = parts.join(\" \");\n\t\tif (entry.context && Object.keys(entry.context).length > 0) output += \"\\n\" + this.formatContext(entry.context);\n\t\tif (entry.metadata && Object.keys(entry.metadata).length > 0) output += \"\\n\" + this.formatMetadata(entry.metadata);\n\t\tif (entry.error) output += \"\\n\" + this.formatError(entry.error);\n\t\tif (entry.tags && entry.tags.length > 0) {\n\t\t\tconst tagsText = entry.tags.map((tag) => `#${tag}`).join(\" \");\n\t\t\toutput += \"\\n\" + this.colorize(`Tags: ${tagsText}`, colors.blue);\n\t\t}\n\t\treturn output;\n\t}\n\tformatTimestamp(timestamp) {\n\t\treturn timestamp.toISOString().substring(11, 23);\n\t}\n\tformatTraceInfo(entry) {\n\t\tconst parts = [`trace:${entry.traceId?.substring(0, 8) || \"unknown\"}`];\n\t\tif (entry.spanId && entry.spanId.length >= 8) parts.push(`span:${entry.spanId.substring(0, 8)}`);\n\t\tif (entry.parentId && entry.parentId.length >= 8) parts.push(`parent:${entry.parentId.substring(0, 8)}`);\n\t\treturn `[${parts.join(\"|\")}]`;\n\t}\n\tformatDuration(duration) {\n\t\tif (duration < 1) return `${(duration * 1e3).toFixed(0)}μs`;\n\t\telse if (duration < 1e3) return `${duration.toFixed(2)}ms`;\n\t\telse return `${(duration / 1e3).toFixed(2)}s`;\n\t}\n\tformatContext(context) {\n\t\tconst formatted = this.formatObject(context, 2);\n\t\treturn this.colorize(`Context: ${formatted}`, colors.cyan);\n\t}\n\tformatMetadata(metadata) {\n\t\tconst formatted = this.formatObject(metadata, 2);\n\t\treturn this.colorize(`Metadata: ${formatted}`, colors.blue);\n\t}\n\tformatError(error) {\n\t\tlet output = this.colorize(`Error: ${error.name}: ${error.message}`, colors.red);\n\t\tif (error.stack) {\n\t\t\tconst indentedStack = error.stack.split(\"\\n\").slice(1, 6).map((line) => ` ${line}`).join(\"\\n\");\n\t\t\toutput += \"\\n\" + this.colorize(indentedStack, colors.gray);\n\t\t}\n\t\treturn output;\n\t}\n\tformatObject(obj, indent = 0) {\n\t\tconst spaces = \" \".repeat(indent);\n\t\tconst entries = Object.entries(obj);\n\t\tif (entries.length === 0) return \"{}\";\n\t\tif (entries[0] && typeof entries[0][1] !== \"object\") return `{ ${entries[0][0]}: ${this.formatValue(entries[0][1])} }`;\n\t\treturn `{\\n${entries.map(([key, value]) => {\n\t\t\treturn `${spaces} ${key}: ${this.formatValue(value, indent + 2)}`;\n\t\t}).join(\"\\n\")}\\n${spaces}}`;\n\t}\n\tformatValue(value, indent = 0) {\n\t\tif (value === null) return \"null\";\n\t\tif (value === void 0) return \"undefined\";\n\t\tif (typeof value === \"string\") return `\"${value}\"`;\n\t\tif (typeof value === \"boolean\" || typeof value === \"number\") return String(value);\n\t\tif (value instanceof Date) return value.toISOString();\n\t\tif (Array.isArray(value)) {\n\t\t\tif (value.length === 0) return \"[]\";\n\t\t\treturn `[${value.map((v) => this.formatValue(v)).join(\", \")}]`;\n\t\t}\n\t\tif (typeof value === \"object\") return this.formatObject(value, indent);\n\t\treturn String(value);\n\t}\n\tcolorize(text, color) {\n\t\tif (!this.enableColors) return text;\n\t\treturn `${color}${text}${colors.reset}`;\n\t}\n};\nvar ProductionFormatter = class {\n\tformat(entry) {\n\t\tconst logObject = {\n\t\t\ttimestamp: entry.timestamp,\n\t\t\tlevel: entry.level,\n\t\t\tmessage: entry.message\n\t\t};\n\t\tif (entry.traceId) logObject.traceId = entry.traceId;\n\t\tif (entry.spanId) logObject.spanId = entry.spanId;\n\t\tif (entry.parentId) logObject.parentId = entry.parentId;\n\t\tif (entry.duration !== void 0) logObject.duration = entry.duration;\n\t\tif (entry.context && Object.keys(entry.context).length > 0) logObject.context = entry.context;\n\t\tif (entry.metadata && Object.keys(entry.metadata).length > 0) logObject.metadata = entry.metadata;\n\t\tif (entry.error) logObject.error = {\n\t\t\tname: entry.error.name,\n\t\t\tmessage: entry.error.message,\n\t\t\tstack: entry.error.stack\n\t\t};\n\t\tif (entry.tags && entry.tags.length > 0) logObject.tags = entry.tags;\n\t\treturn JSON.stringify(logObject);\n\t}\n};\nvar CustomFormatter = class {\n\ttemplate;\n\tdateFormat;\n\tconstructor(template = \"{timestamp} [{level}] {message}\", dateFormat) {\n\t\tthis.template = template;\n\t\tthis.dateFormat = dateFormat || ((date) => date.toISOString());\n\t}\n\tformat(entry) {\n\t\tconst levelName = LogLevel[entry.level];\n\t\tconst timestamp = this.dateFormat(entry.timestamp);\n\t\tlet formatted = this.template.replace(\"{timestamp}\", timestamp).replace(\"{level}\", levelName).replace(\"{message}\", entry.message).replace(\"{traceId}\", entry.traceId || \"\").replace(\"{spanId}\", entry.spanId || \"\").replace(\"{duration}\", entry.duration?.toString() || \"\");\n\t\tif (entry.context) formatted = formatted.replace(\"{context}\", JSON.stringify(entry.context));\n\t\tif (entry.metadata) formatted = formatted.replace(\"{metadata}\", JSON.stringify(entry.metadata));\n\t\treturn formatted;\n\t}\n};\n\n//#endregion\nexport { CustomFormatter, DevFormatter, ProductionFormatter };\n//# sourceMappingURL=formatters.mjs.map"],"mappings":"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"}
@@ -186,4 +186,5 @@ var Logger = class Logger$1 {
186
186
  };
187
187
 
188
188
  //#endregion
189
- export { Logger };
189
+ export { Logger };
190
+ //# sourceMappingURL=logger.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.node.js","names":["Logger"],"sources":["../../../../../../libs/logger/dist/logger.node.mjs"],"sourcesContent":["import { LogContext } from \"./context.node.mjs\";\nimport { LogLevel } from \"./types.mjs\";\nimport { TimerManager } from \"./timer.mjs\";\nimport { Tracer } from \"./tracer.node.mjs\";\nimport { DevFormatter, ProductionFormatter } from \"./formatters.mjs\";\n\n//#region src/logger.node.ts\nvar Logger = class Logger {\n\tconfig;\n\tformatter;\n\tcontext;\n\ttracer;\n\ttimerManager;\n\tconstructor(config) {\n\t\tthis.config = {\n\t\t\tlevel: LogLevel.INFO,\n\t\t\tenvironment: process.env.NODE_ENV || \"development\",\n\t\t\tenableTracing: true,\n\t\t\tenableTiming: true,\n\t\t\tenableContext: true,\n\t\t\tenableColors: true,\n\t\t\tmaxContextDepth: 10,\n\t\t\ttimestampFormat: \"iso\",\n\t\t\t...config\n\t\t};\n\t\tthis.context = LogContext.getInstance();\n\t\tthis.tracer = new Tracer();\n\t\tthis.timerManager = new TimerManager();\n\t\tthis.formatter = this.config.environment === \"production\" ? new ProductionFormatter() : new DevFormatter(this.config.enableColors);\n\t}\n\ttraceLog(message, metadata) {\n\t\tthis.log(LogLevel.TRACE, message, metadata);\n\t}\n\tdebug(message, metadata) {\n\t\tthis.log(LogLevel.DEBUG, message, metadata);\n\t}\n\tinfo(message, metadata) {\n\t\tthis.log(LogLevel.INFO, message, metadata);\n\t}\n\twarn(message, metadata) {\n\t\tthis.log(LogLevel.WARN, message, metadata);\n\t}\n\terror(message, metadata, error) {\n\t\tthis.log(LogLevel.ERROR, message, metadata, error);\n\t}\n\tfatal(message, metadata, error) {\n\t\tthis.log(LogLevel.FATAL, message, metadata, error);\n\t}\n\twithContext(context, fn) {\n\t\treturn this.context.run(context, fn);\n\t}\n\textendContext(additionalContext, fn) {\n\t\treturn this.context.extend(additionalContext, fn);\n\t}\n\tsetContext(key, value) {\n\t\tthis.context.set(key, value);\n\t}\n\tgetContext() {\n\t\treturn this.context.getContext();\n\t}\n\ttrace = async (options, fn) => {\n\t\tif (!this.config.enableTracing) return await fn();\n\t\treturn this.tracer.trace(options, fn);\n\t};\n\tgetTraceId() {\n\t\treturn this.tracer.getCurrentTrace()?.traceId;\n\t}\n\tstartSpan(options) {\n\t\tif (!this.config.enableTracing) return null;\n\t\treturn this.tracer.startSpan(options);\n\t}\n\tfinishSpan(spanId) {\n\t\tif (!this.config.enableTracing) return;\n\t\treturn this.tracer.finishSpan(spanId);\n\t}\n\taddTraceMetadata(key, value) {\n\t\tif (this.config.enableTracing) this.tracer.addMetadata(key, value);\n\t}\n\taddTraceTags(...tags) {\n\t\tif (this.config.enableTracing) this.tracer.addTags(...tags);\n\t}\n\tstartTimer(id) {\n\t\tif (!this.config.enableTiming) return null;\n\t\treturn this.timerManager.start(id);\n\t}\n\tstopTimer(id) {\n\t\tif (!this.config.enableTiming) return;\n\t\treturn this.timerManager.stop(id);\n\t}\n\tgetTimer(id) {\n\t\treturn this.timerManager.get(id);\n\t}\n\tchild(context) {\n\t\tconst childLogger = new Logger(this.config);\n\t\tObject.entries(context).forEach(([key, value]) => {\n\t\t\tchildLogger.setContext(key, value);\n\t\t});\n\t\treturn childLogger;\n\t}\n\tsetLevel(level) {\n\t\tthis.config.level = level;\n\t}\n\tsetFormatter(formatter) {\n\t\tthis.formatter = formatter;\n\t}\n\tasync profile(operationName, fn, options) {\n\t\tconst timer = this.startTimer(`profile-${operationName}`);\n\t\tconst startTime = performance.now();\n\t\ttry {\n\t\t\tconst result = await this.tracer.trace({\n\t\t\t\toperationType: \"custom\",\n\t\t\t\toperationName: `profile:${operationName}`,\n\t\t\t\tautoTiming: true\n\t\t\t}, fn);\n\t\t\tconst duration = performance.now() - startTime;\n\t\t\ttimer?.stop();\n\t\t\tconst logLevel = options?.logLevel || LogLevel.DEBUG;\n\t\t\tthis.log(logLevel, `Profile: ${operationName} completed`, {\n\t\t\t\toperation: operationName,\n\t\t\t\tduration: `${duration.toFixed(2)}ms`,\n\t\t\t\tresult: options?.logResult ? result : \"[result hidden]\"\n\t\t\t});\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tconst duration = performance.now() - startTime;\n\t\t\ttimer?.stop();\n\t\t\tthis.error(`Profile: ${operationName} failed`, {\n\t\t\t\toperation: operationName,\n\t\t\t\tduration: `${duration.toFixed(2)}ms`,\n\t\t\t\terror: error.message\n\t\t\t}, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\tlogRequest(method, url, statusCode, duration) {\n\t\tconst level = this.getHttpLogLevel(statusCode);\n\t\tconst message = `${method.toUpperCase()} ${url}${statusCode ? ` ${statusCode}` : \"\"}`;\n\t\tthis.log(level, message, {\n\t\t\tmethod,\n\t\t\turl,\n\t\t\tstatusCode,\n\t\t\tduration: duration ? `${duration.toFixed(2)}ms` : void 0,\n\t\t\ttype: \"http_request\"\n\t\t});\n\t}\n\tasync flush() {\n\t\tthis.timerManager.clear();\n\t}\n\tgetStats() {\n\t\treturn {\n\t\t\tactiveTimers: this.timerManager.getActive().length,\n\t\t\tactiveSpans: this.tracer.getActiveSpans().length,\n\t\t\tconfig: { ...this.config }\n\t\t};\n\t}\n\toutput(message, level) {\n\t\tif (level >= LogLevel.ERROR) console.error(message);\n\t\telse console.log(message);\n\t}\n\tlog(level, message, metadata, error) {\n\t\tif (level < this.config.level) return;\n\t\tconst currentTrace = this.config.enableTracing ? this.tracer.getCurrentTrace() : void 0;\n\t\tconst contextData = this.config.enableContext ? this.context.getContext() : void 0;\n\t\tconst entry = {\n\t\t\tlevel,\n\t\t\tmessage,\n\t\t\ttimestamp: /* @__PURE__ */ new Date(),\n\t\t\ttraceId: currentTrace?.traceId,\n\t\t\tparentId: currentTrace?.parentId,\n\t\t\tspanId: currentTrace?.spanId,\n\t\t\tcontext: contextData,\n\t\t\tmetadata,\n\t\t\terror,\n\t\t\ttags: currentTrace?.tags\n\t\t};\n\t\tif (currentTrace?.metadata?.duration) entry.duration = currentTrace.metadata.duration;\n\t\tconst formatted = this.formatter.format(entry);\n\t\tthis.output(formatted, level);\n\t}\n\tgetHttpLogLevel(statusCode) {\n\t\tif (!statusCode) return LogLevel.INFO;\n\t\tif (statusCode >= 500) return LogLevel.ERROR;\n\t\tif (statusCode >= 400) return LogLevel.WARN;\n\t\treturn LogLevel.INFO;\n\t}\n};\n\n//#endregion\nexport { Logger };\n//# sourceMappingURL=logger.node.mjs.map"],"mappings":"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"}
@@ -123,4 +123,5 @@ var TimerManager = class {
123
123
  };
124
124
 
125
125
  //#endregion
126
- export { Timer, TimerManager };
126
+ export { Timer, TimerManager };
127
+ //# sourceMappingURL=timer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timer.js","names":[],"sources":["../../../../../../libs/logger/dist/timer.mjs"],"sourcesContent":["//#region src/timer.ts\nvar Timer = class {\n\tid;\n\tstartTime;\n\tlaps = [];\n\tstopped = false;\n\tstopTime;\n\tconstructor(id) {\n\t\tthis.id = id || crypto.randomUUID();\n\t\tthis.startTime = performance.now();\n\t}\n\t/**\n\t* Stop the timer and return elapsed time in milliseconds\n\t*/\n\tstop() {\n\t\tif (this.stopped) return this.getElapsed();\n\t\tthis.stopTime = performance.now();\n\t\tthis.stopped = true;\n\t\tconst elapsed = this.stopTime - this.startTime;\n\t\tthis.laps.push({\n\t\t\tlabel: \"stop\",\n\t\t\ttime: this.stopTime,\n\t\t\telapsed\n\t\t});\n\t\treturn elapsed;\n\t}\n\t/**\n\t* Record a lap time and return elapsed time since start\n\t*/\n\tlap(label) {\n\t\tif (this.stopped) return this.getElapsed();\n\t\tconst now = performance.now();\n\t\tconst elapsed = now - this.startTime;\n\t\tthis.laps.push({\n\t\t\tlabel: label || `lap-${this.laps.length + 1}`,\n\t\t\ttime: now,\n\t\t\telapsed\n\t\t});\n\t\treturn elapsed;\n\t}\n\t/**\n\t* Get elapsed time without stopping the timer\n\t*/\n\tgetElapsed() {\n\t\tif (this.stopped && this.stopTime) return this.stopTime - this.startTime;\n\t\treturn performance.now() - this.startTime;\n\t}\n\t/**\n\t* Get all recorded laps\n\t*/\n\tgetLaps() {\n\t\treturn [...this.laps];\n\t}\n\t/**\n\t* Get timer summary with total time and laps\n\t*/\n\tgetSummary() {\n\t\treturn {\n\t\t\tid: this.id,\n\t\t\ttotalTime: this.getElapsed(),\n\t\t\tisRunning: !this.stopped,\n\t\t\tlaps: this.getLaps()\n\t\t};\n\t}\n\t/**\n\t* Reset the timer (starts a new timing session)\n\t*/\n\treset() {\n\t\tthis.startTime = performance.now();\n\t\tthis.laps = [];\n\t\tthis.stopped = false;\n\t\tthis.stopTime = void 0;\n\t}\n};\n/**\n* Utility class for managing multiple timers\n*/\nvar TimerManager = class {\n\ttimers = /* @__PURE__ */ new Map();\n\t/**\n\t* Start a new timer\n\t*/\n\tstart(id) {\n\t\tconst timer = new Timer(id);\n\t\tthis.timers.set(timer.id, timer);\n\t\treturn timer;\n\t}\n\t/**\n\t* Get an existing timer\n\t*/\n\tget(id) {\n\t\treturn this.timers.get(id);\n\t}\n\t/**\n\t* Stop and remove a timer\n\t*/\n\tstop(id) {\n\t\tconst timer = this.timers.get(id);\n\t\tif (timer) {\n\t\t\tconst elapsed = timer.stop();\n\t\t\tthis.timers.delete(id);\n\t\t\treturn elapsed;\n\t\t}\n\t}\n\t/**\n\t* Get all active timers\n\t*/\n\tgetActive() {\n\t\treturn Array.from(this.timers.values()).filter((timer) => !timer.getSummary().isRunning === false);\n\t}\n\t/**\n\t* Clear all timers\n\t*/\n\tclear() {\n\t\tthis.timers.clear();\n\t}\n\t/**\n\t* Get summary of all timers\n\t*/\n\tgetSummary() {\n\t\treturn Array.from(this.timers.values()).map((timer) => timer.getSummary());\n\t}\n};\n/**\n* Decorator/wrapper function to time async operations\n*/\nasync function timed(operation, options) {\n\tconst timer = new Timer(options?.id);\n\ttry {\n\t\tconst result = await operation();\n\t\tconst elapsed = timer.stop();\n\t\toptions?.onComplete?.(elapsed);\n\t\treturn {\n\t\t\tresult,\n\t\t\telapsed,\n\t\t\ttimer\n\t\t};\n\t} catch (error) {\n\t\ttimer.stop();\n\t\tthrow error;\n\t}\n}\n/**\n* Decorator/wrapper function to time synchronous operations\n*/\nfunction timedSync(operation, options) {\n\tconst timer = new Timer(options?.id);\n\ttry {\n\t\tconst result = operation();\n\t\tconst elapsed = timer.stop();\n\t\toptions?.onComplete?.(elapsed);\n\t\treturn {\n\t\t\tresult,\n\t\t\telapsed,\n\t\t\ttimer\n\t\t};\n\t} catch (error) {\n\t\ttimer.stop();\n\t\tthrow error;\n\t}\n}\n\n//#endregion\nexport { Timer, TimerManager, timed, timedSync };\n//# sourceMappingURL=timer.mjs.map"],"mappings":";AACA,IAAI,QAAQ,MAAM;CACjB;CACA;CACA,OAAO,EAAE;CACT,UAAU;CACV;CACA,YAAY,IAAI;AACf,OAAK,KAAK,MAAM,OAAO,YAAY;AACnC,OAAK,YAAY,YAAY,KAAK;;;;;CAKnC,OAAO;AACN,MAAI,KAAK,QAAS,QAAO,KAAK,YAAY;AAC1C,OAAK,WAAW,YAAY,KAAK;AACjC,OAAK,UAAU;EACf,MAAM,UAAU,KAAK,WAAW,KAAK;AACrC,OAAK,KAAK,KAAK;GACd,OAAO;GACP,MAAM,KAAK;GACX;GACA,CAAC;AACF,SAAO;;;;;CAKR,IAAI,OAAO;AACV,MAAI,KAAK,QAAS,QAAO,KAAK,YAAY;EAC1C,MAAM,MAAM,YAAY,KAAK;EAC7B,MAAM,UAAU,MAAM,KAAK;AAC3B,OAAK,KAAK,KAAK;GACd,OAAO,SAAS,OAAO,KAAK,KAAK,SAAS;GAC1C,MAAM;GACN;GACA,CAAC;AACF,SAAO;;;;;CAKR,aAAa;AACZ,MAAI,KAAK,WAAW,KAAK,SAAU,QAAO,KAAK,WAAW,KAAK;AAC/D,SAAO,YAAY,KAAK,GAAG,KAAK;;;;;CAKjC,UAAU;AACT,SAAO,CAAC,GAAG,KAAK,KAAK;;;;;CAKtB,aAAa;AACZ,SAAO;GACN,IAAI,KAAK;GACT,WAAW,KAAK,YAAY;GAC5B,WAAW,CAAC,KAAK;GACjB,MAAM,KAAK,SAAS;GACpB;;;;;CAKF,QAAQ;AACP,OAAK,YAAY,YAAY,KAAK;AAClC,OAAK,OAAO,EAAE;AACd,OAAK,UAAU;AACf,OAAK,WAAW,KAAK;;;;;;AAMvB,IAAI,eAAe,MAAM;CACxB,yBAAyB,IAAI,KAAK;;;;CAIlC,MAAM,IAAI;EACT,MAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,OAAK,OAAO,IAAI,MAAM,IAAI,MAAM;AAChC,SAAO;;;;;CAKR,IAAI,IAAI;AACP,SAAO,KAAK,OAAO,IAAI,GAAG;;;;;CAK3B,KAAK,IAAI;EACR,MAAM,QAAQ,KAAK,OAAO,IAAI,GAAG;AACjC,MAAI,OAAO;GACV,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAK,OAAO,OAAO,GAAG;AACtB,UAAO;;;;;;CAMT,YAAY;AACX,SAAO,MAAM,KAAK,KAAK,OAAO,QAAQ,CAAC,CAAC,QAAQ,UAAU,CAAC,MAAM,YAAY,CAAC,cAAc,MAAM;;;;;CAKnG,QAAQ;AACP,OAAK,OAAO,OAAO;;;;;CAKpB,aAAa;AACZ,SAAO,MAAM,KAAK,KAAK,OAAO,QAAQ,CAAC,CAAC,KAAK,UAAU,MAAM,YAAY,CAAC"}
@@ -112,4 +112,5 @@ var Tracer = class {
112
112
  };
113
113
 
114
114
  //#endregion
115
- export { Tracer };
115
+ export { Tracer };
116
+ //# sourceMappingURL=tracer.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracer.node.js","names":[],"sources":["../../../../../../libs/logger/dist/tracer.node.mjs"],"sourcesContent":["import { LogContext } from \"./context.node.mjs\";\nimport { Timer } from \"./timer.mjs\";\n\n//#region src/tracer.node.ts\nvar Tracer = class {\n\tcontext;\n\tactiveSpans = /* @__PURE__ */ new Map();\n\tconstructor() {\n\t\tthis.context = LogContext.getInstance();\n\t}\n\t/**\n\t* Start a new trace span\n\t*/\n\tstartSpan(options) {\n\t\tconst parentTrace = this.context.getCurrentTrace();\n\t\tconst span = {\n\t\t\ttraceId: parentTrace?.traceId || this.generateTraceId(),\n\t\t\tparentId: parentTrace?.spanId,\n\t\t\tspanId: this.generateSpanId(),\n\t\t\toperationType: options.operationType,\n\t\t\toperationName: options.operationName,\n\t\t\tstartTime: performance.now(),\n\t\t\tmetadata: { ...options.metadata },\n\t\t\ttags: [...options.tags || []]\n\t\t};\n\t\tthis.activeSpans.set(span.spanId, span);\n\t\tthis.context.setTrace(span);\n\t\treturn span;\n\t}\n\t/**\n\t* Finish a trace span\n\t*/\n\tfinishSpan(spanId) {\n\t\tconst span = this.activeSpans.get(spanId);\n\t\tif (!span) return;\n\t\tconst duration = performance.now() - span.startTime;\n\t\tthis.activeSpans.delete(spanId);\n\t\tif (this.context.getCurrentTrace()?.spanId === spanId && span.parentId) {\n\t\t\tconst parentSpan = this.findSpanById(span.parentId);\n\t\t\tif (parentSpan) this.context.setTrace(parentSpan);\n\t\t}\n\t\treturn duration;\n\t}\n\t/**\n\t* Execute a function within a trace span\n\t*/\n\tasync trace(options, fn) {\n\t\tconst span = this.startSpan(options);\n\t\tconst timer = options.autoTiming !== false ? new Timer(`trace-${span.spanId}`) : void 0;\n\t\ttry {\n\t\t\tconst result = await fn();\n\t\t\tconst duration = this.finishSpan(span.spanId);\n\t\t\tif (timer) timer.stop();\n\t\t\tif (duration !== void 0) span.metadata.duration = duration;\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tspan.metadata.error = {\n\t\t\t\tname: error.name || \"Unknown\",\n\t\t\t\tmessage: error.message || \"Unknown error\",\n\t\t\t\tstack: error.stack\n\t\t\t};\n\t\t\tconst duration = this.finishSpan(span.spanId);\n\t\t\tspan.metadata.duration = duration;\n\t\t\tif (timer) timer.stop();\n\t\t\tthrow error;\n\t\t}\n\t}\n\t/**\n\t* Add metadata to current span\n\t*/\n\taddMetadata(key, value) {\n\t\tconst currentTrace = this.context.getCurrentTrace();\n\t\tif (currentTrace) currentTrace.metadata[key] = value;\n\t}\n\t/**\n\t* Add tags to current span\n\t*/\n\taddTags(...tags) {\n\t\tconst currentTrace = this.context.getCurrentTrace();\n\t\tif (currentTrace) currentTrace.tags.push(...tags);\n\t}\n\t/**\n\t* Get current trace context\n\t*/\n\tgetCurrentTrace() {\n\t\treturn this.context.getCurrentTrace();\n\t}\n\t/**\n\t* Get all active spans\n\t*/\n\tgetActiveSpans() {\n\t\treturn Array.from(this.activeSpans.values());\n\t}\n\t/**\n\t* Find a span by ID\n\t*/\n\tfindSpanById(spanId) {\n\t\treturn this.activeSpans.get(spanId);\n\t}\n\t/**\n\t* Generate a unique trace ID\n\t*/\n\tgenerateTraceId() {\n\t\treturn crypto.randomUUID().replace(/-/g, \"\");\n\t}\n\t/**\n\t* Generate a unique span ID\n\t*/\n\tgenerateSpanId() {\n\t\treturn crypto.randomUUID().replace(/-/g, \"\").substring(0, 16);\n\t}\n};\n\n//#endregion\nexport { Tracer };\n//# sourceMappingURL=tracer.node.mjs.map"],"mappings":";;;;AAIA,IAAI,SAAS,MAAM;CAClB;CACA,8BAA8B,IAAI,KAAK;CACvC,cAAc;AACb,OAAK,UAAU,WAAW,aAAa;;;;;CAKxC,UAAU,SAAS;EAClB,MAAM,cAAc,KAAK,QAAQ,iBAAiB;EAClD,MAAM,OAAO;GACZ,SAAS,aAAa,WAAW,KAAK,iBAAiB;GACvD,UAAU,aAAa;GACvB,QAAQ,KAAK,gBAAgB;GAC7B,eAAe,QAAQ;GACvB,eAAe,QAAQ;GACvB,WAAW,YAAY,KAAK;GAC5B,UAAU,EAAE,GAAG,QAAQ,UAAU;GACjC,MAAM,CAAC,GAAG,QAAQ,QAAQ,EAAE,CAAC;GAC7B;AACD,OAAK,YAAY,IAAI,KAAK,QAAQ,KAAK;AACvC,OAAK,QAAQ,SAAS,KAAK;AAC3B,SAAO;;;;;CAKR,WAAW,QAAQ;EAClB,MAAM,OAAO,KAAK,YAAY,IAAI,OAAO;AACzC,MAAI,CAAC,KAAM;EACX,MAAM,WAAW,YAAY,KAAK,GAAG,KAAK;AAC1C,OAAK,YAAY,OAAO,OAAO;AAC/B,MAAI,KAAK,QAAQ,iBAAiB,EAAE,WAAW,UAAU,KAAK,UAAU;GACvE,MAAM,aAAa,KAAK,aAAa,KAAK,SAAS;AACnD,OAAI,WAAY,MAAK,QAAQ,SAAS,WAAW;;AAElD,SAAO;;;;;CAKR,MAAM,MAAM,SAAS,IAAI;EACxB,MAAM,OAAO,KAAK,UAAU,QAAQ;EACpC,MAAM,QAAQ,QAAQ,eAAe,QAAQ,IAAI,MAAM,SAAS,KAAK,SAAS,GAAG,KAAK;AACtF,MAAI;GACH,MAAM,SAAS,MAAM,IAAI;GACzB,MAAM,WAAW,KAAK,WAAW,KAAK,OAAO;AAC7C,OAAI,MAAO,OAAM,MAAM;AACvB,OAAI,aAAa,KAAK,EAAG,MAAK,SAAS,WAAW;AAClD,UAAO;WACC,OAAO;AACf,QAAK,SAAS,QAAQ;IACrB,MAAM,MAAM,QAAQ;IACpB,SAAS,MAAM,WAAW;IAC1B,OAAO,MAAM;IACb;GACD,MAAM,WAAW,KAAK,WAAW,KAAK,OAAO;AAC7C,QAAK,SAAS,WAAW;AACzB,OAAI,MAAO,OAAM,MAAM;AACvB,SAAM;;;;;;CAMR,YAAY,KAAK,OAAO;EACvB,MAAM,eAAe,KAAK,QAAQ,iBAAiB;AACnD,MAAI,aAAc,cAAa,SAAS,OAAO;;;;;CAKhD,QAAQ,GAAG,MAAM;EAChB,MAAM,eAAe,KAAK,QAAQ,iBAAiB;AACnD,MAAI,aAAc,cAAa,KAAK,KAAK,GAAG,KAAK;;;;;CAKlD,kBAAkB;AACjB,SAAO,KAAK,QAAQ,iBAAiB;;;;;CAKtC,iBAAiB;AAChB,SAAO,MAAM,KAAK,KAAK,YAAY,QAAQ,CAAC;;;;;CAK7C,aAAa,QAAQ;AACpB,SAAO,KAAK,YAAY,IAAI,OAAO;;;;;CAKpC,kBAAkB;AACjB,SAAO,OAAO,YAAY,CAAC,QAAQ,MAAM,GAAG;;;;;CAK7C,iBAAiB;AAChB,SAAO,OAAO,YAAY,CAAC,QAAQ,MAAM,GAAG,CAAC,UAAU,GAAG,GAAG"}
@@ -10,4 +10,5 @@ let LogLevel = /* @__PURE__ */ function(LogLevel$1) {
10
10
  }({});
11
11
 
12
12
  //#endregion
13
- export { LogLevel };
13
+ export { LogLevel };
14
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../../../../libs/logger/dist/types.mjs"],"sourcesContent":["//#region src/types.ts\nlet LogLevel = /* @__PURE__ */ function(LogLevel$1) {\n\tLogLevel$1[LogLevel$1[\"TRACE\"] = 0] = \"TRACE\";\n\tLogLevel$1[LogLevel$1[\"DEBUG\"] = 1] = \"DEBUG\";\n\tLogLevel$1[LogLevel$1[\"INFO\"] = 2] = \"INFO\";\n\tLogLevel$1[LogLevel$1[\"WARN\"] = 3] = \"WARN\";\n\tLogLevel$1[LogLevel$1[\"ERROR\"] = 4] = \"ERROR\";\n\tLogLevel$1[LogLevel$1[\"FATAL\"] = 5] = \"FATAL\";\n\treturn LogLevel$1;\n}({});\n\n//#endregion\nexport { LogLevel };\n//# sourceMappingURL=types.mjs.map"],"mappings":";AACA,IAAI,WAA2B,yBAAS,YAAY;AACnD,YAAW,WAAW,WAAW,KAAK;AACtC,YAAW,WAAW,WAAW,KAAK;AACtC,YAAW,WAAW,UAAU,KAAK;AACrC,YAAW,WAAW,UAAU,KAAK;AACrC,YAAW,WAAW,WAAW,KAAK;AACtC,YAAW,WAAW,WAAW,KAAK;AACtC,QAAO;EACN,EAAE,CAAC"}
@@ -103,4 +103,5 @@ function applyReorder(sequence, orderedFields) {
103
103
  }
104
104
 
105
105
  //#endregion
106
- export { applyOverlayModifications };
106
+ export { applyOverlayModifications };
107
+ //# sourceMappingURL=merger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merger.js","names":[],"sources":["../../../../../../libs/overlay-engine/dist/merger.js"],"sourcesContent":["//#region src/merger.ts\nfunction applyOverlayModifications(target, overlays, options = {}) {\n\tif (!overlays.length) return target;\n\tconst states = target.fields.map((field) => ({\n\t\tkey: field.key,\n\t\tfield: { ...field },\n\t\thidden: field.visible === false\n\t}));\n\tconst fieldMap = new Map(states.map((state) => [state.key, state]));\n\tlet orderSequence = target.fields.map((field) => field.key);\n\tconst handleMissing = (field, overlayId) => {\n\t\tif (options.strict) throw new Error(`Overlay \"${overlayId}\" referenced unknown field \"${field}\".`);\n\t};\n\toverlays.forEach((overlay) => {\n\t\toverlay.modifications.forEach((modification) => {\n\t\t\tswitch (modification.type) {\n\t\t\t\tcase \"hideField\": {\n\t\t\t\t\tconst state = fieldMap.get(modification.field);\n\t\t\t\t\tif (!state) return handleMissing(modification.field, overlay.overlayId);\n\t\t\t\t\tstate.hidden = true;\n\t\t\t\t\tstate.field.visible = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"renameLabel\": {\n\t\t\t\t\tconst state = fieldMap.get(modification.field);\n\t\t\t\t\tif (!state) return handleMissing(modification.field, overlay.overlayId);\n\t\t\t\t\tstate.field.label = modification.newLabel;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"setDefault\": {\n\t\t\t\t\tconst state = fieldMap.get(modification.field);\n\t\t\t\t\tif (!state) return handleMissing(modification.field, overlay.overlayId);\n\t\t\t\t\tstate.field.defaultValue = modification.value;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"addHelpText\": {\n\t\t\t\t\tconst state = fieldMap.get(modification.field);\n\t\t\t\t\tif (!state) return handleMissing(modification.field, overlay.overlayId);\n\t\t\t\t\tstate.field.helpText = modification.text;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"makeRequired\": {\n\t\t\t\t\tconst state = fieldMap.get(modification.field);\n\t\t\t\t\tif (!state) return handleMissing(modification.field, overlay.overlayId);\n\t\t\t\t\tstate.field.required = modification.required ?? true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"reorderFields\": {\n\t\t\t\t\tconst { filtered, missing } = normalizeOrderList(modification.fields, fieldMap);\n\t\t\t\t\tif (missing.length && options.strict) missing.forEach((field) => handleMissing(field, overlay.overlayId));\n\t\t\t\t\torderSequence = applyReorder(orderSequence, filtered);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: break;\n\t\t\t}\n\t\t});\n\t});\n\tconst visibleFields = [];\n\tconst seen = /* @__PURE__ */ new Set();\n\torderSequence.forEach((key) => {\n\t\tconst state = fieldMap.get(key);\n\t\tif (!state || state.hidden) return;\n\t\tseen.add(key);\n\t\tvisibleFields.push(state.field);\n\t});\n\tstates.forEach((state) => {\n\t\tif (state.hidden || seen.has(state.key)) return;\n\t\tvisibleFields.push(state.field);\n\t});\n\tvisibleFields.forEach((field, index) => {\n\t\tfield.order = index;\n\t\tfield.visible = true;\n\t});\n\treturn {\n\t\t...target,\n\t\tfields: visibleFields\n\t};\n}\nfunction normalizeOrderList(fields, fieldMap) {\n\tconst filtered = [];\n\tconst missing = [];\n\tconst seen = /* @__PURE__ */ new Set();\n\tfields.forEach((field) => {\n\t\tif (!field?.trim()) return;\n\t\tif (!fieldMap.has(field)) {\n\t\t\tmissing.push(field);\n\t\t\treturn;\n\t\t}\n\t\tif (seen.has(field)) return;\n\t\tseen.add(field);\n\t\tfiltered.push(field);\n\t});\n\treturn {\n\t\tfiltered,\n\t\tmissing\n\t};\n}\nfunction applyReorder(sequence, orderedFields) {\n\tif (!orderedFields.length) return sequence;\n\tconst orderedSet = new Set(orderedFields);\n\tconst remainder = sequence.filter((key) => !orderedSet.has(key));\n\treturn [...orderedFields, ...remainder];\n}\n\n//#endregion\nexport { applyOverlayModifications };\n//# sourceMappingURL=merger.js.map"],"mappings":"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"}
@@ -103,4 +103,5 @@ function matches(appliesTo, ctx) {
103
103
  }
104
104
 
105
105
  //#endregion
106
- export { OverlayRegistry };
106
+ export { OverlayRegistry };
107
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../../../../../libs/overlay-engine/dist/registry.js"],"sourcesContent":["import { defaultOverlayValidator } from \"./validator.js\";\n\n//#region src/registry.ts\nconst TARGET_KEYS = [\n\t\"capability\",\n\t\"workflow\",\n\t\"dataView\",\n\t\"presentation\",\n\t\"operation\"\n];\nconst SCOPE_WEIGHTS = {\n\ttenantId: 8,\n\trole: 4,\n\tuserId: 16,\n\tdevice: 2,\n\ttags: 1\n};\nvar OverlayRegistry = class {\n\toverlays = /* @__PURE__ */ new Map();\n\tconstructor(options = {}) {\n\t\tthis.options = options;\n\t}\n\tregister(overlay, options) {\n\t\tif (!options?.skipValidation) {\n\t\t\tconst result = (this.options.validator ?? defaultOverlayValidator)(overlay);\n\t\t\tif (!result.valid) {\n\t\t\t\tconst reason = result.issues.map((issue) => `${issue.code}: ${issue.message}`).join(\"; \");\n\t\t\t\tthrow new Error(`Overlay \"${overlay.overlayId}\" failed validation: ${reason}`);\n\t\t\t}\n\t\t}\n\t\tconst normalized = this.ensureSigned(overlay);\n\t\tconst key = this.getKey(normalized.overlayId, normalized.version);\n\t\tconst stored = {\n\t\t\toverlay: normalized,\n\t\t\tspecificity: computeSpecificity(normalized.appliesTo),\n\t\t\tregisteredAt: Date.now()\n\t\t};\n\t\tthis.overlays.set(key, stored);\n\t\treturn normalized;\n\t}\n\tunregister(overlayId, version) {\n\t\tif (version) {\n\t\t\tthis.overlays.delete(this.getKey(overlayId, version));\n\t\t\treturn;\n\t\t}\n\t\tfor (const key of Array.from(this.overlays.keys())) if (key.startsWith(`${overlayId}@`)) this.overlays.delete(key);\n\t}\n\tlist() {\n\t\treturn Array.from(this.overlays.values()).map((entry) => entry.overlay);\n\t}\n\tget(overlayId, version) {\n\t\treturn this.overlays.get(this.getKey(overlayId, version))?.overlay;\n\t}\n\tforContext(query) {\n\t\treturn Array.from(this.overlays.values()).filter((entry) => matches(entry.overlay.appliesTo, query)).sort((a, b) => {\n\t\t\tif (a.specificity !== b.specificity) return a.specificity - b.specificity;\n\t\t\treturn a.registeredAt - b.registeredAt;\n\t\t}).map((entry) => entry.overlay);\n\t}\n\tclear() {\n\t\tthis.overlays.clear();\n\t}\n\tsize() {\n\t\treturn this.overlays.size;\n\t}\n\tensureSigned(input) {\n\t\tif (isSignedOverlay(input)) {\n\t\t\tif (!input.signature?.signature && !this.options.allowUnsigned) throw new Error(`Overlay \"${input.overlayId}\" is missing a signature.`);\n\t\t\treturn input;\n\t\t}\n\t\tif (!this.options.allowUnsigned) throw new Error(`Overlay \"${input.overlayId}\" must be signed before registration.`);\n\t\treturn input;\n\t}\n\tgetKey(overlayId, version) {\n\t\treturn `${overlayId}@${version}`;\n\t}\n};\nfunction isSignedOverlay(spec) {\n\treturn Boolean(spec.signature);\n}\nfunction computeSpecificity(appliesTo) {\n\tlet score = 0;\n\tObject.keys(SCOPE_WEIGHTS).forEach((key) => {\n\t\tif (key === \"tags\" ? Array.isArray(appliesTo.tags) && appliesTo.tags.length > 0 : Boolean(appliesTo[key])) score += SCOPE_WEIGHTS[key];\n\t});\n\treturn score;\n}\nfunction matches(appliesTo, ctx) {\n\tfor (const key of TARGET_KEYS) {\n\t\tconst expected = appliesTo[key];\n\t\tif (expected && expected !== ctx[key]) return false;\n\t}\n\tif (appliesTo.tenantId && appliesTo.tenantId !== ctx.tenantId) return false;\n\tif (appliesTo.role && appliesTo.role !== ctx.role) return false;\n\tif (appliesTo.userId && appliesTo.userId !== ctx.userId) return false;\n\tif (appliesTo.device && appliesTo.device !== ctx.device) return false;\n\tif (appliesTo.tags?.length) {\n\t\tif (!ctx.tags?.length) return false;\n\t\tconst ctxTags = new Set(ctx.tags);\n\t\tif (!appliesTo.tags.every((tag) => ctxTags.has(tag))) return false;\n\t}\n\treturn true;\n}\n\n//#endregion\nexport { OverlayRegistry };\n//# sourceMappingURL=registry.js.map"],"mappings":"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"}
@@ -50,4 +50,5 @@ function extractContext(params) {
50
50
  }
51
51
 
52
52
  //#endregion
53
- export { OverlayEngine };
53
+ export { OverlayEngine };
54
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","names":[],"sources":["../../../../../../libs/overlay-engine/dist/runtime.js"],"sourcesContent":["import { applyOverlayModifications } from \"./merger.js\";\n\n//#region src/runtime.ts\nvar OverlayEngine = class {\n\tregistry;\n\taudit;\n\tconstructor(options) {\n\t\tthis.registry = options.registry;\n\t\tthis.audit = options.audit;\n\t}\n\tapply(params) {\n\t\tconst overlays = params.overlays ?? this.registry.forContext({\n\t\t\tcapability: params.capability,\n\t\t\tworkflow: params.workflow,\n\t\t\tdataView: params.dataView,\n\t\t\tpresentation: params.presentation,\n\t\t\toperation: params.operation,\n\t\t\ttenantId: params.tenantId,\n\t\t\trole: params.role,\n\t\t\tuserId: params.userId,\n\t\t\tdevice: params.device,\n\t\t\ttags: params.tags\n\t\t});\n\t\tconst merged = applyOverlayModifications(params.target, overlays, { strict: params.strict });\n\t\tconst context = extractContext(params);\n\t\toverlays.forEach((overlay) => {\n\t\t\tthis.audit?.({\n\t\t\t\toverlay: {\n\t\t\t\t\toverlayId: overlay.overlayId,\n\t\t\t\t\tversion: overlay.version\n\t\t\t\t},\n\t\t\t\tcontext,\n\t\t\t\ttimestamp: (/* @__PURE__ */ new Date()).toISOString()\n\t\t\t});\n\t\t});\n\t\treturn {\n\t\t\ttarget: merged,\n\t\t\toverlaysApplied: overlays\n\t\t};\n\t}\n};\nfunction extractContext(params) {\n\treturn {\n\t\ttenantId: params.tenantId,\n\t\trole: params.role,\n\t\tuserId: params.userId,\n\t\tdevice: params.device,\n\t\ttags: params.tags\n\t};\n}\n\n//#endregion\nexport { OverlayEngine };\n//# sourceMappingURL=runtime.js.map"],"mappings":";;;AAGA,IAAI,gBAAgB,MAAM;CACzB;CACA;CACA,YAAY,SAAS;AACpB,OAAK,WAAW,QAAQ;AACxB,OAAK,QAAQ,QAAQ;;CAEtB,MAAM,QAAQ;EACb,MAAM,WAAW,OAAO,YAAY,KAAK,SAAS,WAAW;GAC5D,YAAY,OAAO;GACnB,UAAU,OAAO;GACjB,UAAU,OAAO;GACjB,cAAc,OAAO;GACrB,WAAW,OAAO;GAClB,UAAU,OAAO;GACjB,MAAM,OAAO;GACb,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf,MAAM,OAAO;GACb,CAAC;EACF,MAAM,SAAS,0BAA0B,OAAO,QAAQ,UAAU,EAAE,QAAQ,OAAO,QAAQ,CAAC;EAC5F,MAAM,UAAU,eAAe,OAAO;AACtC,WAAS,SAAS,YAAY;AAC7B,QAAK,QAAQ;IACZ,SAAS;KACR,WAAW,QAAQ;KACnB,SAAS,QAAQ;KACjB;IACD;IACA,4BAA4B,IAAI,MAAM,EAAE,aAAa;IACrD,CAAC;IACD;AACF,SAAO;GACN,QAAQ;GACR,iBAAiB;GACjB;;;AAGH,SAAS,eAAe,QAAQ;AAC/B,QAAO;EACN,UAAU,OAAO;EACjB,MAAM,OAAO;EACb,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,MAAM,OAAO;EACb"}
@@ -42,4 +42,5 @@ function toIso(value) {
42
42
  }
43
43
 
44
44
  //#endregion
45
- export { canonicalizeOverlay, signOverlay };
45
+ export { canonicalizeOverlay, signOverlay };
46
+ //# sourceMappingURL=signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.js","names":[],"sources":["../../../../../../libs/overlay-engine/dist/signer.js"],"sourcesContent":["import stringify from \"fast-json-stable-stringify\";\nimport { constants, createPrivateKey, createPublicKey, sign, verify } from \"crypto\";\n\n//#region src/signer.ts\nfunction signOverlay(spec, privateKey, options = {}) {\n\tconst algorithm = options.algorithm ?? \"ed25519\";\n\tconst keyObject = typeof privateKey === \"string\" || Buffer.isBuffer(privateKey) ? createPrivateKey(privateKey) : privateKey;\n\tconst payload = Buffer.from(canonicalizeOverlay(spec), \"utf8\");\n\tlet rawSignature;\n\tif (algorithm === \"ed25519\") rawSignature = sign(null, payload, keyObject);\n\telse if (algorithm === \"rsa-pss-sha256\") rawSignature = sign(\"sha256\", payload, {\n\t\tkey: keyObject,\n\t\tpadding: constants.RSA_PKCS1_PSS_PADDING,\n\t\tsaltLength: 32\n\t});\n\telse throw new Error(`Unsupported overlay signature algorithm: ${algorithm}`);\n\tconst publicKey = options.publicKey ?? createPublicKey(keyObject).export({\n\t\tformat: \"pem\",\n\t\ttype: \"spki\"\n\t}).toString();\n\treturn {\n\t\t...spec,\n\t\tsignature: {\n\t\t\talgorithm,\n\t\t\tsignature: rawSignature.toString(\"base64\"),\n\t\t\tpublicKey,\n\t\t\tkeyId: options.keyId,\n\t\t\tissuedAt: toIso(options.issuedAt) ?? (/* @__PURE__ */ new Date()).toISOString(),\n\t\t\texpiresAt: toIso(options.expiresAt),\n\t\t\tmetadata: options.metadata\n\t\t}\n\t};\n}\nfunction verifyOverlaySignature(overlay) {\n\tif (!overlay.signature?.signature) throw new Error(`Overlay \"${overlay.overlayId}\" is missing signature metadata.`);\n\tconst payload = Buffer.from(canonicalizeOverlay(overlay), \"utf8\");\n\tconst signature = Buffer.from(overlay.signature.signature, \"base64\");\n\tconst publicKey = createPublicKey(overlay.signature.publicKey);\n\tif (overlay.signature.algorithm === \"ed25519\") return verify(null, payload, publicKey, signature);\n\tif (overlay.signature.algorithm === \"rsa-pss-sha256\") return verify(\"sha256\", payload, {\n\t\tkey: publicKey,\n\t\tpadding: constants.RSA_PKCS1_PSS_PADDING,\n\t\tsaltLength: 32\n\t}, signature);\n\tthrow new Error(`Unsupported overlay signature algorithm: ${overlay.signature.algorithm}`);\n}\nfunction canonicalizeOverlay(spec) {\n\tconst { signature, ...rest } = spec;\n\treturn stringify(rest);\n}\nfunction stripSignature(spec) {\n\tconst { signature, ...rest } = spec;\n\treturn { ...rest };\n}\nfunction toIso(value) {\n\tif (!value) return;\n\tif (typeof value === \"string\") return new Date(value).toISOString();\n\treturn value.toISOString();\n}\n\n//#endregion\nexport { canonicalizeOverlay, signOverlay, stripSignature, verifyOverlaySignature };\n//# sourceMappingURL=signer.js.map"],"mappings":";;;;AAIA,SAAS,YAAY,MAAM,YAAY,UAAU,EAAE,EAAE;CACpD,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,YAAY,OAAO,eAAe,YAAY,OAAO,SAAS,WAAW,GAAG,iBAAiB,WAAW,GAAG;CACjH,MAAM,UAAU,OAAO,KAAK,oBAAoB,KAAK,EAAE,OAAO;CAC9D,IAAI;AACJ,KAAI,cAAc,UAAW,gBAAe,KAAK,MAAM,SAAS,UAAU;UACjE,cAAc,iBAAkB,gBAAe,KAAK,UAAU,SAAS;EAC/E,KAAK;EACL,SAAS,UAAU;EACnB,YAAY;EACZ,CAAC;KACG,OAAM,IAAI,MAAM,4CAA4C,YAAY;CAC7E,MAAM,YAAY,QAAQ,aAAa,gBAAgB,UAAU,CAAC,OAAO;EACxE,QAAQ;EACR,MAAM;EACN,CAAC,CAAC,UAAU;AACb,QAAO;EACN,GAAG;EACH,WAAW;GACV;GACA,WAAW,aAAa,SAAS,SAAS;GAC1C;GACA,OAAO,QAAQ;GACf,UAAU,MAAM,QAAQ,SAAS,qBAAqB,IAAI,MAAM,EAAE,aAAa;GAC/E,WAAW,MAAM,QAAQ,UAAU;GACnC,UAAU,QAAQ;GAClB;EACD;;AAeF,SAAS,oBAAoB,MAAM;CAClC,MAAM,EAAE,WAAW,GAAG,SAAS;AAC/B,QAAO,UAAU,KAAK;;AAMvB,SAAS,MAAM,OAAO;AACrB,KAAI,CAAC,MAAO;AACZ,KAAI,OAAO,UAAU,SAAU,QAAO,IAAI,KAAK,MAAM,CAAC,aAAa;AACnE,QAAO,MAAM,aAAa"}
@@ -4,4 +4,5 @@ function defineOverlay(spec) {
4
4
  }
5
5
 
6
6
  //#endregion
7
- export { defineOverlay };
7
+ export { defineOverlay };
8
+ //# sourceMappingURL=spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.js","names":[],"sources":["../../../../../../libs/overlay-engine/dist/spec.js"],"sourcesContent":["//#region src/spec.ts\nconst OVERLAY_SCOPE_ORDER = [\n\t\"tenantId\",\n\t\"role\",\n\t\"userId\",\n\t\"device\",\n\t\"tags\"\n];\nfunction defineOverlay(spec) {\n\treturn spec;\n}\n\n//#endregion\nexport { OVERLAY_SCOPE_ORDER, defineOverlay };\n//# sourceMappingURL=spec.js.map"],"mappings":";AAQA,SAAS,cAAc,MAAM;AAC5B,QAAO"}
@@ -90,4 +90,5 @@ function isFieldModification(mod) {
90
90
  }
91
91
 
92
92
  //#endregion
93
- export { defaultOverlayValidator, validateOverlaySpec };
93
+ export { defaultOverlayValidator, validateOverlaySpec };
94
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","names":[],"sources":["../../../../../../libs/overlay-engine/dist/validator.js"],"sourcesContent":["//#region src/validator.ts\nconst TARGET_KEYS = [\n\t\"capability\",\n\t\"workflow\",\n\t\"dataView\",\n\t\"presentation\",\n\t\"operation\"\n];\nconst defaultOverlayValidator = (spec) => validateOverlaySpec(spec);\nfunction validateOverlaySpec(spec) {\n\tconst issues = [];\n\tif (!spec.overlayId?.trim()) issues.push({\n\t\tcode: \"overlay.id\",\n\t\tmessage: \"overlayId is required\",\n\t\tpath: [\"overlayId\"]\n\t});\n\tif (!spec.version?.trim()) issues.push({\n\t\tcode: \"overlay.version\",\n\t\tmessage: \"version is required\",\n\t\tpath: [\"version\"]\n\t});\n\tif (!TARGET_KEYS.some((key) => {\n\t\tconst value = spec.appliesTo?.[key];\n\t\treturn typeof value === \"string\" && value.trim().length > 0;\n\t})) issues.push({\n\t\tcode: \"overlay.target\",\n\t\tmessage: \"Overlay must specify at least one target (capability, workflow, dataView, presentation, or operation).\",\n\t\tpath: [\"appliesTo\"]\n\t});\n\tif (!spec.modifications?.length) issues.push({\n\t\tcode: \"overlay.modifications.empty\",\n\t\tmessage: \"Overlay must include at least one modification.\",\n\t\tpath: [\"modifications\"]\n\t});\n\telse spec.modifications.forEach((mod, idx) => {\n\t\tvalidateModification(mod, [\"modifications\", String(idx)], issues);\n\t});\n\treturn {\n\t\tvalid: issues.length === 0,\n\t\tissues\n\t};\n}\nfunction validateModification(modification, path, issues) {\n\tconst push = (code, message, extraPath) => {\n\t\tissues.push({\n\t\t\tcode,\n\t\t\tmessage,\n\t\t\tpath: extraPath ? [...path, ...extraPath] : path\n\t\t});\n\t};\n\tif (isFieldModification(modification)) {\n\t\tif (!modification.field?.trim()) push(\"overlay.mod.field\", \"field is required for this modification\", [\"field\"]);\n\t}\n\tswitch (modification.type) {\n\t\tcase \"renameLabel\":\n\t\t\tif (!modification.newLabel?.trim()) push(\"overlay.mod.renameLabel.newLabel\", \"newLabel is required\", [\"newLabel\"]);\n\t\t\tbreak;\n\t\tcase \"reorderFields\": {\n\t\t\tif (!modification.fields?.length) push(\"overlay.mod.reorderFields.fields\", \"fields list cannot be empty\", [\"fields\"]);\n\t\t\tconst seen = /* @__PURE__ */ new Set();\n\t\t\tfor (const field of modification.fields ?? []) {\n\t\t\t\tif (!field?.trim()) {\n\t\t\t\t\tpush(\"overlay.mod.reorderFields.fields.blank\", \"fields entries must be non-empty\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (seen.has(field)) {\n\t\t\t\t\tpush(\"overlay.mod.reorderFields.fields.duplicate\", `field \"${field}\" was listed multiple times`);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tseen.add(field);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase \"setDefault\":\n\t\t\tif (modification.value === void 0) push(\"overlay.mod.setDefault.value\", \"value is required\", [\"value\"]);\n\t\t\tbreak;\n\t\tcase \"addHelpText\":\n\t\t\tif (!modification.text?.trim()) push(\"overlay.mod.addHelpText.text\", \"text is required\", [\"text\"]);\n\t\t\tbreak;\n\t\tcase \"makeRequired\":\n\t\tcase \"hideField\": break;\n\t\tdefault: {\n\t\t\tconst exhaustive = modification;\n\t\t\tthrow new Error(`Unsupported overlay modification ${exhaustive?.type ?? \"unknown\"}`);\n\t\t}\n\t}\n}\nfunction isFieldModification(mod) {\n\treturn \"field\" in mod;\n}\nfunction assertOverlayValid(spec, validator = defaultOverlayValidator) {\n\tconst result = validator(spec);\n\tif (!result.valid) {\n\t\tconst message = result.issues.map((issue) => `${issue.code}: ${issue.message}`).join(\"; \");\n\t\tthrow new Error(`Invalid OverlaySpec \"${spec.overlayId}\": ${message}`);\n\t}\n}\n\n//#endregion\nexport { assertOverlayValid, defaultOverlayValidator, validateOverlaySpec };\n//# sourceMappingURL=validator.js.map"],"mappings":";AACA,MAAM,cAAc;CACnB;CACA;CACA;CACA;CACA;CACA;AACD,MAAM,2BAA2B,SAAS,oBAAoB,KAAK;AACnE,SAAS,oBAAoB,MAAM;CAClC,MAAM,SAAS,EAAE;AACjB,KAAI,CAAC,KAAK,WAAW,MAAM,CAAE,QAAO,KAAK;EACxC,MAAM;EACN,SAAS;EACT,MAAM,CAAC,YAAY;EACnB,CAAC;AACF,KAAI,CAAC,KAAK,SAAS,MAAM,CAAE,QAAO,KAAK;EACtC,MAAM;EACN,SAAS;EACT,MAAM,CAAC,UAAU;EACjB,CAAC;AACF,KAAI,CAAC,YAAY,MAAM,QAAQ;EAC9B,MAAM,QAAQ,KAAK,YAAY;AAC/B,SAAO,OAAO,UAAU,YAAY,MAAM,MAAM,CAAC,SAAS;GACzD,CAAE,QAAO,KAAK;EACf,MAAM;EACN,SAAS;EACT,MAAM,CAAC,YAAY;EACnB,CAAC;AACF,KAAI,CAAC,KAAK,eAAe,OAAQ,QAAO,KAAK;EAC5C,MAAM;EACN,SAAS;EACT,MAAM,CAAC,gBAAgB;EACvB,CAAC;KACG,MAAK,cAAc,SAAS,KAAK,QAAQ;AAC7C,uBAAqB,KAAK,CAAC,iBAAiB,OAAO,IAAI,CAAC,EAAE,OAAO;GAChE;AACF,QAAO;EACN,OAAO,OAAO,WAAW;EACzB;EACA;;AAEF,SAAS,qBAAqB,cAAc,MAAM,QAAQ;CACzD,MAAM,QAAQ,MAAM,SAAS,cAAc;AAC1C,SAAO,KAAK;GACX;GACA;GACA,MAAM,YAAY,CAAC,GAAG,MAAM,GAAG,UAAU,GAAG;GAC5C,CAAC;;AAEH,KAAI,oBAAoB,aAAa,EACpC;MAAI,CAAC,aAAa,OAAO,MAAM,CAAE,MAAK,qBAAqB,2CAA2C,CAAC,QAAQ,CAAC;;AAEjH,SAAQ,aAAa,MAArB;EACC,KAAK;AACJ,OAAI,CAAC,aAAa,UAAU,MAAM,CAAE,MAAK,oCAAoC,wBAAwB,CAAC,WAAW,CAAC;AAClH;EACD,KAAK,iBAAiB;AACrB,OAAI,CAAC,aAAa,QAAQ,OAAQ,MAAK,oCAAoC,+BAA+B,CAAC,SAAS,CAAC;GACrH,MAAM,uBAAuB,IAAI,KAAK;AACtC,QAAK,MAAM,SAAS,aAAa,UAAU,EAAE,EAAE;AAC9C,QAAI,CAAC,OAAO,MAAM,EAAE;AACnB,UAAK,0CAA0C,mCAAmC;AAClF;;AAED,QAAI,KAAK,IAAI,MAAM,EAAE;AACpB,UAAK,8CAA8C,UAAU,MAAM,6BAA6B;AAChG;;AAED,SAAK,IAAI,MAAM;;AAEhB;;EAED,KAAK;AACJ,OAAI,aAAa,UAAU,KAAK,EAAG,MAAK,gCAAgC,qBAAqB,CAAC,QAAQ,CAAC;AACvG;EACD,KAAK;AACJ,OAAI,CAAC,aAAa,MAAM,MAAM,CAAE,MAAK,gCAAgC,oBAAoB,CAAC,OAAO,CAAC;AAClG;EACD,KAAK;EACL,KAAK,YAAa;EAClB,SAAS;GACR,MAAM,aAAa;AACnB,SAAM,IAAI,MAAM,oCAAoC,YAAY,QAAQ,YAAY;;;;AAIvF,SAAS,oBAAoB,KAAK;AACjC,QAAO,WAAW"}
@@ -51,4 +51,5 @@ function detectLayout(summary) {
51
51
  }
52
52
 
53
53
  //#endregion
54
- export { BehaviorAnalyzer };
54
+ export { BehaviorAnalyzer };
55
+ //# sourceMappingURL=analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.js","names":[],"sources":["../../../../../../libs/personalization/dist/analyzer.js"],"sourcesContent":["//#region src/analyzer.ts\nconst DEFAULT_THRESHOLD = 3;\nvar BehaviorAnalyzer = class {\n\tconstructor(store, options = {}) {\n\t\tthis.store = store;\n\t\tthis.options = options;\n\t}\n\tasync analyze(params) {\n\t\tconst query = {\n\t\t\ttenantId: params.tenantId,\n\t\t\tuserId: params.userId,\n\t\t\trole: params.role\n\t\t};\n\t\tif (params.windowMs) query.since = Date.now() - params.windowMs;\n\t\treturn buildInsights(await this.store.summarize(query), this.options);\n\t}\n};\nfunction buildInsights(summary, options) {\n\tconst threshold = options.fieldInactivityThreshold ?? DEFAULT_THRESHOLD;\n\tconst minSamples = options.minSamples ?? 10;\n\tconst ignoredFields = [];\n\tconst frequentlyUsedFields = [];\n\tfor (const [field, count] of Object.entries(summary.fieldCounts)) {\n\t\tif (count <= threshold) ignoredFields.push(field);\n\t\tif (count >= threshold * 4) frequentlyUsedFields.push(field);\n\t}\n\tconst workflowBottlenecks = Object.entries(summary.workflowStepCounts).flatMap(([workflow, steps]) => {\n\t\tconst total = Object.values(steps).reduce((acc, value) => acc + value, 0);\n\t\tif (!total || total < minSamples) return [];\n\t\treturn Object.entries(steps).filter(([, count]) => count / total < .4).map(([step, count]) => ({\n\t\t\tworkflow,\n\t\t\tstep,\n\t\t\tdropRate: 1 - count / total\n\t\t}));\n\t});\n\tconst layoutPreference = detectLayout(summary);\n\treturn {\n\t\tunusedFields: ignoredFields,\n\t\tsuggestedHiddenFields: ignoredFields.slice(0, 5),\n\t\tfrequentlyUsedFields: frequentlyUsedFields.slice(0, 10),\n\t\tworkflowBottlenecks,\n\t\tlayoutPreference\n\t};\n}\nfunction detectLayout(summary) {\n\tconst fieldCount = Object.keys(summary.fieldCounts).length;\n\tif (!fieldCount) return;\n\tif (fieldCount >= 15) return \"table\";\n\tif (fieldCount >= 8) return \"grid\";\n\treturn \"form\";\n}\n\n//#endregion\nexport { BehaviorAnalyzer };\n//# sourceMappingURL=analyzer.js.map"],"mappings":";AACA,MAAM,oBAAoB;AAC1B,IAAI,mBAAmB,MAAM;CAC5B,YAAY,OAAO,UAAU,EAAE,EAAE;AAChC,OAAK,QAAQ;AACb,OAAK,UAAU;;CAEhB,MAAM,QAAQ,QAAQ;EACrB,MAAM,QAAQ;GACb,UAAU,OAAO;GACjB,QAAQ,OAAO;GACf,MAAM,OAAO;GACb;AACD,MAAI,OAAO,SAAU,OAAM,QAAQ,KAAK,KAAK,GAAG,OAAO;AACvD,SAAO,cAAc,MAAM,KAAK,MAAM,UAAU,MAAM,EAAE,KAAK,QAAQ;;;AAGvE,SAAS,cAAc,SAAS,SAAS;CACxC,MAAM,YAAY,QAAQ,4BAA4B;CACtD,MAAM,aAAa,QAAQ,cAAc;CACzC,MAAM,gBAAgB,EAAE;CACxB,MAAM,uBAAuB,EAAE;AAC/B,MAAK,MAAM,CAAC,OAAO,UAAU,OAAO,QAAQ,QAAQ,YAAY,EAAE;AACjE,MAAI,SAAS,UAAW,eAAc,KAAK,MAAM;AACjD,MAAI,SAAS,YAAY,EAAG,sBAAqB,KAAK,MAAM;;CAE7D,MAAM,sBAAsB,OAAO,QAAQ,QAAQ,mBAAmB,CAAC,SAAS,CAAC,UAAU,WAAW;EACrG,MAAM,QAAQ,OAAO,OAAO,MAAM,CAAC,QAAQ,KAAK,UAAU,MAAM,OAAO,EAAE;AACzE,MAAI,CAAC,SAAS,QAAQ,WAAY,QAAO,EAAE;AAC3C,SAAO,OAAO,QAAQ,MAAM,CAAC,QAAQ,GAAG,WAAW,QAAQ,QAAQ,GAAG,CAAC,KAAK,CAAC,MAAM,YAAY;GAC9F;GACA;GACA,UAAU,IAAI,QAAQ;GACtB,EAAE;GACF;CACF,MAAM,mBAAmB,aAAa,QAAQ;AAC9C,QAAO;EACN,cAAc;EACd,uBAAuB,cAAc,MAAM,GAAG,EAAE;EAChD,sBAAsB,qBAAqB,MAAM,GAAG,GAAG;EACvD;EACA;EACA;;AAEF,SAAS,aAAa,SAAS;CAC9B,MAAM,aAAa,OAAO,KAAK,QAAQ,YAAY,CAAC;AACpD,KAAI,CAAC,WAAY;AACjB,KAAI,cAAc,GAAI,QAAO;AAC7B,KAAI,cAAc,EAAG,QAAO;AAC5B,QAAO"}
@@ -55,4 +55,5 @@ function filterEvents(events, query) {
55
55
  }
56
56
 
57
57
  //#endregion
58
- export { InMemoryBehaviorStore };
58
+ export { InMemoryBehaviorStore };
59
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","names":[],"sources":["../../../../../../libs/personalization/dist/store.js"],"sourcesContent":["//#region src/store.ts\nvar InMemoryBehaviorStore = class {\n\tevents = [];\n\tasync record(event) {\n\t\tthis.events.push(event);\n\t}\n\tasync bulkRecord(events) {\n\t\tthis.events.push(...events);\n\t}\n\tasync query(query) {\n\t\treturn filterEvents(this.events, query);\n\t}\n\tasync summarize(query) {\n\t\tconst events = await this.query(query);\n\t\tconst summary = {\n\t\t\tfieldCounts: {},\n\t\t\tfeatureCounts: {},\n\t\t\tworkflowStepCounts: {},\n\t\t\ttotalEvents: events.length\n\t\t};\n\t\tevents.forEach((event) => {\n\t\t\tswitch (event.type) {\n\t\t\t\tcase \"field_access\":\n\t\t\t\t\tsummary.fieldCounts[event.field] = (summary.fieldCounts[event.field] ?? 0) + 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"feature_usage\":\n\t\t\t\t\tsummary.featureCounts[event.feature] = (summary.featureCounts[event.feature] ?? 0) + 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"workflow_step\": {\n\t\t\t\t\tconst workflow = summary.workflowStepCounts[event.workflow] ??= {};\n\t\t\t\t\tworkflow[event.step] = (workflow[event.step] ?? 0) + 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: break;\n\t\t\t}\n\t\t});\n\t\treturn summary;\n\t}\n\tasync clear() {\n\t\tthis.events = [];\n\t}\n};\nfunction filterEvents(events, query) {\n\treturn events.filter((event) => {\n\t\tif (query.tenantId && event.tenantId !== query.tenantId) return false;\n\t\tif (query.userId && event.userId !== query.userId) return false;\n\t\tif (query.role && event.role !== query.role) return false;\n\t\tif (query.since && event.timestamp < query.since) return false;\n\t\tif (query.until && event.timestamp > query.until) return false;\n\t\tif (query.operation && event.type === \"field_access\" && event.operation !== query.operation) return false;\n\t\tif (query.feature && event.type === \"feature_usage\" && event.feature !== query.feature) return false;\n\t\tif (query.workflow && event.type === \"workflow_step\" && event.workflow !== query.workflow) return false;\n\t\treturn true;\n\t});\n}\n\n//#endregion\nexport { InMemoryBehaviorStore };\n//# sourceMappingURL=store.js.map"],"mappings":";AACA,IAAI,wBAAwB,MAAM;CACjC,SAAS,EAAE;CACX,MAAM,OAAO,OAAO;AACnB,OAAK,OAAO,KAAK,MAAM;;CAExB,MAAM,WAAW,QAAQ;AACxB,OAAK,OAAO,KAAK,GAAG,OAAO;;CAE5B,MAAM,MAAM,OAAO;AAClB,SAAO,aAAa,KAAK,QAAQ,MAAM;;CAExC,MAAM,UAAU,OAAO;EACtB,MAAM,SAAS,MAAM,KAAK,MAAM,MAAM;EACtC,MAAM,UAAU;GACf,aAAa,EAAE;GACf,eAAe,EAAE;GACjB,oBAAoB,EAAE;GACtB,aAAa,OAAO;GACpB;AACD,SAAO,SAAS,UAAU;AACzB,WAAQ,MAAM,MAAd;IACC,KAAK;AACJ,aAAQ,YAAY,MAAM,UAAU,QAAQ,YAAY,MAAM,UAAU,KAAK;AAC7E;IACD,KAAK;AACJ,aAAQ,cAAc,MAAM,YAAY,QAAQ,cAAc,MAAM,YAAY,KAAK;AACrF;IACD,KAAK,iBAAiB;KACrB,MAAM,WAAW,QAAQ,mBAAmB,MAAM,cAAc,EAAE;AAClE,cAAS,MAAM,SAAS,SAAS,MAAM,SAAS,KAAK;AACrD;;IAED,QAAS;;IAET;AACF,SAAO;;CAER,MAAM,QAAQ;AACb,OAAK,SAAS,EAAE;;;AAGlB,SAAS,aAAa,QAAQ,OAAO;AACpC,QAAO,OAAO,QAAQ,UAAU;AAC/B,MAAI,MAAM,YAAY,MAAM,aAAa,MAAM,SAAU,QAAO;AAChE,MAAI,MAAM,UAAU,MAAM,WAAW,MAAM,OAAQ,QAAO;AAC1D,MAAI,MAAM,QAAQ,MAAM,SAAS,MAAM,KAAM,QAAO;AACpD,MAAI,MAAM,SAAS,MAAM,YAAY,MAAM,MAAO,QAAO;AACzD,MAAI,MAAM,SAAS,MAAM,YAAY,MAAM,MAAO,QAAO;AACzD,MAAI,MAAM,aAAa,MAAM,SAAS,kBAAkB,MAAM,cAAc,MAAM,UAAW,QAAO;AACpG,MAAI,MAAM,WAAW,MAAM,SAAS,mBAAmB,MAAM,YAAY,MAAM,QAAS,QAAO;AAC/F,MAAI,MAAM,YAAY,MAAM,SAAS,mBAAmB,MAAM,aAAa,MAAM,SAAU,QAAO;AAClG,SAAO;GACN"}
@@ -89,4 +89,5 @@ var BehaviorTracker = class {
89
89
  const createBehaviorTracker = (options) => new BehaviorTracker(options);
90
90
 
91
91
  //#endregion
92
- export { createBehaviorTracker };
92
+ export { createBehaviorTracker };
93
+ //# sourceMappingURL=tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.js","names":[],"sources":["../../../../../../libs/personalization/dist/tracker.js"],"sourcesContent":["import { metrics, trace } from \"@opentelemetry/api\";\n\n//#region src/tracker.ts\nconst DEFAULT_BUFFER_SIZE = 25;\nvar BehaviorTracker = class {\n\tstore;\n\tcontext;\n\ttracer = trace.getTracer(\"lssm.personalization\", \"1.0.0\");\n\tcounter = metrics.getMeter(\"lssm.personalization\", \"1.0.0\").createCounter(\"lssm.personalization.events\", { description: \"Behavior events tracked for personalization\" });\n\tbuffer = [];\n\tbufferSize;\n\tflushTimer;\n\tconstructor(options) {\n\t\tthis.store = options.store;\n\t\tthis.context = options.context;\n\t\tthis.bufferSize = options.bufferSize ?? DEFAULT_BUFFER_SIZE;\n\t\tif (options.autoFlushIntervalMs) this.flushTimer = setInterval(() => {\n\t\t\tthis.flush();\n\t\t}, options.autoFlushIntervalMs);\n\t}\n\ttrackFieldAccess(input) {\n\t\tconst event = {\n\t\t\ttype: \"field_access\",\n\t\t\toperation: input.operation,\n\t\t\tfield: input.field,\n\t\t\ttimestamp: Date.now(),\n\t\t\t...this.context,\n\t\t\tmetadata: {\n\t\t\t\t...this.context.metadata,\n\t\t\t\t...input.metadata\n\t\t\t}\n\t\t};\n\t\tthis.enqueue(event);\n\t}\n\ttrackFeatureUsage(input) {\n\t\tconst event = {\n\t\t\ttype: \"feature_usage\",\n\t\t\tfeature: input.feature,\n\t\t\taction: input.action,\n\t\t\ttimestamp: Date.now(),\n\t\t\t...this.context,\n\t\t\tmetadata: {\n\t\t\t\t...this.context.metadata,\n\t\t\t\t...input.metadata\n\t\t\t}\n\t\t};\n\t\tthis.enqueue(event);\n\t}\n\ttrackWorkflowStep(input) {\n\t\tconst event = {\n\t\t\ttype: \"workflow_step\",\n\t\t\tworkflow: input.workflow,\n\t\t\tstep: input.step,\n\t\t\tstatus: input.status,\n\t\t\ttimestamp: Date.now(),\n\t\t\t...this.context,\n\t\t\tmetadata: {\n\t\t\t\t...this.context.metadata,\n\t\t\t\t...input.metadata\n\t\t\t}\n\t\t};\n\t\tthis.enqueue(event);\n\t}\n\tasync flush() {\n\t\tif (!this.buffer.length) return;\n\t\tconst events = this.buffer;\n\t\tthis.buffer = [];\n\t\tawait this.store.bulkRecord(events);\n\t}\n\tasync dispose() {\n\t\tif (this.flushTimer) clearInterval(this.flushTimer);\n\t\tawait this.flush();\n\t}\n\tenqueue(event) {\n\t\tthis.buffer.push(event);\n\t\tthis.counter.add(1, {\n\t\t\ttenantId: this.context.tenantId,\n\t\t\ttype: event.type\n\t\t});\n\t\tthis.tracer.startActiveSpan(`personalization.${event.type}`, (span) => {\n\t\t\tspan.setAttribute(\"tenant.id\", this.context.tenantId);\n\t\t\tif (this.context.userId) span.setAttribute(\"user.id\", this.context.userId);\n\t\t\tspan.setAttribute(\"personalization.event_type\", event.type);\n\t\t\tspan.end();\n\t\t});\n\t\tif (this.buffer.length >= this.bufferSize) this.flush();\n\t}\n};\nconst createBehaviorTracker = (options) => new BehaviorTracker(options);\n\n//#endregion\nexport { BehaviorTracker, createBehaviorTracker };\n//# sourceMappingURL=tracker.js.map"],"mappings":";;;AAGA,MAAM,sBAAsB;AAC5B,IAAI,kBAAkB,MAAM;CAC3B;CACA;CACA,SAAS,MAAM,UAAU,wBAAwB,QAAQ;CACzD,UAAU,QAAQ,SAAS,wBAAwB,QAAQ,CAAC,cAAc,+BAA+B,EAAE,aAAa,+CAA+C,CAAC;CACxK,SAAS,EAAE;CACX;CACA;CACA,YAAY,SAAS;AACpB,OAAK,QAAQ,QAAQ;AACrB,OAAK,UAAU,QAAQ;AACvB,OAAK,aAAa,QAAQ,cAAc;AACxC,MAAI,QAAQ,oBAAqB,MAAK,aAAa,kBAAkB;AACpE,QAAK,OAAO;KACV,QAAQ,oBAAoB;;CAEhC,iBAAiB,OAAO;EACvB,MAAM,QAAQ;GACb,MAAM;GACN,WAAW,MAAM;GACjB,OAAO,MAAM;GACb,WAAW,KAAK,KAAK;GACrB,GAAG,KAAK;GACR,UAAU;IACT,GAAG,KAAK,QAAQ;IAChB,GAAG,MAAM;IACT;GACD;AACD,OAAK,QAAQ,MAAM;;CAEpB,kBAAkB,OAAO;EACxB,MAAM,QAAQ;GACb,MAAM;GACN,SAAS,MAAM;GACf,QAAQ,MAAM;GACd,WAAW,KAAK,KAAK;GACrB,GAAG,KAAK;GACR,UAAU;IACT,GAAG,KAAK,QAAQ;IAChB,GAAG,MAAM;IACT;GACD;AACD,OAAK,QAAQ,MAAM;;CAEpB,kBAAkB,OAAO;EACxB,MAAM,QAAQ;GACb,MAAM;GACN,UAAU,MAAM;GAChB,MAAM,MAAM;GACZ,QAAQ,MAAM;GACd,WAAW,KAAK,KAAK;GACrB,GAAG,KAAK;GACR,UAAU;IACT,GAAG,KAAK,QAAQ;IAChB,GAAG,MAAM;IACT;GACD;AACD,OAAK,QAAQ,MAAM;;CAEpB,MAAM,QAAQ;AACb,MAAI,CAAC,KAAK,OAAO,OAAQ;EACzB,MAAM,SAAS,KAAK;AACpB,OAAK,SAAS,EAAE;AAChB,QAAM,KAAK,MAAM,WAAW,OAAO;;CAEpC,MAAM,UAAU;AACf,MAAI,KAAK,WAAY,eAAc,KAAK,WAAW;AACnD,QAAM,KAAK,OAAO;;CAEnB,QAAQ,OAAO;AACd,OAAK,OAAO,KAAK,MAAM;AACvB,OAAK,QAAQ,IAAI,GAAG;GACnB,UAAU,KAAK,QAAQ;GACvB,MAAM,MAAM;GACZ,CAAC;AACF,OAAK,OAAO,gBAAgB,mBAAmB,MAAM,SAAS,SAAS;AACtE,QAAK,aAAa,aAAa,KAAK,QAAQ,SAAS;AACrD,OAAI,KAAK,QAAQ,OAAQ,MAAK,aAAa,WAAW,KAAK,QAAQ,OAAO;AAC1E,QAAK,aAAa,8BAA8B,MAAM,KAAK;AAC3D,QAAK,KAAK;IACT;AACF,MAAI,KAAK,OAAO,UAAU,KAAK,WAAY,MAAK,OAAO;;;AAGzD,MAAM,yBAAyB,YAAY,IAAI,gBAAgB,QAAQ"}
@@ -25,4 +25,5 @@ function matches(params, extension) {
25
25
  }
26
26
 
27
27
  //#endregion
28
- export { WorkflowComposer };
28
+ export { WorkflowComposer };
29
+ //# sourceMappingURL=composer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composer.js","names":[],"sources":["../../../../../../libs/workflow-composer/dist/composer.js"],"sourcesContent":["import { applyWorkflowExtension } from \"./injector.js\";\n\n//#region src/composer.ts\nvar WorkflowComposer = class {\n\textensions = [];\n\tregister(extension) {\n\t\tthis.extensions.push(extension);\n\t\treturn this;\n\t}\n\tregisterMany(extensions) {\n\t\textensions.forEach((extension) => this.register(extension));\n\t\treturn this;\n\t}\n\tcompose(params) {\n\t\treturn this.extensions.filter((extension) => matches(params, extension)).sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0)).reduce((acc, extension) => applyWorkflowExtension(acc, extension), params.base);\n\t}\n};\nfunction matches(params, extension) {\n\tif (extension.workflow !== params.base.meta.name) return false;\n\tif (extension.baseVersion && extension.baseVersion !== params.base.meta.version) return false;\n\tif (extension.tenantId && extension.tenantId !== params.tenantId) return false;\n\tif (extension.role && extension.role !== params.role) return false;\n\tif (extension.device && extension.device !== params.device) return false;\n\treturn true;\n}\n\n//#endregion\nexport { WorkflowComposer };\n//# sourceMappingURL=composer.js.map"],"mappings":";;;AAGA,IAAI,mBAAmB,MAAM;CAC5B,aAAa,EAAE;CACf,SAAS,WAAW;AACnB,OAAK,WAAW,KAAK,UAAU;AAC/B,SAAO;;CAER,aAAa,YAAY;AACxB,aAAW,SAAS,cAAc,KAAK,SAAS,UAAU,CAAC;AAC3D,SAAO;;CAER,QAAQ,QAAQ;AACf,SAAO,KAAK,WAAW,QAAQ,cAAc,QAAQ,QAAQ,UAAU,CAAC,CAAC,MAAM,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,YAAY,GAAG,CAAC,QAAQ,KAAK,cAAc,uBAAuB,KAAK,UAAU,EAAE,OAAO,KAAK;;;AAGhN,SAAS,QAAQ,QAAQ,WAAW;AACnC,KAAI,UAAU,aAAa,OAAO,KAAK,KAAK,KAAM,QAAO;AACzD,KAAI,UAAU,eAAe,UAAU,gBAAgB,OAAO,KAAK,KAAK,QAAS,QAAO;AACxF,KAAI,UAAU,YAAY,UAAU,aAAa,OAAO,SAAU,QAAO;AACzE,KAAI,UAAU,QAAQ,UAAU,SAAS,OAAO,KAAM,QAAO;AAC7D,KAAI,UAAU,UAAU,UAAU,WAAW,OAAO,OAAQ,QAAO;AACnE,QAAO"}
@@ -69,4 +69,5 @@ function cloneWorkflowSpec(spec) {
69
69
  }
70
70
 
71
71
  //#endregion
72
- export { applyWorkflowExtension };
72
+ export { applyWorkflowExtension };
73
+ //# sourceMappingURL=injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injector.js","names":[],"sources":["../../../../../../libs/workflow-composer/dist/injector.js"],"sourcesContent":["import { validateExtension } from \"./validator.js\";\n\n//#region src/injector.ts\nfunction applyWorkflowExtension(base, extension) {\n\tvalidateExtension(extension, base);\n\tconst spec = cloneWorkflowSpec(base);\n\tconst steps = [...spec.definition.steps];\n\tlet transitions = [...spec.definition.transitions];\n\tconst hiddenSet = new Set(extension.hiddenSteps ?? []);\n\thiddenSet.forEach((stepId) => {\n\t\tconst idx = steps.findIndex((step) => step.id === stepId);\n\t\tif (idx !== -1) steps.splice(idx, 1);\n\t});\n\tif (hiddenSet.size) transitions = transitions.filter((transition) => !hiddenSet.has(transition.from) && !hiddenSet.has(transition.to));\n\textension.customSteps?.forEach((injection) => {\n\t\tinsertStep(steps, injection);\n\t\twireTransitions(transitions, injection);\n\t});\n\tspec.definition.steps = steps;\n\tspec.definition.transitions = dedupeTransitions(transitions);\n\tspec.meta = {\n\t\t...spec.meta,\n\t\tversion: spec.meta.version\n\t};\n\treturn spec;\n}\nfunction insertStep(steps, injection) {\n\tconst anchorIndex = resolveAnchorIndex(steps, injection);\n\tif (anchorIndex === -1) throw new Error(`Unable to place injected step \"${injection.inject.id}\"`);\n\tsteps.splice(anchorIndex, 0, { ...injection.inject });\n}\nfunction resolveAnchorIndex(steps, injection) {\n\tif (injection.after) {\n\t\tconst idx = steps.findIndex((step) => step.id === injection.after);\n\t\treturn idx === -1 ? -1 : idx + 1;\n\t}\n\tif (injection.before) {\n\t\tconst idx = steps.findIndex((step) => step.id === injection.before);\n\t\treturn idx === -1 ? -1 : idx;\n\t}\n\treturn steps.length;\n}\nfunction wireTransitions(transitions, injection) {\n\tif (!injection.inject.id) return;\n\tif (injection.transitionFrom) transitions.push({\n\t\tfrom: injection.transitionFrom,\n\t\tto: injection.inject.id,\n\t\tcondition: injection.when\n\t});\n\tif (injection.transitionTo) transitions.push({\n\t\tfrom: injection.inject.id,\n\t\tto: injection.transitionTo,\n\t\tcondition: injection.when\n\t});\n}\nfunction dedupeTransitions(transitions) {\n\tconst seen = /* @__PURE__ */ new Set();\n\tconst result = [];\n\ttransitions.forEach((transition) => {\n\t\tconst key = `${transition.from}->${transition.to}:${transition.condition ?? \"\"}`;\n\t\tif (seen.has(key)) return;\n\t\tseen.add(key);\n\t\tresult.push(transition);\n\t});\n\treturn result;\n}\nfunction cloneWorkflowSpec(spec) {\n\treturn JSON.parse(JSON.stringify(spec));\n}\n\n//#endregion\nexport { applyWorkflowExtension };\n//# sourceMappingURL=injector.js.map"],"mappings":";;;AAGA,SAAS,uBAAuB,MAAM,WAAW;AAChD,mBAAkB,WAAW,KAAK;CAClC,MAAM,OAAO,kBAAkB,KAAK;CACpC,MAAM,QAAQ,CAAC,GAAG,KAAK,WAAW,MAAM;CACxC,IAAI,cAAc,CAAC,GAAG,KAAK,WAAW,YAAY;CAClD,MAAM,YAAY,IAAI,IAAI,UAAU,eAAe,EAAE,CAAC;AACtD,WAAU,SAAS,WAAW;EAC7B,MAAM,MAAM,MAAM,WAAW,SAAS,KAAK,OAAO,OAAO;AACzD,MAAI,QAAQ,GAAI,OAAM,OAAO,KAAK,EAAE;GACnC;AACF,KAAI,UAAU,KAAM,eAAc,YAAY,QAAQ,eAAe,CAAC,UAAU,IAAI,WAAW,KAAK,IAAI,CAAC,UAAU,IAAI,WAAW,GAAG,CAAC;AACtI,WAAU,aAAa,SAAS,cAAc;AAC7C,aAAW,OAAO,UAAU;AAC5B,kBAAgB,aAAa,UAAU;GACtC;AACF,MAAK,WAAW,QAAQ;AACxB,MAAK,WAAW,cAAc,kBAAkB,YAAY;AAC5D,MAAK,OAAO;EACX,GAAG,KAAK;EACR,SAAS,KAAK,KAAK;EACnB;AACD,QAAO;;AAER,SAAS,WAAW,OAAO,WAAW;CACrC,MAAM,cAAc,mBAAmB,OAAO,UAAU;AACxD,KAAI,gBAAgB,GAAI,OAAM,IAAI,MAAM,kCAAkC,UAAU,OAAO,GAAG,GAAG;AACjG,OAAM,OAAO,aAAa,GAAG,EAAE,GAAG,UAAU,QAAQ,CAAC;;AAEtD,SAAS,mBAAmB,OAAO,WAAW;AAC7C,KAAI,UAAU,OAAO;EACpB,MAAM,MAAM,MAAM,WAAW,SAAS,KAAK,OAAO,UAAU,MAAM;AAClE,SAAO,QAAQ,KAAK,KAAK,MAAM;;AAEhC,KAAI,UAAU,QAAQ;EACrB,MAAM,MAAM,MAAM,WAAW,SAAS,KAAK,OAAO,UAAU,OAAO;AACnE,SAAO,QAAQ,KAAK,KAAK;;AAE1B,QAAO,MAAM;;AAEd,SAAS,gBAAgB,aAAa,WAAW;AAChD,KAAI,CAAC,UAAU,OAAO,GAAI;AAC1B,KAAI,UAAU,eAAgB,aAAY,KAAK;EAC9C,MAAM,UAAU;EAChB,IAAI,UAAU,OAAO;EACrB,WAAW,UAAU;EACrB,CAAC;AACF,KAAI,UAAU,aAAc,aAAY,KAAK;EAC5C,MAAM,UAAU,OAAO;EACvB,IAAI,UAAU;EACd,WAAW,UAAU;EACrB,CAAC;;AAEH,SAAS,kBAAkB,aAAa;CACvC,MAAM,uBAAuB,IAAI,KAAK;CACtC,MAAM,SAAS,EAAE;AACjB,aAAY,SAAS,eAAe;EACnC,MAAM,MAAM,GAAG,WAAW,KAAK,IAAI,WAAW,GAAG,GAAG,WAAW,aAAa;AAC5E,MAAI,KAAK,IAAI,IAAI,CAAE;AACnB,OAAK,IAAI,IAAI;AACb,SAAO,KAAK,WAAW;GACtB;AACF,QAAO;;AAER,SAAS,kBAAkB,MAAM;AAChC,QAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC"}
@@ -33,4 +33,5 @@ function validateExtension(extension, base) {
33
33
  }
34
34
 
35
35
  //#endregion
36
- export { validateExtension };
36
+ export { validateExtension };
37
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","names":[],"sources":["../../../../../../libs/workflow-composer/dist/validator.js"],"sourcesContent":["//#region src/validator.ts\nfunction validateExtension(extension, base) {\n\tconst issues = [];\n\tconst stepIds = new Set(base.definition.steps.map((step) => step.id));\n\textension.customSteps?.forEach((injection, idx) => {\n\t\tif (!injection.inject.id) issues.push({\n\t\t\tcode: \"workflow.extension.step.id\",\n\t\t\tmessage: `customSteps[${idx}] is missing an id`\n\t\t});\n\t\tif (!injection.after && !injection.before) issues.push({\n\t\t\tcode: \"workflow.extension.step.anchor\",\n\t\t\tmessage: `customSteps[${idx}] must set after or before`\n\t\t});\n\t\tif (injection.after && !stepIds.has(injection.after)) issues.push({\n\t\t\tcode: \"workflow.extension.step.after\",\n\t\t\tmessage: `customSteps[${idx}] references unknown step \"${injection.after}\"`\n\t\t});\n\t\tif (injection.before && !stepIds.has(injection.before)) issues.push({\n\t\t\tcode: \"workflow.extension.step.before\",\n\t\t\tmessage: `customSteps[${idx}] references unknown step \"${injection.before}\"`\n\t\t});\n\t});\n\textension.hiddenSteps?.forEach((stepId) => {\n\t\tif (!stepIds.has(stepId)) issues.push({\n\t\t\tcode: \"workflow.extension.hidden-step\",\n\t\t\tmessage: `hidden step \"${stepId}\" does not exist`\n\t\t});\n\t});\n\tif (issues.length) {\n\t\tconst reason = issues.map((issue) => `${issue.code}: ${issue.message}`).join(\"; \");\n\t\tthrow new Error(`Invalid workflow extension for ${extension.workflow}: ${reason}`);\n\t}\n}\n\n//#endregion\nexport { validateExtension };\n//# sourceMappingURL=validator.js.map"],"mappings":";AACA,SAAS,kBAAkB,WAAW,MAAM;CAC3C,MAAM,SAAS,EAAE;CACjB,MAAM,UAAU,IAAI,IAAI,KAAK,WAAW,MAAM,KAAK,SAAS,KAAK,GAAG,CAAC;AACrE,WAAU,aAAa,SAAS,WAAW,QAAQ;AAClD,MAAI,CAAC,UAAU,OAAO,GAAI,QAAO,KAAK;GACrC,MAAM;GACN,SAAS,eAAe,IAAI;GAC5B,CAAC;AACF,MAAI,CAAC,UAAU,SAAS,CAAC,UAAU,OAAQ,QAAO,KAAK;GACtD,MAAM;GACN,SAAS,eAAe,IAAI;GAC5B,CAAC;AACF,MAAI,UAAU,SAAS,CAAC,QAAQ,IAAI,UAAU,MAAM,CAAE,QAAO,KAAK;GACjE,MAAM;GACN,SAAS,eAAe,IAAI,6BAA6B,UAAU,MAAM;GACzE,CAAC;AACF,MAAI,UAAU,UAAU,CAAC,QAAQ,IAAI,UAAU,OAAO,CAAE,QAAO,KAAK;GACnE,MAAM;GACN,SAAS,eAAe,IAAI,6BAA6B,UAAU,OAAO;GAC1E,CAAC;GACD;AACF,WAAU,aAAa,SAAS,WAAW;AAC1C,MAAI,CAAC,QAAQ,IAAI,OAAO,CAAE,QAAO,KAAK;GACrC,MAAM;GACN,SAAS,gBAAgB,OAAO;GAChC,CAAC;GACD;AACF,KAAI,OAAO,QAAQ;EAClB,MAAM,SAAS,OAAO,KAAK,UAAU,GAAG,MAAM,KAAK,IAAI,MAAM,UAAU,CAAC,KAAK,KAAK;AAClF,QAAM,IAAI,MAAM,kCAAkC,UAAU,SAAS,IAAI,SAAS"}
@@ -1,4 +1,5 @@
1
1
  //#region src/overlay-customization.d.ts
2
2
  declare function runOverlayCustomizationExample(): Promise<void>;
3
3
  //#endregion
4
- export { runOverlayCustomizationExample };
4
+ export { runOverlayCustomizationExample };
5
+ //# sourceMappingURL=overlay-customization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-customization.d.ts","names":[],"sources":["../src/overlay-customization.ts"],"sourcesContent":[],"mappings":";iBAWsB,8BAAA,CAAA,GAAkC"}
@@ -50,4 +50,5 @@ async function runOverlayCustomizationExample() {
50
50
  }
51
51
 
52
52
  //#endregion
53
- export { runOverlayCustomizationExample };
53
+ export { runOverlayCustomizationExample };
54
+ //# sourceMappingURL=overlay-customization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlay-customization.js","names":[],"sources":["../src/overlay-customization.ts"],"sourcesContent":["import { defineOverlay } from '@lssm/lib.overlay-engine/spec';\nimport { signOverlay } from '@lssm/lib.overlay-engine/signer';\nimport { OverlayEngine, OverlayRegistry } from '@lssm/lib.overlay-engine';\nimport { Logger, LogLevel } from '@lssm/lib.logger';\n\nconst logger = new Logger({\n level: process.env.NODE_ENV === 'production' ? LogLevel.INFO : LogLevel.DEBUG,\n environment: process.env.NODE_ENV || 'development',\n enableColors: process.env.NODE_ENV !== 'production',\n});\n\nexport async function runOverlayCustomizationExample(): Promise<void> {\n const registry = new OverlayRegistry({ allowUnsigned: true });\n const engine = new OverlayEngine({ registry });\n\n const overlay = defineOverlay({\n overlayId: 'demo-overlay',\n version: '1.0.0',\n appliesTo: {\n capability: 'billing.createOrder',\n tenantId: 'demo',\n },\n modifications: [\n { type: 'hideField', field: 'internalNotes' },\n {\n type: 'renameLabel',\n field: 'customerReference',\n newLabel: 'PO Number',\n },\n ],\n });\n\n const signed = await signOverlay(overlay, process.env.PRIVATE_KEY_PEM ?? '');\n registry.register(signed);\n\n const result = engine.apply({\n target: {\n fields: [\n {\n key: 'customerReference',\n label: 'Customer Reference',\n visible: true,\n },\n { key: 'internalNotes', label: 'Internal Notes', visible: true },\n ],\n },\n capability: 'billing.createOrder',\n tenantId: 'demo',\n });\n\n logger.info('Overlay applied', { fields: result.target.fields });\n}\n"],"mappings":";;;;;;;;;;AAKA,MAAM,SAAS,IAAI,OAAO;CACxB,OAAO,QAAQ,IAAI,aAAa,eAAe,SAAS,OAAO,SAAS;CACxE,aAAa,QAAQ,IAAI,YAAY;CACrC,cAAc,QAAQ,IAAI,aAAa;CACxC,CAAC;AAEF,eAAsB,iCAAgD;CACpE,MAAM,WAAW,IAAI,gBAAgB,EAAE,eAAe,MAAM,CAAC;CAC7D,MAAM,SAAS,IAAI,cAAc,EAAE,UAAU,CAAC;CAmB9C,MAAM,SAAS,MAAM,YAjBL,cAAc;EAC5B,WAAW;EACX,SAAS;EACT,WAAW;GACT,YAAY;GACZ,UAAU;GACX;EACD,eAAe,CACb;GAAE,MAAM;GAAa,OAAO;GAAiB,EAC7C;GACE,MAAM;GACN,OAAO;GACP,UAAU;GACX,CACF;EACF,CAAC,EAEwC,QAAQ,IAAI,mBAAmB,GAAG;AAC5E,UAAS,SAAS,OAAO;CAEzB,MAAM,SAAS,OAAO,MAAM;EAC1B,QAAQ,EACN,QAAQ,CACN;GACE,KAAK;GACL,OAAO;GACP,SAAS;GACV,EACD;GAAE,KAAK;GAAiB,OAAO;GAAkB,SAAS;GAAM,CACjE,EACF;EACD,YAAY;EACZ,UAAU;EACX,CAAC;AAEF,QAAO,KAAK,mBAAmB,EAAE,QAAQ,OAAO,OAAO,QAAQ,CAAC"}
@@ -4,4 +4,5 @@ import { WorkflowSpec } from "@lssm/lib.contracts/workflow/spec";
4
4
  declare function composeTenantWorkflowExample(): WorkflowSpec;
5
5
  declare function logTenantWorkflowSteps(workflow: WorkflowSpec): void;
6
6
  //#endregion
7
- export { composeTenantWorkflowExample, logTenantWorkflowSteps };
7
+ export { composeTenantWorkflowExample, logTenantWorkflowSteps };
8
+ //# sourceMappingURL=workflow-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-extension.d.ts","names":[],"sources":["../src/workflow-extension.ts"],"sourcesContent":[],"mappings":";;;iBA8BgB,4BAAA,CAAA,GAAgC;iBAwBhC,sBAAA,WAAiC"}
@@ -64,4 +64,5 @@ function logTenantWorkflowSteps(workflow) {
64
64
  }
65
65
 
66
66
  //#endregion
67
- export { composeTenantWorkflowExample, logTenantWorkflowSteps };
67
+ export { composeTenantWorkflowExample, logTenantWorkflowSteps };
68
+ //# sourceMappingURL=workflow-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-extension.js","names":["BaseWorkflow: WorkflowSpec"],"sources":["../src/workflow-extension.ts"],"sourcesContent":["import type { WorkflowSpec } from '@lssm/lib.contracts/workflow/spec';\nimport { WorkflowComposer } from '@lssm/lib.workflow-composer';\nimport { Logger, LogLevel } from '@lssm/lib.logger';\n\nconst logger = new Logger({\n level: process.env.NODE_ENV === 'production' ? LogLevel.INFO : LogLevel.DEBUG,\n environment: process.env.NODE_ENV || 'development',\n enableColors: process.env.NODE_ENV !== 'production',\n});\n\nconst BaseWorkflow: WorkflowSpec = {\n meta: {\n name: 'billing.invoiceApproval',\n version: 1,\n title: 'Invoice Approval',\n owners: [],\n tags: [],\n description: '',\n domain: 'billing',\n stability: 'stable',\n },\n definition: {\n steps: [\n { id: 'validate-invoice', type: 'automation', label: 'Validate Invoice' },\n { id: 'final-approval', type: 'human', label: 'Final Approval' },\n ],\n transitions: [{ from: 'validate-invoice', to: 'final-approval' }],\n },\n};\n\nexport function composeTenantWorkflowExample(): WorkflowSpec {\n const composer = new WorkflowComposer();\n composer.register({\n workflow: 'billing.invoiceApproval',\n tenantId: 'acme',\n customSteps: [\n {\n after: 'validate-invoice',\n inject: {\n id: 'acme-legal',\n type: 'human',\n label: 'ACME Legal Review',\n },\n transitionTo: 'final-approval',\n },\n ],\n });\n\n return composer.compose({\n base: BaseWorkflow,\n tenantId: 'acme',\n });\n}\n\nexport function logTenantWorkflowSteps(workflow: WorkflowSpec): void {\n logger.info('Tenant workflow composed', {\n workflow: workflow.meta.name,\n steps: workflow.definition.steps.map((step) => step.id),\n });\n}\n"],"mappings":";;;;;;AAIA,MAAM,SAAS,IAAI,OAAO;CACxB,OAAO,QAAQ,IAAI,aAAa,eAAe,SAAS,OAAO,SAAS;CACxE,aAAa,QAAQ,IAAI,YAAY;CACrC,cAAc,QAAQ,IAAI,aAAa;CACxC,CAAC;AAEF,MAAMA,eAA6B;CACjC,MAAM;EACJ,MAAM;EACN,SAAS;EACT,OAAO;EACP,QAAQ,EAAE;EACV,MAAM,EAAE;EACR,aAAa;EACb,QAAQ;EACR,WAAW;EACZ;CACD,YAAY;EACV,OAAO,CACL;GAAE,IAAI;GAAoB,MAAM;GAAc,OAAO;GAAoB,EACzE;GAAE,IAAI;GAAkB,MAAM;GAAS,OAAO;GAAkB,CACjE;EACD,aAAa,CAAC;GAAE,MAAM;GAAoB,IAAI;GAAkB,CAAC;EAClE;CACF;AAED,SAAgB,+BAA6C;CAC3D,MAAM,WAAW,IAAI,kBAAkB;AACvC,UAAS,SAAS;EAChB,UAAU;EACV,UAAU;EACV,aAAa,CACX;GACE,OAAO;GACP,QAAQ;IACN,IAAI;IACJ,MAAM;IACN,OAAO;IACR;GACD,cAAc;GACf,CACF;EACF,CAAC;AAEF,QAAO,SAAS,QAAQ;EACtB,MAAM;EACN,UAAU;EACX,CAAC;;AAGJ,SAAgB,uBAAuB,UAA8B;AACnE,QAAO,KAAK,4BAA4B;EACtC,UAAU,SAAS,KAAK;EACxB,OAAO,SAAS,WAAW,MAAM,KAAK,SAAS,KAAK,GAAG;EACxD,CAAC"}