@flyingrobots/bijou-tui 2.1.0 → 3.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.
Files changed (128) hide show
  1. package/README.md +64 -21
  2. package/dist/animate.d.ts +0 -2
  3. package/dist/animate.d.ts.map +1 -1
  4. package/dist/animate.js +17 -26
  5. package/dist/animate.js.map +1 -1
  6. package/dist/app-frame-actions.d.ts +1 -5
  7. package/dist/app-frame-actions.d.ts.map +1 -1
  8. package/dist/app-frame-actions.js +21 -17
  9. package/dist/app-frame-actions.js.map +1 -1
  10. package/dist/app-frame-render.d.ts +2 -0
  11. package/dist/app-frame-render.d.ts.map +1 -1
  12. package/dist/app-frame-render.js +55 -8
  13. package/dist/app-frame-render.js.map +1 -1
  14. package/dist/app-frame-types.d.ts +9 -0
  15. package/dist/app-frame-types.d.ts.map +1 -1
  16. package/dist/app-frame-types.js +4 -4
  17. package/dist/app-frame-types.js.map +1 -1
  18. package/dist/app-frame.d.ts +39 -2
  19. package/dist/app-frame.d.ts.map +1 -1
  20. package/dist/app-frame.js +195 -31
  21. package/dist/app-frame.js.map +1 -1
  22. package/dist/canvas.d.ts +37 -25
  23. package/dist/canvas.d.ts.map +1 -1
  24. package/dist/canvas.js +116 -30
  25. package/dist/canvas.js.map +1 -1
  26. package/dist/commands.d.ts.map +1 -1
  27. package/dist/commands.js +12 -4
  28. package/dist/commands.js.map +1 -1
  29. package/dist/css/install.d.ts +4 -0
  30. package/dist/css/install.d.ts.map +1 -0
  31. package/dist/css/install.js +24 -0
  32. package/dist/css/install.js.map +1 -0
  33. package/dist/css/parser.d.ts +14 -0
  34. package/dist/css/parser.d.ts.map +1 -0
  35. package/dist/css/parser.js +92 -0
  36. package/dist/css/parser.js.map +1 -0
  37. package/dist/css/resolver.d.ts +36 -0
  38. package/dist/css/resolver.d.ts.map +1 -0
  39. package/dist/css/resolver.js +130 -0
  40. package/dist/css/resolver.js.map +1 -0
  41. package/dist/css/text-style.d.ts +17 -0
  42. package/dist/css/text-style.d.ts.map +1 -0
  43. package/dist/css/text-style.js +59 -0
  44. package/dist/css/text-style.js.map +1 -0
  45. package/dist/css/types.d.ts +27 -0
  46. package/dist/css/types.d.ts.map +1 -0
  47. package/dist/css/types.js +5 -0
  48. package/dist/css/types.js.map +1 -0
  49. package/dist/driver.d.ts +14 -7
  50. package/dist/driver.d.ts.map +1 -1
  51. package/dist/driver.js +38 -17
  52. package/dist/driver.js.map +1 -1
  53. package/dist/eventbus.d.ts +42 -3
  54. package/dist/eventbus.d.ts.map +1 -1
  55. package/dist/eventbus.js +127 -3
  56. package/dist/eventbus.js.map +1 -1
  57. package/dist/focus-area.d.ts +4 -0
  58. package/dist/focus-area.d.ts.map +1 -1
  59. package/dist/focus-area.js +11 -1
  60. package/dist/focus-area.js.map +1 -1
  61. package/dist/index.d.ts +13 -2
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +9 -0
  64. package/dist/index.js.map +1 -1
  65. package/dist/layout-v3.d.ts +10 -0
  66. package/dist/layout-v3.d.ts.map +1 -0
  67. package/dist/layout-v3.js +35 -0
  68. package/dist/layout-v3.js.map +1 -0
  69. package/dist/motion/motion.d.ts +14 -0
  70. package/dist/motion/motion.d.ts.map +1 -0
  71. package/dist/motion/motion.js +31 -0
  72. package/dist/motion/motion.js.map +1 -0
  73. package/dist/motion/reconciler.d.ts +15 -0
  74. package/dist/motion/reconciler.d.ts.map +1 -0
  75. package/dist/motion/reconciler.js +109 -0
  76. package/dist/motion/reconciler.js.map +1 -0
  77. package/dist/motion/types.d.ts +52 -0
  78. package/dist/motion/types.d.ts.map +1 -0
  79. package/dist/motion/types.js +2 -0
  80. package/dist/motion/types.js.map +1 -0
  81. package/dist/notification.d.ts +73 -0
  82. package/dist/notification.d.ts.map +1 -0
  83. package/dist/notification.js +693 -0
  84. package/dist/notification.js.map +1 -0
  85. package/dist/overlay.d.ts +3 -1
  86. package/dist/overlay.d.ts.map +1 -1
  87. package/dist/overlay.js.map +1 -1
  88. package/dist/pipeline/middleware/css.d.ts +20 -0
  89. package/dist/pipeline/middleware/css.d.ts.map +1 -0
  90. package/dist/pipeline/middleware/css.js +41 -0
  91. package/dist/pipeline/middleware/css.js.map +1 -0
  92. package/dist/pipeline/middleware/grayscale.d.ts +9 -0
  93. package/dist/pipeline/middleware/grayscale.d.ts.map +1 -0
  94. package/dist/pipeline/middleware/grayscale.js +39 -0
  95. package/dist/pipeline/middleware/grayscale.js.map +1 -0
  96. package/dist/pipeline/middleware/motion.d.ts +6 -0
  97. package/dist/pipeline/middleware/motion.d.ts.map +1 -0
  98. package/dist/pipeline/middleware/motion.js +19 -0
  99. package/dist/pipeline/middleware/motion.js.map +1 -0
  100. package/dist/pipeline/middleware/paint.d.ts +6 -0
  101. package/dist/pipeline/middleware/paint.d.ts.map +1 -0
  102. package/dist/pipeline/middleware/paint.js +21 -0
  103. package/dist/pipeline/middleware/paint.js.map +1 -0
  104. package/dist/pipeline/pipeline.d.ts +56 -0
  105. package/dist/pipeline/pipeline.d.ts.map +1 -0
  106. package/dist/pipeline/pipeline.js +45 -0
  107. package/dist/pipeline/pipeline.js.map +1 -0
  108. package/dist/runtime.d.ts +1 -1
  109. package/dist/runtime.d.ts.map +1 -1
  110. package/dist/runtime.js +180 -18
  111. package/dist/runtime.js.map +1 -1
  112. package/dist/screen.d.ts +12 -1
  113. package/dist/screen.d.ts.map +1 -1
  114. package/dist/screen.js +14 -1
  115. package/dist/screen.js.map +1 -1
  116. package/dist/subapp/mount.d.ts +67 -0
  117. package/dist/subapp/mount.d.ts.map +1 -0
  118. package/dist/subapp/mount.js +60 -0
  119. package/dist/subapp/mount.js.map +1 -0
  120. package/dist/types.d.ts +75 -8
  121. package/dist/types.d.ts.map +1 -1
  122. package/dist/types.js +9 -0
  123. package/dist/types.js.map +1 -1
  124. package/dist/view-output.d.ts +15 -0
  125. package/dist/view-output.d.ts.map +1 -0
  126. package/dist/view-output.js +53 -0
  127. package/dist/view-output.js.map +1 -0
  128. package/package.json +3 -3
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Resolves the final styles for a component based on a CSS sheet and terminal dimensions.
3
+ *
4
+ * @param identity - The component's identity (type, id, classes).
5
+ * @param sheet - The parsed BCSS sheet.
6
+ * @param terminal - Current terminal dimensions for media query matching.
7
+ * @param graph - The TokenGraph for resolving var() references.
8
+ * @param mode - The theme mode (light/dark).
9
+ * @returns A record of computed style properties.
10
+ */
11
+ export function resolveStyles(identity, sheet, terminal, graph, mode = 'dark') {
12
+ const matchedRules = [];
13
+ // 1. Collect rules from main sheet
14
+ for (const rule of sheet.rules) {
15
+ const specificity = getMatchSpecificity(identity, rule.selectors);
16
+ if (specificity > 0) {
17
+ matchedRules.push({ rule, specificity });
18
+ }
19
+ }
20
+ // 2. Collect rules from active media queries
21
+ for (const mq of sheet.mediaQueries) {
22
+ if (matchesMediaQuery(mq.condition, terminal)) {
23
+ for (const rule of mq.rules) {
24
+ const specificity = getMatchSpecificity(identity, rule.selectors);
25
+ if (specificity > 0) {
26
+ // Media query rules have slightly higher base priority in CSS
27
+ matchedRules.push({ rule, specificity: specificity + 0.1 });
28
+ }
29
+ }
30
+ }
31
+ }
32
+ // 3. Sort by specificity (and then order of appearance)
33
+ matchedRules.sort((a, b) => a.specificity - b.specificity);
34
+ // 4. Merge declarations into final object
35
+ const finalStyles = {};
36
+ for (const { rule } of matchedRules) {
37
+ for (const decl of rule.declarations) {
38
+ // !important handling
39
+ if (decl.important || !isImportant(finalStyles, decl.property)) {
40
+ finalStyles[decl.property] = resolveValue(decl.value, graph, mode);
41
+ if (decl.important) {
42
+ finalStyles[`__important_${decl.property}`] = 'true';
43
+ }
44
+ }
45
+ }
46
+ }
47
+ return finalStyles;
48
+ }
49
+ /**
50
+ * Resolve a CSS value, handling var(token.path) references via the TokenGraph.
51
+ */
52
+ function resolveValue(value, graph, mode = 'dark') {
53
+ if (!graph)
54
+ return value;
55
+ // Simple regex for var(path.to.token)
56
+ const varRegex = /var\(([^)]+)\)/g;
57
+ return value.replace(varRegex, (_, path) => {
58
+ try {
59
+ // Try to get as full token first, then fallback to color
60
+ const resolved = graph.get(path.trim(), mode);
61
+ return resolved.hex;
62
+ }
63
+ catch {
64
+ return 'inherit'; // Fallback for unresolved vars
65
+ }
66
+ });
67
+ }
68
+ function isImportant(styles, property) {
69
+ return styles[`__important_${property}`] === 'true';
70
+ }
71
+ /**
72
+ * Calculate match specificity for a component identity against a set of selectors.
73
+ * Returns 0 if no match, otherwise a positive number representing specificity.
74
+ */
75
+ function getMatchSpecificity(identity, selectors) {
76
+ let maxSpecificity = 0;
77
+ for (const selector of selectors) {
78
+ let match = true;
79
+ let specificity = 0;
80
+ // Type match
81
+ if (selector.type && selector.type !== '*') {
82
+ if (identity.type !== selector.type)
83
+ match = false;
84
+ specificity += 1;
85
+ }
86
+ // ID match
87
+ if (selector.id) {
88
+ if (identity.id !== selector.id)
89
+ match = false;
90
+ specificity += 100;
91
+ }
92
+ // Class match (all classes in selector must be present on component)
93
+ if (selector.classes.length > 0) {
94
+ for (const cls of selector.classes) {
95
+ if (!identity.classes?.includes(cls)) {
96
+ match = false;
97
+ break;
98
+ }
99
+ }
100
+ specificity += selector.classes.length * 10;
101
+ }
102
+ if (match) {
103
+ maxSpecificity = Math.max(maxSpecificity, specificity);
104
+ }
105
+ }
106
+ return maxSpecificity;
107
+ }
108
+ /**
109
+ * Evaluate a basic media query condition like "(width < 80)" or "(height >= 24)".
110
+ */
111
+ export function matchesMediaQuery(condition, terminal) {
112
+ // Simple regex for (property op value)
113
+ const regex = /\((width|height)\s*(<|>|<=|>=|==|!=)\s*(\d+)\)/;
114
+ const match = condition.match(regex);
115
+ if (!match)
116
+ return false;
117
+ const property = match[1] === 'width' ? terminal.width : terminal.height;
118
+ const op = match[2];
119
+ const value = parseInt(match[3], 10);
120
+ switch (op) {
121
+ case '<': return property < value;
122
+ case '>': return property > value;
123
+ case '<=': return property <= value;
124
+ case '>=': return property >= value;
125
+ case '==': return property === value;
126
+ case '!=': return property !== value;
127
+ default: return false;
128
+ }
129
+ }
130
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/css/resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { BijouContext } from '@flyingrobots/bijou';
2
+ export interface StyledTextToken {
3
+ hex?: string;
4
+ bg?: string;
5
+ modifiers?: string[];
6
+ }
7
+ export interface BCSSIdentity {
8
+ type: string;
9
+ id?: string;
10
+ classes?: string[];
11
+ }
12
+ type BCSSStyles = Record<string, string>;
13
+ export declare function mergeBCSSModifiers(base: readonly string[] | undefined, styles: BCSSStyles): string[] | undefined;
14
+ export declare function resolveBCSSTextToken(ctx: BijouContext, identity: BCSSIdentity, base?: StyledTextToken): StyledTextToken;
15
+ export declare function styleTextWithBCSS(text: string, ctx: BijouContext | undefined, identity: BCSSIdentity, base?: StyledTextToken): string;
16
+ export {};
17
+ //# sourceMappingURL=text-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-style.d.ts","sourceRoot":"","sources":["../../src/css/text-style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEzC,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EACnC,MAAM,EAAE,UAAU,GACjB,MAAM,EAAE,GAAG,SAAS,CAoCtB;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,YAAY,EACtB,IAAI,GAAE,eAAoB,GACzB,eAAe,CAOjB;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,GAAG,SAAS,EAC7B,QAAQ,EAAE,YAAY,EACtB,IAAI,GAAE,eAAoB,GACzB,MAAM,CAcR"}
@@ -0,0 +1,59 @@
1
+ export function mergeBCSSModifiers(base, styles) {
2
+ const modifiers = new Set(base ?? []);
3
+ const fontWeight = styles['font-weight']?.trim().toLowerCase();
4
+ if (fontWeight === 'bold' || fontWeight === '700' || fontWeight === '800' || fontWeight === '900') {
5
+ modifiers.add('bold');
6
+ }
7
+ else if (fontWeight === 'normal' || fontWeight === '400') {
8
+ modifiers.delete('bold');
9
+ }
10
+ const fontStyle = styles['font-style']?.trim().toLowerCase();
11
+ if (fontStyle === 'italic') {
12
+ modifiers.add('italic');
13
+ }
14
+ else if (fontStyle === 'normal') {
15
+ modifiers.delete('italic');
16
+ }
17
+ const decoration = styles['text-decoration']?.trim().toLowerCase();
18
+ if (decoration === 'none') {
19
+ modifiers.delete('underline');
20
+ modifiers.delete('curly-underline');
21
+ modifiers.delete('dotted-underline');
22
+ modifiers.delete('dashed-underline');
23
+ modifiers.delete('strikethrough');
24
+ modifiers.delete('strike');
25
+ }
26
+ else if (decoration) {
27
+ if (decoration.includes('underline')) {
28
+ modifiers.add('underline');
29
+ }
30
+ if (decoration.includes('line-through')) {
31
+ modifiers.add('strikethrough');
32
+ modifiers.delete('strike');
33
+ }
34
+ }
35
+ return modifiers.size > 0 ? Array.from(modifiers) : undefined;
36
+ }
37
+ export function resolveBCSSTextToken(ctx, identity, base = {}) {
38
+ const styles = ctx.resolveBCSS(identity);
39
+ return {
40
+ hex: styles['color'] ?? base.hex,
41
+ bg: styles['background'] ?? base.bg,
42
+ modifiers: mergeBCSSModifiers(base.modifiers, styles),
43
+ };
44
+ }
45
+ export function styleTextWithBCSS(text, ctx, identity, base = {}) {
46
+ if (!ctx)
47
+ return text;
48
+ const styles = ctx.resolveBCSS(identity);
49
+ const token = {
50
+ hex: styles['color'] ?? base.hex,
51
+ bg: styles['background'] ?? base.bg,
52
+ modifiers: mergeBCSSModifiers(base.modifiers, styles),
53
+ };
54
+ if (token.hex == null && token.bg == null && (token.modifiers == null || token.modifiers.length === 0)) {
55
+ return text;
56
+ }
57
+ return ctx.style.styled(token, text);
58
+ }
59
+ //# sourceMappingURL=text-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-style.js","sourceRoot":"","sources":["../../src/css/text-style.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * AST types for Bijou CSS (BCSS).
3
+ */
4
+ export interface BCSSDeclaration {
5
+ property: string;
6
+ value: string;
7
+ important: boolean;
8
+ }
9
+ export interface BCSSSelector {
10
+ type?: string;
11
+ id?: string;
12
+ classes: string[];
13
+ raw: string;
14
+ }
15
+ export interface BCSSRule {
16
+ selectors: BCSSSelector[];
17
+ declarations: BCSSDeclaration[];
18
+ }
19
+ export interface BCSSMediaQuery {
20
+ condition: string;
21
+ rules: BCSSRule[];
22
+ }
23
+ export interface BCSSSheet {
24
+ rules: BCSSRule[];
25
+ mediaQueries: BCSSMediaQuery[];
26
+ }
27
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/css/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,YAAY,EAAE,eAAe,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,YAAY,EAAE,cAAc,EAAE,CAAC;CAChC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * AST types for Bijou CSS (BCSS).
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/css/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/dist/driver.d.ts CHANGED
@@ -16,6 +16,7 @@
16
16
  * ```
17
17
  */
18
18
  import type { App, RunOptions } from './types.js';
19
+ import { type Surface } from '@flyingrobots/bijou';
19
20
  /** A single step in a scripted interaction sequence. */
20
21
  export type ScriptStep<M = never> = {
21
22
  /** Key to send (raw terminal key string, e.g., 'a', '\x1b[A', '\x03'). */
@@ -30,6 +31,13 @@ export type ScriptStep<M = never> = {
30
31
  };
31
32
  /** Milliseconds to wait before sending this step. Default: 0. */
32
33
  delay?: number;
34
+ } | {
35
+ /** Pulse event to emit. */
36
+ pulse: {
37
+ dt: number;
38
+ };
39
+ /** Milliseconds to wait before sending this step. Default: 0. */
40
+ delay?: number;
33
41
  } | {
34
42
  /** Custom message to emit directly onto the bus. */
35
43
  msg: M;
@@ -39,7 +47,9 @@ export type ScriptStep<M = never> = {
39
47
  /** Options for {@link runScript}, extending the base {@link RunOptions}. */
40
48
  export interface RunScriptOptions extends RunOptions {
41
49
  /** Capture each rendered frame. */
42
- onFrame?: (frame: string, index: number) => void;
50
+ onFrame?: (frame: Surface, index: number) => void;
51
+ /** Pulse frequency used to drive animation commands. Set to `false` to disable. */
52
+ pulseFps?: number | false;
43
53
  }
44
54
  /**
45
55
  * Result returned by {@link runScript} after all steps have been processed.
@@ -50,7 +60,7 @@ export interface RunScriptResult<Model> {
50
60
  /** Final model state after all steps. */
51
61
  model: Model;
52
62
  /** All rendered frames in order. */
53
- frames: string[];
63
+ frames: Surface[];
54
64
  /** Total elapsed time in milliseconds. */
55
65
  elapsed: number;
56
66
  }
@@ -65,11 +75,8 @@ export interface RunScriptResult<Model> {
65
75
  * - A command returns QUIT
66
76
  * - All script steps are exhausted (auto-quits)
67
77
  *
68
- * **Limitation:** Between steps the driver yields via `queueMicrotask`,
69
- * which only settles microtask-based async (e.g. `Promise.resolve()`).
70
- * Commands that use `setTimeout`, real I/O, or other macrotask-based async
71
- * may not have completed before the next key is dispatched. Use `delay`
72
- * on subsequent steps to allow time for macrotask-based commands.
78
+ * Between steps the driver waits for the event bus to go idle, so command
79
+ * chains settle deterministically without relying on microtask-only yields.
73
80
  *
74
81
  * @template Model - The application model type.
75
82
  * @template M - The message (action) type for the TEA update cycle.
@@ -1 +1 @@
1
- {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAQ7D,wDAAwD;AACxD,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,KAAK,IAC5B;IACA,0EAA0E;IAC1E,GAAG,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACC;IACA,4BAA4B;IAC5B,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACC;IACA,oDAAoD;IACpD,GAAG,EAAE,CAAC,CAAC;IACP,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEJ,4EAA4E;AAC5E,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,mCAAmC;IACnC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe,CAAC,KAAK;IACpC,yCAAyC;IACzC,KAAK,EAAE,KAAK,CAAC;IACb,oCAAoC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,CAAC,EACtC,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAClB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAoFjC"}
1
+ {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAI7D,OAAO,EAAE,KAAK,OAAO,EAAuB,MAAM,qBAAqB,CAAC;AAQxE,wDAAwD;AACxD,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,KAAK,IAC5B;IACA,0EAA0E;IAC1E,GAAG,EAAE,MAAM,CAAC;IACZ,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACC;IACA,4BAA4B;IAC5B,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACC;IACA,2BAA2B;IAC3B,KAAK,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACtB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACC;IACA,oDAAoD;IACpD,GAAG,EAAE,CAAC,CAAC;IACP,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEJ,4EAA4E;AAC5E,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,mCAAmC;IACnC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe,CAAC,KAAK;IACpC,yCAAyC;IACzC,KAAK,EAAE,KAAK,CAAC;IACb,oCAAoC;IACpC,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,CAAC,EACtC,GAAG,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,EAClB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CA2GjC"}
package/dist/driver.js CHANGED
@@ -15,8 +15,12 @@
15
15
  * console.log(result.frames); // all rendered frames
16
16
  * ```
17
17
  */
18
+ import { isResizeMsg } from './types.js';
18
19
  import { createEventBus } from './eventbus.js';
19
20
  import { parseKey } from './keys.js';
21
+ import { resolveClock, sleep } from '@flyingrobots/bijou';
22
+ import { installBCSSResolver } from './css/install.js';
23
+ import { normalizeViewOutput } from './view-output.js';
20
24
  // ---------------------------------------------------------------------------
21
25
  // Implementation
22
26
  // ---------------------------------------------------------------------------
@@ -31,11 +35,8 @@ import { parseKey } from './keys.js';
31
35
  * - A command returns QUIT
32
36
  * - All script steps are exhausted (auto-quits)
33
37
  *
34
- * **Limitation:** Between steps the driver yields via `queueMicrotask`,
35
- * which only settles microtask-based async (e.g. `Promise.resolve()`).
36
- * Commands that use `setTimeout`, real I/O, or other macrotask-based async
37
- * may not have completed before the next key is dispatched. Use `delay`
38
- * on subsequent steps to allow time for macrotask-based commands.
38
+ * Between steps the driver waits for the event bus to go idle, so command
39
+ * chains settle deterministically without relying on microtask-only yields.
39
40
  *
40
41
  * @template Model - The application model type.
41
42
  * @template M - The message (action) type for the TEA update cycle.
@@ -45,12 +46,25 @@ import { parseKey } from './keys.js';
45
46
  * @returns The final model, all rendered frames, and elapsed time.
46
47
  */
47
48
  export async function runScript(app, steps, options) {
48
- const start = Date.now();
49
+ const clock = resolveClock(options?.ctx);
50
+ const start = clock.now();
49
51
  const frames = [];
50
- const bus = createEventBus();
52
+ const bus = createEventBus({ clock });
53
+ const ctx = options?.ctx;
54
+ if (ctx != null) {
55
+ installBCSSResolver(ctx, options?.css);
56
+ }
51
57
  const [initModel, initCmds] = app.init();
52
58
  let model = initModel;
53
59
  let running = true;
60
+ let currentSize = {
61
+ width: Math.max(0, Math.floor(ctx?.runtime.columns || 80)),
62
+ height: Math.max(0, Math.floor(ctx?.runtime.rows || 24)),
63
+ };
64
+ // Start heartbeat for animations when enabled.
65
+ if (options?.pulseFps !== false) {
66
+ bus.startPulse(options?.pulseFps ?? ctx?.runtime.refreshRate ?? 60);
67
+ }
54
68
  /** Stop the scripted driver event loop. */
55
69
  function shutdown() {
56
70
  running = false;
@@ -61,7 +75,13 @@ export async function runScript(app, steps, options) {
61
75
  return;
62
76
  const [newModel, cmds] = app.update(msg, model);
63
77
  model = newModel;
64
- const frame = app.view(model);
78
+ if (isResizeMsg(msg)) {
79
+ currentSize = {
80
+ width: Math.max(0, msg.columns),
81
+ height: Math.max(0, msg.rows),
82
+ };
83
+ }
84
+ const frame = normalizeViewOutput(app.view(model), currentSize).surface;
65
85
  frames.push(frame);
66
86
  options?.onFrame?.(frame, frames.length - 1);
67
87
  for (const cmd of cmds) {
@@ -70,21 +90,20 @@ export async function runScript(app, steps, options) {
70
90
  });
71
91
  try {
72
92
  // Capture initial frame
73
- const initFrame = app.view(model);
93
+ const initFrame = normalizeViewOutput(app.view(model), currentSize).surface;
74
94
  frames.push(initFrame);
75
95
  options?.onFrame?.(initFrame, 0);
76
96
  // Run init commands
77
97
  for (const cmd of initCmds) {
78
98
  bus.runCmd(cmd);
79
99
  }
80
- // Yield so microtask-based init commands can settle
81
- await new Promise((r) => queueMicrotask(r));
100
+ await bus.drain();
82
101
  // Feed script steps
83
102
  for (const step of steps) {
84
103
  if (!running)
85
104
  break;
86
105
  if (step.delay && step.delay > 0) {
87
- await new Promise((r) => setTimeout(r, step.delay));
106
+ await sleep(clock, step.delay);
88
107
  }
89
108
  if (!running)
90
109
  break;
@@ -92,6 +111,9 @@ export async function runScript(app, steps, options) {
92
111
  const keyMsg = parseKey(step.key);
93
112
  bus.emit(keyMsg);
94
113
  }
114
+ else if ('pulse' in step) {
115
+ bus.emit({ type: 'pulse', dt: step.pulse.dt });
116
+ }
95
117
  else if ('resize' in step) {
96
118
  const resizeMsg = {
97
119
  type: 'resize',
@@ -107,19 +129,18 @@ export async function runScript(app, steps, options) {
107
129
  const _exhaustive = step;
108
130
  throw new Error(`runScript: unhandled script step variant: ${JSON.stringify(_exhaustive)}`);
109
131
  }
110
- // Yield to allow async commands to settle
111
- await new Promise((r) => queueMicrotask(r));
132
+ await bus.drain();
112
133
  }
113
- // Final yield so any trailing commands can settle
114
- await new Promise((r) => queueMicrotask(r));
134
+ await bus.drain();
115
135
  }
116
136
  finally {
137
+ bus.stopPulse();
117
138
  bus.dispose();
118
139
  }
119
140
  return {
120
141
  model,
121
142
  frames,
122
- elapsed: Date.now() - start,
143
+ elapsed: clock.now() - start,
123
144
  };
124
145
  }
125
146
  //# sourceMappingURL=driver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"driver.js","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"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"}
@@ -25,14 +25,24 @@
25
25
  * ```
26
26
  */
27
27
  import type { IOPort } from '@flyingrobots/bijou';
28
- import type { Cmd, KeyMsg, MouseMsg, ResizeMsg } from './types.js';
28
+ import { type ClockPort } from '@flyingrobots/bijou';
29
+ import type { Cmd, KeyMsg, MouseMsg, PulseMsg, ResizeMsg } from './types.js';
29
30
  /**
30
31
  * Union of all message types the bus can carry — built-in key, resize,
31
- * mouse messages plus any app-defined custom message type.
32
+ * mouse, and pulse messages plus any app-defined custom message type.
32
33
  *
33
34
  * @template M - Application-defined custom message type.
34
35
  */
35
- export type BusMsg<M> = KeyMsg | ResizeMsg | MouseMsg | M;
36
+ export type BusMsg<M> = KeyMsg | ResizeMsg | MouseMsg | PulseMsg | M;
37
+ /**
38
+ * Middleware function for intercepting and modifying messages.
39
+ *
40
+ * Call `next(msg)` to continue the message chain. Omitting the call
41
+ * halts message propagation.
42
+ *
43
+ * @template M - Application-defined custom message type.
44
+ */
45
+ export type Middleware<M> = (msg: BusMsg<M>, next: (msg: BusMsg<M>) => void) => void;
36
46
  /**
37
47
  * Centralized event bus that unifies all input sources into a single
38
48
  * typed event stream for TEA applications.
@@ -87,6 +97,33 @@ export interface EventBus<M> {
87
97
  * @returns A disposable that removes this quit handler.
88
98
  */
89
99
  onQuit(handler: () => void): Disposable;
100
+ /**
101
+ * Start the system animation heartbeat at the specified frequency.
102
+ * Emits `PulseMsg` to all subscribers.
103
+ *
104
+ * @param fps - Frames per second. Default: 60.
105
+ */
106
+ startPulse(fps?: number): void;
107
+ /** Stop the system animation heartbeat. */
108
+ stopPulse(): void;
109
+ /**
110
+ * Register a listener for the system heartbeat pulse.
111
+ *
112
+ * @param handler - Callback invoked every pulse with the time delta.
113
+ * @returns A disposable that removes this pulse listener.
114
+ */
115
+ onPulse(handler: (dt: number) => void): Disposable;
116
+ /**
117
+ * Register a middleware function to intercept or modify messages.
118
+ *
119
+ * Middleware are executed in the order they are registered.
120
+ *
121
+ * @param middleware - The middleware function.
122
+ * @returns A disposable that removes this middleware.
123
+ */
124
+ use(middleware: Middleware<M>): Disposable;
125
+ /** Resolve once all in-flight commands have settled. */
126
+ drain(): Promise<void>;
90
127
  /** Disconnect all sources and remove all subscribers. */
91
128
  dispose(): void;
92
129
  }
@@ -96,6 +133,8 @@ export interface CreateEventBusOptions {
96
133
  onCommandRejected?: (error: unknown) => void;
97
134
  /** Called to surface error messages (replaces direct `console.error` usage). */
98
135
  onError?: (message: string, error: unknown) => void;
136
+ /** Clock/scheduler override for deterministic command and pulse timing. */
137
+ clock?: ClockPort;
99
138
  }
100
139
  /** Handle for unsubscribing or disconnecting a resource. */
101
140
  interface Disposable {
@@ -1 +1 @@
1
- {"version":3,"file":"eventbus.d.ts","sourceRoot":"","sources":["../src/eventbus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQnE;;;;;GAKG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB;;;;;;OAMG;IACH,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,UAAU,CAAC;IAElD;;;;OAIG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAE3B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,UAAU,CAAC;IAEjE;;;;;;;;;;OAUG;IACH,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAE1B;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,UAAU,CAAC;IAExC,yDAAyD;IACzD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,qDAAqD;AACrD,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,gFAAgF;IAChF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAED,4DAA4D;AAC5D,UAAU,UAAU;IAClB,0DAA0D;IAC1D,OAAO,IAAI,IAAI,CAAC;CACjB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,qBAAqB,GAAG,QAAQ,CAAC,CAAC,CAAC,CA+HjF"}
1
+ {"version":3,"file":"eventbus.d.ts","sourceRoot":"","sources":["../src/eventbus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ7E;;;;;GAKG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC;AAErE;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC;AAErF;;;;;GAKG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB;;;;;;OAMG;IACH,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,UAAU,CAAC;IAElD;;;;OAIG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAE3B;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,UAAU,CAAC;IAEjE;;;;;;;;;;OAUG;IACH,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAE1B;;;;;;;OAOG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,UAAU,CAAC;IAExC;;;;;OAKG;IACH,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/B,2CAA2C;IAC3C,SAAS,IAAI,IAAI,CAAC;IAElB;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,UAAU,CAAC;IAEnD;;;;;;;OAOG;IACH,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC;IAE3C,wDAAwD;IACxD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,yDAAyD;IACzD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,qDAAqD;AACrD,MAAM,WAAW,qBAAqB;IACpC,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,gFAAgF;IAChF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,2EAA2E;IAC3E,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,4DAA4D;AAC5D,UAAU,UAAU;IAClB,0DAA0D;IAC1D,OAAO,IAAI,IAAI,CAAC;CACjB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,qBAAqB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAkQjF"}