@bitcobblers/wod-wiki-lang 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,640 @@
1
+ import { _ as ScriptRuntime, aq as MemoryType, q as IRuntimeBlock, as as MemoryValueOf, ac as DisplayState, at as RoundState, a1 as TimerState, X as IScriptRuntime, F as TypedMemoryReference, a5 as ButtonConfig, K as StackSnapshot } from './browserRuntimeNow-SxxdmtB7.js';
2
+ export { az as createBrowserRuntimeNow, aE as getRuntimeNowMs, aH as runtimeNow } from './browserRuntimeNow-SxxdmtB7.js';
3
+ import { IMetricSource, IOutputStatement, MetricContainer, TimeSpan } from '@bitcobblers/wod-wiki-core';
4
+ import React$1, { ReactNode } from 'react';
5
+
6
+ /**
7
+ * useRuntimeExecution - Custom React hook for managing ScriptRuntime execution
8
+ *
9
+ * Encapsulates execution logic, interval management, and lifecycle cleanup.
10
+ *
11
+ * Architecture Decision:
12
+ * - Fixed 20ms tick rate (50 ticks per second)
13
+ * - No speed control (removed for simplicity)
14
+ * - Automatic cleanup on unmount
15
+ * - Reusable across components
16
+ */
17
+
18
+ /**
19
+ * Execution status states
20
+ */
21
+ type ExecutionStatus = 'idle' | 'running' | 'paused' | 'completed' | 'error';
22
+ /**
23
+ * Return type for useRuntimeExecution hook
24
+ */
25
+ interface UseRuntimeExecutionReturn {
26
+ status: ExecutionStatus;
27
+ elapsedTime: number;
28
+ stepCount: number;
29
+ startTime: number | null;
30
+ start: () => void;
31
+ pause: () => void;
32
+ stop: () => void;
33
+ reset: () => void;
34
+ step: () => void;
35
+ }
36
+ /**
37
+ * Manages ScriptRuntime execution lifecycle with fixed 20ms tick rate
38
+ *
39
+ * @param runtime - The ScriptRuntime instance to execute (null if not ready)
40
+ * @returns Object with execution state and control methods
41
+ */
42
+ declare const useRuntimeExecution: (runtime: ScriptRuntime | null) => UseRuntimeExecutionReturn;
43
+
44
+ /**
45
+ * React hook to subscribe to a specific memory type on a block.
46
+ *
47
+ * Automatically subscribes when the block or type changes, and
48
+ * unsubscribes on cleanup. Returns the current value and updates
49
+ * reactively when behaviors modify the memory.
50
+ *
51
+ * @param block The runtime block to subscribe to (can be undefined)
52
+ * @param type The memory type to subscribe to
53
+ * @returns The current memory value or undefined
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * function TimerComponent({ block }: { block: IRuntimeBlock }) {
58
+ * const timerState = useBlockMemory(block, 'time');
59
+ *
60
+ * if (!timerState) return null;
61
+ *
62
+ * return <div>Direction: {timerState.direction}</div>;
63
+ * }
64
+ * ```
65
+ */
66
+ declare function useBlockMemory<T extends MemoryType>(block: IRuntimeBlock | undefined, type: T): MemoryValueOf<T> | undefined;
67
+ /**
68
+ * Hook for subscribing to timer state from a block.
69
+ *
70
+ * @param block The runtime block
71
+ * @returns The current TimerState or undefined
72
+ */
73
+ declare function useTimerState(block: IRuntimeBlock | undefined): TimerState | undefined;
74
+ /**
75
+ * Hook for subscribing to round state from a block.
76
+ *
77
+ * @param block The runtime block
78
+ * @returns The current RoundState or undefined
79
+ */
80
+ declare function useRoundState(block: IRuntimeBlock | undefined): RoundState | undefined;
81
+ /**
82
+ * Hook for subscribing to display state from a block.
83
+ *
84
+ * @param block The runtime block
85
+ * @returns The current DisplayState or undefined
86
+ */
87
+ declare function useDisplayState(block: IRuntimeBlock | undefined): DisplayState | undefined;
88
+ /**
89
+ * Derived timer display values for UI rendering.
90
+ */
91
+ interface TimerDisplayValues {
92
+ /** Total elapsed time in milliseconds */
93
+ elapsed: number;
94
+ /** Remaining time in milliseconds (for countdowns) */
95
+ remaining: number | undefined;
96
+ /** Whether the timer is currently running (not paused) */
97
+ isRunning: boolean;
98
+ /** Timer direction */
99
+ direction: 'up' | 'down';
100
+ /** Whether the timer has completed (countdown reached 0) */
101
+ isComplete: boolean;
102
+ /** Formatted time string (MM:SS or HH:MM:SS) */
103
+ formatted: string;
104
+ }
105
+ /**
106
+ * Hook for derived timer display values.
107
+ *
108
+ * Computes elapsed time, remaining time, and formatted display strings
109
+ * from the raw timer state. Uses requestAnimationFrame for smooth 60fps
110
+ * updates when the timer is running.
111
+ *
112
+ * Consolidated with useTimerElapsed - both now share calculateDuration utility.
113
+ *
114
+ * @param block The runtime block
115
+ * @returns Derived timer display values or null if no timer
116
+ *
117
+ * @example
118
+ * ```tsx
119
+ * function TimerDisplay({ block }: { block: IRuntimeBlock }) {
120
+ * const display = useTimerDisplay(block);
121
+ *
122
+ * if (!display) return <div>No timer</div>;
123
+ *
124
+ * return (
125
+ * <div>
126
+ * <span>{display.formatted}</span>
127
+ * {display.direction === 'down' && (
128
+ * <span>{formatTime(display.remaining ?? 0)} remaining</span>
129
+ * )}
130
+ * </div>
131
+ * );
132
+ * }
133
+ * ```
134
+ */
135
+ declare function useTimerDisplay(block: IRuntimeBlock | undefined): TimerDisplayValues | null;
136
+ /**
137
+ * Derived round display values for UI rendering.
138
+ */
139
+ interface RoundDisplayValues {
140
+ /** Current round number */
141
+ current: number;
142
+ /** Total rounds (undefined for unbounded) */
143
+ total: number | undefined;
144
+ /** Formatted round label (e.g., "Round 3 of 5") */
145
+ label: string;
146
+ /** Progress as a fraction 0-1 (undefined for unbounded) */
147
+ progress: number | undefined;
148
+ }
149
+ /**
150
+ * Hook for derived round display values.
151
+ *
152
+ * @param block The runtime block
153
+ * @returns Derived round display values or null if no rounds
154
+ */
155
+ declare function useRoundDisplay(block: IRuntimeBlock | undefined): RoundDisplayValues | null;
156
+ /**
157
+ * Hook for subscribing to the display metrics source from a block.
158
+ *
159
+ * Returns the `IMetricSource` interface from the block's `'metric:display'`
160
+ * memory entry (`DisplayMetricMemory`). The returned source provides
161
+ * precedence-resolved metric that update reactively when the underlying
162
+ * metric memory or runtime state changes.
163
+ *
164
+ * This is the primary hook for UI components that need to render metrics
165
+ * from a runtime block with proper origin precedence (user > runtime > compiler > parser).
166
+ *
167
+ * @param block The runtime block (can be undefined)
168
+ * @returns The IMetricSource for the block, or undefined if no metrics:display memory
169
+ *
170
+ * @example
171
+ * ```tsx
172
+ * function BlockView({ block }: { block: IRuntimeBlock }) {
173
+ * const source = useFragmentSource(block);
174
+ * if (!source) return null;
175
+ *
176
+ * const metrics = source.getDisplayMetrics();
177
+ * return <MetricVisualizer metric={metric} />;
178
+ * }
179
+ * ```
180
+ */
181
+ declare function useFragmentSource(block: IRuntimeBlock | undefined): IMetricSource | undefined;
182
+
183
+ /**
184
+ * Data structure returned by useOutputStatements hook
185
+ * Consolidated from separate implementations in runtime/hooks and clock/hooks
186
+ */
187
+ interface OutputStatementsData {
188
+ /** All output statements sorted by start time */
189
+ outputs: IOutputStatement[];
190
+ /** Outputs indexed by ID for quick lookup */
191
+ byId: Map<number, IOutputStatement>;
192
+ /** Outputs indexed by sourceBlockKey */
193
+ byBlockKey: Map<string, IOutputStatement[]>;
194
+ /** Segment outputs (timed execution segments) */
195
+ segments: IOutputStatement[];
196
+ /** Completion outputs */
197
+ completions: IOutputStatement[];
198
+ /** Metric outputs */
199
+ metrics: IOutputStatement[];
200
+ }
201
+ /**
202
+ * React hook that subscribes to output statement updates from a runtime.
203
+ *
204
+ * Unified hook that works with or without a runtime parameter:
205
+ * - useOutputStatements() - uses runtime from context
206
+ * - useOutputStatements(runtime) - uses provided runtime parameter
207
+ *
208
+ * Returns enriched OutputStatementsData with indexed maps for performance.
209
+ * Consolidated from separate runtime/hooks and clock/hooks implementations.
210
+ *
211
+ * @param runtime Optional runtime instance. If not provided, uses context.
212
+ * @returns OutputStatementsData containing outputs and indexed maps
213
+ *
214
+ * @example
215
+ * ```tsx
216
+ * // With context (default)
217
+ * const data = useOutputStatements();
218
+ *
219
+ * // With explicit runtime parameter
220
+ * const data = useOutputStatements(myRuntime);
221
+ * ```
222
+ */
223
+ declare function useOutputStatements(runtime?: IScriptRuntime | null): OutputStatementsData;
224
+ /**
225
+ * Live Tier-2 (running-total) snapshot for display during an active session.
226
+ *
227
+ * Returns the analytics engine's current projection set — totals like total
228
+ * volume / distance / load, recomputed per segment. These values are ephemeral:
229
+ * they are shown live but never persisted; only the finalized values reach the
230
+ * records after the WOD completes. Reuses the output subscription as its change
231
+ * signal (the snapshot is replaced, not appended).
232
+ */
233
+ declare function useLiveAnalytics(runtime?: IScriptRuntime | null): IOutputStatement[];
234
+ /**
235
+ * Hook to get a specific output by ID
236
+ */
237
+ declare function useOutputStatement(runtime: IScriptRuntime | null, id: number | null): IOutputStatement | undefined;
238
+ /**
239
+ * Hook to get outputs for a specific block
240
+ */
241
+ declare function useBlockOutputs(runtime: IScriptRuntime | null, blockKey: string | null): IOutputStatement[];
242
+ /**
243
+ * Hook to compute output hierarchy (parent-child relationships) based on stackLevel
244
+ */
245
+ declare function useOutputHierarchy(runtime: IScriptRuntime | null): Map<number, number>;
246
+
247
+ /**
248
+ * React hook for subscribing to memory reference changes.
249
+ *
250
+ * This hook automatically manages the subscription lifecycle:
251
+ * - Subscribes when the component mounts or when memoryRef changes
252
+ * - Unsubscribes when the component unmounts or when memoryRef changes
253
+ * - Returns the current value and updates when the memory changes
254
+ *
255
+ * @param memoryRef The memory reference to subscribe to (can be undefined)
256
+ * @returns The current value from the memory reference, or undefined if not available
257
+ *
258
+ * @example
259
+ * ```tsx
260
+ * const runtime = useScriptRuntime();
261
+ * const timeSpansRef = runtime.memory.search({
262
+ * type: 'timer-time-spans',
263
+ * ownerId: blockKey
264
+ * })[0] as TypedMemoryReference<TimeSpan[]>;
265
+ *
266
+ * const timeSpans = useMemorySubscription(timeSpansRef);
267
+ * ```
268
+ */
269
+ declare function useMemorySubscription<T>(memoryRef: TypedMemoryReference<T> | undefined): T | undefined;
270
+
271
+ /**
272
+ * Result of the next-preview resolution.
273
+ *
274
+ * `metrics` contains the display metrics for the next child that
275
+ * will be pushed by the deepest block on the stack that has a
276
+ * `metrics:next` memory location.
277
+ */
278
+ interface NextPreview {
279
+ /** Fragments describing the next child to be executed */
280
+ metrics: MetricContainer;
281
+ /** The block that owns this preview (the parent that will push the child) */
282
+ block: IRuntimeBlock;
283
+ }
284
+ /**
285
+ * Hook that resolves the "Up Next" preview from the runtime stack.
286
+ *
287
+ * Walks the stack from leaf (index 0) to root, finding the first block
288
+ * that has a non-empty `metrics:next` memory location. This gives the
289
+ * deepest (most specific) preview of what's coming next.
290
+ *
291
+ * The hook subscribes to `metrics:next` memory changes on all stack
292
+ * blocks, so it re-renders when the preview updates (e.g., after a
293
+ * child completes and the next child is queued).
294
+ *
295
+ * @returns NextPreview if any block has a next preview, or null
296
+ *
297
+ * @example
298
+ * ```tsx
299
+ * function UpNextCard() {
300
+ * const preview = useNextPreview();
301
+ * if (!preview) return <span>End of session</span>;
302
+ *
303
+ * return <MetricSourceRow metric={preview.metrics} />;
304
+ * }
305
+ * ```
306
+ */
307
+ declare function useNextPreview(): NextPreview | null;
308
+
309
+ type FragmentSourceStatus = 'pending' | 'active' | 'completed' | 'failed' | 'skipped';
310
+ interface FragmentSourceEntry {
311
+ source: IMetricSource;
312
+ depth: number;
313
+ isLeaf?: boolean;
314
+ isHeader?: boolean;
315
+ isLinked?: boolean;
316
+ status?: FragmentSourceStatus;
317
+ label?: string;
318
+ metricGroups?: any[];
319
+ }
320
+ /**
321
+ * Represents a timer on the stack with its owning block context.
322
+ */
323
+ interface StackTimerEntry {
324
+ /** The block that owns this timer */
325
+ block: IRuntimeBlock;
326
+ /** The timer state from block memory */
327
+ timer: TimerState;
328
+ /** Whether this timer is pinned to the primary display */
329
+ isPinned: boolean;
330
+ }
331
+ /**
332
+ * Hook that scans the runtime stack for all blocks with timer memory.
333
+ * Returns timer entries ordered from bottom of stack (index 0) to top.
334
+ *
335
+ * Timer data is read directly from block memory via lock.getMemory('time').
336
+ * When a block is popped from the stack, its memory subscriptions are cleaned
337
+ * up automatically, and the stack event triggers a re-render here.
338
+ *
339
+ * @returns Array of stack timer entries
340
+ */
341
+ declare function useStackTimers(): StackTimerEntry[];
342
+ /**
343
+ * Determines which timer should be displayed as the primary (big) timer.
344
+ *
345
+ * Pin Resolution Strategy:
346
+ * 1. If the top-of-stack block is a Rest block, its timer is ALWAYS primary.
347
+ * Rest countdowns should be front-and-center so users see time remaining.
348
+ * 2. Otherwise, find the LOWEST (root-closest) block with role === 'primary'.
349
+ * This lets parent blocks (AMRAP, EMOM) keep their timer pinned while
350
+ * child exercises execute beneath them.
351
+ * 3. If no pinned timer exists, use the leaf (top-of-stack) timer.
352
+ *
353
+ * @returns The primary timer entry, or undefined if no timers on stack
354
+ */
355
+ declare function usePrimaryTimer(): StackTimerEntry | undefined;
356
+ /**
357
+ * Returns all timers that are NOT the primary timer.
358
+ * These are displayed as secondary/context timers in the UI.
359
+ */
360
+ declare function useSecondaryTimers(): StackTimerEntry[];
361
+ /**
362
+ * Aggregates control buttons from all blocks on the stack.
363
+ *
364
+ * Button Resolution Strategy:
365
+ * - Collect pinned buttons (isPinned === true) from ALL stack levels
366
+ * - Collect non-pinned buttons from the TOP block only
367
+ * - Deduplicate by button ID (pinned take precedence)
368
+ *
369
+ * When a block is popped, its buttons are automatically removed because
370
+ * the stack subscription triggers a re-scan.
371
+ *
372
+ * @returns Array of active button configurations
373
+ */
374
+ declare function useActiveControls(): ButtonConfig[];
375
+ /**
376
+ * Represents a metrics source on the stack with layout context.
377
+ *
378
+ * Extends the generic FragmentSourceEntry with a block reference for
379
+ * runtime-specific scenarios (accessing memory, dispatching events).
380
+ */
381
+ interface StackFragmentEntry extends FragmentSourceEntry {
382
+ /** The owning runtime block */
383
+ block: IRuntimeBlock;
384
+ }
385
+ /**
386
+ * Hook that converts the runtime stack into an array of IMetricSource entries.
387
+ *
388
+ * Each block on the stack with a `'metric:display'` memory entry produces a
389
+ * `StackFragmentEntry` containing the `IMetricSource` and layout context
390
+ * (depth, leaf status, label).
391
+ *
392
+ * This is the preferred way for UI components to access metrics data from
393
+ * the stack, replacing `useStackDisplayItems()` which returns `IDisplayItem[]`.
394
+ *
395
+ * @returns Array of stack metrics entries, or undefined if no blocks on stack
396
+ *
397
+ * @example
398
+ * ```tsx
399
+ * function StackView() {
400
+ * const entries = useStackFragmentSources();
401
+ * if (!entries) return null;
402
+ *
403
+ * return entries.map(entry => (
404
+ * <MetricVisualizer
405
+ * key={entry.source.id}
406
+ * metrics={entry.source.getDisplayMetrics()}
407
+ * />
408
+ * ));
409
+ * }
410
+ * ```
411
+ */
412
+ declare function useStackFragmentSources(): StackFragmentEntry[] | undefined;
413
+ /**
414
+ * Represents a display entry with list-based memory access.
415
+ *
416
+ * Replaces IMetricSource adapter with direct IMetric[][] access.
417
+ */
418
+ interface StackDisplayEntry {
419
+ /** The owning runtime block */
420
+ block: IRuntimeBlock;
421
+ /** Display rows - each row is an array of metrics */
422
+ displayRows: MetricContainer[];
423
+ /** Display label from block */
424
+ label: string;
425
+ /** Nesting depth for indentation (0 = root level) */
426
+ depth: number;
427
+ /** Whether this is the leaf (most active) entry */
428
+ isLeaf: boolean;
429
+ /** Raw metrics groups from block memory (for backward compatibility) */
430
+ metricGroups?: readonly MetricContainer[];
431
+ }
432
+ /**
433
+ * Hook that reads list-based memory directly from runtime stack blocks.
434
+ *
435
+ * This is the Phase 3 UI migration hook that consumes the list-based memory
436
+ * API populated by Phase 2 behaviors. It subscribes to all 'metric:display'
437
+ * memory locations and returns display rows without requiring IMetricSource
438
+ * adapter layer.
439
+ *
440
+ * Each block can have multiple 'metric:display' memory locations (non-unique
441
+ * tags in list-based API), where each location stores IMetric[]. These
442
+ * are returned as displayRows: IMetric[][].
443
+ *
444
+ * @returns Array of stack display entries, or undefined if no blocks on stack
445
+ *
446
+ * @example
447
+ * ```tsx
448
+ * function StackView() {
449
+ * const entries = useStackDisplayRows();
450
+ * if (!entries) return null;
451
+ *
452
+ * return entries.map(entry => (
453
+ * <div key={entry.block.key.toString()}>
454
+ * {entry.displayRows.map((row, idx) => (
455
+ * <MetricSourceRow key={idx} metrics={row} />
456
+ * ))}
457
+ * </div>
458
+ * ));
459
+ * }
460
+ * ```
461
+ */
462
+ declare function useStackDisplayRows(): StackDisplayEntry[] | undefined;
463
+
464
+ /**
465
+ * Hook that subscribes to stack snapshots via `runtime.subscribeToStack()`.
466
+ *
467
+ * Returns the latest StackSnapshot, which contains:
468
+ * - `blocks` — current stack (bottom-to-top)
469
+ * - `affectedBlock` — the block that was pushed/popped
470
+ * - `depth` — stack depth after the event
471
+ * - `clockTime` — runtime clock time at event
472
+ * - `type` — 'push' | 'pop' | 'clear' | 'initial'
473
+ *
474
+ * This is the primary hook for UI components that need to react to stack
475
+ * structural changes. For high-frequency timer updates, subscribe to
476
+ * block memory separately.
477
+ *
478
+ * @returns The latest StackSnapshot
479
+ *
480
+ * @example
481
+ * ```tsx
482
+ * function StackDisplay() {
483
+ * const snapshot = useStackSnapshot();
484
+ *
485
+ * return (
486
+ * <div>
487
+ * <p>Depth: {snapshot.depth}</p>
488
+ * {snapshot.blocks.map(block => (
489
+ * <div key={block.key.toString()}>{block.label}</div>
490
+ * ))}
491
+ * </div>
492
+ * );
493
+ * }
494
+ * ```
495
+ */
496
+ declare function useStackSnapshot(): StackSnapshot;
497
+ /**
498
+ * Hook that returns the current stack blocks from the most recent snapshot.
499
+ * Convenience wrapper over useStackSnapshot().
500
+ *
501
+ * @returns Readonly array of blocks currently on the stack
502
+ */
503
+ declare function useSnapshotBlocks(): readonly IRuntimeBlock[];
504
+ /**
505
+ * Hook that returns the current (top) block on the stack from the snapshot.
506
+ * Returns undefined if the stack is empty.
507
+ *
508
+ * @returns The top block on the stack, or undefined if empty
509
+ */
510
+ declare function useSnapshotCurrentBlock(): IRuntimeBlock | undefined;
511
+
512
+ /**
513
+ * Result from useTimerElapsed hook.
514
+ */
515
+ interface UseTimerElapsedResult {
516
+ elapsed: number;
517
+ isRunning: boolean;
518
+ timeSpans: readonly TimeSpan[];
519
+ }
520
+ /**
521
+ * Hook to calculate elapsed time for a timer block by key.
522
+ *
523
+ * This hook uses the unified TimerState from runtime memory to provide
524
+ * real-time elapsed time calculation. It polls for updates when the timer
525
+ * is running to show current time, but only subscribes to memory changes
526
+ * for start/stop/pause/resume events.
527
+ *
528
+ * ## When to Use This Hook
529
+ *
530
+ * Use this hook when your component receives a `blockKey: string` from the
531
+ * display stack system. This is the standard integration pattern for:
532
+ * - ClockAnchor
533
+ * - DigitalClock
534
+ * - Display stack consumers
535
+ *
536
+ * ## When to Use useTimerDisplay Instead
537
+ *
538
+ * If you have direct access to an `IRuntimeBlock` reference (e.g., from
539
+ * `runtime.stack.current()`), prefer `useTimerDisplay(block)` which provides
540
+ * formatted time strings and richer display values.
541
+ *
542
+ * ## Features
543
+ * - Zero polling for completed timers
544
+ * - Subscription-based updates for state changes
545
+ * - 60fps animation frame updates when running
546
+ *
547
+ * @param blockKey The block key to track elapsed time for
548
+ * @returns Object with elapsed time, running state, and time spans
549
+ *
550
+ * @example
551
+ * ```tsx
552
+ * // Display stack integration (this hook)
553
+ * function KeyBasedTimer({ blockKey }: { blockKey: string }) {
554
+ * const { elapsed, isRunning } = useTimerElapsed(blockKey);
555
+ * const formatted = formatMs(elapsed);
556
+ * return <div className={isRunning ? 'running' : ''}>{formatted}</div>;
557
+ * }
558
+ *
559
+ * // Direct block access (use useTimerDisplay instead)
560
+ * function BlockTimer({ block }: { block: IRuntimeBlock }) {
561
+ * const display = useTimerDisplay(block);
562
+ * return <div>{display?.formatted}</div>;
563
+ * }
564
+ * ```
565
+ */
566
+ declare function useTimerElapsed(blockKey: string): UseTimerElapsedResult;
567
+
568
+ interface ScriptRuntimeProviderProps {
569
+ runtime: IScriptRuntime;
570
+ children: ReactNode;
571
+ }
572
+ /**
573
+ * Provides IScriptRuntime context to child components.
574
+ * Must wrap any components that need access to runtime memory or state.
575
+ *
576
+ * @example
577
+ * ```tsx
578
+ * const runtime = new ScriptRuntime();
579
+ * const script = parseWorkout('For Time: 30 Jumping Jacks');
580
+ * runtime.execute(script);
581
+ *
582
+ * return (
583
+ * <ScriptRuntimeProvider runtime={runtime}>
584
+ * <ClockAnchor blockKey="block-001" />
585
+ * </ScriptRuntimeProvider>
586
+ * );
587
+ * ```
588
+ */
589
+ declare const ScriptRuntimeProvider: React.FC<ScriptRuntimeProviderProps>;
590
+ /**
591
+ * Hook to access the IScriptRuntime from context.
592
+ * Must be used within a ScriptRuntimeProvider.
593
+ *
594
+ * @throws Error if called outside ScriptRuntimeProvider
595
+ * @returns IScriptRuntime instance
596
+ */
597
+ declare function useScriptRuntime(): IScriptRuntime;
598
+
599
+ interface BlockTimerDisplayProps {
600
+ /** The runtime block to display timer for */
601
+ block: IRuntimeBlock | undefined;
602
+ /** Optional CSS class name */
603
+ className?: string;
604
+ /** Show round information if available */
605
+ showRounds?: boolean;
606
+ /** Compact mode for smaller displays */
607
+ compact?: boolean;
608
+ }
609
+ /**
610
+ * BlockTimerDisplay - Timer display using new behavior-based hooks.
611
+ *
612
+ * This component demonstrates the preferred pattern for displaying timer
613
+ * state from runtime blocks using the new useTimerDisplay and useRoundDisplay
614
+ * hooks.
615
+ *
616
+ * ## Features
617
+ * - 60fps animation for running timers
618
+ * - Automatic format detection (countdown vs countup)
619
+ * - Round display integration
620
+ * - Zero polling for completed timers
621
+ *
622
+ * ## Usage
623
+ *
624
+ * When you have direct access to an IRuntimeBlock (e.g., from the stack),
625
+ * use this component:
626
+ *
627
+ * \\\ sx
628
+ * const block = runtime.stack.current();
629
+ * return <BlockTimerDisplay block={block} showRounds />;
630
+ * \\\
631
+ *
632
+ * For display stack integration where you only have a blockKey string,
633
+ * continue using DigitalClock or ClockAnchor with useTimerElapsed.
634
+ *
635
+ * @see useTimerDisplay
636
+ * @see useRoundDisplay
637
+ */
638
+ declare const BlockTimerDisplay: React$1.FC<BlockTimerDisplayProps>;
639
+
640
+ export { BlockTimerDisplay, type BlockTimerDisplayProps, type ExecutionStatus, type FragmentSourceEntry, type FragmentSourceStatus, type NextPreview, type OutputStatementsData, type RoundDisplayValues, ScriptRuntimeProvider, type ScriptRuntimeProviderProps, type StackDisplayEntry, type StackFragmentEntry, type StackTimerEntry, type TimerDisplayValues, type UseRuntimeExecutionReturn, type UseTimerElapsedResult, useActiveControls, useBlockMemory, useBlockOutputs, useDisplayState, useFragmentSource, useLiveAnalytics, useMemorySubscription, useNextPreview, useOutputHierarchy, useOutputStatement, useOutputStatements, usePrimaryTimer, useRoundDisplay, useRoundState, useRuntimeExecution, useScriptRuntime, useSecondaryTimers, useSnapshotBlocks, useSnapshotCurrentBlock, useStackDisplayRows, useStackFragmentSources, useStackSnapshot, useStackTimers, useTimerDisplay, useTimerElapsed, useTimerState };