qnce-engine 1.3.1 → 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 (168) hide show
  1. package/README.md +136 -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 +56 -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 +135 -60
  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 +109 -3
  38. package/dist/engine/core.d.ts.map +1 -1
  39. package/dist/engine/core.js +486 -36
  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 +22 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +34 -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 +88 -0
  121. package/dist/telemetry/core.d.ts.map +1 -0
  122. package/dist/telemetry/core.js +303 -0
  123. package/dist/telemetry/core.js.map +1 -0
  124. package/dist/telemetry/types.d.ts +76 -0
  125. package/dist/telemetry/types.d.ts.map +1 -0
  126. package/dist/telemetry/types.js +4 -0
  127. package/dist/telemetry/types.js.map +1 -0
  128. package/dist/tsdoc-metadata.json +11 -0
  129. package/dist/ui/__tests__/AutosaveIndicator.test.js +10 -13
  130. package/dist/ui/__tests__/AutosaveIndicator.test.js.map +1 -1
  131. package/dist/ui/__tests__/UndoRedoControls.test.js +7 -9
  132. package/dist/ui/__tests__/UndoRedoControls.test.js.map +1 -1
  133. package/dist/ui/components/AutosaveIndicator.d.ts +1 -0
  134. package/dist/ui/components/AutosaveIndicator.d.ts.map +1 -1
  135. package/dist/ui/components/AutosaveIndicator.js +2 -1
  136. package/dist/ui/components/AutosaveIndicator.js.map +1 -1
  137. package/dist/ui/components/UndoRedoControls.d.ts +1 -0
  138. package/dist/ui/components/UndoRedoControls.d.ts.map +1 -1
  139. package/dist/ui/components/UndoRedoControls.js +1 -0
  140. package/dist/ui/components/UndoRedoControls.js.map +1 -1
  141. package/dist/ui/hooks/useKeyboardShortcuts.d.ts +1 -0
  142. package/dist/ui/hooks/useKeyboardShortcuts.d.ts.map +1 -1
  143. package/dist/ui/hooks/useKeyboardShortcuts.js +17 -5
  144. package/dist/ui/hooks/useKeyboardShortcuts.js.map +1 -1
  145. package/dist/ui/types.d.ts +6 -0
  146. package/dist/ui/types.d.ts.map +1 -1
  147. package/dist/ui/types.js +1 -0
  148. package/dist/ui/types.js.map +1 -1
  149. package/dist/utils/debug-logger.d.ts +20 -0
  150. package/dist/utils/debug-logger.d.ts.map +1 -0
  151. package/dist/utils/debug-logger.js +24 -0
  152. package/dist/utils/debug-logger.js.map +1 -0
  153. package/dist/utils/hot-profiler.d.ts +21 -0
  154. package/dist/utils/hot-profiler.d.ts.map +1 -0
  155. package/dist/utils/hot-profiler.js +36 -0
  156. package/dist/utils/hot-profiler.js.map +1 -0
  157. package/dist/utils/intern.d.ts +11 -0
  158. package/dist/utils/intern.d.ts.map +1 -0
  159. package/dist/utils/intern.js +45 -0
  160. package/dist/utils/intern.js.map +1 -0
  161. package/dist/utils/logger.d.ts +34 -0
  162. package/dist/utils/logger.d.ts.map +1 -0
  163. package/dist/utils/logger.js +115 -0
  164. package/dist/utils/logger.js.map +1 -0
  165. package/docs/PERFORMANCE.md +330 -0
  166. package/examples/fluent-builder-prototype.ts +71 -0
  167. package/examples/quantum-integration-demo.ts +51 -0
  168. package/package.json +25 -9
package/README.md CHANGED
@@ -2,20 +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.0 (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
 
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).
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
+
11
48
  ## Core Concepts
12
49
 
13
50
  - **Superposition:** Multiple narrative outcomes exist simultaneously until a choice is made
14
51
  - **Collapse:** Player choices "collapse" the narrative to a specific path, updating state and flags
15
52
  - **Entanglement:** Early decisions affect later outcomes, enabling complex, interconnected stories
16
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
+
17
56
  ## ✨ Current Features (v1.3.0)
18
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
+
19
64
  ### 💾 State Persistence & Checkpoints
20
65
  - **Complete save/load system** with data integrity validation
21
66
  - **Lightweight checkpoints** for undo/redo functionality
@@ -51,6 +96,7 @@
51
96
  - **Background processing** for non-blocking operations
52
97
  - **Hot-reload capabilities** with <3.5ms story updates
53
98
  - **Comprehensive monitoring** with built-in CLI tools
99
+ - **Adaptive perf pipeline (beta)** with dynamic batch sizing & backoff
54
100
 
55
101
  #### Basic Flag-Based Conditions
56
102
 
@@ -213,6 +259,10 @@ engine.clearConditionEvaluator();
213
259
  - **Expression Caching:** Conditions are compiled once and cached for subsequent evaluations
214
260
  - **Safe Evaluation:** All expressions are sanitized to prevent code injection
215
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`
216
266
  - **Error Isolation:** Invalid conditions don't affect other choices in the same node
217
267
 
218
268
  ### ⚡ Performance Infrastructure
@@ -221,6 +271,7 @@ engine.clearConditionEvaluator();
221
271
  - **🔥 Hot-Reload:** <3.5ms live story updates with delta patching
222
272
  - **📊 Real-time Profiling:** Comprehensive event instrumentation and analysis
223
273
  - **🖥️ Live Monitoring:** `qnce-perf` CLI dashboard with performance alerts
274
+ - **🧠 Adaptive Flush (Beta):** Dynamic telemetry/perf batch sizing + rejection backoff for smoother throughput
224
275
 
225
276
  ### Performance Dashboard
226
277
  ```bash
@@ -232,10 +283,67 @@ qnce-perf live 1000
232
283
 
233
284
  # Export performance data
234
285
  qnce-perf export > performance-report.json
286
+
287
+ # Stream NDJSON (metrics+thread stats per line)
288
+ qnce-perf stream 1000 | jq '.'
235
289
  ```
236
290
 
237
291
  **[📚 Complete Performance Guide →](docs/PERFORMANCE.md)**
238
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
+
239
347
  ## Installation
240
348
 
241
349
  ```bash
@@ -578,7 +686,7 @@ const engine = createQNCEEngine(storyData, {}, true, {
578
686
  // Monitor performance in real-time with CLI dashboard
579
687
  ```
580
688
 
581
- **📖 Complete Performance Guide:** [docs/PERFORMANCE_GUIDE.md](docs/PERFORMANCE_GUIDE.md)
689
+ **📖 Complete Performance Guide:** [docs/PERFORMANCE.md](docs/PERFORMANCE.md)
582
690
 
583
691
  ## Core API
584
692
 
@@ -1076,6 +1184,17 @@ npm run build:watch
1076
1184
  npm run lint
1077
1185
  ```
1078
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
+
1079
1198
  ## License
1080
1199
 
1081
1200
  MIT - See LICENSE file for details.
@@ -1218,3 +1337,18 @@ try {
1218
1337
  }
1219
1338
  }
1220
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":"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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 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"}