@flyingrobots/bijou-tui 3.0.0 → 4.0.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 (122) hide show
  1. package/LICENSE +159 -21
  2. package/README.md +181 -32
  3. package/dist/app-frame-actions.d.ts +1 -5
  4. package/dist/app-frame-actions.d.ts.map +1 -1
  5. package/dist/app-frame-actions.js +23 -20
  6. package/dist/app-frame-actions.js.map +1 -1
  7. package/dist/app-frame-render.d.ts +17 -11
  8. package/dist/app-frame-render.d.ts.map +1 -1
  9. package/dist/app-frame-render.js +106 -100
  10. package/dist/app-frame-render.js.map +1 -1
  11. package/dist/app-frame-types.d.ts +10 -1
  12. package/dist/app-frame-types.d.ts.map +1 -1
  13. package/dist/app-frame-types.js.map +1 -1
  14. package/dist/app-frame.d.ts +39 -2
  15. package/dist/app-frame.d.ts.map +1 -1
  16. package/dist/app-frame.js +222 -78
  17. package/dist/app-frame.js.map +1 -1
  18. package/dist/browsable-list.d.ts +20 -1
  19. package/dist/browsable-list.d.ts.map +1 -1
  20. package/dist/browsable-list.js +38 -10
  21. package/dist/browsable-list.js.map +1 -1
  22. package/dist/command-palette.d.ts +17 -1
  23. package/dist/command-palette.d.ts.map +1 -1
  24. package/dist/command-palette.js +45 -20
  25. package/dist/command-palette.js.map +1 -1
  26. package/dist/commands.d.ts.map +1 -1
  27. package/dist/commands.js +11 -3
  28. package/dist/commands.js.map +1 -1
  29. package/dist/css/text-style.d.ts +2 -1
  30. package/dist/css/text-style.d.ts.map +1 -1
  31. package/dist/css/text-style.js +33 -0
  32. package/dist/css/text-style.js.map +1 -1
  33. package/dist/design-language.d.ts +49 -0
  34. package/dist/design-language.d.ts.map +1 -0
  35. package/dist/design-language.js +70 -0
  36. package/dist/design-language.js.map +1 -0
  37. package/dist/driver.d.ts +10 -6
  38. package/dist/driver.d.ts.map +1 -1
  39. package/dist/driver.js +18 -17
  40. package/dist/driver.js.map +1 -1
  41. package/dist/eventbus.d.ts +5 -0
  42. package/dist/eventbus.d.ts.map +1 -1
  43. package/dist/eventbus.js +44 -7
  44. package/dist/eventbus.js.map +1 -1
  45. package/dist/file-picker.d.ts +19 -1
  46. package/dist/file-picker.d.ts.map +1 -1
  47. package/dist/file-picker.js +47 -20
  48. package/dist/file-picker.js.map +1 -1
  49. package/dist/flex.d.ts +35 -1
  50. package/dist/flex.d.ts.map +1 -1
  51. package/dist/flex.js +127 -1
  52. package/dist/flex.js.map +1 -1
  53. package/dist/focus-area.d.ts +13 -1
  54. package/dist/focus-area.d.ts.map +1 -1
  55. package/dist/focus-area.js +89 -12
  56. package/dist/focus-area.js.map +1 -1
  57. package/dist/grid.d.ts +10 -0
  58. package/dist/grid.d.ts.map +1 -1
  59. package/dist/grid.js +25 -0
  60. package/dist/grid.js.map +1 -1
  61. package/dist/help.d.ts +41 -0
  62. package/dist/help.d.ts.map +1 -1
  63. package/dist/help.js +50 -0
  64. package/dist/help.js.map +1 -1
  65. package/dist/index.d.ts +19 -17
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +18 -14
  68. package/dist/index.js.map +1 -1
  69. package/dist/layout-node-surface.d.ts +9 -0
  70. package/dist/layout-node-surface.d.ts.map +1 -0
  71. package/dist/layout-node-surface.js +42 -0
  72. package/dist/layout-node-surface.js.map +1 -0
  73. package/dist/navigable-table.d.ts +16 -1
  74. package/dist/navigable-table.d.ts.map +1 -1
  75. package/dist/navigable-table.js +32 -1
  76. package/dist/navigable-table.js.map +1 -1
  77. package/dist/notification.d.ts +89 -0
  78. package/dist/notification.d.ts.map +1 -0
  79. package/dist/notification.js +821 -0
  80. package/dist/notification.js.map +1 -0
  81. package/dist/overlay.d.ts +24 -9
  82. package/dist/overlay.d.ts.map +1 -1
  83. package/dist/overlay.js +236 -138
  84. package/dist/overlay.js.map +1 -1
  85. package/dist/pager.d.ts +16 -0
  86. package/dist/pager.d.ts.map +1 -1
  87. package/dist/pager.js +61 -1
  88. package/dist/pager.js.map +1 -1
  89. package/dist/runtime.d.ts.map +1 -1
  90. package/dist/runtime.js +79 -68
  91. package/dist/runtime.js.map +1 -1
  92. package/dist/split-pane.d.ts +12 -1
  93. package/dist/split-pane.d.ts.map +1 -1
  94. package/dist/split-pane.js +31 -1
  95. package/dist/split-pane.js.map +1 -1
  96. package/dist/status-bar.d.ts +12 -0
  97. package/dist/status-bar.d.ts.map +1 -1
  98. package/dist/status-bar.js +45 -16
  99. package/dist/status-bar.js.map +1 -1
  100. package/dist/surface-layout.d.ts +19 -0
  101. package/dist/surface-layout.d.ts.map +1 -0
  102. package/dist/surface-layout.js +87 -0
  103. package/dist/surface-layout.js.map +1 -0
  104. package/dist/transition-shaders.d.ts +10 -8
  105. package/dist/transition-shaders.d.ts.map +1 -1
  106. package/dist/transition-shaders.js +65 -19
  107. package/dist/transition-shaders.js.map +1 -1
  108. package/dist/types.d.ts +32 -2
  109. package/dist/types.d.ts.map +1 -1
  110. package/dist/view-output.d.ts +4 -4
  111. package/dist/view-output.d.ts.map +1 -1
  112. package/dist/view-output.js +24 -26
  113. package/dist/view-output.js.map +1 -1
  114. package/dist/viewport.d.ts +30 -1
  115. package/dist/viewport.d.ts.map +1 -1
  116. package/dist/viewport.js +77 -1
  117. package/dist/viewport.js.map +1 -1
  118. package/package.json +4 -4
  119. package/dist/layout-v3.d.ts +0 -10
  120. package/dist/layout-v3.d.ts.map +0 -1
  121. package/dist/layout-v3.js +0 -35
  122. package/dist/layout-v3.js.map +0 -1
@@ -38,7 +38,7 @@ export interface RenderContext<PageModel, Msg> {
38
38
  }
39
39
  /** Output of a layout node render pass. */
40
40
  export interface RenderResult {
41
- readonly output: string;
41
+ readonly surface: import('@flyingrobots/bijou').Surface;
42
42
  readonly paneRects: ReadonlyMap<string, import('./layout-rect.js').LayoutRect>;
43
43
  readonly paneOrder: readonly string[];
44
44
  }
@@ -83,10 +83,18 @@ export type FrameAction = {
83
83
  type: 'dock-left';
84
84
  } | {
85
85
  type: 'dock-right';
86
+ } | {
87
+ type: 'runtime-issue';
88
+ issue: RuntimeIssue;
89
+ } | {
90
+ type: 'notification-tick';
91
+ atMs: number;
86
92
  } | {
87
93
  type: 'transition';
88
94
  progress: number;
89
95
  generation: number;
96
+ dt: number;
97
+ elapsedMs: number;
90
98
  } | {
91
99
  type: 'transition-complete';
92
100
  generation: number;
@@ -132,4 +140,5 @@ export declare function emitMsgForPage<Msg>(pageId: string, msg: Msg): Cmd<Msg>;
132
140
  export declare function wrapCmdForPage<Msg>(pageId: string, cmd: Cmd<Msg>): Cmd<Msg>;
133
141
  /** Convert a binding's key combo into a synthetic KeyMsg for dispatch. */
134
142
  export declare function comboToMsg(binding: BindingInfo): KeyMsg;
143
+ import type { RuntimeIssue } from './types.js';
135
144
  //# sourceMappingURL=app-frame-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-frame-types.d.ts","sourceRoot":"","sources":["../src/app-frame-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-frame-types.d.ts","sourceRoot":"","sources":["../src/app-frame-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAMjD,eAAO,MAAM,cAAc,eAA+B,CAAC;AAC3D,eAAO,MAAM,eAAe,eAAgC,CAAC;AAM7D,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAE,SAAQ,UAAU,CAAC,SAAS,CAAC;IAC/E,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;CAC/D;AAED,yEAAyE;AACzE,MAAM,WAAW,YAAY,CAAC,GAAG;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;CACpC;AAED,qEAAqE;AACrE,MAAM,WAAW,aAAa,CAAC,SAAS,EAAE,GAAG;IAC3C,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC5F,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;CACpC;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,qBAAqB,EAAE,OAAO,CAAC;IACxD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,kBAAkB,EAAE,UAAU,CAAC,CAAC;IAC/E,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAMD,wGAAwG;AACxG,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC3F;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AAMzB,qEAAqE;AACrE,MAAM,WAAW,aAAa,CAAC,GAAG;IAChC,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;CACnB;AAED,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B;AAMD,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAKxE;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,cAAc,CAKhE;AAED,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAAC,GAAG,CAAC,CAKhF;AAED,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,CAM9D;AAED,yEAAyE;AACzE,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAE/C;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAEtE;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAM3E;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAQvD;AACD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"app-frame-types.js","sourceRoot":"","sources":["../src/app-frame-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAMlC,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AA4F7D,8EAA8E;AAC9E,4BAA4B;AAC5B,8EAA8E;AAE9E,mEAAmE;AACnE,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ;WAC3B,KAAK,KAAK,IAAI;WACd,eAAe,IAAI,KAAK;WACvB,KAAwB,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;AAC3D,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,OAAO;QACL,CAAC,eAAe,CAAC,EAAE,IAAI;QACvB,MAAM;KACP,CAAC;AACJ,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,eAAe,CAAM,KAAc;IACjD,OAAO,OAAO,KAAK,KAAK,QAAQ;WAC3B,KAAK,KAAK,IAAI;WACd,cAAc,IAAI,KAAK;WACtB,KAA4B,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;AAC9D,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAM,MAAc,EAAE,GAAQ;IACvD,OAAO;QACL,CAAC,cAAc,CAAC,EAAE,IAAI;QACtB,MAAM;QACN,GAAG;KACc,CAAC;AACtB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,OAAO,CAAM,GAAQ;IACnC,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC;AACrC,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAM,MAAc,EAAE,GAAQ;IAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAAM,MAAc,EAAE,GAAa;IAC/D,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAmB,CAAC,EAAE,IAAI,CAAC,CAAC;QAC1F,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QAC3D,OAAO,WAAW,CAAC,MAAM,EAAE,MAAa,CAAC,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,OAAoB;IAC7C,OAAO;QACL,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;QACtB,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;QACxB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK;KAC3B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"app-frame-types.js","sourceRoot":"","sources":["../src/app-frame-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAMlC,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AA8F7D,8EAA8E;AAC9E,4BAA4B;AAC5B,8EAA8E;AAE9E,mEAAmE;AACnE,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ;WAC3B,KAAK,KAAK,IAAI;WACd,eAAe,IAAI,KAAK;WACvB,KAAwB,CAAC,eAAe,CAAC,KAAK,IAAI,CAAC;AAC3D,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,OAAO;QACL,CAAC,eAAe,CAAC,EAAE,IAAI;QACvB,MAAM;KACP,CAAC;AACJ,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,eAAe,CAAM,KAAc;IACjD,OAAO,OAAO,KAAK,KAAK,QAAQ;WAC3B,KAAK,KAAK,IAAI;WACd,cAAc,IAAI,KAAK;WACtB,KAA4B,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;AAC9D,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,WAAW,CAAM,MAAc,EAAE,GAAQ;IACvD,OAAO;QACL,CAAC,cAAc,CAAC,EAAE,IAAI;QACtB,MAAM;QACN,GAAG;KACc,CAAC;AACtB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,OAAO,CAAM,GAAQ;IACnC,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC;AACrC,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAM,MAAc,EAAE,GAAQ;IAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAAM,MAAc,EAAE,GAAa;IAC/D,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC1B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAmB,CAAC,EAAE,IAAI,CAAC,CAAC;QAC1F,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QAC3D,OAAO,WAAW,CAAC,MAAM,EAAE,MAAa,CAAC,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,OAAoB;IAC7C,OAAO;QACL,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;QACtB,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;QACxB,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK;KAC3B,CAAC;AACJ,CAAC"}
@@ -4,9 +4,10 @@
4
4
  * Provides tabs, pane focus/scroll isolation, shell key handling, help,
5
5
  * panel-scoped overlay context, and optional frame-level command palette.
6
6
  */
7
+ import { type OverflowBehavior } from '@flyingrobots/bijou';
7
8
  import { type BindingSource } from './help.js';
8
9
  import type { KeyMap } from './keybindings.js';
9
- import type { App, Cmd } from './types.js';
10
+ import type { App, Cmd, KeyMsg } from './types.js';
10
11
  import type { Overlay } from './overlay.js';
11
12
  import type { TransitionShaderFn } from './transition-shaders.js';
12
13
  import { type BuiltinTransition } from './transition-shaders.js';
@@ -21,6 +22,8 @@ import type { SerializedLayoutState } from './layout-preset.js';
21
22
  import type { OverflowX } from './focus-area.js';
22
23
  import type { Timeline, TimelineState } from './timeline.js';
23
24
  import type { ViewOutput } from './view-output.js';
25
+ import { type NotificationPlacement, type NotificationState } from './notification.js';
26
+ import type { FrameAction } from './app-frame-types.js';
24
27
  /** Page declaration consumed by {@link createFramedApp}. */
25
28
  export interface FramePage<PageModel, Msg> {
26
29
  /** Stable page id. */
@@ -35,6 +38,8 @@ export interface FramePage<PageModel, Msg> {
35
38
  layout(model: PageModel): FrameLayoutNode;
36
39
  /** Optional page keymap. */
37
40
  keyMap?: KeyMap<Msg>;
41
+ /** Optional modal keymap. When present, it captures all keys until dismissed. */
42
+ modalKeyMap?: (model: PageModel) => KeyMap<Msg> | undefined;
38
43
  /** Optional help source override. */
39
44
  helpSource?: BindingSource;
40
45
  /** Optional page-scoped command items for command palette listing/execution. */
@@ -49,7 +54,7 @@ export interface FrameCommandItem<Msg> extends CommandPaletteItem {
49
54
  export type FrameLayoutNode = {
50
55
  readonly kind: 'pane';
51
56
  readonly paneId: string;
52
- /** Pane content may be a legacy string, a Surface, or a LayoutNode. */
57
+ /** Pane content must be a Surface or LayoutNode. */
53
58
  readonly render: (width: number, height: number) => ViewOutput;
54
59
  readonly overflowX?: OverflowX;
55
60
  } | {
@@ -82,6 +87,21 @@ export interface FrameOverlayContext<PageModel> {
82
87
  /** Full-screen bounds. */
83
88
  readonly screenRect: LayoutRect;
84
89
  }
90
+ /** Configuration for frame-managed runtime notifications. */
91
+ export interface FrameRuntimeNotificationOptions {
92
+ /** Enable routing framework warnings/errors through notifications. Default: true. */
93
+ readonly enabled?: boolean;
94
+ /** Stack placement. Default: 'LOWER_RIGHT'. */
95
+ readonly placement?: NotificationPlacement;
96
+ /** Auto-dismiss delay. Default: 6000ms. */
97
+ readonly durationMs?: number | null;
98
+ /** Render margin from the viewport edge. Default: 1. */
99
+ readonly margin?: number;
100
+ /** Gap between stacked notifications. Default: 1. */
101
+ readonly gap?: number;
102
+ /** Text overflow behavior. Default: 'wrap'. */
103
+ readonly overflow?: OverflowBehavior;
104
+ }
85
105
  /** Page transition styles — a built-in name or a custom shader function. */
86
106
  export type PageTransition = BuiltinTransition | TransitionShaderFn;
87
107
  /** `createFramedApp()` options. */
@@ -98,10 +118,23 @@ export interface CreateFramedAppOptions<PageModel, Msg> {
98
118
  readonly initialRows?: number;
99
119
  /** Optional global keymap layered above page keymap. */
100
120
  readonly globalKeys?: KeyMap<Msg>;
121
+ /** Resolve key conflicts in favor of the frame shell or the active page. Default: 'frame-first'. */
122
+ readonly keyPriority?: 'frame-first' | 'page-first';
123
+ /** Optional override for the short help strip source shown beneath the frame header. */
124
+ readonly helpLineSource?: (args: {
125
+ readonly model: FrameModel<PageModel>;
126
+ readonly activePage: FramePage<PageModel, Msg>;
127
+ readonly frameKeys: KeyMap<FrameAction>;
128
+ readonly globalKeys?: KeyMap<Msg>;
129
+ }) => BindingSource | undefined;
130
+ /** Optional observer that receives every key plus the route that handled it. Returned messages are scoped to the active page. */
131
+ readonly observeKey?: (msg: KeyMsg, route: 'palette' | 'help' | 'frame' | 'global' | 'page' | 'unhandled') => Msg | undefined;
101
132
  /** Enable frame-level command palette (`ctrl+p` / `:`). */
102
133
  readonly enableCommandPalette?: boolean;
103
134
  /** Optional overlay provider (receives pane rects for panel scoping). */
104
135
  readonly overlayFactory?: (ctx: FrameOverlayContext<PageModel>) => readonly Overlay[];
136
+ /** Optional runtime warning/error notifications managed by the frame shell. */
137
+ readonly runtimeNotifications?: boolean | FrameRuntimeNotificationOptions;
105
138
  /** Optional page transition style. Default: 'none'. */
106
139
  readonly transition?: PageTransition;
107
140
  /** Transition duration in milliseconds. Default: 300. */
@@ -186,6 +219,10 @@ export interface FrameModel<PageModel> {
186
219
  readonly dockStateByPage: Readonly<Record<string, PanelDockState>>;
187
220
  /** Per-page split ratio overrides (from layout presets/session restore). */
188
221
  readonly splitRatioOverrides: Readonly<Record<string, Readonly<Record<string, number>>>>;
222
+ /** Frame-managed runtime notifications. */
223
+ readonly runtimeNotifications: NotificationState<never>;
224
+ /** Whether the runtime notification tick loop is active. */
225
+ readonly runtimeNotificationLoopActive: boolean;
189
226
  }
190
227
  /**
191
228
  * Create a fully framed TEA app shell.
@@ -1 +1 @@
1
- {"version":3,"file":"app-frame.d.ts","sourceRoot":"","sources":["../src/app-frame.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAKpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAwCnD,4DAA4D;AAC5D,MAAM,WAAW,SAAS,CAAC,SAAS,EAAE,GAAG;IACvC,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iBAAiB;IACjB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8BAA8B;IAC9B,IAAI,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChC,iDAAiD;IACjD,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5D,wBAAwB;IACxB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,eAAe,CAAC;IAC1C,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,qCAAqC;IACrC,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,gFAAgF;IAChF,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,SAAS,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;CACvE;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB,CAAC,GAAG,CAAE,SAAQ,kBAAkB;IAC/D,qDAAqD;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;CACvB;AAED,qCAAqC;AACrC,MAAM,MAAM,eAAe,GACvB;IACA,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,UAAU,CAAC;IAC/D,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;CAChC,GACC;IACA,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B,GACC;IACA,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;CAC3D,CAAC;AAEJ,yCAAyC;AACzC,MAAM,WAAW,mBAAmB,CAAC,SAAS;IAC5C,sBAAsB;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,yBAAyB;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACpD,0BAA0B;IAC1B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC;AAED,4EAA4E;AAC5E,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;AAEpE,mCAAmC;AACnC,MAAM,WAAW,sBAAsB,CAAC,SAAS,EAAE,GAAG;IACpD,wBAAwB;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC;IACrD,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,yEAAyE;IACzE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,wDAAwD;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IACxC,yEAAyE;IACzE,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,CAAC,SAAS,CAAC,KAAK,SAAS,OAAO,EAAE,CAAC;IACtF,uDAAuD;IACvD,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC;IACrC,yDAAyD;IACzD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,uEAAuE;IACvE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,cAAc,CAAC;IACnE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,QAAQ,CAAC;IACvC,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,qBAAqB,CAAC;CAChD;AAED,sCAAsC;AACtC,MAAM,WAAW,eAAe;IAC9B,yBAAyB;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU,CAAC,SAAS;IACnC,8BAA8B;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,yBAAyB;IACzB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,iCAAiC;IACjC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IACzD,yCAAyC;IACzC,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IACzE,0CAA0C;IAC1C,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3F,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,qDAAqD;IACrD,QAAQ,CAAC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IAC9C,qDAAqD;IACrD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,oCAAoC;IACpC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,2DAA2D;IAC3D,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,yCAAyC;IACzC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,cAAc,CAAC;IAC3C,uEAAuE;IACvE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,uDAAuD;IACvD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,QAAQ,CAAC;IACvC,gDAAgD;IAChD,QAAQ,CAAC,uBAAuB,CAAC,EAAE,aAAa,CAAC;IACjD,uFAAuF;IACvF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,uDAAuD;IACvD,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACzE,qCAAqC;IACrC,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAC3E,iCAAiC;IACjC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;IACnE,4EAA4E;IAC5E,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;CAC1F;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,GAAG,EAC5C,OAAO,EAAE,sBAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,GAC9C,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,CAwSjC"}
1
+ {"version":3,"file":"app-frame.d.ts","sourceRoot":"","sources":["../src/app-frame.ts"],"names":[],"mappings":"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"}
package/dist/app-frame.js CHANGED
@@ -4,20 +4,58 @@
4
4
  * Provides tabs, pane focus/scroll isolation, shell key handling, help,
5
5
  * panel-scoped overlay context, and optional frame-level command palette.
6
6
  */
7
- import { createSurface, parseAnsiToSurface, resolveSafeCtx } from '@flyingrobots/bijou';
7
+ import { createSurface, resolveClock, resolveSafeCtx, } from '@flyingrobots/bijou';
8
8
  import { helpView } from './help.js';
9
9
  import { isKeyMsg, isMouseMsg, isResizeMsg } from './types.js';
10
- import { modal } from './overlay.js';
11
- import { fitBlock } from './layout-utils.js';
10
+ import { compositeSurface, modal } from './overlay.js';
12
11
  import { commandPalette, commandPaletteKeyMap, } from './command-palette.js';
13
12
  import { restoreLayoutState } from './layout-preset.js';
14
- import { isFrameScopedMsg, isPageScopedMsg, wrapCmdForPage, emitMsg, emitMsgForPage, } from './app-frame-types.js';
13
+ import { createNotificationState, dismissNotification, hitTestNotificationStack, notificationsNeedTick, pushNotification, renderNotificationStack, tickNotifications, trimNotificationsToViewport, } from './notification.js';
14
+ import { isFrameScopedMsg, isPageScopedMsg, wrapCmdForPage, emitMsg, emitMsgForPage, wrapFrameMsg, } from './app-frame-types.js';
15
15
  import { createFrameKeyMap, frameBodyRect, mergeBindingSources, } from './app-frame-utils.js';
16
- import { renderHeaderLine, renderHelpLine, renderPageContent, renderMaximizedPane, renderTransition, } from './app-frame-render.js';
17
- import { applyFrameAction, syncPageFrameState, } from './app-frame-actions.js';
16
+ import { resolveHeaderLine, renderHelpLine, renderPageContent, renderMaximizedPane, renderTransition, } from './app-frame-render.js';
17
+ import { applyFrameAction, switchTab, syncPageFrameState, } from './app-frame-actions.js';
18
18
  import { handlePaletteKey, openCommandPalette, } from './app-frame-palette.js';
19
- import { visibleLength } from './viewport.js';
20
19
  // ---------------------------------------------------------------------------
20
+ // Frame Notification Helpers
21
+ // ---------------------------------------------------------------------------
22
+ const FRAME_NOTIFICATION_TICK_MS = 40;
23
+ const DEFAULT_FRAME_NOTIFICATION_DURATION_MS = 6_000;
24
+ function resolveFrameNotificationOptions(options) {
25
+ if (options.runtimeNotifications === false) {
26
+ return {
27
+ enabled: false,
28
+ placement: 'LOWER_RIGHT',
29
+ durationMs: DEFAULT_FRAME_NOTIFICATION_DURATION_MS,
30
+ margin: 1,
31
+ gap: 1,
32
+ overflow: 'wrap',
33
+ };
34
+ }
35
+ const configured = options.runtimeNotifications === true || options.runtimeNotifications == null
36
+ ? {}
37
+ : options.runtimeNotifications;
38
+ return {
39
+ enabled: configured.enabled ?? true,
40
+ placement: configured.placement ?? 'LOWER_RIGHT',
41
+ durationMs: configured.durationMs ?? DEFAULT_FRAME_NOTIFICATION_DURATION_MS,
42
+ margin: configured.margin ?? 1,
43
+ gap: configured.gap ?? 1,
44
+ overflow: configured.overflow ?? 'wrap',
45
+ };
46
+ }
47
+ function createFrameNotificationTickCmd() {
48
+ return async (_emit, caps) => {
49
+ if (!caps.sleep) {
50
+ throw new Error('createFrameNotificationTickCmd requires sleep capability');
51
+ }
52
+ await caps.sleep(FRAME_NOTIFICATION_TICK_MS);
53
+ return wrapFrameMsg({
54
+ type: 'notification-tick',
55
+ atMs: caps.now?.() ?? 0,
56
+ });
57
+ };
58
+ }
21
59
  // Factory
22
60
  // ---------------------------------------------------------------------------
23
61
  /**
@@ -40,6 +78,7 @@ export function createFramedApp(options) {
40
78
  throw new Error(`createFramedApp: defaultPageId "${defaultPageId}" not found in pages`);
41
79
  }
42
80
  const frameKeys = createFrameKeyMap();
81
+ const frameNotificationOptions = resolveFrameNotificationOptions(options);
43
82
  const paletteKeys = commandPaletteKeyMap({
44
83
  focusNext: { type: 'cp-next' },
45
84
  focusPrev: { type: 'cp-prev' },
@@ -48,6 +87,90 @@ export function createFramedApp(options) {
48
87
  select: { type: 'cp-select' },
49
88
  close: { type: 'cp-close' },
50
89
  });
90
+ function withObservedKey(model, cmds, msg, route) {
91
+ const observed = options.observeKey?.(msg, route);
92
+ if (observed === undefined)
93
+ return [...cmds];
94
+ return [emitMsgForPage(model.activePageId, observed), ...cmds];
95
+ }
96
+ function updateTargetPage(model, targetPageId, targetMsg) {
97
+ const targetPage = pagesById.get(targetPageId);
98
+ if (targetPage == null)
99
+ return [model, []];
100
+ const pageModel = model.pageModels[targetPageId];
101
+ const updateResult = targetPage.update(targetMsg, pageModel);
102
+ let nextPageModel = pageModel;
103
+ let cmds = [];
104
+ if (updateResult !== undefined && updateResult !== null) {
105
+ if (Array.isArray(updateResult)) {
106
+ nextPageModel = (updateResult[0] ?? pageModel);
107
+ cmds = (updateResult[1] ?? []);
108
+ }
109
+ else {
110
+ nextPageModel = updateResult;
111
+ }
112
+ }
113
+ const nextModels = { ...model.pageModels, [targetPageId]: nextPageModel };
114
+ const synced = syncPageFrameState({ ...model, pageModels: nextModels }, targetPageId, pagesById);
115
+ const wrappedCmds = Array.isArray(cmds)
116
+ ? cmds.map((cmd) => wrapCmdForPage(targetPageId, cmd))
117
+ : [];
118
+ return [synced, wrappedCmds];
119
+ }
120
+ function handleFrameMouse(msg, model) {
121
+ if (model.helpOpen || model.commandPalette != null)
122
+ return [model, []];
123
+ if (msg.action !== 'press' || msg.button !== 'left')
124
+ return undefined;
125
+ if (frameNotificationOptions.enabled) {
126
+ const nowMs = resolveClock(resolveSafeCtx()).now();
127
+ const notificationTarget = hitTestNotificationStack(model.runtimeNotifications, {
128
+ screenWidth: model.columns,
129
+ screenHeight: model.rows,
130
+ margin: frameNotificationOptions.margin,
131
+ gap: frameNotificationOptions.gap,
132
+ ctx: resolveSafeCtx() ?? undefined,
133
+ }, msg.col, msg.row);
134
+ if (notificationTarget?.kind === 'dismiss') {
135
+ return applyFrameNotificationState(model, dismissNotification(model.runtimeNotifications, notificationTarget.item.id, nowMs), nowMs);
136
+ }
137
+ if (notificationTarget != null) {
138
+ return [model, []];
139
+ }
140
+ }
141
+ if (msg.row === 0) {
142
+ const header = resolveHeaderLine(model, options, pagesById);
143
+ const tab = header.tabTargets.find((target) => msg.col >= target.startCol && msg.col <= target.endCol);
144
+ if (tab != null) {
145
+ const currentIndex = model.pageOrder.indexOf(model.activePageId);
146
+ const nextIndex = model.pageOrder.indexOf(tab.pageId);
147
+ if (currentIndex >= 0 && nextIndex >= 0 && nextIndex !== currentIndex) {
148
+ return switchTab(model, nextIndex - currentIndex, pagesById, options);
149
+ }
150
+ return [model, []];
151
+ }
152
+ return [model, []];
153
+ }
154
+ return undefined;
155
+ }
156
+ function applyFrameNotificationState(model, notifications, nowMs, forceTick = false) {
157
+ const trimmed = trimNotificationsToViewport(notifications, {
158
+ screenWidth: model.columns,
159
+ screenHeight: model.rows,
160
+ margin: frameNotificationOptions.margin,
161
+ gap: frameNotificationOptions.gap,
162
+ }, nowMs);
163
+ const needsTick = notificationsNeedTick(trimmed);
164
+ const nextModel = {
165
+ ...model,
166
+ runtimeNotifications: trimmed,
167
+ runtimeNotificationLoopActive: needsTick,
168
+ };
169
+ if (needsTick && (forceTick || !model.runtimeNotificationLoopActive)) {
170
+ return [nextModel, [createFrameNotificationTickCmd()]];
171
+ }
172
+ return [nextModel, []];
173
+ }
51
174
  const app = {
52
175
  init() {
53
176
  const pageModels = {};
@@ -73,6 +196,8 @@ export function createFramedApp(options) {
73
196
  maximizedPaneByPage: {},
74
197
  dockStateByPage: {},
75
198
  splitRatioOverrides: {},
199
+ runtimeNotifications: createNotificationState(),
200
+ runtimeNotificationLoopActive: false,
76
201
  };
77
202
  for (const pageId of pageOrder) {
78
203
  model = syncPageFrameState(model, pageId, pagesById);
@@ -95,16 +220,31 @@ export function createFramedApp(options) {
95
220
  update(msg, model) {
96
221
  if (isFrameScopedMsg(msg)) {
97
222
  const action = msg.action;
223
+ if (action.type === 'runtime-issue') {
224
+ if (!frameNotificationOptions.enabled)
225
+ return [model, []];
226
+ const notifications = pushNotification(model.runtimeNotifications, {
227
+ title: action.issue.level === 'warning' ? 'Framework warning' : 'Runtime error',
228
+ message: action.issue.message,
229
+ variant: 'TOAST',
230
+ tone: action.issue.level === 'warning' ? 'WARNING' : 'ERROR',
231
+ placement: frameNotificationOptions.placement,
232
+ durationMs: frameNotificationOptions.durationMs,
233
+ overflow: frameNotificationOptions.overflow,
234
+ }, action.issue.atMs);
235
+ return applyFrameNotificationState(model, notifications, action.issue.atMs);
236
+ }
237
+ if (action.type === 'notification-tick') {
238
+ const notifications = tickNotifications(model.runtimeNotifications, action.atMs);
239
+ return applyFrameNotificationState(model, notifications, action.atMs, true);
240
+ }
98
241
  if (action.type === 'transition') {
99
242
  // Ignore stale transition ticks from a previous generation
100
243
  if (action.generation !== model.transitionGeneration)
101
244
  return [model, []];
102
- // Advance timeline using wall-clock elapsed time
103
- if (model.transitionTimeline && model.transitionTimelineState && model.transitionStartMs != null) {
104
- const elapsedMs = Date.now() - model.transitionStartMs;
105
- const elapsedSec = Math.max(0, elapsedMs / 1000);
106
- // Step from init to current elapsed time (tweens are deterministic)
107
- const state = model.transitionTimeline.step(model.transitionTimeline.init(), elapsedSec);
245
+ // Advance timeline from deterministic pulse deltas.
246
+ if (model.transitionTimeline && model.transitionTimelineState) {
247
+ const state = model.transitionTimeline.step(model.transitionTimelineState, Math.max(0, action.dt));
108
248
  const vals = model.transitionTimeline.values(state);
109
249
  const progress = Math.min(1, Math.max(0, vals['progress'] ?? action.progress));
110
250
  if (model.transitionTimeline.done(state) || progress >= 1) {
@@ -158,65 +298,77 @@ export function createFramedApp(options) {
158
298
  }
159
299
  if (isKeyMsg(msg)) {
160
300
  if (model.commandPalette != null) {
161
- return handlePaletteKey(msg, model, paletteKeys, options, pagesById);
301
+ const [nextModel, cmds] = handlePaletteKey(msg, model, paletteKeys, options, pagesById);
302
+ return [nextModel, withObservedKey(model, cmds, msg, 'palette')];
162
303
  }
163
304
  // Help acts as a modal layer when open: only close keys are handled.
164
305
  if (model.helpOpen) {
165
306
  if (!msg.ctrl && !msg.alt && (msg.key === 'escape' || msg.key === '?')) {
166
- return [{ ...model, helpOpen: false }, []];
307
+ return [{ ...model, helpOpen: false }, withObservedKey(model, [], msg, 'help')];
308
+ }
309
+ return [model, withObservedKey(model, [], msg, 'help')];
310
+ }
311
+ const activePage = pagesById.get(model.activePageId);
312
+ const activePageModel = model.pageModels[model.activePageId];
313
+ const modalKeyMap = activePage.modalKeyMap?.(activePageModel);
314
+ if (modalKeyMap != null) {
315
+ const modalAction = modalKeyMap.handle(msg);
316
+ if (modalAction !== undefined) {
317
+ return [model, withObservedKey(model, [emitMsgForPage(model.activePageId, modalAction)], msg, 'page')];
167
318
  }
168
- return [model, []];
319
+ return [model, withObservedKey(model, [], msg, 'page')];
169
320
  }
321
+ const pageAction = activePage.keyMap?.handle(msg);
322
+ const globalAction = options.globalKeys?.handle(msg);
170
323
  const frameAction = frameKeys.handle(msg);
324
+ const keyPriority = options.keyPriority ?? 'frame-first';
325
+ if (keyPriority === 'page-first') {
326
+ if (pageAction !== undefined) {
327
+ return [model, withObservedKey(model, [emitMsgForPage(model.activePageId, pageAction)], msg, 'page')];
328
+ }
329
+ if (globalAction !== undefined) {
330
+ return [model, withObservedKey(model, [emitMsg(globalAction)], msg, 'global')];
331
+ }
332
+ if (frameAction !== undefined) {
333
+ if (frameAction.type === 'open-palette' && options.enableCommandPalette) {
334
+ return [openCommandPalette(model, frameKeys, options, pagesById), withObservedKey(model, [], msg, 'frame')];
335
+ }
336
+ const [nextModel, cmds] = applyFrameAction(frameAction, model, options, pagesById);
337
+ return [nextModel, withObservedKey(model, cmds, msg, 'frame')];
338
+ }
339
+ return [model, withObservedKey(model, [], msg, 'unhandled')];
340
+ }
171
341
  if (frameAction !== undefined) {
172
342
  // Handle palette opening here since applyFrameAction doesn't have access to palette deps
173
343
  if (frameAction.type === 'open-palette' && options.enableCommandPalette) {
174
- return [openCommandPalette(model, frameKeys, options, pagesById), []];
344
+ return [openCommandPalette(model, frameKeys, options, pagesById), withObservedKey(model, [], msg, 'frame')];
175
345
  }
176
- return applyFrameAction(frameAction, model, options, pagesById);
346
+ const [nextModel, cmds] = applyFrameAction(frameAction, model, options, pagesById);
347
+ return [nextModel, withObservedKey(model, cmds, msg, 'frame')];
177
348
  }
178
- const globalAction = options.globalKeys?.handle(msg);
179
349
  if (globalAction !== undefined) {
180
- return [model, [emitMsg(globalAction)]];
350
+ return [model, withObservedKey(model, [emitMsg(globalAction)], msg, 'global')];
181
351
  }
182
- const activePage = pagesById.get(model.activePageId);
183
- const pageAction = activePage.keyMap?.handle(msg);
184
352
  if (pageAction !== undefined) {
185
- return [model, [emitMsgForPage(model.activePageId, pageAction)]];
353
+ return [model, withObservedKey(model, [emitMsgForPage(model.activePageId, pageAction)], msg, 'page')];
186
354
  }
187
- return [model, []];
355
+ return [model, withObservedKey(model, [], msg, 'unhandled')];
188
356
  }
189
357
  if (isMouseMsg(msg)) {
190
- return [model, []];
358
+ const frameResult = handleFrameMouse(msg, model);
359
+ if (frameResult != null)
360
+ return frameResult;
361
+ return updateTargetPage(model, model.activePageId, msg);
191
362
  }
192
363
  // Custom message path: route to originating page when command messages are scoped.
193
364
  const scoped = isPageScopedMsg(msg) ? msg : undefined;
194
365
  const targetPageId = scoped?.pageId ?? model.activePageId;
195
- const targetPage = pagesById.get(targetPageId);
196
- if (targetPage == null)
197
- return [model, []];
198
366
  const targetMsg = scoped?.msg ?? msg;
199
- const pageModel = model.pageModels[targetPageId];
200
- const updateResult = targetPage.update(targetMsg, pageModel);
201
- let nextPageModel = pageModel; // Default to current
202
- let cmds = [];
203
- if (updateResult !== undefined && updateResult !== null) {
204
- if (Array.isArray(updateResult)) {
205
- nextPageModel = (updateResult[0] ?? pageModel);
206
- cmds = (updateResult[1] ?? []);
207
- }
208
- else {
209
- nextPageModel = updateResult;
210
- }
211
- }
212
- const nextModels = { ...model.pageModels, [targetPageId]: nextPageModel };
213
- const synced = syncPageFrameState({ ...model, pageModels: nextModels }, targetPageId, pagesById);
214
- const wrappedCmds = Array.isArray(cmds) ? cmds.map((cmd) => wrapCmdForPage(targetPageId, cmd)) : [];
215
- return [synced, wrappedCmds];
367
+ return updateTargetPage(model, targetPageId, targetMsg);
216
368
  },
217
369
  view(model) {
218
370
  const activePage = pagesById.get(model.activePageId);
219
- const header = renderHeaderLine(model, options, pagesById);
371
+ const header = resolveHeaderLine(model, options, pagesById).surface;
220
372
  const helpLine = renderHelpLine(model, frameKeys, options, activePage);
221
373
  const bodyRect = frameBodyRect(model.columns, model.rows);
222
374
  // Check for maximized pane — if set, render only that pane at full body rect
@@ -225,16 +377,15 @@ export function createFramedApp(options) {
225
377
  const activeResult = maximizedPaneId
226
378
  ? renderMaximizedPane(model.activePageId, model, bodyRect, pagesById, maximizedPaneId)
227
379
  : renderPageContent(model.activePageId, model, bodyRect, pagesById);
228
- let bodyOutput = activeResult.output;
380
+ let bodySurface = activeResult.surface;
229
381
  const activeTransition = model.activeTransition ?? options.transition;
230
382
  if (model.previousPageId != null && model.transitionProgress < 1 && activeTransition && activeTransition !== 'none') {
231
383
  const ctx = resolveSafeCtx();
232
384
  if (ctx) {
233
385
  const prevResult = renderPageContent(model.previousPageId, model, bodyRect, pagesById);
234
- bodyOutput = renderTransition(prevResult.output, activeResult.output, activeTransition, model.transitionProgress, bodyRect.width, bodyRect.height, ctx, model.transitionFrame);
386
+ bodySurface = renderTransition(prevResult.surface, activeResult.surface, activeTransition, model.transitionProgress, bodyRect.width, bodyRect.height, ctx, model.transitionFrame);
235
387
  }
236
388
  }
237
- bodyOutput = fitBlock(bodyOutput, bodyRect.width, bodyRect.height).join('\n');
238
389
  const overlays = [];
239
390
  if (options.overlayFactory != null) {
240
391
  overlays.push(...options.overlayFactory({
@@ -244,6 +395,16 @@ export function createFramedApp(options) {
244
395
  screenRect: { row: 0, col: 0, width: model.columns, height: model.rows },
245
396
  }));
246
397
  }
398
+ if (frameNotificationOptions.enabled) {
399
+ const ctx = resolveSafeCtx();
400
+ overlays.push(...renderNotificationStack(model.runtimeNotifications, {
401
+ screenWidth: model.columns,
402
+ screenHeight: model.rows,
403
+ margin: frameNotificationOptions.margin,
404
+ gap: frameNotificationOptions.gap,
405
+ ctx: ctx ?? undefined,
406
+ }));
407
+ }
247
408
  if (model.helpOpen) {
248
409
  const full = helpView(mergeBindingSources(frameKeys, options.globalKeys, activePage.helpSource ?? activePage.keyMap));
249
410
  overlays.push(modal({
@@ -269,48 +430,31 @@ export function createFramedApp(options) {
269
430
  return composeFrameSurface({
270
431
  width: model.columns,
271
432
  height: model.rows,
272
- header,
273
- helpLine,
274
- bodyOutput,
433
+ headerSurface: header,
434
+ helpLineSurface: helpLine,
435
+ bodySurface,
275
436
  bodyRect,
276
437
  overlays,
277
438
  dimBackground: overlays.length > 0,
278
439
  });
279
440
  },
441
+ routeRuntimeIssue(issue) {
442
+ if (!frameNotificationOptions.enabled)
443
+ return undefined;
444
+ return wrapFrameMsg({ type: 'runtime-issue', issue });
445
+ },
280
446
  };
281
447
  return app;
282
448
  }
283
449
  function composeFrameSurface(options) {
284
450
  const frame = createSurface(options.width, options.height);
285
- frame.blit(parseAnsiToSurface(options.header, options.width, 1), 0, 0);
451
+ frame.blit(options.headerSurface, 0, 0);
286
452
  if (options.height > 1) {
287
- frame.blit(parseAnsiToSurface(options.helpLine, options.width, 1), 0, 1);
453
+ frame.blit(options.helpLineSurface, 0, 1);
288
454
  }
289
455
  if (options.bodyRect.width > 0 && options.bodyRect.height > 0) {
290
- frame.blit(parseAnsiToSurface(options.bodyOutput, options.bodyRect.width, options.bodyRect.height), options.bodyRect.col, options.bodyRect.row);
291
- }
292
- if (options.dimBackground) {
293
- dimSurface(frame);
456
+ frame.blit(options.bodySurface, options.bodyRect.col, options.bodyRect.row);
294
457
  }
295
- for (const overlay of options.overlays) {
296
- const overlaySurface = parseAnsiToSurface(overlay.content, maxVisibleWidth(overlay.content), overlay.content.split('\n').length);
297
- frame.blit(overlaySurface, overlay.col, overlay.row);
298
- }
299
- return frame;
300
- }
301
- function dimSurface(surface) {
302
- for (let y = 0; y < surface.height; y++) {
303
- for (let x = 0; x < surface.width; x++) {
304
- const cell = surface.get(x, y);
305
- if (cell.empty || cell.char === ' ')
306
- continue;
307
- const modifiers = new Set(cell.modifiers ?? []);
308
- modifiers.add('dim');
309
- surface.set(x, y, { ...cell, modifiers: Array.from(modifiers) });
310
- }
311
- }
312
- }
313
- function maxVisibleWidth(text) {
314
- return text.split('\n').reduce((max, line) => Math.max(max, visibleLength(line)), 0);
458
+ return compositeSurface(frame, options.overlays, { dim: options.dimBackground });
315
459
  }
316
460
  //# sourceMappingURL=app-frame.js.map