@nan0web/ui 1.12.0 → 1.12.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.
- package/package.json +8 -8
- package/src/App/Core/CoreApp.js +1 -1
- package/src/View/View.js +16 -3
- package/src/core/Intent.js +4 -2
- package/src/domain/ModelAsApp.js +1 -1
- package/src/domain/app/ConfigApp.js +61 -0
- package/src/domain/app/UIApp.js +2 -1
- package/types/App/Core/CoreApp.d.ts +2 -2
- package/types/View/View.d.ts +14 -5
- package/types/core/Intent.d.ts +7 -1
- package/types/domain/ModelAsApp.d.ts +2 -2
- package/types/domain/app/ConfigApp.d.ts +21 -0
- package/types/domain/app/UIApp.d.ts +3 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nan0web/ui",
|
|
3
|
-
"version": "1.12.
|
|
3
|
+
"version": "1.12.1",
|
|
4
4
|
"description": "NaN•Web UI. One application logic (algorithm) and many UI.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -74,23 +74,23 @@
|
|
|
74
74
|
"lit": "^3.3.2",
|
|
75
75
|
"vite": "^6.4.1",
|
|
76
76
|
"vitest": "^3.2.4",
|
|
77
|
-
"@nan0web/db-fs": "1.2.
|
|
77
|
+
"@nan0web/db-fs": "1.2.2",
|
|
78
78
|
"@nan0web/event": "1.0.1",
|
|
79
|
-
"@nan0web/icons": "1.1.0",
|
|
80
79
|
"@nan0web/i18n": "1.5.0",
|
|
81
|
-
"@nan0web/
|
|
80
|
+
"@nan0web/icons": "1.1.0",
|
|
82
81
|
"@nan0web/inspect": "1.0.0",
|
|
83
|
-
"@nan0web/
|
|
82
|
+
"@nan0web/ui-cli": "2.13.1",
|
|
84
83
|
"@nan0web/nan0web.app": "0.1.0",
|
|
85
|
-
"@nan0web/
|
|
86
|
-
"@nan0web/
|
|
84
|
+
"@nan0web/ui-lit": "1.1.0",
|
|
85
|
+
"@nan0web/test": "1.1.4",
|
|
86
|
+
"@nan0web/release": "1.0.3"
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
89
|
"string-width": "^7.2.0",
|
|
90
90
|
"@nan0web/co": "2.0.1",
|
|
91
91
|
"@nan0web/core": "1.1.3",
|
|
92
92
|
"@nan0web/log": "1.1.1",
|
|
93
|
-
"@nan0web/types": "1.7.
|
|
93
|
+
"@nan0web/types": "1.7.3"
|
|
94
94
|
},
|
|
95
95
|
"scripts": {
|
|
96
96
|
"prebuild": "rm -rf types/",
|
package/src/App/Core/CoreApp.js
CHANGED
|
@@ -15,7 +15,7 @@ export default class CoreApp {
|
|
|
15
15
|
/** @type {Map<string, CommandFn>} Registered command handlers */
|
|
16
16
|
commands
|
|
17
17
|
|
|
18
|
-
/** @type {
|
|
18
|
+
/** @type {Record<string, any>} App state */
|
|
19
19
|
state
|
|
20
20
|
|
|
21
21
|
/** @type {Message} Starting command parsed from argv */
|
package/src/View/View.js
CHANGED
|
@@ -28,7 +28,7 @@ export default class View {
|
|
|
28
28
|
frame
|
|
29
29
|
/** @type {Locale} */
|
|
30
30
|
locale
|
|
31
|
-
/** @type {Map} */
|
|
31
|
+
/** @type {Map<string, string>} */
|
|
32
32
|
vocab
|
|
33
33
|
/** @type {number[]} */
|
|
34
34
|
windowSize
|
|
@@ -43,7 +43,7 @@ export default class View {
|
|
|
43
43
|
* @param {number} [input.startedAt]
|
|
44
44
|
* @param {Frame} [input.frame]
|
|
45
45
|
* @param {Locale} [input.locale]
|
|
46
|
-
* @param {Map} [input.vocab]
|
|
46
|
+
* @param {Map<string, string>} [input.vocab]
|
|
47
47
|
* @param {number[]} [input.windowSize]
|
|
48
48
|
* @param {Map<string, ComponentFn>} [input.components]
|
|
49
49
|
* @param {string} [input.renderMethod]
|
|
@@ -66,7 +66,7 @@ export default class View {
|
|
|
66
66
|
this.frame = frame
|
|
67
67
|
this.locale = locale
|
|
68
68
|
this.vocab = vocab
|
|
69
|
-
this.windowSize = null === windowSize ? this.stdout.getWindowSize() : windowSize
|
|
69
|
+
this.windowSize = /** @type {number[]} */ (null === windowSize ? this.stdout.getWindowSize() : windowSize)
|
|
70
70
|
this.components = components
|
|
71
71
|
this.renderMethod = renderMethod
|
|
72
72
|
if (!empty(frame)) {
|
|
@@ -85,6 +85,10 @@ export default class View {
|
|
|
85
85
|
getWindowSize() {
|
|
86
86
|
return equal(this.windowSize, [0, 0]) ? this.stdout.getWindowSize() : this.windowSize
|
|
87
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* @param {number} width
|
|
90
|
+
* @param {number} height
|
|
91
|
+
*/
|
|
88
92
|
setWindowSize(width, height) {
|
|
89
93
|
this.windowSize = [width, height]
|
|
90
94
|
}
|
|
@@ -181,6 +185,7 @@ export default class View {
|
|
|
181
185
|
}
|
|
182
186
|
}
|
|
183
187
|
|
|
188
|
+
/** @param {any} value */
|
|
184
189
|
t(value) {
|
|
185
190
|
if (typeOf(Array)(value)) {
|
|
186
191
|
value = value.map((row) => {
|
|
@@ -196,16 +201,22 @@ export default class View {
|
|
|
196
201
|
return this.vocab.has(value) ? this.vocab.get(value) : value
|
|
197
202
|
}
|
|
198
203
|
|
|
204
|
+
/** @param {any[]} args */
|
|
199
205
|
debug(...args) {
|
|
206
|
+
// @ts-ignore
|
|
200
207
|
return this.render(1)([StdOut.STYLES.dim, 'Debug: ', args.join(' '), Frame.EOL, StdOut.RESET])
|
|
201
208
|
}
|
|
202
209
|
|
|
210
|
+
/** @param {any[]} args */
|
|
203
211
|
info(...args) {
|
|
212
|
+
// @ts-ignore
|
|
204
213
|
return this.render(1)([StdOut.COLORS.green, 'Info : ', args.join(' '), Frame.EOL, StdOut.RESET])
|
|
205
214
|
}
|
|
206
215
|
|
|
216
|
+
/** @param {any[]} args */
|
|
207
217
|
warn(...args) {
|
|
208
218
|
return this.render(1)([
|
|
219
|
+
// @ts-ignore
|
|
209
220
|
StdOut.COLORS.yellow,
|
|
210
221
|
'Warn : ',
|
|
211
222
|
args.join(' '),
|
|
@@ -214,8 +225,10 @@ export default class View {
|
|
|
214
225
|
])
|
|
215
226
|
}
|
|
216
227
|
|
|
228
|
+
/** @param {any[]} args */
|
|
217
229
|
error(...args) {
|
|
218
230
|
return this.render(1)([
|
|
231
|
+
// @ts-ignore
|
|
219
232
|
StdOut.COLORS.red,
|
|
220
233
|
StdOut.STYLES.bold,
|
|
221
234
|
'Error: ',
|
package/src/core/Intent.js
CHANGED
|
@@ -72,6 +72,7 @@ import { IntentErrorModel } from './IntentErrorModel.js'
|
|
|
72
72
|
* @typedef {Object} ResultIntent
|
|
73
73
|
* @property {'result'} type
|
|
74
74
|
* @property {*} data - The raw result data (JSON-serializable).
|
|
75
|
+
* @property {boolean} [raw] - If true, Adapter MUST output data raw (no UI decorations).
|
|
75
76
|
*/
|
|
76
77
|
|
|
77
78
|
/**
|
|
@@ -312,10 +313,11 @@ export function render(component, props = {}) {
|
|
|
312
313
|
/**
|
|
313
314
|
* Create a result intent.
|
|
314
315
|
* @param {*} data - The raw result data.
|
|
316
|
+
* @param {boolean} [raw=false] - If true, result is printed raw.
|
|
315
317
|
* @returns {ResultIntent}
|
|
316
318
|
*/
|
|
317
|
-
export function result(data) {
|
|
318
|
-
return { type: 'result', data }
|
|
319
|
+
export function result(data, raw = false) {
|
|
320
|
+
return { type: 'result', data, raw }
|
|
319
321
|
}
|
|
320
322
|
|
|
321
323
|
/**
|
package/src/domain/ModelAsApp.js
CHANGED
|
@@ -16,7 +16,7 @@ export class ModelAsApp extends Model {
|
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* @param {Partial<ModelAsApp> | Record<string, any>} [data={}]
|
|
19
|
-
* @param {ModelAsAppOptions} [options={}]
|
|
19
|
+
* @param {Partial<ModelAsAppOptions>} [options={}]
|
|
20
20
|
*/
|
|
21
21
|
constructor(data = {}, options = {}) {
|
|
22
22
|
super(data, options)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ModelAsApp } from '../ModelAsApp.js'
|
|
2
|
+
import { show, result, render } from '../../core/Intent.js'
|
|
3
|
+
|
|
4
|
+
export default class ConfigApp extends ModelAsApp {
|
|
5
|
+
static name = 'config'
|
|
6
|
+
static alias = 'cfg'
|
|
7
|
+
|
|
8
|
+
static resource = {
|
|
9
|
+
type: 'string',
|
|
10
|
+
help: 'Resource to configure (e.g. agents)',
|
|
11
|
+
positional: true,
|
|
12
|
+
default: 'agents',
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static action = {
|
|
16
|
+
type: 'string',
|
|
17
|
+
help: 'Action to perform (e.g. list)',
|
|
18
|
+
positional: true,
|
|
19
|
+
default: 'list',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
constructor(data = {}, options = {}) {
|
|
23
|
+
super(data, options)
|
|
24
|
+
this.resource = data.resource || 'agents'
|
|
25
|
+
this.action = data.action || 'list'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async *run() {
|
|
29
|
+
if (this.resource === 'agents') {
|
|
30
|
+
if (this.action === 'list') {
|
|
31
|
+
const DBFS = (await import('@nan0web/db-fs')).default
|
|
32
|
+
const db = new DBFS({ root: process.cwd() })
|
|
33
|
+
const config = await db.loadDocument('nan0web.nan0', {}).catch(() => ({}))
|
|
34
|
+
|
|
35
|
+
if (!config || !config.agents || !Array.isArray(config.agents)) {
|
|
36
|
+
yield show('No agents configured in nan0web.nan0')
|
|
37
|
+
return result({ success: true })
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const tableData = config.agents.map((a) => ({
|
|
41
|
+
ID: a.id,
|
|
42
|
+
Description: a.description,
|
|
43
|
+
Workflows: a.workflows ? a.workflows.length : 0,
|
|
44
|
+
Inspectors: a.inspectors ? a.inspectors.length : 0,
|
|
45
|
+
}))
|
|
46
|
+
|
|
47
|
+
yield render('Table', {
|
|
48
|
+
data: tableData,
|
|
49
|
+
columns: ['ID', 'Description', 'Workflows', 'Inspectors'],
|
|
50
|
+
interactive: false
|
|
51
|
+
})
|
|
52
|
+
return result({ success: true })
|
|
53
|
+
}
|
|
54
|
+
yield show(`Unknown action for agents: ${this.action}`, 'error')
|
|
55
|
+
return result({ success: false })
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
yield show(`Unknown config resource: ${this.resource}`, 'error')
|
|
59
|
+
return result({ success: false })
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/domain/app/UIApp.js
CHANGED
|
@@ -2,13 +2,14 @@ import { ModelAsApp } from '../ModelAsApp.js'
|
|
|
2
2
|
import { resolvePositionalArgs } from '@nan0web/ui-cli'
|
|
3
3
|
import SnapshotAuditor from './SnapshotAuditor.js'
|
|
4
4
|
import GalleryCommand from './GalleryCommand.js'
|
|
5
|
+
import ConfigApp from './ConfigApp.js'
|
|
5
6
|
import { show, result } from '../../core/Intent.js'
|
|
6
7
|
|
|
7
8
|
export class UIApp extends ModelAsApp {
|
|
8
9
|
static command = {
|
|
9
10
|
type: 'string',
|
|
10
11
|
help: 'Command to run (e.g. gallery)',
|
|
11
|
-
options: [GalleryCommand, SnapshotAuditor],
|
|
12
|
+
options: [GalleryCommand, SnapshotAuditor, ConfigApp],
|
|
12
13
|
default: GalleryCommand.alias || GalleryCommand.name,
|
|
13
14
|
positional: true,
|
|
14
15
|
}
|
|
@@ -20,8 +20,8 @@ export default class CoreApp {
|
|
|
20
20
|
name: string;
|
|
21
21
|
/** @type {Map<string, CommandFn>} Registered command handlers */
|
|
22
22
|
commands: Map<string, CommandFn>;
|
|
23
|
-
/** @type {
|
|
24
|
-
state:
|
|
23
|
+
/** @type {Record<string, any>} App state */
|
|
24
|
+
state: Record<string, any>;
|
|
25
25
|
/** @type {Message} Starting command parsed from argv */
|
|
26
26
|
startCommand: Message;
|
|
27
27
|
/**
|
package/types/View/View.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export default class View {
|
|
|
22
22
|
* @param {number} [input.startedAt]
|
|
23
23
|
* @param {Frame} [input.frame]
|
|
24
24
|
* @param {Locale} [input.locale]
|
|
25
|
-
* @param {Map} [input.vocab]
|
|
25
|
+
* @param {Map<string, string>} [input.vocab]
|
|
26
26
|
* @param {number[]} [input.windowSize]
|
|
27
27
|
* @param {Map<string, ComponentFn>} [input.components]
|
|
28
28
|
* @param {string} [input.renderMethod]
|
|
@@ -33,7 +33,7 @@ export default class View {
|
|
|
33
33
|
startedAt?: number | undefined;
|
|
34
34
|
frame?: Frame | undefined;
|
|
35
35
|
locale?: Locale | undefined;
|
|
36
|
-
vocab?: Map<
|
|
36
|
+
vocab?: Map<string, string> | undefined;
|
|
37
37
|
windowSize?: number[] | undefined;
|
|
38
38
|
components?: Map<string, ComponentFn> | undefined;
|
|
39
39
|
renderMethod?: string | undefined;
|
|
@@ -48,8 +48,8 @@ export default class View {
|
|
|
48
48
|
frame: Frame;
|
|
49
49
|
/** @type {Locale} */
|
|
50
50
|
locale: Locale;
|
|
51
|
-
/** @type {Map} */
|
|
52
|
-
vocab: Map<
|
|
51
|
+
/** @type {Map<string, string>} */
|
|
52
|
+
vocab: Map<string, string>;
|
|
53
53
|
/** @type {number[]} */
|
|
54
54
|
windowSize: number[];
|
|
55
55
|
/** @type {Map<string, ComponentFn>} */
|
|
@@ -60,7 +60,11 @@ export default class View {
|
|
|
60
60
|
get RenderMethod(): typeof FrameRenderMethod;
|
|
61
61
|
get RenderOptions(): typeof RenderOptions;
|
|
62
62
|
getWindowSize(): number[];
|
|
63
|
-
|
|
63
|
+
/**
|
|
64
|
+
* @param {number} width
|
|
65
|
+
* @param {number} height
|
|
66
|
+
*/
|
|
67
|
+
setWindowSize(width: number, height: number): void;
|
|
64
68
|
startTimer(): void;
|
|
65
69
|
spent(checkpoint?: number): number;
|
|
66
70
|
/**
|
|
@@ -71,10 +75,15 @@ export default class View {
|
|
|
71
75
|
render(shouldRender?: boolean | number | Function | ComponentFn, options?: RenderOptions): (value: Frame | string | string[], ...args: any) => Frame;
|
|
72
76
|
clear(shouldRender?: number): Frame;
|
|
73
77
|
progress(shouldRender?: boolean): (value: any) => Frame;
|
|
78
|
+
/** @param {any} value */
|
|
74
79
|
t(value: any): any;
|
|
80
|
+
/** @param {any[]} args */
|
|
75
81
|
debug(...args: any[]): Frame;
|
|
82
|
+
/** @param {any[]} args */
|
|
76
83
|
info(...args: any[]): Frame;
|
|
84
|
+
/** @param {any[]} args */
|
|
77
85
|
warn(...args: any[]): Frame;
|
|
86
|
+
/** @param {any[]} args */
|
|
78
87
|
error(...args: any[]): Frame;
|
|
79
88
|
/**
|
|
80
89
|
* @param {string} name
|
package/types/core/Intent.d.ts
CHANGED
|
@@ -59,9 +59,10 @@ export function render(component: string, props?: object): RenderIntent;
|
|
|
59
59
|
/**
|
|
60
60
|
* Create a result intent.
|
|
61
61
|
* @param {*} data - The raw result data.
|
|
62
|
+
* @param {boolean} [raw=false] - If true, result is printed raw.
|
|
62
63
|
* @returns {ResultIntent}
|
|
63
64
|
*/
|
|
64
|
-
export function result(data: any): ResultIntent;
|
|
65
|
+
export function result(data: any, raw?: boolean): ResultIntent;
|
|
65
66
|
/**
|
|
66
67
|
* @typedef {Object} ShowData
|
|
67
68
|
* @property {any} [component]
|
|
@@ -135,6 +136,7 @@ export function agent(task: string, context?: AgentContext): AgentIntent;
|
|
|
135
136
|
* @typedef {Object} ResultIntent
|
|
136
137
|
* @property {'result'} type
|
|
137
138
|
* @property {*} data - The raw result data (JSON-serializable).
|
|
139
|
+
* @property {boolean} [raw] - If true, Adapter MUST output data raw (no UI decorations).
|
|
138
140
|
*/
|
|
139
141
|
/**
|
|
140
142
|
* Model requests rendering of a pure UI component (Header, Footer, Static Map).
|
|
@@ -364,6 +366,10 @@ export type ResultIntent = {
|
|
|
364
366
|
* - The raw result data (JSON-serializable).
|
|
365
367
|
*/
|
|
366
368
|
data: any;
|
|
369
|
+
/**
|
|
370
|
+
* - If true, Adapter MUST output data raw (no UI decorations).
|
|
371
|
+
*/
|
|
372
|
+
raw?: boolean | undefined;
|
|
367
373
|
};
|
|
368
374
|
/**
|
|
369
375
|
* Model requests rendering of a pure UI component (Header, Footer, Static Map).
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
export class ModelAsApp extends Model {
|
|
6
6
|
/**
|
|
7
7
|
* @param {Partial<ModelAsApp> | Record<string, any>} [data={}]
|
|
8
|
-
* @param {ModelAsAppOptions} [options={}]
|
|
8
|
+
* @param {Partial<ModelAsAppOptions>} [options={}]
|
|
9
9
|
*/
|
|
10
|
-
constructor(data?: Partial<ModelAsApp> | Record<string, any>, options?: ModelAsAppOptions);
|
|
10
|
+
constructor(data?: Partial<ModelAsApp> | Record<string, any>, options?: Partial<ModelAsAppOptions>);
|
|
11
11
|
/** @returns {ModelAsAppOptions} */
|
|
12
12
|
get _(): ModelAsAppOptions;
|
|
13
13
|
/**
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default class ConfigApp extends ModelAsApp {
|
|
2
|
+
static name: string;
|
|
3
|
+
static alias: string;
|
|
4
|
+
static resource: {
|
|
5
|
+
type: string;
|
|
6
|
+
help: string;
|
|
7
|
+
positional: boolean;
|
|
8
|
+
default: string;
|
|
9
|
+
};
|
|
10
|
+
static action: {
|
|
11
|
+
type: string;
|
|
12
|
+
help: string;
|
|
13
|
+
positional: boolean;
|
|
14
|
+
default: string;
|
|
15
|
+
};
|
|
16
|
+
constructor(data?: {}, options?: {});
|
|
17
|
+
resource: any;
|
|
18
|
+
action: any;
|
|
19
|
+
run(): AsyncGenerator<import("../../core/Intent.js").ShowIntent | import("../../core/Intent.js").RenderIntent, import("../../core/Intent.js").ResultIntent, unknown>;
|
|
20
|
+
}
|
|
21
|
+
import { ModelAsApp } from '../ModelAsApp.js';
|
|
@@ -2,7 +2,7 @@ export class UIApp extends ModelAsApp {
|
|
|
2
2
|
static command: {
|
|
3
3
|
type: string;
|
|
4
4
|
help: string;
|
|
5
|
-
options: (typeof SnapshotAuditor | typeof GalleryCommand)[];
|
|
5
|
+
options: (typeof SnapshotAuditor | typeof GalleryCommand | typeof ConfigApp)[];
|
|
6
6
|
default: string;
|
|
7
7
|
positional: boolean;
|
|
8
8
|
};
|
|
@@ -22,7 +22,7 @@ export class UIApp extends ModelAsApp {
|
|
|
22
22
|
/** @type {string[]} */ _positionals: string[];
|
|
23
23
|
/** @type {string} Type of command to run */ command: string;
|
|
24
24
|
/** @type {boolean} Show help message */ help: boolean;
|
|
25
|
-
run(): AsyncGenerator<import("../../core/Intent.js").ShowIntent | (import("../../core/Intent.js").AskIntent & {
|
|
25
|
+
run(): AsyncGenerator<import("../../core/Intent.js").ShowIntent | import("../../core/Intent.js").RenderIntent | (import("../../core/Intent.js").AskIntent & {
|
|
26
26
|
$value?: any;
|
|
27
27
|
$success?: boolean;
|
|
28
28
|
$files?: Record<string, string>;
|
|
@@ -37,11 +37,6 @@ export class UIApp extends ModelAsApp {
|
|
|
37
37
|
$success?: boolean;
|
|
38
38
|
$files?: Record<string, string>;
|
|
39
39
|
$message?: string;
|
|
40
|
-
}) | (import("../../core/Intent.js").RenderIntent & {
|
|
41
|
-
$value?: any;
|
|
42
|
-
$success?: boolean;
|
|
43
|
-
$files?: Record<string, string>;
|
|
44
|
-
$message?: string;
|
|
45
40
|
}) | (import("../../core/Intent.js").AgentIntent & {
|
|
46
41
|
$value?: any;
|
|
47
42
|
$success?: boolean;
|
|
@@ -58,3 +53,4 @@ export default UIApp;
|
|
|
58
53
|
import { ModelAsApp } from '../ModelAsApp.js';
|
|
59
54
|
import SnapshotAuditor from './SnapshotAuditor.js';
|
|
60
55
|
import GalleryCommand from './GalleryCommand.js';
|
|
56
|
+
import ConfigApp from './ConfigApp.js';
|