@nan0web/ui 1.0.3 → 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 (41) hide show
  1. package/README.md +18 -20
  2. package/package.json +15 -16
  3. package/src/App/Core/UI.js +0 -46
  4. package/src/App/Core/Widget.js +4 -6
  5. package/src/App/User/Command/Message.js +23 -37
  6. package/src/App/User/Command/index.js +3 -8
  7. package/src/App/User/UserApp.js +30 -10
  8. package/src/README.md.js +33 -33
  9. package/src/StdIn.js +12 -13
  10. package/src/View/View.js +5 -5
  11. package/src/core/Form/Form.js +8 -6
  12. package/src/core/Form/Input.js +1 -1
  13. package/src/core/Form/Message.js +6 -5
  14. package/src/core/InputAdapter.js +2 -2
  15. package/src/core/Message/Message.js +109 -19
  16. package/src/core/Message/OutputMessage.js +7 -7
  17. package/src/core/Message/index.js +3 -4
  18. package/src/core/Stream.js +10 -10
  19. package/src/core/UiAdapter.js +189 -0
  20. package/src/core/index.js +3 -6
  21. package/src/index.js +4 -4
  22. package/types/App/Core/UI.d.ts +0 -10
  23. package/types/App/Core/Widget.d.ts +6 -7
  24. package/types/App/User/Command/Message.d.ts +15 -28
  25. package/types/App/User/Command/index.d.ts +3 -4
  26. package/types/App/User/UserApp.d.ts +14 -7
  27. package/types/StdIn.d.ts +13 -13
  28. package/types/View/View.d.ts +6 -6
  29. package/types/core/Form/Form.d.ts +2 -5
  30. package/types/core/Form/Input.d.ts +1 -1
  31. package/types/core/Form/Message.d.ts +5 -10
  32. package/types/core/Intent.d.ts +91 -0
  33. package/types/core/Message/Message.d.ts +58 -15
  34. package/types/core/Message/OutputMessage.d.ts +3 -3
  35. package/types/core/Message/index.d.ts +3 -4
  36. package/types/core/Stream.d.ts +5 -4
  37. package/types/core/UiAdapter.d.ts +104 -0
  38. package/types/core/index.d.ts +2 -3
  39. package/types/index.d.ts +4 -4
  40. package/src/App/User/Command/Options.js +0 -48
  41. package/src/core/Message/InputMessage.js +0 -119
@@ -1,6 +1,6 @@
1
+ import Message from "@nan0web/co"
1
2
  import FormMessage from "./Message.js"
2
3
  import FormInput from "./Input.js"
3
- import Message from "@nan0web/co"
4
4
 
5
5
  /**
6
6
  * Abstract form for data entry.
@@ -112,10 +112,10 @@ export default class UIForm extends FormMessage {
112
112
  /**
113
113
  * Validates the entire form.
114
114
  *
115
- * @returns {{isValid: boolean, errors: Object}} Validation result.
115
+ * @returns {Map<string, string>} Map of validation errors, empty if valid.
116
116
  */
117
117
  validate() {
118
- const errors = {}
118
+ const errors = new Map()
119
119
  let isValid = true
120
120
 
121
121
  this.fields.forEach((field) => {
@@ -123,7 +123,7 @@ export default class UIForm extends FormMessage {
123
123
 
124
124
  // Required validation based on field definition or schema
125
125
  if (field.required && (fieldValue === '' || fieldValue === null || fieldValue === undefined)) {
126
- errors[field.name] = 'This field is required'
126
+ errors.set(field.name, 'This field is required')
127
127
  isValid = false
128
128
  return
129
129
  }
@@ -132,12 +132,14 @@ export default class UIForm extends FormMessage {
132
132
  const { isValid: fieldValid, errors: fieldErrors } = this.validateField(field.name, fieldValue)
133
133
 
134
134
  if (!fieldValid) {
135
- Object.assign(errors, fieldErrors)
135
+ for (const [key, err] of Object.entries(fieldErrors)) {
136
+ errors.set(key, err)
137
+ }
136
138
  isValid = false
137
139
  }
138
140
  })
139
141
 
140
- return { isValid, errors }
142
+ return errors
141
143
  }
142
144
 
143
145
  /**
@@ -27,7 +27,7 @@ export default class FormInput {
27
27
  /** @type {boolean} */ required = false
28
28
  /** @type {string} */ placeholder = ''
29
29
  /** @type {InputOptions} */ options = []
30
- /** @type {Function|null} */ validation = null
30
+ /** @type {import("@nan0web/co").ValidateFn|null} */ validation = null
31
31
  /** @type {*} */ defaultValue = null
32
32
 
33
33
  /**
@@ -1,12 +1,13 @@
1
- import InputMessage from "../Message/InputMessage.js"
1
+ import UiMessage from "../Message/Message.js"
2
2
 
3
3
  /**
4
- * FormMessage – specialized InputMessage for forms.
4
+ * FormMessage – specialized UiMessage for forms.
5
+ * It carries form-specific data and schema for validation.
5
6
  *
6
7
  * @class FormMessage
7
- * @extends InputMessage
8
+ * @extends UiMessage
8
9
  */
9
- export default class FormMessage extends InputMessage {
10
+ export default class FormMessage extends UiMessage {
10
11
  /**
11
12
  * Creates a FormMessage.
12
13
  *
@@ -80,4 +81,4 @@ export default class FormMessage extends InputMessage {
80
81
 
81
82
  return { isValid: Object.keys(errors).length === 0, errors }
82
83
  }
83
- }
84
+ }
@@ -1,6 +1,6 @@
1
1
  import Event from "@nan0web/event/oop"
2
- import InputMessage from "./Message/InputMessage.js"
3
2
  import CancelError from "./Error/CancelError.js"
3
+ import UiMessage from "./Message/Message.js"
4
4
 
5
5
  /**
6
6
  * Abstract input adapter for UI implementations.
@@ -21,7 +21,7 @@ export default class InputAdapter extends Event {
21
21
  */
22
22
  start() {
23
23
  this.emit('input',
24
- InputMessage.from({ value: "Adapter started" })
24
+ UiMessage.from({ body: "Adapter started" })
25
25
  )
26
26
  }
27
27
 
@@ -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
  /**
@@ -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,15 +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"
14
9
 
15
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,10 +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"
35
34
  export { default as Error, CancelError } from "./core/Error/index.js"
35
+ export { default as UiAdapter } from "./core/UiAdapter.js"
@@ -22,16 +22,6 @@ declare class UI extends Widget {
22
22
  * @throws {Error} Always thrown as this method must be implemented by subclasses
23
23
  */
24
24
  convertInput(rawInput: any): Message[];
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[]>;
35
25
  /**
36
26
  * Sets up event handlers for UI process events.
37
27
  * @param {ComponentFn} UIProcess - Process view component
@@ -1,12 +1,10 @@
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())
@@ -16,10 +14,10 @@ declare class Widget extends EventProcessor {
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";