@nan0web/ui 1.0.2 → 1.0.4

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 (58) hide show
  1. package/README.md +19 -54
  2. package/package.json +21 -17
  3. package/src/App/Core/CoreApp.js +14 -19
  4. package/src/App/Core/UI.js +4 -50
  5. package/src/App/Core/Widget.js +4 -6
  6. package/src/App/User/Command/Message.js +23 -37
  7. package/src/App/User/Command/index.js +3 -8
  8. package/src/App/User/UserApp.js +32 -27
  9. package/src/App/User/UserUI.js +4 -4
  10. package/src/App/User/index.js +0 -6
  11. package/src/App/index.js +0 -3
  12. package/src/README.md.js +33 -57
  13. package/src/StdIn.js +12 -15
  14. package/src/View/View.js +5 -5
  15. package/src/core/Error/index.js +9 -0
  16. package/src/core/Form/Form.js +43 -23
  17. package/src/core/Form/Input.js +16 -7
  18. package/src/core/Form/Message.js +6 -8
  19. package/src/core/InputAdapter.js +6 -2
  20. package/src/core/Message/Message.js +109 -19
  21. package/src/core/Message/OutputMessage.js +8 -8
  22. package/src/core/Message/index.js +3 -4
  23. package/src/core/Stream.js +10 -10
  24. package/src/core/UiAdapter.js +189 -0
  25. package/src/core/index.js +5 -6
  26. package/src/index.js +5 -4
  27. package/types/App/Core/CoreApp.d.ts +9 -9
  28. package/types/App/Core/UI.d.ts +5 -15
  29. package/types/App/Core/Widget.d.ts +7 -8
  30. package/types/App/User/Command/Message.d.ts +15 -29
  31. package/types/App/User/Command/Options.d.ts +9 -2
  32. package/types/App/User/Command/index.d.ts +3 -7
  33. package/types/App/User/UserApp.d.ts +19 -9
  34. package/types/App/User/UserUI.d.ts +0 -9
  35. package/types/App/User/index.d.ts +0 -4
  36. package/types/App/index.d.ts +1 -3
  37. package/types/Frame/Frame.d.ts +5 -5
  38. package/types/StdIn.d.ts +13 -13
  39. package/types/View/View.d.ts +9 -9
  40. package/types/core/Error/index.d.ts +6 -0
  41. package/types/core/Form/Form.d.ts +14 -11
  42. package/types/core/Form/Input.d.ts +20 -7
  43. package/types/core/Form/Message.d.ts +5 -4
  44. package/types/core/InputAdapter.d.ts +2 -0
  45. package/types/core/Intent.d.ts +91 -0
  46. package/types/core/Message/InputMessage.d.ts +5 -5
  47. package/types/core/Message/Message.d.ts +58 -15
  48. package/types/core/Message/OutputMessage.d.ts +4 -4
  49. package/types/core/Message/index.d.ts +3 -4
  50. package/types/core/Stream.d.ts +5 -4
  51. package/types/core/StreamEntry.d.ts +1 -1
  52. package/types/core/UiAdapter.d.ts +104 -0
  53. package/types/core/index.d.ts +3 -3
  54. package/types/index.d.ts +5 -4
  55. package/src/App/Command/Options.js +0 -78
  56. package/src/App/Command/index.js +0 -9
  57. package/src/App/User/Command/Options.js +0 -48
  58. package/src/core/Message/InputMessage.js +0 -119
@@ -1,12 +1,36 @@
1
- import { Message as BaseMessage } from "@nan0web/co"
1
+ import { Message } from "@nan0web/co"
2
2
 
3
3
  /**
4
- * Base UI message class.
4
+ * @typedef {Object} MessageBodySchema
5
+ * @property {boolean} [required]
6
+ * @property {string} [help]
7
+ * @property {RegExp} [pattern]
8
+ * @property {string[]} [options]
9
+ * @property {*} [defaultValue]
10
+ * @property {Function} [validate]
11
+ */
12
+
13
+ /**
14
+ * Base message class for UI communications.
15
+ * A message holds structured data (body) defined by a static Body class.
16
+ * It can represent commands, forms, alerts, or any UI unit.
17
+ *
18
+ * @class UiMessage
19
+ * @extends Message
5
20
  *
6
- * @class UIMessage
7
- * @extends BaseMessage
21
+ * @example
22
+ * class UserLoginMessage extends UiMessage {
23
+ * static Body = class {
24
+ * static username = { required: true, help: "Enter username" }
25
+ * static password = { required: true, type: "password" }
26
+ * constructor({ username = "", password = "" }) {
27
+ * this.username = username
28
+ * this.password = password
29
+ * }
30
+ * }
31
+ * }
8
32
  */
9
- class UIMessage extends BaseMessage {
33
+ export default class UiMessage extends Message {
10
34
  static TYPES = {
11
35
  TEXT: 'text',
12
36
  FORM: 'form',
@@ -25,7 +49,7 @@ class UIMessage extends BaseMessage {
25
49
  id = ""
26
50
 
27
51
  /**
28
- * Creates a UIMessage.
52
+ * Creates a UiMessage.
29
53
  *
30
54
  * @param {Object} [input={}] - Message properties.
31
55
  */
@@ -45,14 +69,62 @@ class UIMessage extends BaseMessage {
45
69
  }
46
70
 
47
71
  /**
48
- * Creates a UIMessage instance from plain data.
72
+ * Checks whether the message contains any body content.
49
73
  *
50
- * @param {Object} data - Message data.
51
- * @returns {UIMessage}
74
+ * @returns {boolean}
52
75
  */
53
- static from(data) {
54
- if (data instanceof UIMessage) return data
55
- return new this(data)
76
+ get empty() {
77
+ return !this.body
78
+ }
79
+
80
+ /**
81
+ * Validates the message body against its schema.
82
+ *
83
+ * NOTE: The signature must exactly match `Message.validate` – it returns a
84
+ * `Map<string,string>` regardless of the generic type, otherwise TypeScript
85
+ * reports incompatibility with the base class.
86
+ *
87
+ * @param {any} [body=this.body] - Optional body to validate.
88
+ * @returns {Map<string,string>} Map of validation errors, empty if valid.
89
+ */
90
+ validate(body = this.body) {
91
+ /** @type {any} */
92
+ const Class = /** @type {typeof Message} */ (this.constructor).Body
93
+ const result = new Map()
94
+ const entries = /** @type {Array<[string, MessageBodySchema]>} */ (Object.entries(Class))
95
+
96
+ for (const [field, schema] of entries) {
97
+ const value = body[field]
98
+ const fn = schema?.validate
99
+ if ("function" === typeof fn) {
100
+ const ok = fn.apply(body, [value])
101
+ if (ok !== true) {
102
+ result.set(field, String(ok))
103
+ continue
104
+ }
105
+ }
106
+ const required = schema?.required ?? false
107
+ if (required && !value) {
108
+ result.set(field, "Required")
109
+ continue
110
+ }
111
+ if (schema?.pattern && schema.pattern instanceof RegExp) {
112
+ if (!schema.pattern.test(value)) {
113
+ result.set(field, `Does not match pattern: ${schema.pattern}`)
114
+ continue
115
+ }
116
+ }
117
+ if (schema?.options) {
118
+ if (!Array.isArray(schema.options)) {
119
+ throw new Error("Schema options must be an array of possible values")
120
+ }
121
+ if (!schema.options.includes(value)) {
122
+ result.set(field, "Enumeration must have one value")
123
+ continue
124
+ }
125
+ }
126
+ }
127
+ return result
56
128
  }
57
129
 
58
130
  /**
@@ -61,17 +133,35 @@ class UIMessage extends BaseMessage {
61
133
  * @returns {boolean}
62
134
  */
63
135
  isValidType() {
64
- return Object.values(UIMessage.TYPES).includes(this.type)
136
+ return Object.values(UiMessage.TYPES).includes(this.type)
65
137
  }
66
138
 
67
139
  /**
68
- * Checks whether the message contains any body content.
140
+ * Creates a UiMessage instance from plain data.
69
141
  *
70
- * @returns {boolean}
142
+ * @param {Object} data - Message data.
143
+ * @returns {UiMessage}
71
144
  */
72
- isEmpty() {
73
- return !this.body || this.body.length === 0
145
+ static from(data) {
146
+ if (data instanceof UiMessage) return data
147
+ return new this(data)
74
148
  }
75
- }
76
149
 
77
- export default UIMessage
150
+ /**
151
+ * Initializes body from input using static Body schema.
152
+ *
153
+ * @param {Object} input - Input object.
154
+ * @param {Function} BodyClass - Static body class with defaults and schema.
155
+ * @returns {Object} Parsed body.
156
+ */
157
+ static parseBody(input = {}, BodyClass) {
158
+ const result = {}
159
+ const entries = /** @type {Array<[string, MessageBodySchema]>} */ (Object.entries(BodyClass))
160
+
161
+ for (const [field, schema] of entries) {
162
+ const { defaultValue = undefined, ...schemaProps } = schema
163
+ result[field] = input[field] ?? defaultValue
164
+ }
165
+ return result
166
+ }
167
+ }
@@ -1,12 +1,12 @@
1
- import UIMessage from "./Message.js"
1
+ import UiMessage from "./Message.js"
2
2
 
3
3
  /**
4
4
  * OutputMessage – message sent from the system to the UI.
5
5
  *
6
6
  * @class OutputMessage
7
- * @extends UIMessage
7
+ * @extends UiMessage
8
8
  */
9
- export default class OutputMessage extends UIMessage {
9
+ export default class OutputMessage extends UiMessage {
10
10
  static PRIORITY = {
11
11
  LOW: 0,
12
12
  NORMAL: 1,
@@ -52,9 +52,9 @@ export default class OutputMessage extends UIMessage {
52
52
  this.priority = Number(priority)
53
53
 
54
54
  if (!this.type && this.error) {
55
- this.type = UIMessage.TYPES.ERROR
55
+ this.type = UiMessage.TYPES.ERROR
56
56
  } else if (!this.type) {
57
- this.type = UIMessage.TYPES.INFO
57
+ this.type = UiMessage.TYPES.INFO
58
58
  }
59
59
  }
60
60
 
@@ -72,11 +72,11 @@ export default class OutputMessage extends UIMessage {
72
72
  }
73
73
  /** @returns {boolean} */
74
74
  get isError() {
75
- return this.error !== null || this.type === UIMessage.TYPES.ERROR
75
+ return this.error !== null || this.type === UiMessage.TYPES.ERROR
76
76
  }
77
77
  /** @returns {boolean} */
78
78
  get isInfo() {
79
- return this.type === UIMessage.TYPES.INFO || this.type === UIMessage.TYPES.SUCCESS
79
+ return this.type === UiMessage.TYPES.INFO || this.type === UiMessage.TYPES.SUCCESS
80
80
  }
81
81
 
82
82
  /**
@@ -140,4 +140,4 @@ export default class OutputMessage extends UIMessage {
140
140
  if (input instanceof OutputMessage) return input
141
141
  return new OutputMessage(input)
142
142
  }
143
- }
143
+ }
@@ -1,7 +1,6 @@
1
- import UIMessage from "./Message.js"
2
- import InputMessage from "./InputMessage.js"
1
+ import UiMessage from "./Message.js"
3
2
  import OutputMessage from "./OutputMessage.js"
4
3
 
5
- export { UIMessage, InputMessage, OutputMessage }
4
+ export { UiMessage, OutputMessage }
6
5
 
7
- export default UIMessage
6
+ export default UiMessage
@@ -1,7 +1,9 @@
1
1
  import StreamEntry from "./StreamEntry.js"
2
2
 
3
+ export { StreamEntry } // Export if needed
4
+
3
5
  /**
4
- * Agnostic UI stream for processing progress.
6
+ * Agnostic UI stream for processing progress using async generators.
5
7
  *
6
8
  * @class UIStream
7
9
  */
@@ -29,17 +31,17 @@ export default class UIStream {
29
31
  }
30
32
 
31
33
  /**
32
- * Runs a generator with progress callbacks and abort handling.
34
+ * Runs an async generator with progress callbacks and abort handling.
33
35
  *
34
36
  * @param {AbortSignal} signal - Abort signal.
35
- * @param {Function} generator - Function returning an async iterator.
37
+ * @param {() => AsyncGenerator<StreamEntry>} generatorFn - Function that returns an async generator.
36
38
  * @param {Function} [onProgress] - Called with (progress, item).
37
39
  * @param {Function} [onError] - Called with (errorMessage, item).
38
40
  * @param {Function} [onComplete] - Called with (item) when done.
39
41
  * @returns {Promise<void>}
40
42
  */
41
- static async process(signal, generator, onProgress, onError, onComplete) {
42
- const iter = generator()
43
+ static async process(signal, generatorFn, onProgress, onError, onComplete) {
44
+ const iter = generatorFn()
43
45
 
44
46
  try {
45
47
  for await (const item of iter) {
@@ -47,13 +49,11 @@ export default class UIStream {
47
49
  throw new DOMException('Aborted', 'AbortError')
48
50
  }
49
51
 
50
- if (item.progress !== undefined) {
51
- onProgress?.(item.progress, item)
52
- } else if (item.error) {
53
- onError?.(item.error, item)
54
- } else if (item.done) {
52
+ if (item.done) {
55
53
  onComplete?.(item)
56
54
  break
55
+ } else if (item.error) {
56
+ onError?.(item.error, item)
57
57
  } else {
58
58
  // Intermediate results
59
59
  onProgress?.(null, item)
@@ -0,0 +1,189 @@
1
+ import EventProcessor from "@nan0web/event/oop"
2
+ import CancelError from "./Error/CancelError.js"
3
+ import UIMessage from "./Message/Message.js"
4
+ import UIForm from "./Form/Form.js"
5
+ import FormInput from "./Form/Input.js"
6
+
7
+ /**
8
+ * Unified UI Adapter that handles both input and output operations.
9
+ * It manages user interactions and rendering of messages, forms, and progress.
10
+ *
11
+ * @class UiAdapter
12
+ * @extends EventProcessor
13
+ *
14
+ * @example
15
+ * const adapter = new UiAdapter()
16
+ * adapter.output = new View()
17
+ *
18
+ * const result = await adapter.requireInput(new LoginMessage())
19
+ * console.log(result) // { username: "user", password: "pass" }
20
+ */
21
+ export default class UiAdapter extends EventProcessor {
22
+ static CancelError = CancelError
23
+ /** @returns {typeof CancelError} */
24
+ get CancelError() {
25
+ return /** @type {typeof UiAdapter} */ (this.constructor).CancelError
26
+ }
27
+
28
+ /** @type {OutputAdapter | null} Output interface for rendering */
29
+ output = null
30
+
31
+ /**
32
+ * Starts listening for input and emits an `input` event.
33
+ *
34
+ * @returns {void}
35
+ */
36
+ start() {
37
+ this.emit('input', UIMessage.from({ body: "Adapter started" }))
38
+ }
39
+
40
+ /**
41
+ * Stops listening for input and output streams.
42
+ * Default implementation does nothing; override in subclasses to perform cleanup.
43
+ *
44
+ * @returns {void}
45
+ */
46
+ stop() {
47
+ // Default implementation – does nothing
48
+ }
49
+
50
+ /**
51
+ * Checks whether the adapter is ready to receive input.
52
+ *
53
+ * @returns {boolean} Always true in base class; override for specific checks.
54
+ */
55
+ isReady() {
56
+ return true
57
+ }
58
+
59
+ /**
60
+ * Helper to ask a question.
61
+ * Must be implemented by subclasses.
62
+ *
63
+ * @param {string} question - Question to ask the user.
64
+ * @returns {Promise<string>} User's response.
65
+ * @throws {Error} If not implemented in subclass.
66
+ */
67
+ async ask(question) {
68
+ throw new Error('ask() method must be implemented in subclass')
69
+ }
70
+
71
+ /**
72
+ * Generic selection prompt.
73
+ * Must be implemented by subclasses.
74
+ *
75
+ * @param {object} config - Selection configuration.
76
+ * @param {string[]} [config.options=[]] - List of options to choose from.
77
+ * @returns {Promise<{ index: number, value: string | null }>} Selected option.
78
+ * @throws {Error} If not implemented in subclass.
79
+ */
80
+ async select(config) {
81
+ throw new Error('select() method must be implemented in subclass')
82
+ }
83
+
84
+ /**
85
+ * Ensures a message's body is fully and validly filled.
86
+ * Generates a form from the message's static Body schema,
87
+ * then iteratively collects input until all fields are valid or cancelled.
88
+ *
89
+ * @template {UIMessage} T
90
+ * @param {T} msg - Message instance needing input.
91
+ * @returns {Promise<T['body']>} Updated and validated message body.
92
+ *
93
+ * @example
94
+ * const body = await adapter.requireInput(new LoginMessage({ body: { username: "user" } }))
95
+ * // → prompts for password, returns { username: "user", password: "..." }
96
+ */
97
+ async requireInput(msg) {
98
+ if (!msg) {
99
+ throw new Error("Message instance is required")
100
+ }
101
+ if (!(msg instanceof UIMessage)) {
102
+ throw new TypeError("Message must be an instance of UIMessage")
103
+ }
104
+ /** @type {Map<string,string>} */
105
+ let errors = msg.validate()
106
+ while (errors.size > 0) {
107
+ const form = generateForm(
108
+ /** @type {any} */ (msg.constructor).Body,
109
+ { initialState: msg.body }
110
+ )
111
+
112
+ const formResult = await this.processForm ? this.processForm(form, msg.body) : {} // Assume method exists or handle differently, but error indicates missing method; perhaps remove if not used
113
+ if (formResult.escaped) {
114
+ throw new CancelError("User cancelled form")
115
+ }
116
+
117
+ const updatedBody = { ...msg.body, ...formResult.form.state }
118
+ const updatedErrors = msg.validate(updatedBody)
119
+
120
+ if (updatedErrors.size > 0) {
121
+ if (this.output) {
122
+ await this.output.render("Alert", {
123
+ variant: "error",
124
+ content: Array.from(updatedErrors.values()).join("\n")
125
+ })
126
+ }
127
+ errors = updatedErrors
128
+ continue
129
+ }
130
+ msg.body = updatedBody
131
+ break
132
+ }
133
+ return msg.body
134
+ }
135
+
136
+ /**
137
+ * Renders a message to the user interface.
138
+ * Must be implemented by subclasses.
139
+ *
140
+ * @param {UIMessage} message - Message to render.
141
+ * @emits rendered
142
+ * @throws {Error} If not implemented in subclass.
143
+ */
144
+ render(message) {
145
+ throw new Error("render() must be implemented by subclass")
146
+ this.emit("rendered", message)
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Generates a UIForm from a static Body schema.
152
+ *
153
+ * @param {Function} BodyClass - Class defining field schema.
154
+ * @param {Object} [options={}] - Generation options.
155
+ * @param {Object} [options.initialState={}] - Pre-filled form values.
156
+ * @param {Function} [options.t] - Optional translation function.
157
+ * @returns {UIForm} Form instance ready for input.
158
+ */
159
+ export function generateForm(BodyClass, options = {}) {
160
+ const { initialState = {}, t = v => v } = options
161
+ const fields = []
162
+
163
+ for (const [name, schema] of Object.entries(BodyClass)) {
164
+ if (typeof schema !== "object" || schema === null || !name || !schema.help) continue
165
+
166
+ const label = t(schema.help) || name
167
+ const placeholder = t(schema.placeholder || schema.defaultValue || "")
168
+ const isRequired = !!schema.required
169
+
170
+ fields.push(
171
+ new FormInput({
172
+ name,
173
+ label,
174
+ type: schema.type || FormInput.TYPES.TEXT,
175
+ required: isRequired,
176
+ placeholder,
177
+ options: schema.options ? schema.options.map(o => String(o)) : [],
178
+ validation: schema.validate
179
+ ? (value) => {
180
+ const res = schema.validate(value)
181
+ return res === true ? true : typeof res === "string" ? res : `Invalid ${name}`
182
+ }
183
+ : () => true,
184
+ }),
185
+ )
186
+ }
187
+
188
+ return new UIForm({ fields })
189
+ }
package/src/core/index.js CHANGED
@@ -1,13 +1,12 @@
1
- // export default App
2
-
3
1
  export { default as InputAdapter } from "./InputAdapter.js"
4
2
  export { default as OutputAdapter } from "./OutputAdapter.js"
5
3
  export { default as UIStream } from "./Stream.js"
6
4
 
7
- export { default as UIMessage } from "./Message/Message.js"
8
- export { default as InputMessage } from "./Message/InputMessage.js"
9
- export { default as OutputMessage } from "./Message/OutputMessage.js"
10
-
5
+ export { default as UiMessage } from "./Message/Message.js"
11
6
  export { default as FormMessage } from "./Form/Message.js"
12
7
  export { default as FormInput } from "./Form/Input.js"
13
8
  export { default as UIForm } from "./Form/Form.js"
9
+
10
+ export { default as Error, CancelError } from "./Error/index.js"
11
+
12
+ export { default as UiAdapter } from "./UiAdapter.js"
package/src/index.js CHANGED
@@ -26,9 +26,10 @@ export {
26
26
  export { default as FormMessage } from "./core/Form/Message.js"
27
27
  export { default as FormInput } from "./core/Form/Input.js"
28
28
  export { default as InputAdapter } from "./core/InputAdapter.js"
29
- export { default as InputMessage } from "./core/Message/InputMessage.js"
30
29
  export { default as OutputAdapter } from "./core/OutputAdapter.js"
31
30
  export { default as OutputMessage } from "./core/Message/OutputMessage.js"
32
- export { default as UIForm } from "./core/Form/Form.js"
33
- export { default as UIMessage } from "./core/Message/Message.js"
34
- export { default as UIStream } from "./core/Stream.js"
31
+ export { default as UiForm } from "./core/Form/Form.js"
32
+ export { default as UiMessage } from "./core/Message/Message.js"
33
+ export { default as UiStream } from "./core/Stream.js"
34
+ export { default as Error, CancelError } from "./core/Error/index.js"
35
+ export { default as UiAdapter } from "./core/UiAdapter.js"
@@ -9,12 +9,12 @@ export default class CoreApp {
9
9
  * @param {object} props - CoreApp properties
10
10
  * @param {string} [props.name="CoreApp"] - App name
11
11
  * @param {object} [props.state={}] - Initial state object
12
- * @param {string[]} [props.argv=[]] - Command line arguments to parse
12
+ * @param {Message} [props.startCommand=new Message()] - Command line arguments to parse
13
13
  */
14
14
  constructor(props?: {
15
15
  name?: string | undefined;
16
16
  state?: object;
17
- argv?: string[] | undefined;
17
+ startCommand?: Message | undefined;
18
18
  });
19
19
  /** @type {string} App name */
20
20
  name: string;
@@ -22,8 +22,8 @@ export default class CoreApp {
22
22
  commands: Map<string, CommandFn>;
23
23
  /** @type {object} App state */
24
24
  state: object;
25
- /** @type {CommandMessage} Starting command parsed from argv */
26
- startCommand: CommandMessage;
25
+ /** @type {Message} Starting command parsed from argv */
26
+ startCommand: Message;
27
27
  /**
28
28
  * Sets app state.
29
29
  * @param {string|object} state - State key or object with multiple keys
@@ -44,19 +44,19 @@ export default class CoreApp {
44
44
  toString(): string;
45
45
  /**
46
46
  * Process a command message.
47
- * @param {CommandMessage} commandMessage - Command to process
47
+ * @param {Message} msg - Command to process
48
48
  * @param {UI} ui - UI instance to use for rendering
49
49
  * @returns {Promise<any>} Output of the command
50
50
  * @throws {Error} If the command is not registered
51
51
  */
52
- processCommand(commandMessage: CommandMessage, ui: UI): Promise<any>;
52
+ processCommand(msg: Message, ui: UI): Promise<any>;
53
53
  /**
54
54
  * Process an array of command messages sequentially.
55
- * @param {CommandMessage[]} commandMessages - Array of commands to process
55
+ * @param {Message[]} Messages - Array of commands to process
56
56
  * @param {UI} ui - UI instance to use for rendering
57
57
  * @returns {Promise<any[]>} Array of command outputs
58
58
  */
59
- processCommands(commandMessages: CommandMessage[], ui: UI): Promise<any[]>;
59
+ processCommands(Messages: Message[], ui: UI): Promise<any[]>;
60
60
  /**
61
61
  * Select a command to run. Must be implemented by subclasses.
62
62
  * @param {UI} ui - UI instance for interaction
@@ -66,5 +66,5 @@ export default class CoreApp {
66
66
  selectCommand(ui: UI): Promise<string>;
67
67
  }
68
68
  export type CommandFn = Function;
69
- import { CommandMessage } from "../Command/index.js";
69
+ import { Message } from "@nan0web/co";
70
70
  import UI from "./UI.js";
@@ -11,27 +11,17 @@ declare class UI extends Widget {
11
11
  * @param {CoreApp} app - The app to connect to this UI
12
12
  * @param {View} [view] - View instance for rendering (default: new View())
13
13
  */
14
- constructor(app: CoreApp, view?: View | undefined);
14
+ constructor(app: CoreApp, view?: View);
15
15
  /** @type {CoreApp} The app instance connected to this UI */
16
16
  app: CoreApp;
17
17
  /**
18
- * Convert raw input to CommandMessage array.
18
+ * Convert raw input to Message array.
19
19
  * Must be implemented by subclasses.
20
20
  * @param {any} rawInput - Raw input to convert
21
- * @returns {CommandMessage[]} Array of command messages
21
+ * @returns {Message[]} Array of command messages
22
22
  * @throws {Error} Always thrown as this method must be implemented by subclasses
23
23
  */
24
- convertInput(rawInput: any): CommandMessage[];
25
- /**
26
- * Process input, run commands on app, and output results.
27
- * Supports progress callback.
28
- * @emits {start} Emitted when processing begins
29
- * @emits {data} Emitted for each command being processed
30
- * @emits {end} Emitted when all commands have been processed
31
- * @param {any} rawInput - Raw input to process
32
- * @returns {Promise<any[]>} Results of command processing
33
- */
34
- process(rawInput: any): Promise<any[]>;
24
+ convertInput(rawInput: any): Message[];
35
25
  /**
36
26
  * Sets up event handlers for UI process events.
37
27
  * @param {ComponentFn} UIProcess - Process view component
@@ -45,5 +35,5 @@ declare class UI extends Widget {
45
35
  }
46
36
  import Widget from "./Widget.js";
47
37
  import CoreApp from "./CoreApp.js";
48
- import { CommandMessage } from "../Command/index.js";
38
+ import { Message } from "@nan0web/co";
49
39
  import View from "../../View/View.js";
@@ -1,25 +1,23 @@
1
- export default Widget;
2
- export type ComponentFn = import("./UI.js").ComponentFn;
3
1
  /** @typedef {import("./UI.js").ComponentFn} ComponentFn */
4
2
  /**
5
3
  * Abstract Widget class.
6
4
  * Widget is a view with ability to input data in a specific format.
7
5
  * Input and output data are typed classes.
8
6
  */
9
- declare class Widget extends EventProcessor {
7
+ export default class Widget extends EventProcessor {
10
8
  /**
11
9
  * Creates a new Widget instance.
12
10
  * @param {View} [view] - View instance (default: new View())
13
11
  */
14
- constructor(view?: View | undefined);
12
+ constructor(view?: View);
15
13
  /** @type {View} The view associated with this widget */
16
14
  view: View;
17
15
  /**
18
16
  * Ask user for input data of specific class.
19
- * @param {InputMessage} input - instance of InputMessage or similar
20
- * @returns {Promise<InputMessage | null>} instance of InputMessage or null
17
+ * @param {UiMessage} input - instance of UiMessage or similar
18
+ * @returns {Promise<UiMessage | null>} instance of UiMessage or null
21
19
  */
22
- ask(input: InputMessage): Promise<InputMessage | null>;
20
+ ask(input: UiMessage): Promise<UiMessage | null>;
23
21
  /**
24
22
  * @param {AsyncGenerator<StreamEntry>} stream
25
23
  * @returns {Promise<void>}
@@ -34,7 +32,8 @@ declare class Widget extends EventProcessor {
34
32
  */
35
33
  render(viewFnOrName: Function | string, outputData: object): any;
36
34
  }
35
+ export type ComponentFn = import("./UI.js").ComponentFn;
37
36
  import EventProcessor from "@nan0web/event/oop";
38
37
  import View from "../../View/View.js";
39
- import InputMessage from "../../core/Message/InputMessage.js";
38
+ import { UiMessage } from "../../core/index.js";
40
39
  import { StreamEntry } from "@nan0web/db";
@@ -1,30 +1,16 @@
1
- export default UserAppCommandMessage;
2
- /**
3
- * Extends Command.Message to include user-specific command options.
4
- */
5
- declare class UserAppCommandMessage extends CommandMessage {
6
- /**
7
- * Parses an array of strings into a UserAppCommandMessage.
8
- * @param {string[] | string} value - Arguments to parse
9
- * @returns {UserAppCommandMessage} Parsed command message
10
- */
11
- static parse(value?: string[] | string): UserAppCommandMessage;
12
- /**
13
- * Creates a new UserAppCommandMessage instance.
14
- * @param {object} props - Command message properties
15
- * @param {string[]} [props.args=[]] - Command arguments
16
- * @param {Partial<UserAppCommandOptions>} [props.opts={}] - User-specific options
17
- */
18
- constructor(props?: {
19
- args?: string[] | undefined;
20
- opts?: Partial<UserAppCommandOptions> | undefined;
21
- });
22
- /**
23
- * @param {Partial<UserAppCommandOptions>} value
24
- */
25
- set opts(arg: UserAppCommandOptions);
26
- /** @returns {UserAppCommandOptions} */
27
- get opts(): UserAppCommandOptions;
1
+ export class DepsCommand extends UIMessage {
2
+ static Body: typeof DepsCommandParams;
3
+ constructor(input?: {});
4
+ /** @type {DepsCommandParams} */
5
+ body: DepsCommandParams;
6
+ }
7
+ export default DepsCommand;
8
+ import UIMessage from "../../../core/Message/Message.js";
9
+ declare class DepsCommandParams {
10
+ static fix: {
11
+ help: string;
12
+ defaultValue: boolean;
13
+ };
14
+ constructor(input?: {});
15
+ fix: boolean;
28
16
  }
29
- import { CommandMessage } from "../../Command/index.js";
30
- import UserAppCommandOptions from "./Options.js";