qnce-engine 1.3.2 → 1.4.1

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 (166) hide show
  1. package/README.md +134 -2
  2. package/dist/adapters/contracts.d.ts +1 -1
  3. package/dist/adapters/contracts.d.ts.map +1 -1
  4. package/dist/adapters/storage/MockAdapters.d.ts +89 -0
  5. package/dist/adapters/storage/MockAdapters.d.ts.map +1 -0
  6. package/dist/adapters/storage/MockAdapters.js +109 -0
  7. package/dist/adapters/storage/MockAdapters.js.map +1 -0
  8. package/dist/adapters/story/CustomJSONAdapter.d.ts +1 -1
  9. package/dist/adapters/story/CustomJSONAdapter.d.ts.map +1 -1
  10. package/dist/adapters/story/CustomJSONAdapter.js +20 -14
  11. package/dist/adapters/story/CustomJSONAdapter.js.map +1 -1
  12. package/dist/adapters/story/InkAdapter.d.ts +1 -1
  13. package/dist/adapters/story/InkAdapter.d.ts.map +1 -1
  14. package/dist/adapters/story/InkAdapter.js +7 -10
  15. package/dist/adapters/story/InkAdapter.js.map +1 -1
  16. package/dist/adapters/story/TwisonAdapter.d.ts +1 -1
  17. package/dist/adapters/story/TwisonAdapter.d.ts.map +1 -1
  18. package/dist/adapters/story/TwisonAdapter.js +2 -2
  19. package/dist/adapters/story/TwisonAdapter.js.map +1 -1
  20. package/dist/cli/audit.js +1 -0
  21. package/dist/cli/audit.js.map +1 -1
  22. package/dist/cli/import.d.ts.map +1 -1
  23. package/dist/cli/import.js +31 -20
  24. package/dist/cli/import.js.map +1 -1
  25. package/dist/cli/init.js +1 -0
  26. package/dist/cli/init.js.map +1 -1
  27. package/dist/cli/perf.d.ts.map +1 -1
  28. package/dist/cli/perf.js +30 -0
  29. package/dist/cli/perf.js.map +1 -1
  30. package/dist/cli/play.d.ts.map +1 -1
  31. package/dist/cli/play.js +90 -77
  32. package/dist/cli/play.js.map +1 -1
  33. package/dist/engine/condition.d.ts +25 -3
  34. package/dist/engine/condition.d.ts.map +1 -1
  35. package/dist/engine/condition.js +358 -64
  36. package/dist/engine/condition.js.map +1 -1
  37. package/dist/engine/core.d.ts +93 -1
  38. package/dist/engine/core.d.ts.map +1 -1
  39. package/dist/engine/core.js +405 -33
  40. package/dist/engine/core.js.map +1 -1
  41. package/dist/engine/demo-story.d.ts +1 -0
  42. package/dist/engine/demo-story.d.ts.map +1 -1
  43. package/dist/engine/demo-story.js +1 -0
  44. package/dist/engine/demo-story.js.map +1 -1
  45. package/dist/engine/error-factory.d.ts +86 -0
  46. package/dist/engine/error-factory.d.ts.map +1 -0
  47. package/dist/engine/error-factory.js +87 -0
  48. package/dist/engine/error-factory.js.map +1 -0
  49. package/dist/engine/errors.d.ts +3 -0
  50. package/dist/engine/errors.d.ts.map +1 -1
  51. package/dist/engine/errors.js +3 -0
  52. package/dist/engine/errors.js.map +1 -1
  53. package/dist/engine/validation.js +1 -1
  54. package/dist/engine/validation.js.map +1 -1
  55. package/dist/index.d.ts +20 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +29 -1
  58. package/dist/index.js.map +1 -1
  59. package/dist/integrations/react.d.ts +20 -3
  60. package/dist/integrations/react.d.ts.map +1 -1
  61. package/dist/integrations/react.js +15 -2
  62. package/dist/integrations/react.js.map +1 -1
  63. package/dist/narrative/branching/models.d.ts +1 -0
  64. package/dist/narrative/branching/models.d.ts.map +1 -1
  65. package/dist/narrative/branching/models.js.map +1 -1
  66. package/dist/performance/AdaptiveControllers.d.ts +51 -0
  67. package/dist/performance/AdaptiveControllers.d.ts.map +1 -0
  68. package/dist/performance/AdaptiveControllers.js +87 -0
  69. package/dist/performance/AdaptiveControllers.js.map +1 -0
  70. package/dist/performance/ContextPool.d.ts +1 -0
  71. package/dist/performance/ContextPool.d.ts.map +1 -0
  72. package/dist/performance/ContextPool.js +2 -0
  73. package/dist/performance/ContextPool.js.map +1 -0
  74. package/dist/performance/HotReloadDelta.d.ts +5 -0
  75. package/dist/performance/HotReloadDelta.d.ts.map +1 -1
  76. package/dist/performance/HotReloadDelta.js +18 -4
  77. package/dist/performance/HotReloadDelta.js.map +1 -1
  78. package/dist/performance/ObjectPool.d.ts.map +1 -1
  79. package/dist/performance/ObjectPool.js +4 -1
  80. package/dist/performance/ObjectPool.js.map +1 -1
  81. package/dist/performance/PerfReporter.d.ts +69 -0
  82. package/dist/performance/PerfReporter.d.ts.map +1 -1
  83. package/dist/performance/PerfReporter.js +314 -28
  84. package/dist/performance/PerfReporter.js.map +1 -1
  85. package/dist/performance/ThreadPool.d.ts +5 -0
  86. package/dist/performance/ThreadPool.d.ts.map +1 -1
  87. package/dist/performance/ThreadPool.js +33 -5
  88. package/dist/performance/ThreadPool.js.map +1 -1
  89. package/dist/persistence/StorageAdapters.d.ts.map +1 -1
  90. package/dist/persistence/StorageAdapters.js +13 -19
  91. package/dist/persistence/StorageAdapters.js.map +1 -1
  92. package/dist/qnce-engine.d.ts +2258 -0
  93. package/dist/quantum/entangler.d.ts +13 -0
  94. package/dist/quantum/entangler.d.ts.map +1 -0
  95. package/dist/quantum/entangler.js +24 -0
  96. package/dist/quantum/entangler.js.map +1 -0
  97. package/dist/quantum/flags.d.ts +24 -0
  98. package/dist/quantum/flags.d.ts.map +1 -0
  99. package/dist/quantum/flags.js +29 -0
  100. package/dist/quantum/flags.js.map +1 -0
  101. package/dist/quantum/integration.d.ts +26 -0
  102. package/dist/quantum/integration.d.ts.map +1 -0
  103. package/dist/quantum/integration.js +38 -0
  104. package/dist/quantum/integration.js.map +1 -0
  105. package/dist/quantum/measurement.d.ts +22 -0
  106. package/dist/quantum/measurement.d.ts.map +1 -0
  107. package/dist/quantum/measurement.js +44 -0
  108. package/dist/quantum/measurement.js.map +1 -0
  109. package/dist/quantum/phase.d.ts +20 -0
  110. package/dist/quantum/phase.d.ts.map +1 -0
  111. package/dist/quantum/phase.js +22 -0
  112. package/dist/quantum/phase.js.map +1 -0
  113. package/dist/quantum/types.d.ts +12 -0
  114. package/dist/quantum/types.d.ts.map +1 -0
  115. package/dist/quantum/types.js +5 -0
  116. package/dist/quantum/types.js.map +1 -0
  117. package/dist/schemas/validateStoryData.d.ts.map +1 -1
  118. package/dist/schemas/validateStoryData.js +8 -2
  119. package/dist/schemas/validateStoryData.js.map +1 -1
  120. package/dist/telemetry/core.d.ts +27 -1
  121. package/dist/telemetry/core.d.ts.map +1 -1
  122. package/dist/telemetry/core.js +63 -8
  123. package/dist/telemetry/core.js.map +1 -1
  124. package/dist/telemetry/types.d.ts +27 -0
  125. package/dist/telemetry/types.d.ts.map +1 -1
  126. package/dist/tsdoc-metadata.json +11 -0
  127. package/dist/ui/__tests__/AutosaveIndicator.test.js +10 -13
  128. package/dist/ui/__tests__/AutosaveIndicator.test.js.map +1 -1
  129. package/dist/ui/__tests__/UndoRedoControls.test.js +7 -9
  130. package/dist/ui/__tests__/UndoRedoControls.test.js.map +1 -1
  131. package/dist/ui/components/AutosaveIndicator.d.ts +1 -0
  132. package/dist/ui/components/AutosaveIndicator.d.ts.map +1 -1
  133. package/dist/ui/components/AutosaveIndicator.js +2 -1
  134. package/dist/ui/components/AutosaveIndicator.js.map +1 -1
  135. package/dist/ui/components/UndoRedoControls.d.ts +1 -0
  136. package/dist/ui/components/UndoRedoControls.d.ts.map +1 -1
  137. package/dist/ui/components/UndoRedoControls.js +1 -0
  138. package/dist/ui/components/UndoRedoControls.js.map +1 -1
  139. package/dist/ui/hooks/useKeyboardShortcuts.d.ts +1 -0
  140. package/dist/ui/hooks/useKeyboardShortcuts.d.ts.map +1 -1
  141. package/dist/ui/hooks/useKeyboardShortcuts.js +17 -5
  142. package/dist/ui/hooks/useKeyboardShortcuts.js.map +1 -1
  143. package/dist/ui/types.d.ts +6 -0
  144. package/dist/ui/types.d.ts.map +1 -1
  145. package/dist/ui/types.js +1 -0
  146. package/dist/ui/types.js.map +1 -1
  147. package/dist/utils/debug-logger.d.ts +20 -0
  148. package/dist/utils/debug-logger.d.ts.map +1 -0
  149. package/dist/utils/debug-logger.js +24 -0
  150. package/dist/utils/debug-logger.js.map +1 -0
  151. package/dist/utils/hot-profiler.d.ts +21 -0
  152. package/dist/utils/hot-profiler.d.ts.map +1 -0
  153. package/dist/utils/hot-profiler.js +36 -0
  154. package/dist/utils/hot-profiler.js.map +1 -0
  155. package/dist/utils/intern.d.ts +11 -0
  156. package/dist/utils/intern.d.ts.map +1 -0
  157. package/dist/utils/intern.js +45 -0
  158. package/dist/utils/intern.js.map +1 -0
  159. package/dist/utils/logger.d.ts +34 -0
  160. package/dist/utils/logger.d.ts.map +1 -0
  161. package/dist/utils/logger.js +115 -0
  162. package/dist/utils/logger.js.map +1 -0
  163. package/docs/PERFORMANCE.md +330 -0
  164. package/examples/fluent-builder-prototype.ts +71 -0
  165. package/examples/quantum-integration-demo.ts +51 -0
  166. package/package.json +25 -9
package/README.md CHANGED
@@ -2,22 +2,65 @@
2
2
 
3
3
  **Quantum Narrative Convergence Engine** - A framework-agnostic TypeScript library for creating interactive narrative experiences with quantum-inspired mechanics.
4
4
 
5
- > **🚀 Latest v1.3.1 (Import & Persistence):** New `qnce-import` CLI (Custom JSON, Twison with tags→`meta.tags`, experimental Ink), persistence adapters (Memory, LocalStorage, SessionStorage, File, IndexedDB), and `qnce-play` support for storage backends and non-interactive runs.
5
+ > **🚀 Latest v1.4.0 (Adaptive Performance & Quantum Primitives):** Adaptive perf pipeline (dynamic batch sizing, backoff, guarded retry, smoothed p95), expanded telemetry metrics, structured logging, memory optimizations, and first experimental quantum primitives (Entangler, Phase, Measurement). Previous 1.3.x delivered import & persistence foundations.
6
6
 
7
7
  [![npm version](https://badge.fury.io/js/qnce-engine.svg)](https://badge.fury.io/js/qnce-engine)
8
+ [![npm downloads](https://img.shields.io/npm/d18m/qnce-engine.svg)](https://www.npmjs.com/package/qnce-engine)
8
9
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
9
10
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
11
 
11
12
  > New: Lightweight, privacy-safe telemetry (opt-in). CLI now supports `--telemetry` and `--telemetry-report`, with p50/p95 batch send latency. See the wiki: [Analytics & Telemetry](https://github.com/ByteSower/qnce-engine/blob/main/wiki/Analytics-and-Telemetry.md).
12
13
 
14
+ ## TL;DR Quickstart
15
+
16
+ ```bash
17
+ # Install
18
+ npm install qnce-engine
19
+
20
+ # Play the demo story (from this repo)
21
+ node examples/quickstart-demo.js
22
+
23
+ # Live performance monitor (global CLI)
24
+ npm install -g qnce-engine
25
+ qnce-perf dashboard
26
+ qnce-perf stream 1000 | jq '.' # NDJSON streaming (optional)
27
+ ```
28
+
29
+ New to coding? Start here:
30
+ - Beginner Guide (no code): wiki/Beginner-Guide.md
31
+ - Getting Started: wiki/Getting-Started.md
32
+
33
+ ## Documentation & Guides
34
+
35
+ - Getting Started (wiki)
36
+ - Analytics & Telemetry (wiki)
37
+ - Branching Guide (wiki)
38
+ - Performance Tuning (wiki)
39
+ - Error Handling & Debug (docs/ERROR-HANDLING-AND-DEBUG.md)
40
+ - Adapter Lifecycle (docs/ADAPTER-LIFECYCLE.md)
41
+ - Deprecation Policy (docs/DEPRECATION-POLICY.md)
42
+
43
+ ## Public Roadmap
44
+
45
+ High-level, non-sensitive roadmap: [`docs/PUBLIC_ROADMAP.md`](./docs/PUBLIC_ROADMAP.md). Internal sprint artifacts are intentionally excluded from the repository for security/privacy.
46
+
47
+
13
48
  ## Core Concepts
14
49
 
15
50
  - **Superposition:** Multiple narrative outcomes exist simultaneously until a choice is made
16
51
  - **Collapse:** Player choices "collapse" the narrative to a specific path, updating state and flags
17
52
  - **Entanglement:** Early decisions affect later outcomes, enabling complex, interconnected stories
18
53
 
54
+ New to coding? See the no-code [Beginner Guide](wiki/Beginner-Guide.md) to create and play a story from the terminal.
55
+
19
56
  ## ✨ Current Features (v1.3.0)
20
57
 
58
+ ### 🧪 Experimental (Opt-in)
59
+ Early quantum helpers are available behind feature flags. They are off by default and safe to ignore. See the wiki for details and examples:
60
+
61
+ - Experimental APIs: https://github.com/ByteSower/qnce-engine/blob/main/wiki/API-Reference.md#-experimental-opt-in
62
+ - Release Notes (Unreleased): https://github.com/ByteSower/qnce-engine/blob/main/wiki/Release-Notes.md#unreleased
63
+
21
64
  ### 💾 State Persistence & Checkpoints
22
65
  - **Complete save/load system** with data integrity validation
23
66
  - **Lightweight checkpoints** for undo/redo functionality
@@ -53,6 +96,7 @@
53
96
  - **Background processing** for non-blocking operations
54
97
  - **Hot-reload capabilities** with <3.5ms story updates
55
98
  - **Comprehensive monitoring** with built-in CLI tools
99
+ - **Adaptive perf pipeline (beta)** with dynamic batch sizing & backoff
56
100
 
57
101
  #### Basic Flag-Based Conditions
58
102
 
@@ -215,6 +259,10 @@ engine.clearConditionEvaluator();
215
259
  - **Expression Caching:** Conditions are compiled once and cached for subsequent evaluations
216
260
  - **Safe Evaluation:** All expressions are sanitized to prevent code injection
217
261
  - **Minimal Overhead:** Choice filtering adds <1ms to `getAvailableChoices()` calls
262
+
263
+ ## Examples
264
+
265
+ - Opt‑in quantum helpers (FeatureFlags + attachQuantumFeatures): `examples/quantum-integration-demo.ts`
218
266
  - **Error Isolation:** Invalid conditions don't affect other choices in the same node
219
267
 
220
268
  ### ⚡ Performance Infrastructure
@@ -223,6 +271,7 @@ engine.clearConditionEvaluator();
223
271
  - **🔥 Hot-Reload:** <3.5ms live story updates with delta patching
224
272
  - **📊 Real-time Profiling:** Comprehensive event instrumentation and analysis
225
273
  - **🖥️ Live Monitoring:** `qnce-perf` CLI dashboard with performance alerts
274
+ - **🧠 Adaptive Flush (Beta):** Dynamic telemetry/perf batch sizing + rejection backoff for smoother throughput
226
275
 
227
276
  ### Performance Dashboard
228
277
  ```bash
@@ -234,10 +283,67 @@ qnce-perf live 1000
234
283
 
235
284
  # Export performance data
236
285
  qnce-perf export > performance-report.json
286
+
287
+ # Stream NDJSON (metrics+thread stats per line)
288
+ qnce-perf stream 1000 | jq '.'
237
289
  ```
238
290
 
239
291
  **[📚 Complete Performance Guide →](docs/PERFORMANCE.md)**
240
292
 
293
+ ### Adaptive Performance (Beta)
294
+
295
+ The PerfReporter now implements adaptive heuristics to optimize background flush behavior.
296
+
297
+ Key components:
298
+
299
+ 1. Exponential Backoff (R2)
300
+ - Triggered after consecutive flush dispatch rejections (e.g. thread pool queue full)
301
+ - Delay doubles each rejection (base 20ms, cap 500ms)
302
+ - Prevents tight retry loops and reduces queue pressure
303
+
304
+ 2. Dynamic Batch Sizing (R6)
305
+ - Starts from a configured base batch size
306
+ - Upscales when: backlog is large AND p95 send latency remains low (<25ms or <50ms tiers)
307
+ * Low latency + backlog > 2× base ⇒ scale toward up to ~3× base
308
+ * Low latency + backlog > 4× base ⇒ scale toward up to ~4× base (ceiling)
309
+ - Downscales aggressively when rejection streak ≥2 (divides batch by streak factor, never below 10)
310
+ - Exposed via `lastEffectiveBatchSize` in flush metrics snapshot
311
+
312
+ 3. Rejection Rate Metric
313
+ - `rejectionRate` (0–1) = rejectedFlushes / (accepted + rejected)
314
+ - Fast signal for sustained downstream pressure; enables dashboard or future auto-tuning hooks
315
+
316
+ 4. Debug Accessor
317
+ - `__getInternalPerfDebug()` includes: `consecutiveRejects`, `backoffDelayMs`, `nextAllowedFlushTime`, `lastEffectiveBatchSize`
318
+
319
+ 5. Environment Flag
320
+ - Set `QNCE_SUPPRESS_PERF_WARN=1` to silence repetitive flush failure warnings (e.g. in CI)
321
+ - Set `QNCE_DISABLE_ADAPTIVE_BATCH=1` to force fixed `batchSize` (disables dynamic scaling but keeps backoff)
322
+
323
+ Status & Stability:
324
+ - Marked `@beta` and subject to heuristic tuning (thresholds & scaling formula may evolve)
325
+ - Safe to consume metrics (`rejectionRate`, `lastEffectiveBatchSize`, `adaptiveEnabled`) for observability, not yet for strict alert SLAs
326
+
327
+ Example (inspection inside tests / diagnostics):
328
+ ```ts
329
+ import { getPerfReporter } from 'qnce-engine/performance';
330
+
331
+ const reporter = getPerfReporter();
332
+ const snapshot = reporter.getFlushMetrics();
333
+ console.log(snapshot.rejectionRate, snapshot.lastEffectiveBatchSize, snapshot.adaptiveEnabled);
334
+
335
+ // Internal (beta) debug details
336
+ // @ts-expect-error internal accessor
337
+ console.log(reporter.__getInternalPerfDebug());
338
+
339
+ // Force fixed batch sizing (example)
340
+ // (Re-create reporter before use to apply config/env values)
341
+ // const fixed = getPerfReporter({ batchSize: 100, disableAdaptiveBatch: true });
342
+ // Snapshot field `adaptiveEnabled` will be false when dynamic sizing disabled.
343
+ ```
344
+
345
+ If you experiment with tuning, please open an issue with: base batch size, average backlog, p95 latency trajectory, and observed rejectionRate.
346
+
241
347
  ## Installation
242
348
 
243
349
  ```bash
@@ -580,7 +686,7 @@ const engine = createQNCEEngine(storyData, {}, true, {
580
686
  // Monitor performance in real-time with CLI dashboard
581
687
  ```
582
688
 
583
- **📖 Complete Performance Guide:** [docs/PERFORMANCE_GUIDE.md](docs/PERFORMANCE_GUIDE.md)
689
+ **📖 Complete Performance Guide:** [docs/PERFORMANCE.md](docs/PERFORMANCE.md)
584
690
 
585
691
  ## Core API
586
692
 
@@ -1078,6 +1184,17 @@ npm run build:watch
1078
1184
  npm run lint
1079
1185
  ```
1080
1186
 
1187
+ ## 🔒 Security
1188
+
1189
+ QNCE Engine follows security best practices and provides guidance for secure usage:
1190
+
1191
+ - **Vulnerability Reporting**: Please report security vulnerabilities privately via [GitHub Security Advisories](https://github.com/ByteSower/qnce-engine/security/advisories/new)
1192
+ - **Supported Versions**: Security updates are provided for current stable versions (1.3.x) and previous major version (1.2.x)
1193
+ - **Input Validation**: Always validate story data and user inputs from untrusted sources
1194
+ - **State Security**: Use QNCE's built-in integrity validation when loading serialized states
1195
+
1196
+ For detailed security guidelines, see our [Security Policy](SECURITY.md).
1197
+
1081
1198
  ## License
1082
1199
 
1083
1200
  MIT - See LICENSE file for details.
@@ -1220,3 +1337,18 @@ try {
1220
1337
  }
1221
1338
  }
1222
1339
  ```
1340
+
1341
+ ## 🧪 Experimental (Opt-in)
1342
+
1343
+ These are off by default and safe to import. Enable with `FeatureFlags` when ready to experiment.
1344
+
1345
+ ```ts
1346
+ import { attachQuantumFeatures, FeatureFlags, Phase } from 'qnce-engine';
1347
+ const engine = createQNCEEngine(story);
1348
+ const q = attachQuantumFeatures(engine, new FeatureFlags({ 'quantum.phases': true, 'quantum.entanglement': true }));
1349
+ const alpha = new Phase('alpha', ({ flags }) => !!flags.unlockAlpha);
1350
+ q.isPhaseActive(alpha);
1351
+ q.entangle(e => e.bind('a', 'b', v => Number(v) * 2));
1352
+ ```
1353
+
1354
+ APIs: `FeatureFlags`, `Phase`, `Entangler`, `attachQuantumFeatures` (all `@experimental`).
@@ -11,7 +11,7 @@ export interface StoryAdapter {
11
11
  detect?(source: unknown): boolean;
12
12
  mapIds?(storyData: StoryData, strategy?: 'deterministic' | 'passthrough'): StoryData;
13
13
  }
14
- export interface SaveEnvelope<TPayload = any> {
14
+ export interface SaveEnvelope<TPayload = unknown> {
15
15
  version: number;
16
16
  storyId: string;
17
17
  storyVersion: string;
@@ -1 +1 @@
1
- {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/adapters/contracts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5E,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,gBAAgB,CAAC;IACjD,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;IAClC,MAAM,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,aAAa,GAAG,SAAS,CAAC;CACtF;AAGD,MAAM,WAAW,YAAY,CAAC,QAAQ,GAAG,GAAG;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,QAAQ,CAAC;CACnB"}
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/adapters/contracts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5E,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,gBAAgB,CAAC;IACjD,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;IAClC,MAAM,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,eAAe,GAAG,aAAa,GAAG,SAAS,CAAC;CACtF;AAGD,MAAM,WAAW,YAAY,CAAC,QAAQ,GAAG,OAAO;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,QAAQ,CAAC;CACnB"}
@@ -0,0 +1,89 @@
1
+ import type { StorageAdapter, SerializedState, PersistenceResult, SerializationOptions, LoadOptions } from '../../engine/types';
2
+ export interface FailingAdapterOptions {
3
+ failSaves?: boolean;
4
+ failLoads?: boolean;
5
+ failDeletes?: boolean;
6
+ delayMs?: number;
7
+ }
8
+ /** Adapter that can be configured to fail certain operations */
9
+ export declare class FailingStorageAdapter implements StorageAdapter {
10
+ private opts;
11
+ constructor(opts?: FailingAdapterOptions);
12
+ save(key: string, data: SerializedState, _options?: SerializationOptions): Promise<PersistenceResult>;
13
+ load(key: string, _options?: LoadOptions): Promise<SerializedState | null>;
14
+ delete(key: string): Promise<boolean>;
15
+ list(): Promise<string[]>;
16
+ exists(key: string): Promise<boolean>;
17
+ getStats(): Promise<{
18
+ totalSize: number;
19
+ keyCount: number;
20
+ [k: string]: unknown;
21
+ }>;
22
+ clear(): Promise<boolean>;
23
+ }
24
+ export interface RetryAdapterOptions {
25
+ failCount: number;
26
+ maxAttempts?: number;
27
+ delayMs?: number;
28
+ }
29
+ /** Adapter that fails first N saves then succeeds, to exercise retry logic (future). */
30
+ export declare class FlakySaveAdapter implements StorageAdapter {
31
+ private opts;
32
+ private attempts;
33
+ constructor(opts: RetryAdapterOptions);
34
+ save(key: string, data: SerializedState, _options?: SerializationOptions): Promise<PersistenceResult>;
35
+ load(key: string): Promise<SerializedState | null>;
36
+ delete(key: string): Promise<boolean>;
37
+ list(): Promise<string[]>;
38
+ exists(key: string): Promise<boolean>;
39
+ getStats(): Promise<{
40
+ totalSize: number;
41
+ keyCount: number;
42
+ [k: string]: unknown;
43
+ }>;
44
+ clear(): Promise<boolean>;
45
+ }
46
+ /** Adapter introducing artificial latency without failures. */
47
+ export declare class SlowStorageAdapter implements StorageAdapter {
48
+ private delayMs;
49
+ constructor(delayMs?: number);
50
+ private lag;
51
+ save(key: string, data: SerializedState): Promise<PersistenceResult>;
52
+ load(key: string): Promise<SerializedState | null>;
53
+ delete(key: string): Promise<boolean>;
54
+ list(): Promise<string[]>;
55
+ exists(key: string): Promise<boolean>;
56
+ getStats(): Promise<{
57
+ totalSize: number;
58
+ keyCount: number;
59
+ [k: string]: unknown;
60
+ }>;
61
+ clear(): Promise<boolean>;
62
+ }
63
+ export interface TimeoutAdapterOptions {
64
+ timeoutFailCount: number;
65
+ resolveDelayMs?: number;
66
+ timeoutDelayMs?: number;
67
+ }
68
+ /**
69
+ * Adapter that simulates network timeouts for the first N save attempts by rejecting.
70
+ * After those attempts it succeeds (optionally with a delay). Useful to exercise retry logic and telemetry attempts field.
71
+ */
72
+ export declare class TimeoutSaveAdapter implements StorageAdapter {
73
+ private opts;
74
+ private attempt;
75
+ constructor(opts: TimeoutAdapterOptions);
76
+ private delay;
77
+ save(key: string, data: SerializedState): Promise<PersistenceResult>;
78
+ load(key: string): Promise<SerializedState | null>;
79
+ delete(key: string): Promise<boolean>;
80
+ list(): Promise<string[]>;
81
+ exists(key: string): Promise<boolean>;
82
+ getStats(): Promise<{
83
+ totalSize: number;
84
+ keyCount: number;
85
+ [k: string]: unknown;
86
+ }>;
87
+ clear(): Promise<boolean>;
88
+ }
89
+ //# sourceMappingURL=MockAdapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockAdapters.d.ts","sourceRoot":"","sources":["../../../src/adapters/storage/MockAdapters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TimeoutSaveAdapter = exports.SlowStorageAdapter = exports.FlakySaveAdapter = exports.FailingStorageAdapter = void 0;
4
+ /** Simple in-memory backing store shared across mock adapters */
5
+ const store = new Map();
6
+ /** Adapter that can be configured to fail certain operations */
7
+ class FailingStorageAdapter {
8
+ opts;
9
+ constructor(opts = {}) {
10
+ this.opts = opts;
11
+ }
12
+ async save(key, data, _options) {
13
+ if (this.opts.delayMs)
14
+ await new Promise(r => setTimeout(r, this.opts.delayMs));
15
+ if (this.opts.failSaves)
16
+ return { success: false, error: 'mock-save-failed' };
17
+ store.set(key, data);
18
+ return { success: true };
19
+ }
20
+ async load(key, _options) {
21
+ if (this.opts.delayMs)
22
+ await new Promise(r => setTimeout(r, this.opts.delayMs));
23
+ if (this.opts.failLoads)
24
+ throw new Error('mock-load-failed');
25
+ return store.get(key) ?? null;
26
+ }
27
+ async delete(key) {
28
+ if (this.opts.failDeletes)
29
+ return false;
30
+ return store.delete(key);
31
+ }
32
+ async list() { return [...store.keys()]; }
33
+ async exists(key) { return store.has(key); }
34
+ async getStats() { return { totalSize: store.size, keyCount: store.size }; }
35
+ async clear() { store.clear(); return true; }
36
+ }
37
+ exports.FailingStorageAdapter = FailingStorageAdapter;
38
+ /** Adapter that fails first N saves then succeeds, to exercise retry logic (future). */
39
+ class FlakySaveAdapter {
40
+ opts;
41
+ attempts = 0;
42
+ constructor(opts) {
43
+ this.opts = opts;
44
+ }
45
+ async save(key, data, _options) {
46
+ if (this.opts.delayMs)
47
+ await new Promise(r => setTimeout(r, this.opts.delayMs));
48
+ this.attempts++;
49
+ if (this.attempts <= this.opts.failCount)
50
+ return { success: false, error: 'transient-error' };
51
+ store.set(key, data);
52
+ return { success: true }; // attempts tracked internally; tests inspect adapter state if needed
53
+ }
54
+ async load(key) { return store.get(key) ?? null; }
55
+ async delete(key) { return store.delete(key); }
56
+ async list() { return [...store.keys()]; }
57
+ async exists(key) { return store.has(key); }
58
+ async getStats() { return { totalSize: store.size, keyCount: store.size }; }
59
+ async clear() { store.clear(); return true; }
60
+ }
61
+ exports.FlakySaveAdapter = FlakySaveAdapter;
62
+ /** Adapter introducing artificial latency without failures. */
63
+ class SlowStorageAdapter {
64
+ delayMs;
65
+ constructor(delayMs = 25) {
66
+ this.delayMs = delayMs;
67
+ }
68
+ async lag() { await new Promise(r => setTimeout(r, this.delayMs)); }
69
+ async save(key, data) { await this.lag(); store.set(key, data); return { success: true }; }
70
+ async load(key) { await this.lag(); return store.get(key) ?? null; }
71
+ async delete(key) { await this.lag(); return store.delete(key); }
72
+ async list() { await this.lag(); return [...store.keys()]; }
73
+ async exists(key) { await this.lag(); return store.has(key); }
74
+ async getStats() { return { totalSize: store.size, keyCount: store.size }; }
75
+ async clear() { await this.lag(); store.clear(); return true; }
76
+ }
77
+ exports.SlowStorageAdapter = SlowStorageAdapter;
78
+ /**
79
+ * Adapter that simulates network timeouts for the first N save attempts by rejecting.
80
+ * After those attempts it succeeds (optionally with a delay). Useful to exercise retry logic and telemetry attempts field.
81
+ */
82
+ class TimeoutSaveAdapter {
83
+ opts;
84
+ attempt = 0;
85
+ constructor(opts) {
86
+ this.opts = opts;
87
+ }
88
+ async delay(ms) { if (ms)
89
+ await new Promise(r => setTimeout(r, ms)); }
90
+ async save(key, data) {
91
+ this.attempt++;
92
+ if (this.attempt <= this.opts.timeoutFailCount) {
93
+ await this.delay(this.opts.timeoutDelayMs);
94
+ // Simulate a network timeout by throwing (engine converts to failed PersistenceResult)
95
+ throw new Error('timeout');
96
+ }
97
+ await this.delay(this.opts.resolveDelayMs);
98
+ store.set(key, data);
99
+ return { success: true };
100
+ }
101
+ async load(key) { return store.get(key) ?? null; }
102
+ async delete(key) { return store.delete(key); }
103
+ async list() { return [...store.keys()]; }
104
+ async exists(key) { return store.has(key); }
105
+ async getStats() { return { totalSize: store.size, keyCount: store.size }; }
106
+ async clear() { store.clear(); return true; }
107
+ }
108
+ exports.TimeoutSaveAdapter = TimeoutSaveAdapter;
109
+ //# sourceMappingURL=MockAdapters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockAdapters.js","sourceRoot":"","sources":["../../../src/adapters/storage/MockAdapters.ts"],"names":[],"mappings":";;;AAGA,iEAAiE;AACjE,MAAM,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;AASjD,gEAAgE;AAChE,MAAa,qBAAqB;IACZ;IAApB,YAAoB,OAA8B,EAAE;QAAhC,SAAI,GAAJ,IAAI,CAA4B;IAAG,CAAC;IACxD,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,IAAqB,EAAE,QAA+B;QAC5E,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAChF,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;QAC9E,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,QAAsB;QAC5C,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAChF,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC7D,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IAChC,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QACxC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD,KAAK,CAAC,IAAI,KAAwB,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,KAAK,CAAC,MAAM,CAAC,GAAW,IAAsB,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtE,KAAK,CAAC,QAAQ,KAA4E,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnJ,KAAK,CAAC,KAAK,KAAuB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;CAChE;AArBD,sDAqBC;AAQD,wFAAwF;AACxF,MAAa,gBAAgB;IAEP;IADZ,QAAQ,GAAG,CAAC,CAAC;IACrB,YAAoB,IAAyB;QAAzB,SAAI,GAAJ,IAAI,CAAqB;IAAG,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,IAAqB,EAAE,QAA+B;QAC5E,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAChF,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;QAC9F,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,qEAAqE;IACjG,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAW,IAAqC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC3F,KAAK,CAAC,MAAM,CAAC,GAAW,IAAsB,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzE,KAAK,CAAC,IAAI,KAAwB,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,KAAK,CAAC,MAAM,CAAC,GAAW,IAAsB,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtE,KAAK,CAAC,QAAQ,KAA4E,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnJ,KAAK,CAAC,KAAK,KAAuB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;CAChE;AAhBD,4CAgBC;AAED,+DAA+D;AAC/D,MAAa,kBAAkB;IACT;IAApB,YAAoB,UAAU,EAAE;QAAZ,YAAO,GAAP,OAAO,CAAK;IAAG,CAAC;IAC5B,KAAK,CAAC,GAAG,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,IAAqB,IAAgC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAChJ,KAAK,CAAC,IAAI,CAAC,GAAW,IAAqC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC7G,KAAK,CAAC,MAAM,CAAC,GAAW,IAAsB,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC3F,KAAK,CAAC,IAAI,KAAwB,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/E,KAAK,CAAC,MAAM,CAAC,GAAW,IAAsB,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxF,KAAK,CAAC,QAAQ,KAA4E,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnJ,KAAK,CAAC,KAAK,KAAuB,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;CAClF;AAVD,gDAUC;AAQD;;;GAGG;AACH,MAAa,kBAAkB;IAET;IADZ,OAAO,GAAG,CAAC,CAAC;IACpB,YAAoB,IAA2B;QAA3B,SAAI,GAAJ,IAAI,CAAuB;IAAG,CAAC;IAC3C,KAAK,CAAC,KAAK,CAAC,EAAW,IAAI,IAAI,EAAE;QAAE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,IAAqB;QAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC/C,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC3C,uFAAuF;YACvF,MAAM,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3C,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,GAAW,IAAqC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC3F,KAAK,CAAC,MAAM,CAAC,GAAW,IAAsB,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACzE,KAAK,CAAC,IAAI,KAAwB,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,KAAK,CAAC,MAAM,CAAC,GAAW,IAAsB,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACtE,KAAK,CAAC,QAAQ,KAA4E,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnJ,KAAK,CAAC,KAAK,KAAuB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;CAChE;AArBD,gDAqBC"}
@@ -3,7 +3,7 @@ import type { StoryData } from '../../engine/core';
3
3
  import type { ValidationResult } from '../../engine/validation';
4
4
  export declare class CustomJSONAdapter implements StoryAdapter {
5
5
  load(source: string | object, options?: AdapterOptions): Promise<StoryData>;
6
- validate(_storyData: StoryData): ValidationResult;
6
+ validate(): ValidationResult;
7
7
  detect(source: unknown): boolean;
8
8
  }
9
9
  export default CustomJSONAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"CustomJSONAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/story/CustomJSONAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,qBAAa,iBAAkB,YAAW,YAAY;IAC9C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC;IA+DjF,QAAQ,CAAC,UAAU,EAAE,SAAS,GAAG,gBAAgB;IAIjD,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAYjC;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"CustomJSONAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/story/CustomJSONAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,qBAAa,iBAAkB,YAAW,YAAY;IAC9C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC;IA6FjF,QAAQ,IAAI,gBAAgB;IAI5B,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAYjC;AAED,eAAe,iBAAiB,CAAC"}
@@ -9,7 +9,7 @@ class CustomJSONAdapter {
9
9
  if (!data || typeof data !== 'object')
10
10
  throw new Error('Invalid story source');
11
11
  const initialNodeId = data.initialNodeId || 'start';
12
- const nodes = data.nodes || [];
12
+ const nodes = data.nodes ?? [];
13
13
  if (!Array.isArray(nodes))
14
14
  throw new Error('Invalid nodes array');
15
15
  const normalized = {
@@ -17,10 +17,14 @@ class CustomJSONAdapter {
17
17
  nodes: nodes.map((n) => ({
18
18
  id: String(n.id),
19
19
  text: String(n.text ?? ''),
20
- meta: n.meta && typeof n.meta === 'object'
21
- ? {
22
- tags: Array.isArray(n.meta.tags) ? n.meta.tags.map((t) => String(t)) : undefined
23
- }
20
+ meta: n && typeof n === 'object' && n.meta && typeof n.meta === 'object'
21
+ ? (() => {
22
+ const meta = n.meta;
23
+ const tags = meta.tags;
24
+ return {
25
+ tags: Array.isArray(tags) ? tags.map((t) => String(t)) : undefined,
26
+ };
27
+ })()
24
28
  : undefined,
25
29
  choices: Array.isArray(n.choices)
26
30
  ? n.choices.map((c) => ({
@@ -54,25 +58,27 @@ class CustomJSONAdapter {
54
58
  }
55
59
  }
56
60
  else {
57
- // Lenient mode: warn on unknown keys
61
+ // Lenient mode: ignore unknown keys silently
58
62
  const allowedNodeKeys = new Set(['id', 'text', 'choices', 'meta']);
59
63
  const allowedChoiceKeys = new Set([
60
64
  'text', 'nextNodeId', 'flagEffects', 'flagRequirements', 'timeRequirements', 'inventoryRequirements', 'enabled', 'condition'
61
65
  ]);
62
66
  for (const n of nodes) {
63
- for (const k of Object.keys(n))
64
- if (!allowedNodeKeys.has(k))
65
- console.warn(`[QNCE] Unknown node key ignored: ${k}`);
66
- for (const c of (n.choices || [])) {
67
- for (const ck of Object.keys(c))
68
- if (!allowedChoiceKeys.has(ck))
69
- console.warn(`[QNCE] Unknown choice key ignored: ${ck}`);
67
+ for (const k of Object.keys(n)) {
68
+ // ignore unknown keys
69
+ void (allowedNodeKeys.has(k));
70
+ }
71
+ for (const c of n.choices || []) {
72
+ for (const ck of Object.keys(c)) {
73
+ // ignore unknown keys
74
+ void (allowedChoiceKeys.has(ck));
75
+ }
70
76
  }
71
77
  }
72
78
  }
73
79
  return normalized;
74
80
  }
75
- validate(_storyData) {
81
+ validate() {
76
82
  return { isValid: true };
77
83
  }
78
84
  detect(source) {
@@ -1 +1 @@
1
- {"version":3,"file":"CustomJSONAdapter.js","sourceRoot":"","sources":["../../../src/adapters/story/CustomJSONAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CustomJSONAdapter.js","sourceRoot":"","sources":["../../../src/adapters/story/CustomJSONAdapter.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import type { StoryData } from '../../engine/core';
3
3
  import type { ValidationResult } from '../../engine/validation';
4
4
  export declare class InkAdapter implements StoryAdapter {
5
5
  load(source: string | object, options?: AdapterOptions): Promise<StoryData>;
6
- validate(_storyData: StoryData): ValidationResult;
6
+ validate(): ValidationResult;
7
7
  detect(source: unknown): boolean;
8
8
  }
9
9
  export default InkAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"InkAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/story/InkAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,qBAAa,UAAW,YAAW,YAAY;IACvC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC;IAwBjF,QAAQ,CAAC,UAAU,EAAE,SAAS,GAAG,gBAAgB;IAEjD,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAKjC;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"InkAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/story/InkAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,qBAAa,UAAW,YAAW,YAAY;IACvC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC;IAuBjF,QAAQ,IAAI,gBAAgB;IAE5B,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAKjC;AAED,eAAe,UAAU,CAAC"}
@@ -9,23 +9,20 @@ class InkAdapter {
9
9
  const obj = typeof source === 'string' ? JSON.parse(source) : source;
10
10
  if (!obj || typeof obj !== 'object')
11
11
  throw new Error('Invalid Ink JSON');
12
- // Heuristic: accept a simplified format { knots: { [name]: { text, choices: [{ text, target }] } } , start?: string }
13
- const knots = obj.knots || {};
12
+ const knots = (obj.knots) || {};
14
13
  const idPrefix = options?.idPrefix ?? '';
15
- if (!options?.experimentalInk && (obj.inkVersion || obj.listDefs || obj.inkState)) {
16
- console.warn('[QNCE] Ink JSON appears complex; using minimal adapter. Pass experimentalInk to attempt richer import.');
17
- }
14
+ // Silently proceed in non-experimental mode; no console noise in library code
18
15
  const nodes = Object.keys(knots).map((k) => ({
19
16
  id: `${idPrefix}${k}`,
20
- text: String(knots[k].text ?? ''),
21
- choices: Array.isArray(knots[k].choices)
22
- ? knots[k].choices.map((c) => ({ text: String(c.text ?? ''), nextNodeId: `${idPrefix}${c.target}` }))
17
+ text: String(knots[k]?.text ?? ''),
18
+ choices: Array.isArray(knots[k]?.choices)
19
+ ? knots[k].choices.map((c) => ({ text: String(c.text ?? ''), nextNodeId: `${idPrefix}${String(c.target ?? '')}` }))
23
20
  : [],
24
21
  }));
25
22
  const initialNodeId = `${idPrefix}${(obj.start ?? Object.keys(knots)[0] ?? 'start')}`;
26
23
  return { initialNodeId, nodes };
27
24
  }
28
- validate(_storyData) { return { isValid: true }; }
25
+ validate() { return { isValid: true }; }
29
26
  detect(source) {
30
27
  let obj = source;
31
28
  if (typeof source === 'string') {
@@ -36,7 +33,7 @@ class InkAdapter {
36
33
  return false;
37
34
  }
38
35
  }
39
- return !!obj && typeof obj === 'object' && (!!obj.knots || !!obj.inkVersion);
36
+ return !!obj && typeof obj === 'object' && ('knots' in obj || 'inkVersion' in obj);
40
37
  }
41
38
  }
42
39
  exports.InkAdapter = InkAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"InkAdapter.js","sourceRoot":"","sources":["../../../src/adapters/story/InkAdapter.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,sGAAsG;;;AAMtG,yEAAyE;AACzE,MAAa,UAAU;IACrB,KAAK,CAAC,IAAI,CAAC,MAAuB,EAAE,OAAwB;QAC1D,MAAM,GAAG,GAAQ,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1E,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAEzE,sHAAsH;QACtH,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;QAEzC,IAAI,CAAE,OAAe,EAAE,eAAe,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3F,OAAO,CAAC,IAAI,CAAC,wGAAwG,CAAC,CAAC;QACzH,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3C,EAAE,EAAE,GAAG,QAAQ,GAAG,CAAC,EAAE;YACrB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YACjC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;gBACtC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC1G,CAAC,CAAC,EAAE;SACP,CAAC,CAAC,CAAC;QAEJ,MAAM,aAAa,GAAG,GAAG,QAAQ,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC;QACtF,OAAO,EAAE,aAAa,EAAE,KAAK,EAAe,CAAC;IAC/C,CAAC;IAED,QAAQ,CAAC,UAAqB,IAAsB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAE/E,MAAM,CAAC,MAAe;QACpB,IAAI,GAAG,GAAQ,MAAM,CAAC;QACtB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAAC,IAAI,CAAC;gBAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,KAAK,CAAC;YAAC,CAAC;QAAC,CAAC;QAC7F,OAAO,CAAC,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC/E,CAAC;CACF;AAhCD,gCAgCC;AAED,kBAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"InkAdapter.js","sourceRoot":"","sources":["../../../src/adapters/story/InkAdapter.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,sGAAsG;;;AAMtG,yEAAyE;AACzE,MAAa,UAAU;IACrB,KAAK,CAAC,IAAI,CAAC,MAAuB,EAAE,OAAwB;QAC5D,MAAM,GAAG,GAA4B,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAAkC,CAAC;QACzH,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAI3E,MAAM,KAAK,GAAG,CAAE,GAAwC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACpE,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;QAEzC,8EAA8E;QAE9E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3C,EAAE,EAAE,GAAG,QAAQ,GAAG,CAAC,EAAE;YACrB,IAAI,EAAE,MAAM,CAAE,KAAK,CAAC,CAAC,CAAsB,EAAE,IAAI,IAAI,EAAE,CAAC;YACxD,OAAO,EAAE,KAAK,CAAC,OAAO,CAAE,KAAK,CAAC,CAAC,CAAsB,EAAE,OAAO,CAAC;gBAC7D,CAAC,CAAG,KAAK,CAAC,CAAC,CAAU,CAAC,OAAuD,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9K,CAAC,CAAC,EAAE;SACP,CAAC,CAAC,CAAC;QAEJ,MAAM,aAAa,GAAG,GAAG,QAAQ,GAAG,CAAG,GAA2B,CAAC,KAAgB,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC;QAC3H,OAAO,EAAE,aAAa,EAAE,KAAK,EAAe,CAAC;IAC/C,CAAC;IAED,QAAQ,KAAuB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAE1D,MAAM,CAAC,MAAe;QACtB,IAAI,GAAG,GAAY,MAAM,CAAC;QACxB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAAC,IAAI,CAAC;gBAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,KAAK,CAAC;YAAC,CAAC;QAAC,CAAC;QAC/F,OAAO,CAAC,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,OAAO,IAAI,GAAG,IAAI,YAAY,IAAI,GAAG,CAAC,CAAC;IACnF,CAAC;CACF;AA/BD,gCA+BC;AAED,kBAAe,UAAU,CAAC"}
@@ -3,7 +3,7 @@ import type { StoryData } from '../../engine/core';
3
3
  import type { ValidationResult } from '../../engine/validation';
4
4
  export declare class TwisonAdapter implements StoryAdapter {
5
5
  load(source: string | object, options?: AdapterOptions): Promise<StoryData>;
6
- validate(_storyData: StoryData): ValidationResult;
6
+ validate(): ValidationResult;
7
7
  detect(source: unknown): boolean;
8
8
  }
9
9
  export default TwisonAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"TwisonAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/story/TwisonAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAiBhE,qBAAa,aAAc,YAAW,YAAY;IAC1C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC;IA4CjF,QAAQ,CAAC,UAAU,EAAE,SAAS,GAAG,gBAAgB;IAIjD,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAOjC;AAED,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"TwisonAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/story/TwisonAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAiBhE,qBAAa,aAAc,YAAW,YAAY;IAC1C,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC;IA4CjF,QAAQ,IAAI,gBAAgB;IAI5B,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;CAOjC;AAED,eAAe,aAAa,CAAC"}