@nan0web/ui 1.12.3 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/package.json +29 -20
  2. package/src/Component/index.js +1 -5
  3. package/src/Model/Element.js +183 -0
  4. package/src/Theme/AppTheme.js +19 -0
  5. package/src/Theme/CustomTheme.js +32 -0
  6. package/src/Theme/DarkLightTheme.js +34 -0
  7. package/src/Theme/Theme.js +25 -0
  8. package/src/Theme/atoms/Avatar.js +20 -0
  9. package/src/Theme/atoms/Badge.js +28 -0
  10. package/src/Theme/atoms/Button.js +88 -0
  11. package/src/Theme/atoms/Checkbox.js +26 -0
  12. package/src/Theme/atoms/Input.js +28 -0
  13. package/src/Theme/atoms/Radio.js +26 -0
  14. package/src/Theme/atoms/Select.js +16 -0
  15. package/src/Theme/atoms/TextArea.js +17 -0
  16. package/src/Theme/atoms/Typography.js +26 -0
  17. package/src/Theme/atoms/index.js +11 -0
  18. package/src/Theme/createTheme.js +22 -0
  19. package/src/Theme/index.js +20 -0
  20. package/src/Theme/molecules/Card.js +24 -0
  21. package/src/Theme/molecules/index.js +3 -0
  22. package/src/Theme/organisms/Modal.js +24 -0
  23. package/src/Theme/organisms/index.js +3 -0
  24. package/src/Theme/presets/HighContrastTheme.js +65 -0
  25. package/src/Theme/presets/NightTheme.js +66 -0
  26. package/src/Theme/presets/index.js +4 -0
  27. package/src/Theme/tokens.js +115 -0
  28. package/src/core/InputAdapter.js +1 -2
  29. package/src/core/Intent.js +22 -8
  30. package/src/core/Message/Message.js +3 -0
  31. package/src/core/OutputAdapter.js +9 -13
  32. package/src/core/index.js +7 -4
  33. package/src/domain/ModelAsApp.js +1 -1
  34. package/src/domain/app/IntentAuditor.js +53 -0
  35. package/src/domain/app/JsIntentAuditor.js +145 -0
  36. package/src/domain/app/PyIntentAuditor.js +144 -0
  37. package/src/domain/app/SnapshotAuditor.js +8 -8
  38. package/src/domain/components/ShellModel.js +2 -2
  39. package/src/index.js +35 -9
  40. package/src/inspect.js +3 -0
  41. package/src/utils/format.js +21 -0
  42. package/src/utils/processI18n.js +27 -0
  43. package/src/utils/resolveContext.js +79 -0
  44. package/types/Component/index.d.ts +1 -5
  45. package/types/Model/Element.d.ts +87 -0
  46. package/types/Theme/AppTheme.d.ts +14 -0
  47. package/types/Theme/CustomTheme.d.ts +21 -0
  48. package/types/Theme/DarkLightTheme.d.ts +16 -0
  49. package/types/Theme/Theme.d.ts +18 -0
  50. package/types/Theme/atoms/Avatar.d.ts +14 -0
  51. package/types/Theme/atoms/Badge.d.ts +22 -0
  52. package/types/Theme/atoms/Button.d.ts +144 -0
  53. package/types/Theme/atoms/Checkbox.d.ts +20 -0
  54. package/types/Theme/atoms/Input.d.ts +22 -0
  55. package/types/Theme/atoms/Radio.d.ts +20 -0
  56. package/types/Theme/atoms/Select.d.ts +15 -0
  57. package/types/Theme/atoms/TextArea.d.ts +17 -0
  58. package/types/Theme/atoms/Typography.d.ts +47 -0
  59. package/types/Theme/atoms/index.d.ts +10 -0
  60. package/types/Theme/createTheme.d.ts +7 -0
  61. package/types/Theme/index.d.ts +10 -0
  62. package/types/Theme/molecules/Card.d.ts +18 -0
  63. package/types/Theme/molecules/index.d.ts +2 -0
  64. package/types/Theme/organisms/Modal.d.ts +18 -0
  65. package/types/Theme/organisms/index.d.ts +2 -0
  66. package/types/Theme/presets/HighContrastTheme.d.ts +2 -0
  67. package/types/Theme/presets/NightTheme.d.ts +2 -0
  68. package/types/Theme/presets/index.d.ts +3 -0
  69. package/types/Theme/tokens.d.ts +119 -0
  70. package/types/core/Intent.d.ts +10 -7
  71. package/types/core/Message/Message.d.ts +3 -0
  72. package/types/core/OutputAdapter.d.ts +2 -4
  73. package/types/core/index.d.ts +5 -2
  74. package/types/domain/Document.d.ts +2 -1
  75. package/types/domain/FooterModel.d.ts +2 -1
  76. package/types/domain/ModelAsApp.d.ts +48 -48
  77. package/types/domain/app/IntentAuditor.d.ts +23 -0
  78. package/types/domain/app/JsIntentAuditor.d.ts +22 -0
  79. package/types/domain/app/PyIntentAuditor.d.ts +22 -0
  80. package/types/domain/app/SnapshotAuditor.d.ts +5 -6
  81. package/types/domain/components/ShellModel.d.ts +1 -5
  82. package/types/index.d.ts +7 -9
  83. package/types/inspect.d.ts +3 -0
  84. package/types/utils/format.d.ts +5 -0
  85. package/types/utils/processI18n.d.ts +8 -0
  86. package/types/utils/resolveContext.d.ts +21 -0
  87. package/src/App/Command/DepsCommand.js +0 -24
  88. package/src/App/Core/CoreApp.js +0 -125
  89. package/src/App/Core/UI.js +0 -63
  90. package/src/App/Core/Widget.js +0 -61
  91. package/src/App/Core/index.js +0 -11
  92. package/src/App/Scenario.js +0 -45
  93. package/src/App/User/Command/Message.js +0 -3
  94. package/src/App/User/Command/index.js +0 -5
  95. package/src/App/User/UserApp.js +0 -85
  96. package/src/App/User/UserUI.js +0 -20
  97. package/src/App/User/index.js +0 -9
  98. package/src/App/index.js +0 -14
  99. package/src/Component/Process/Input.js +0 -63
  100. package/src/Component/Process/Process.js +0 -24
  101. package/src/Component/Process/index.js +0 -5
  102. package/src/Component/Welcome/Input.js +0 -48
  103. package/src/Component/Welcome/Welcome.js +0 -22
  104. package/src/Component/Welcome/index.js +0 -5
  105. package/src/Frame/Frame.js +0 -608
  106. package/src/Frame/Props.js +0 -96
  107. package/src/StdIn.js +0 -100
  108. package/src/StdOut.js +0 -95
  109. package/src/View/RenderOptions.js +0 -48
  110. package/src/View/View.js +0 -306
  111. package/src/core/Message/index.js +0 -6
  112. package/types/App/Command/DepsCommand.d.ts +0 -14
  113. package/types/App/Core/CoreApp.d.ts +0 -70
  114. package/types/App/Core/UI.d.ts +0 -38
  115. package/types/App/Core/Widget.d.ts +0 -39
  116. package/types/App/Core/index.d.ts +0 -10
  117. package/types/App/Scenario.d.ts +0 -26
  118. package/types/App/User/Command/Message.d.ts +0 -2
  119. package/types/App/User/Command/index.d.ts +0 -3
  120. package/types/App/User/UserApp.d.ts +0 -41
  121. package/types/App/User/UserUI.d.ts +0 -9
  122. package/types/App/User/index.d.ts +0 -8
  123. package/types/App/index.d.ts +0 -12
  124. package/types/Component/Process/Input.d.ts +0 -48
  125. package/types/Component/Process/Process.d.ts +0 -13
  126. package/types/Component/Process/index.d.ts +0 -4
  127. package/types/Component/Welcome/Input.d.ts +0 -34
  128. package/types/Component/Welcome/Welcome.d.ts +0 -13
  129. package/types/Component/Welcome/index.d.ts +0 -4
  130. package/types/Frame/Frame.d.ts +0 -186
  131. package/types/Frame/Props.d.ts +0 -77
  132. package/types/StdIn.d.ts +0 -62
  133. package/types/StdOut.d.ts +0 -52
  134. package/types/View/RenderOptions.d.ts +0 -29
  135. package/types/View/View.d.ts +0 -124
  136. package/types/core/Message/index.d.ts +0 -4
package/src/StdIn.js DELETED
@@ -1,100 +0,0 @@
1
- import EventProcessor from '@nan0web/event/oop'
2
- import { typeOf } from '@nan0web/types'
3
- import { UiMessage } from './core/index.js'
4
-
5
- class Processor extends EventProcessor {}
6
-
7
- /**
8
- * Handles standard input stream with message buffering.
9
- */
10
- export default class StdIn extends EventProcessor {
11
- /** @type {number} Read interval in milliseconds */
12
- static READ_INTERVAL = 99
13
-
14
- /** @type {string[]} Messages to ignore */
15
- static IGNORE_MESSAGES = ['', 'undefined']
16
-
17
- /**
18
- * Creates a new StdIn instance.
19
- * @param {object} props - StdIn properties
20
- * @param {Processor} [props.processor] - Input processor
21
- * @param {UiMessage[]} [props.stream=[]] - Initial input stream
22
- */
23
- constructor(props = {}) {
24
- super()
25
- const { processor = new Processor(), stream = [] } = props
26
- /** @type {Processor} Input processor */
27
- this.processor = processor
28
- /** @type {UiMessage[]} Input message buffer */
29
- this.stream = stream
30
- this.processor?.on('data', (data) => {
31
- this.write(data)
32
- })
33
- }
34
-
35
- /**
36
- * Checks if there are messages waiting in the input stream.
37
- * @returns {boolean} True if waiting messages, false otherwise
38
- */
39
- get waiting() {
40
- return this.stream.length > 0
41
- }
42
-
43
- /**
44
- * Checks if the input stream has ended (no messages left).
45
- * @returns {boolean} True if no messages left, false otherwise
46
- */
47
- get ended() {
48
- return 0 === this.stream.length
49
- }
50
-
51
- /**
52
- * Reads a message from the input stream.
53
- * Waits until messages are available if stream is empty.
54
- * @returns {Promise<UiMessage>} Next input message
55
- */
56
- async read() {
57
- while (this.ended) {
58
- await new Promise((resolve) => setTimeout(resolve, StdIn.READ_INTERVAL))
59
- }
60
- return this.stream.shift() ?? new UiMessage()
61
- }
62
-
63
- /**
64
- * Writes a message to the input stream.
65
- * @param {string} message - Message to write
66
- * @returns {boolean} True if message accepted, False if ignored
67
- */
68
- write(message) {
69
- // this.processor?.emit("data", message)
70
- const text = String(message)
71
- if (StdIn.IGNORE_MESSAGES.includes(text)) {
72
- return false
73
- }
74
- this.stream.push(this.decode(text))
75
- return true
76
- }
77
-
78
- /**
79
- * Decodes a message into an UiMessage instance.
80
- * @param {UiMessage | string[] | any} message - Message to decode
81
- * @returns {UiMessage} Decoded input message
82
- */
83
- decode(message) {
84
- if (message instanceof UiMessage) return message
85
- if (Array.isArray(message) && message.every(typeOf(String))) {
86
- return new UiMessage({ value: message })
87
- }
88
- return new UiMessage(message)
89
- }
90
-
91
- /**
92
- * Creates a StdIn instance from the given input.
93
- * @param {StdIn|object} input - The input to create from
94
- * @returns {StdIn} A StdIn instance
95
- */
96
- static from(input) {
97
- if (input instanceof StdIn) return input
98
- return new this(input)
99
- }
100
- }
package/src/StdOut.js DELETED
@@ -1,95 +0,0 @@
1
- import { typeOf } from '@nan0web/types'
2
- import EventProcessor from '@nan0web/event/oop'
3
-
4
- /**
5
- * Handles standard output stream with formatting capabilities.
6
- */
7
- class StdOut extends EventProcessor {
8
- /** @type {string} End of line character */
9
- static EOL = '\n'
10
-
11
- /** @type {string} Beginning of line character */
12
- static BOL = '\r'
13
-
14
- /** @type {string} Reset formatting escape code */
15
- static RESET = '\x1b[0m'
16
-
17
- /** @type {string} Clear screen escape code */
18
- static CLEAR = '\x1b[2J\x1b[H'
19
-
20
- /** @type {object} Color escape codes */
21
- static COLORS = {
22
- red: '\x1b[31m',
23
- green: '\x1b[32m',
24
- yellow: '\x1b[33m',
25
- blue: '\x1b[34m',
26
- magenta: '\x1b[35m',
27
- cyan: '\x1b[36m',
28
- white: '\x1b[37m',
29
- gray: '\x1b[90m',
30
- black: '\x1b[30m',
31
- }
32
-
33
- /** @type {Record<string, string>} Style escape codes */
34
- static STYLES = {
35
- dim: '\x1b[2m',
36
- bold: '\x1b[1m',
37
- underline: '\x1b[4m',
38
- }
39
-
40
- /**
41
- * @todo define go top by rows constants.
42
- */
43
-
44
- /** @type {string[]} Output stream buffer */
45
- stream = []
46
-
47
- /** @type {number[]} Window size [width, height] */
48
- windowSize = []
49
-
50
- /** @type {any} Output processor */
51
- processor
52
-
53
- /**
54
- * Creates a new StdOut instance.
55
- * @param {object} props - StdOut properties
56
- * @param {any} [props.processor] - Output processor
57
- * @param {string[]} [props.stream=[]] - Initial output stream
58
- * @param {number[]} [props.windowSize=[144, 33]] - Window size [width, height]
59
- */
60
- constructor(props = {}) {
61
- super()
62
- const { processor, stream = [], windowSize = [144, 33] } = props
63
- this.processor = processor
64
- this.stream = stream
65
- this.windowSize = windowSize
66
- }
67
-
68
- /**
69
- * Writes output to the output stream.
70
- * Must be overwritten by other apps.
71
- * @param {any} output - Output to write
72
- * @param {Function} onError - Error handler callback
73
- */
74
- write(output, onError = (v) => 1) {
75
- /**
76
- * @todo manage the
77
- */
78
- if (typeOf(Array)(output)) {
79
- output = output.join('\n')
80
- }
81
- this.stream.push(output)
82
- this.processor?.write(output, onError)
83
- this.emit('data', output)
84
- }
85
-
86
- /**
87
- * Gets the window size.
88
- * @returns {number[]} Window size [width, height]
89
- */
90
- getWindowSize() {
91
- return this.processor?.getWindowSize?.() ?? this.windowSize
92
- }
93
- }
94
-
95
- export default StdOut
@@ -1,48 +0,0 @@
1
- import Frame from '../Frame/Frame.js'
2
-
3
- class RenderOptions {
4
- static DEFAULTS = {
5
- resizeToView: false,
6
- translateFrame: false,
7
- render: true,
8
- renderMethod: Frame.RenderMethod.VISIBLE,
9
- }
10
- /** @type {boolean} [false] */
11
- resizeToView
12
- /** @type {boolean} [false] */
13
- translateFrame
14
- /** @type {boolean} [true] */
15
- render
16
- /** @type {string} */
17
- renderMethod
18
- /** @type {number} */
19
- width
20
- /** @type {number} */
21
- height
22
- constructor(props = {}) {
23
- const DEFAULTS = this.DEFAULTS
24
- const {
25
- resizeToView = DEFAULTS.resizeToView,
26
- translateFrame = DEFAULTS.translateFrame,
27
- render = DEFAULTS.render,
28
- renderMethod = DEFAULTS.renderMethod,
29
- width = 0,
30
- height = 0,
31
- } = props
32
- this.resizeToView = resizeToView
33
- this.translateFrame = translateFrame
34
- this.render = render
35
- this.renderMethod = renderMethod
36
- this.width = width
37
- this.height = height
38
- }
39
- get DEFAULTS() {
40
- return /** @type {typeof RenderOptions} */ (this.constructor).DEFAULTS
41
- }
42
- static from(props = {}) {
43
- if (props instanceof RenderOptions) return props
44
- return new this(props)
45
- }
46
- }
47
-
48
- export default RenderOptions
package/src/View/View.js DELETED
@@ -1,306 +0,0 @@
1
- import { empty, equal, typeOf } from '@nan0web/types'
2
- import Frame, { FrameRenderMethod } from '../Frame/Frame.js'
3
- import Locale from '../Locale.js'
4
- import StdOut from '../StdOut.js'
5
- import StdIn from '../StdIn.js'
6
- import RenderOptions from './RenderOptions.js'
7
- import UiMessage from '../core/Message/Message.js'
8
-
9
- /**
10
- * @typedef {Object} ComponentFn
11
- * @property {string} name
12
- * @property {(input: UiMessage) => Promise<any>} ask
13
- * @property {Function} bind
14
- */
15
-
16
- export default class View {
17
- /** @type {typeof RenderOptions} */
18
- static RenderOptions = RenderOptions
19
- /** @type {typeof FrameRenderMethod} */
20
- static RenderMethod = Frame.RenderMethod
21
- /** @type {StdIn} */
22
- stdin
23
- /** @type {StdOut} */
24
- stdout
25
- /** @type {number} */
26
- startedAt
27
- /** @type {Frame} */
28
- frame
29
- /** @type {Locale} */
30
- locale
31
- /** @type {Map<string, string>} */
32
- vocab
33
- /** @type {number[]} */
34
- windowSize
35
- /** @type {Map<string, ComponentFn>} */
36
- components
37
- /** @type {string} */
38
- renderMethod
39
- /**
40
- * @param {object} [input]
41
- * @param {StdIn} [input.stdin]
42
- * @param {StdOut} [input.stdout]
43
- * @param {number} [input.startedAt]
44
- * @param {Frame} [input.frame]
45
- * @param {Locale} [input.locale]
46
- * @param {Map<string, string>} [input.vocab]
47
- * @param {number[]} [input.windowSize]
48
- * @param {Map<string, ComponentFn>} [input.components]
49
- * @param {string} [input.renderMethod]
50
- */
51
- constructor(input = {}) {
52
- const {
53
- stdin = new StdIn(),
54
- stdout = new StdOut(),
55
- startedAt = Date.now(),
56
- frame = new Frame(),
57
- locale = Locale.from('uk-UA'),
58
- vocab = new Map(),
59
- windowSize = [0, 0],
60
- components = new Map(),
61
- renderMethod = Frame.RenderMethod.VISIBLE,
62
- } = input
63
- this.stdin = stdin
64
- this.stdout = stdout
65
- this.startedAt = startedAt
66
- this.frame = frame
67
- this.locale = locale
68
- this.vocab = vocab
69
- this.windowSize = /** @type {number[]} */ (null === windowSize ? this.stdout.getWindowSize() : windowSize)
70
- this.components = components
71
- this.renderMethod = renderMethod
72
- if (!empty(frame)) {
73
- this.render(1)(this.frame)
74
- }
75
- }
76
- get empty() {
77
- return empty(this.frame)
78
- }
79
- get RenderMethod() {
80
- return /** @type {typeof View} */ (this.constructor).RenderMethod
81
- }
82
- get RenderOptions() {
83
- return /** @type {typeof View} */ (this.constructor).RenderOptions
84
- }
85
- getWindowSize() {
86
- return equal(this.windowSize, [0, 0]) ? this.stdout.getWindowSize() : this.windowSize
87
- }
88
- /**
89
- * @param {number} width
90
- * @param {number} height
91
- */
92
- setWindowSize(width, height) {
93
- this.windowSize = [width, height]
94
- }
95
- startTimer() {
96
- this.startedAt = Date.now()
97
- }
98
- spent(checkpoint = this.startedAt) {
99
- return Math.round((Date.now() - checkpoint) / 1000)
100
- }
101
- /**
102
- * @param {boolean | number | Function | ComponentFn} [shouldRender=0]
103
- * @param {RenderOptions} [options]
104
- * @returns {(value: Frame|string|string[], ...args: any) => Frame}
105
- */
106
- render(shouldRender = 0, options = new this.RenderOptions()) {
107
- const [width, height] = this.getWindowSize()
108
- options = this.RenderOptions.from({
109
- ...options,
110
- renderMethod: this.renderMethod,
111
- width,
112
- height,
113
- // @ts-ignore
114
- })
115
- const renderFn =
116
- 'function' === typeof shouldRender // no errors.
117
- ? // const renderFn = typeOf(Function)(shouldRender) // Property 'bind' does not exist on type 'number | boolean | Function'.
118
- shouldRender.bind(this)
119
- : 'string' === typeof shouldRender
120
- ? this.components.get(shouldRender)?.bind(this)
121
- : null
122
-
123
- return (value, ...args) => {
124
- if (renderFn) {
125
- /** @type {Frame} */
126
- let rendered = renderFn.bind(this)(value, ...args)
127
- if (!(rendered instanceof Frame)) {
128
- rendered = new Frame({
129
- value: rendered,
130
- renderMethod: options.renderMethod,
131
- width: options.width,
132
- height: options.height,
133
- })
134
- }
135
- rendered = View.fixFrame(rendered, options)
136
- rendered = rendered.transform(this.t.bind(this))
137
- rendered.render()
138
- if (options.render) {
139
- this.stdout.write(String(rendered))
140
- this.frame = rendered
141
- }
142
- return rendered
143
- }
144
-
145
- let frame = Frame.from({ ...options, value })
146
- frame = View.fixFrame(frame, options)
147
- let clearFrame = false
148
- if (String(frame.value[0] ?? '') === Frame.BOF) {
149
- frame.value = frame.value.slice(1)
150
- clearFrame = true
151
- }
152
- let translated = options.translateFrame ? frame.transform(this.t.bind(this)) : frame
153
- translated = View.fixFrame(translated, options)
154
-
155
- let rendered = translated
156
- rendered.render()
157
- if (shouldRender) {
158
- if (clearFrame) {
159
- const distance = options.height - frame.value.length
160
- this.stdout.write(Frame.BOF)
161
- for (let i = 0; i < distance; i++) {
162
- this.stdout.write(Frame.EOL)
163
- }
164
- }
165
- this.stdout.write(Frame.RESET + String(rendered))
166
- this.frame = rendered
167
- }
168
- return rendered
169
- }
170
- }
171
-
172
- clear(shouldRender = 0) {
173
- const [width, height] = this.windowSize
174
- const frame = new Frame({ width, height, renderMethod: Frame.RenderMethod.REPLACE })
175
- frame.value = []
176
- for (let i = 0; i < height; i++) frame.value.push([])
177
- return this.render(shouldRender)(frame)
178
- }
179
-
180
- progress(shouldRender = false) {
181
- return (value) => {
182
- const frame = Frame.from(value)
183
- frame.renderMethod = Frame.RenderMethod.REPLACE
184
- return this.render(!!shouldRender)(frame)
185
- }
186
- }
187
-
188
- /** @param {any} value */
189
- t(value) {
190
- if (typeOf(Array)(value)) {
191
- value = value.map((row) => {
192
- if (typeOf(Array)(row)) {
193
- return row.map((col) => {
194
- return this.vocab.has(col) ? this.vocab.get(col) : col
195
- })
196
- }
197
- return this.vocab.has(row) ? this.vocab.get(row) : row
198
- })
199
- return value
200
- }
201
- return this.vocab.has(value) ? this.vocab.get(value) : value
202
- }
203
-
204
- /** @param {any[]} args */
205
- debug(...args) {
206
- // @ts-ignore
207
- return this.render(1)([StdOut.STYLES.dim, 'Debug: ', args.join(' '), Frame.EOL, StdOut.RESET])
208
- }
209
-
210
- /** @param {any[]} args */
211
- info(...args) {
212
- // @ts-ignore
213
- return this.render(1)([StdOut.COLORS.green, 'Info : ', args.join(' '), Frame.EOL, StdOut.RESET])
214
- }
215
-
216
- /** @param {any[]} args */
217
- warn(...args) {
218
- return this.render(1)([
219
- // @ts-ignore
220
- StdOut.COLORS.yellow,
221
- 'Warn : ',
222
- args.join(' '),
223
- Frame.EOL,
224
- StdOut.RESET,
225
- ])
226
- }
227
-
228
- /** @param {any[]} args */
229
- error(...args) {
230
- return this.render(1)([
231
- // @ts-ignore
232
- StdOut.COLORS.red,
233
- StdOut.STYLES.bold,
234
- 'Error: ',
235
- args.join(' '),
236
- Frame.EOL,
237
- StdOut.RESET,
238
- ])
239
- }
240
-
241
- /**
242
- * @param {string} name
243
- * @param {ComponentFn} component
244
- */
245
- register(name, component) {
246
- if (undefined === component && 'function' === typeof name) {
247
- component = name
248
- name = component.name
249
- }
250
- this.components.set(name, component)
251
- }
252
-
253
- /**
254
- * @param {string} name
255
- */
256
- unregister(name) {
257
- this.components.delete(name)
258
- }
259
-
260
- /**
261
- * @param {string} name
262
- * @returns {boolean}
263
- */
264
- has(name) {
265
- return this.components.has(name)
266
- }
267
-
268
- /**
269
- * @param {string} name
270
- * @returns {ComponentFn | undefined}
271
- */
272
- get(name) {
273
- return this.components.get(name)
274
- }
275
-
276
- /**
277
- * @param {UiMessage} input
278
- * @returns {Promise<UiMessage | null>}
279
- */
280
- async ask(input) {
281
- const name = input.constructor.name.replace(/Input$/, '')
282
- const component = this.get(name)
283
- if (component) {
284
- return await component.ask.apply(this, [input])
285
- }
286
- let result = null
287
- do {
288
- const answer = await this.stdin.read()
289
- result = /** @type {typeof UiMessage} */ (input.constructor).from(answer)
290
- } while (!result.isValid && !result.head.cancelled)
291
- return result.head.cancelled ? null : result
292
- }
293
-
294
- /**
295
- * @param {Frame} frame
296
- * @param {RenderOptions} [options]
297
- * @returns {Frame}
298
- */
299
- static fixFrame(frame, options = new RenderOptions()) {
300
- if (options.resizeToView && !equal(options.width, frame.width, options.height, frame.height)) {
301
- frame.setWindowSize(options.width, options.height)
302
- }
303
- // @todo add multiline visibility, for instance extended frame row into rows if it's wider than width.
304
- return frame
305
- }
306
- }
@@ -1,6 +0,0 @@
1
- import UiMessage from './Message.js'
2
- import OutputMessage from './OutputMessage.js'
3
-
4
- export { UiMessage, OutputMessage }
5
-
6
- export default UiMessage
@@ -1,14 +0,0 @@
1
- export class DepsCommand extends UiMessage {
2
- static Body: typeof DepsCommandBody;
3
- constructor(input?: {});
4
- }
5
- export default DepsCommand;
6
- import UiMessage from '../../core/Message/Message.js';
7
- declare class DepsCommandBody {
8
- static fix: {
9
- help: string;
10
- defaultValue: boolean;
11
- };
12
- constructor(input?: {});
13
- fix: boolean;
14
- }
@@ -1,70 +0,0 @@
1
- /** @typedef {Function} CommandFn */
2
- /**
3
- * Abstract base class for all apps.
4
- * Each app processes input commands and produces output.
5
- */
6
- export default class CoreApp {
7
- /**
8
- * Creates a new CoreApp instance.
9
- * @param {object} props - CoreApp properties
10
- * @param {string} [props.name="CoreApp"] - App name
11
- * @param {object} [props.state={}] - Initial state object
12
- * @param {Message} [props.startCommand=new Message()] - Command line arguments to parse
13
- */
14
- constructor(props?: {
15
- name?: string | undefined;
16
- state?: object;
17
- startCommand?: Message | undefined;
18
- });
19
- /** @type {string} App name */
20
- name: string;
21
- /** @type {Map<string, CommandFn>} Registered command handlers */
22
- commands: Map<string, CommandFn>;
23
- /** @type {Record<string, any>} App state */
24
- state: Record<string, any>;
25
- /** @type {Message} Starting command parsed from argv */
26
- startCommand: Message;
27
- /**
28
- * Sets app state.
29
- * @param {string|object} state - State key or object with multiple keys
30
- * @param {any} [value] - State value if state is a string key
31
- * @returns {object} Updated state
32
- */
33
- set(state: string | object, value?: any): object;
34
- /**
35
- * Register a command handler.
36
- * @param {string} commandName - Name of the command to register
37
- * @param {Function} handler - async function or sync function that accepts params and returns output
38
- */
39
- registerCommand(commandName: string, handler: Function): void;
40
- /**
41
- * Returns a string representation of the app.
42
- * @returns {string} String representation including name and state
43
- */
44
- toString(): string;
45
- /**
46
- * Process a command message.
47
- * @param {Message} msg - Command to process
48
- * @param {UI} ui - UI instance to use for rendering
49
- * @returns {Promise<any>} Output of the command
50
- * @throws {Error} If the command is not registered
51
- */
52
- processCommand(msg: Message, ui: UI): Promise<any>;
53
- /**
54
- * Process an array of command messages sequentially.
55
- * @param {Message[]} Messages - Array of commands to process
56
- * @param {UI} ui - UI instance to use for rendering
57
- * @returns {Promise<any[]>} Array of command outputs
58
- */
59
- processCommands(Messages: Message[], ui: UI): Promise<any[]>;
60
- /**
61
- * Select a command to run. Must be implemented by subclasses.
62
- * @param {UI} ui - UI instance for interaction
63
- * @returns {Promise<string>} Command name to execute
64
- * @throws {Error} Always thrown as this method must be implemented by subclasses
65
- */
66
- selectCommand(ui: UI): Promise<string>;
67
- }
68
- export type CommandFn = Function;
69
- import { Message } from '@nan0web/co';
70
- import UI from './UI.js';
@@ -1,38 +0,0 @@
1
- /** @typedef {import("../../View/View.js").ComponentFn} ComponentFn */
2
- /**
3
- * Abstract UI class to connect apps and widgets.
4
- * Supports input/output data typed classes and views.
5
- */
6
- export default class UI extends Widget {
7
- /**
8
- * Creates a new UI instance.
9
- * @param {CoreApp} app - The app to connect to this UI
10
- * @param {View} [view] - View instance for rendering (default: new View())
11
- */
12
- constructor(app: CoreApp, view?: View);
13
- /** @type {CoreApp} The app instance connected to this UI */
14
- app: CoreApp;
15
- /**
16
- * Convert raw input to Message array.
17
- * Must be implemented by subclasses.
18
- * @param {any} rawInput - Raw input to convert
19
- * @returns {Message[]} Array of command messages
20
- * @throws {Error} Always thrown as this method must be implemented by subclasses
21
- */
22
- convertInput(rawInput: any): Message[];
23
- /**
24
- * Sets up event handlers for UI process events.
25
- * @param {ComponentFn} UIProcess - Process view component
26
- */
27
- show(UIProcess: ComponentFn): void;
28
- /**
29
- * Output results to the interface.
30
- * @param {any[]} results - Results to output
31
- */
32
- output(results: any[]): void;
33
- }
34
- export type ComponentFn = import("../../View/View.js").ComponentFn;
35
- import Widget from './Widget.js';
36
- import CoreApp from './CoreApp.js';
37
- import { Message } from '@nan0web/co';
38
- import View from '../../View/View.js';