@mihe-dev/js 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +114 -2
- package/dist/audio.d.ts +121 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/audio.js +377 -0
- package/dist/audio.js.map +1 -0
- package/dist/card-view.d.ts +79 -0
- package/dist/card-view.d.ts.map +1 -0
- package/dist/card-view.js +99 -0
- package/dist/card-view.js.map +1 -0
- package/dist/chart.d.ts +15 -0
- package/dist/chart.d.ts.map +1 -0
- package/dist/chart.js +58 -0
- package/dist/chart.js.map +1 -0
- package/dist/client.d.ts +226 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +358 -0
- package/dist/client.js.map +1 -0
- package/dist/commands.d.ts +70 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +295 -0
- package/dist/commands.js.map +1 -0
- package/dist/debug.d.ts +17 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +29 -0
- package/dist/debug.js.map +1 -0
- package/dist/declarations.d.ts +160 -0
- package/dist/declarations.d.ts.map +1 -0
- package/dist/declarations.js +171 -0
- package/dist/declarations.js.map +1 -0
- package/dist/highlight.d.ts +77 -0
- package/dist/highlight.d.ts.map +1 -0
- package/dist/highlight.js +233 -0
- package/dist/highlight.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/mihe.d.ts +364 -0
- package/dist/mihe.d.ts.map +1 -0
- package/dist/mihe.iife.min.js +217 -0
- package/dist/mihe.iife.min.js.map +7 -0
- package/dist/mihe.js +758 -0
- package/dist/mihe.js.map +1 -0
- package/dist/mihe.min.js +217 -0
- package/dist/mihe.min.js.map +7 -0
- package/dist/store.d.ts +175 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +208 -0
- package/dist/store.js.map +1 -0
- package/dist/voice.d.ts +192 -0
- package/dist/voice.d.ts.map +1 -0
- package/dist/voice.js +443 -0
- package/dist/voice.js.map +1 -0
- package/dist/widget/card.d.ts +17 -0
- package/dist/widget/card.d.ts.map +1 -0
- package/dist/widget/card.js +31 -0
- package/dist/widget/card.js.map +1 -0
- package/dist/widget/dom.d.ts +24 -0
- package/dist/widget/dom.d.ts.map +1 -0
- package/dist/widget/dom.js +49 -0
- package/dist/widget/dom.js.map +1 -0
- package/dist/widget/element.d.ts +88 -0
- package/dist/widget/element.d.ts.map +1 -0
- package/dist/widget/element.js +285 -0
- package/dist/widget/element.js.map +1 -0
- package/dist/widget/format.d.ts +24 -0
- package/dist/widget/format.d.ts.map +1 -0
- package/dist/widget/format.js +64 -0
- package/dist/widget/format.js.map +1 -0
- package/dist/widget/icons.d.ts +5 -0
- package/dist/widget/icons.d.ts.map +1 -0
- package/dist/widget/icons.js +19 -0
- package/dist/widget/icons.js.map +1 -0
- package/dist/widget/launcher.d.ts +13 -0
- package/dist/widget/launcher.d.ts.map +1 -0
- package/dist/widget/launcher.js +27 -0
- package/dist/widget/launcher.js.map +1 -0
- package/dist/widget/mark.d.ts +10 -0
- package/dist/widget/mark.d.ts.map +1 -0
- package/dist/widget/mark.js +20 -0
- package/dist/widget/mark.js.map +1 -0
- package/dist/widget/orb.d.ts +92 -0
- package/dist/widget/orb.d.ts.map +1 -0
- package/dist/widget/orb.js +500 -0
- package/dist/widget/orb.js.map +1 -0
- package/dist/widget/panel.d.ts +40 -0
- package/dist/widget/panel.d.ts.map +1 -0
- package/dist/widget/panel.js +240 -0
- package/dist/widget/panel.js.map +1 -0
- package/dist/widget/styles.d.ts +22 -0
- package/dist/widget/styles.d.ts.map +1 -0
- package/dist/widget/styles.js +192 -0
- package/dist/widget/styles.js.map +1 -0
- package/package.json +43 -4
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an app declares about tabs, tables and charts, and how each becomes
|
|
3
|
+
* what the store holds (amendment 67, doc 08).
|
|
4
|
+
*
|
|
5
|
+
* Shared by the JavaScript API (`mihe.registerTable(…)`) and the React hooks
|
|
6
|
+
* (`useAssistantTable(…)`), so the two can't send the model different things
|
|
7
|
+
* for the same table. Each builder takes `latest`, a function returning the
|
|
8
|
+
* declaration as it is now: rows, closures and data are read at the moment of
|
|
9
|
+
* a read rather than captured at registration, so a table that re-renders
|
|
10
|
+
* every second doesn't re-register every second.
|
|
11
|
+
*/
|
|
12
|
+
import { summarise, thin } from "./chart.js";
|
|
13
|
+
/** Long cells are cut here: a notes field should not cost a page of tokens. */
|
|
14
|
+
const MAX_CELL_CHARS = 200;
|
|
15
|
+
export function toCell(value) {
|
|
16
|
+
if (value === null || value === undefined)
|
|
17
|
+
return null;
|
|
18
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
19
|
+
return value;
|
|
20
|
+
const text = value instanceof Date
|
|
21
|
+
? value.toISOString()
|
|
22
|
+
: typeof value === "string"
|
|
23
|
+
? value
|
|
24
|
+
: JSON.stringify(value);
|
|
25
|
+
return text.length > MAX_CELL_CHARS ? `${text.slice(0, MAX_CELL_CHARS)}…` : text;
|
|
26
|
+
}
|
|
27
|
+
/** The tabs as the store holds them. `onChange` is read at call time. */
|
|
28
|
+
export function tabsDeclaration(latest) {
|
|
29
|
+
const tabs = latest();
|
|
30
|
+
return {
|
|
31
|
+
kind: "tabs",
|
|
32
|
+
label: tabs.label,
|
|
33
|
+
options: tabs.tabs.map(({ value, label }) => ({ value, label })),
|
|
34
|
+
value: tabs.value,
|
|
35
|
+
onChange: (value) => latest().onChange(value),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* What identifies a tab set's declaration, without its closure: when this
|
|
40
|
+
* changes, the store needs the new declaration.
|
|
41
|
+
*/
|
|
42
|
+
export function tabsSignature(tabs) {
|
|
43
|
+
return JSON.stringify({
|
|
44
|
+
label: tabs.label,
|
|
45
|
+
tabs: tabs.tabs.map(({ value, label }) => ({ value, label })),
|
|
46
|
+
value: tabs.value,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/** The query parameters a table accepts, as the store holds them. */
|
|
50
|
+
function queryParams(query) {
|
|
51
|
+
return Object.entries(query.params).map(([key, param]) => ({
|
|
52
|
+
key,
|
|
53
|
+
kind: param.kind,
|
|
54
|
+
values: param.kind === "enum" ? [...param.values] : [],
|
|
55
|
+
description: param.description ?? "",
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* What identifies a table's declaration, without its rows or closures: when
|
|
60
|
+
* this changes, the store needs the new declaration. The rows' count is in
|
|
61
|
+
* it, because the screen context reports how many are loaded.
|
|
62
|
+
*/
|
|
63
|
+
export function tableSignature(table) {
|
|
64
|
+
return JSON.stringify({
|
|
65
|
+
label: table.label,
|
|
66
|
+
columns: table.columns.map(({ key, label }) => ({ key, label })),
|
|
67
|
+
rowIdName: table.rowIdName,
|
|
68
|
+
opens: table.opens?.screenId,
|
|
69
|
+
total: table.total,
|
|
70
|
+
loaded: table.rows.length,
|
|
71
|
+
query: table.query
|
|
72
|
+
? {
|
|
73
|
+
params: queryParams(table.query),
|
|
74
|
+
canShow: table.query.show !== undefined,
|
|
75
|
+
}
|
|
76
|
+
: undefined,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/** The table as the store holds it. Rows and closures are read at call time. */
|
|
80
|
+
export function tableDeclaration(latest) {
|
|
81
|
+
const table = latest();
|
|
82
|
+
// One rendering for rows read and rows found, so a search result looks
|
|
83
|
+
// exactly like a read: declared columns only, cells cut, `open` params.
|
|
84
|
+
const render = (row) => {
|
|
85
|
+
const { rowId, columns, opens } = latest();
|
|
86
|
+
const out = {};
|
|
87
|
+
for (const column of columns) {
|
|
88
|
+
const raw = column.value ? column.value(row) : row[column.key];
|
|
89
|
+
out[column.label] = toCell(raw);
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
id: rowId(row),
|
|
93
|
+
...(opens ? { open: opens.params(row) } : {}),
|
|
94
|
+
...out,
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
return {
|
|
98
|
+
label: table.label,
|
|
99
|
+
columns: table.columns.map(({ key, label }) => ({ key, label })),
|
|
100
|
+
rowIdName: table.rowIdName,
|
|
101
|
+
opens: table.opens?.screenId,
|
|
102
|
+
total: table.total,
|
|
103
|
+
loadedRows: table.rows.length,
|
|
104
|
+
read: (offset, limit) => latest().rows.slice(offset, offset + limit).map(render),
|
|
105
|
+
...(table.query
|
|
106
|
+
? {
|
|
107
|
+
query: {
|
|
108
|
+
params: queryParams(table.query),
|
|
109
|
+
run: async (params) => {
|
|
110
|
+
const query = latest().query;
|
|
111
|
+
if (!query)
|
|
112
|
+
throw new Error("This table can no longer be searched.");
|
|
113
|
+
const found = await query.run(params);
|
|
114
|
+
return {
|
|
115
|
+
rows: found.rows.map(render),
|
|
116
|
+
...(found.total === undefined ? {} : { total: found.total }),
|
|
117
|
+
};
|
|
118
|
+
},
|
|
119
|
+
...(table.query.show
|
|
120
|
+
? { show: (params) => latest().query?.show?.(params) }
|
|
121
|
+
: {}),
|
|
122
|
+
},
|
|
123
|
+
}
|
|
124
|
+
: {}),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/** Each series' points, read from the chart as it is now. */
|
|
128
|
+
function chartPoints(chart, key) {
|
|
129
|
+
const format = chart.x.format;
|
|
130
|
+
return chart.data.flatMap((datum) => {
|
|
131
|
+
const raw = datum[key];
|
|
132
|
+
const y = typeof raw === "number" ? raw : raw == null ? NaN : Number(raw);
|
|
133
|
+
if (!Number.isFinite(y))
|
|
134
|
+
return [];
|
|
135
|
+
const xRaw = datum[chart.x.key];
|
|
136
|
+
return [{ x: format ? format(xRaw) : String(xRaw), y }];
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The chart as the store holds it: each series summarised here, in the
|
|
141
|
+
* browser, and the points read at call time when an exact value is wanted.
|
|
142
|
+
*/
|
|
143
|
+
export function chartDeclaration(latest) {
|
|
144
|
+
const chart = latest();
|
|
145
|
+
const ordered = chart.x.kind !== "category";
|
|
146
|
+
return {
|
|
147
|
+
title: chart.title,
|
|
148
|
+
xLabel: chart.x.label,
|
|
149
|
+
xKind: ordered ? "ordered" : "category",
|
|
150
|
+
series: chart.series.map((s) => {
|
|
151
|
+
const summary = summarise(chartPoints(chart, s.key), ordered);
|
|
152
|
+
return {
|
|
153
|
+
name: s.name,
|
|
154
|
+
...(s.unit ? { unit: s.unit } : {}),
|
|
155
|
+
...(summary ? { summary } : {}),
|
|
156
|
+
};
|
|
157
|
+
}),
|
|
158
|
+
read: (name, limit) => {
|
|
159
|
+
const current = latest();
|
|
160
|
+
return current.series
|
|
161
|
+
.filter((s) => name === undefined || s.name === name)
|
|
162
|
+
.map((s) => ({ name: s.name, points: thin(chartPoints(current, s.key), limit) }));
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/** What identifies a chart's declaration: its summaries, not its closures. */
|
|
167
|
+
export function chartSignature(chart) {
|
|
168
|
+
const { read: _read, ...declared } = chartDeclaration(() => chart);
|
|
169
|
+
return JSON.stringify(declared);
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=declarations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"declarations.js","sourceRoot":"","sources":["../../../js/src/declarations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAsH1C,+EAA+E;AAC/E,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC1E,MAAM,IAAI,GACR,KAAK,YAAY,IAAI;QACnB,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE;QACrB,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACnF,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,eAAe,CAAC,MAA2B;IACzD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC;IACtB,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAmB;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7D,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;AACL,CAAC;AAED,qEAAqE;AACrE,SAAS,WAAW,CAAC,KAAmC;IACtD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,GAAG;QACH,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;QACtD,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;KACrC,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAM,KAA0B;IAC5D,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ;QAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM;QACzB,KAAK,EAAE,KAAK,CAAC,KAAK;YAChB,CAAC,CAAC;gBACE,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,KAAqC,CAAC;gBAChE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS;aACxC;YACH,CAAC,CAAC,SAAS;KACd,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAM,MAAiC;IACrE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;IAEvB,uEAAuE;IACvE,wEAAwE;IACxE,MAAM,MAAM,GAAG,CAAC,GAAQ,EAAE,EAAE;QAC1B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAAC;QAC3C,MAAM,GAAG,GAAqD,EAAE,CAAC;QACjE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,GAA+B,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5F,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;QACD,OAAO;YACL,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC;YACd,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,GAAG,GAAG;SACP,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ;QAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM;QAC7B,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;QAChF,GAAG,CAAC,KAAK,CAAC,KAAK;YACb,CAAC,CAAC;gBACE,KAAK,EAAE;oBACL,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,KAAqC,CAAC;oBAChE,GAAG,EAAE,KAAK,EAAE,MAA8B,EAAE,EAAE;wBAC5C,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC;wBAC7B,IAAI,CAAC,KAAK;4BAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;wBACrE,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;wBACtC,OAAO;4BACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;4BAC5B,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;yBAC7D,CAAC;oBACJ,CAAC;oBACD,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI;wBAClB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAA8B,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE;wBAC9E,CAAC,CAAC,EAAE,CAAC;iBACR;aACF;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,6DAA6D;AAC7D,SAAS,WAAW,CAAQ,KAA4B,EAAE,GAAW;IACnE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QAClC,MAAM,GAAG,GAAI,KAAiC,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,CAAC,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;QACnC,MAAM,IAAI,GAAI,KAAiC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAQ,MAAmC;IACzE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;IACvB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC;IAC5C,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK;QACrB,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;QACvC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC7B,MAAM,OAAO,GAAG,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9D,OAAO;gBACL,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChC,CAAC;QACJ,CAAC,CAAC;QACF,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACpB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC;YACzB,OAAO,OAAO,CAAC,MAAM;iBAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;iBACpD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACtF,CAAC;KACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,cAAc,CAAQ,KAA4B;IAChE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,GAAG,gBAAgB,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IACnE,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The highlight and focus engine (spec §12).
|
|
3
|
+
*
|
|
4
|
+
* Draws an overlay over a registered element rather than mutating the
|
|
5
|
+
* element's own styles. Two reasons: the host app's CSS is not ours to touch,
|
|
6
|
+
* and an overlay cannot leave residue if the SDK unmounts mid-tutorial.
|
|
7
|
+
*
|
|
8
|
+
* Elements are found by the `data-mihe-component` attribute that
|
|
9
|
+
* `useAssistantComponent` spreads onto them. Never by CSS selector or
|
|
10
|
+
* position — the assistant points at things the app has declared, and at
|
|
11
|
+
* nothing else.
|
|
12
|
+
*/
|
|
13
|
+
export declare const COMPONENT_ATTRIBUTE = "data-mihe-component";
|
|
14
|
+
export declare function findComponent(componentKey: string): HTMLElement | null;
|
|
15
|
+
export declare class HighlightEngine {
|
|
16
|
+
private overlay;
|
|
17
|
+
private caption;
|
|
18
|
+
private target;
|
|
19
|
+
private tracking;
|
|
20
|
+
private observer;
|
|
21
|
+
private frame;
|
|
22
|
+
/** Draw attention to a component. Returns false if it is not on the page. */
|
|
23
|
+
highlight(componentKey: string, message?: string): boolean;
|
|
24
|
+
/** Move keyboard focus into a component, highlighting it too. */
|
|
25
|
+
focus(componentKey: string, message?: string): boolean;
|
|
26
|
+
scrollTo(componentKey: string): boolean;
|
|
27
|
+
clear(): void;
|
|
28
|
+
private ensureOverlay;
|
|
29
|
+
private setCaption;
|
|
30
|
+
private position;
|
|
31
|
+
/** Coalesced, because a MutationObserver can fire many times per render. */
|
|
32
|
+
private reposition;
|
|
33
|
+
/** Escape is the universal "get this off my screen". */
|
|
34
|
+
private onKeyDown;
|
|
35
|
+
/**
|
|
36
|
+
* Any click outside the target dismisses.
|
|
37
|
+
*
|
|
38
|
+
* The overlay dims the whole page, so it reads as a modal — but it is
|
|
39
|
+
* `pointer-events: none`, so clicks reach the app underneath. Without this
|
|
40
|
+
* the user clicks away, the app responds, and the dim stays: it looks
|
|
41
|
+
* dismissible and is not. Clicks on the target itself are left alone, since
|
|
42
|
+
* that is the click the highlight is asking for and the app's own handler
|
|
43
|
+
* usually removes the highlight's reason for existing anyway.
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* A click ends the highlight, with one exception that has an exception.
|
|
47
|
+
*
|
|
48
|
+
* Clicking away dismisses it: the user has moved on and a ring around
|
|
49
|
+
* something they are no longer looking at is clutter.
|
|
50
|
+
*
|
|
51
|
+
* Clicking *inside* the target does not, because the target is often an
|
|
52
|
+
* input the user has just been asked to fill — losing the marker the moment
|
|
53
|
+
* they click into the field would undo the pointing.
|
|
54
|
+
*
|
|
55
|
+
* But if the target is something clicking *activates* — a button, a link —
|
|
56
|
+
* then the click was the action, and the highlight has done its job. Without
|
|
57
|
+
* this the ring survives the thing it pointed at: the assistant highlighted
|
|
58
|
+
* "Receive Stock", the user clicked, the form opened, and the outline stayed
|
|
59
|
+
* behind the dialog pointing at a button nobody needed any more.
|
|
60
|
+
*/
|
|
61
|
+
private onPointerDown;
|
|
62
|
+
/**
|
|
63
|
+
* Keep the overlay glued to its target, and remove it when the target goes.
|
|
64
|
+
*
|
|
65
|
+
* Scroll and resize are listened to rather than polled; `capture: true` on
|
|
66
|
+
* scroll catches scrolling inside containers, not just the window.
|
|
67
|
+
*
|
|
68
|
+
* The MutationObserver is what makes the overlay mortal. `position` already
|
|
69
|
+
* clears when the target has left the DOM, but it only ran on scroll and
|
|
70
|
+
* resize — so a highlighted element that unmounted while the page sat still
|
|
71
|
+
* (a form closing after submit, say) left the overlay stranded over the page
|
|
72
|
+
* with no way to dismiss it.
|
|
73
|
+
*/
|
|
74
|
+
private startTracking;
|
|
75
|
+
private stopTracking;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=highlight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight.d.ts","sourceRoot":"","sources":["../../../js/src/highlight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAoBzD,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAItE;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,KAAK,CAAK;IAElB,6EAA6E;IAC7E,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAc1D,iEAAiE;IACjE,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAiBtD,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAOvC,KAAK,IAAI,IAAI;IAQb,OAAO,CAAC,aAAa;IAuCrB,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,QAAQ,CAgBd;IAEF,4EAA4E;IAC5E,OAAO,CAAC,UAAU,CAMhB;IAEF,wDAAwD;IACxD,OAAO,CAAC,SAAS,CAEf;IAEF;;;;;;;;;OASG;IACH;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,aAAa,CAKnB;IAEF;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,YAAY;CAerB"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The highlight and focus engine (spec §12).
|
|
3
|
+
*
|
|
4
|
+
* Draws an overlay over a registered element rather than mutating the
|
|
5
|
+
* element's own styles. Two reasons: the host app's CSS is not ours to touch,
|
|
6
|
+
* and an overlay cannot leave residue if the SDK unmounts mid-tutorial.
|
|
7
|
+
*
|
|
8
|
+
* Elements are found by the `data-mihe-component` attribute that
|
|
9
|
+
* `useAssistantComponent` spreads onto them. Never by CSS selector or
|
|
10
|
+
* position — the assistant points at things the app has declared, and at
|
|
11
|
+
* nothing else.
|
|
12
|
+
*/
|
|
13
|
+
export const COMPONENT_ATTRIBUTE = "data-mihe-component";
|
|
14
|
+
const OVERLAY_ID = "mihe-highlight";
|
|
15
|
+
const PADDING = 6;
|
|
16
|
+
/**
|
|
17
|
+
* Whether clicking this element does something, rather than merely selecting
|
|
18
|
+
* it. Buttons and links act; inputs and containers receive.
|
|
19
|
+
*
|
|
20
|
+
* Read from the element rather than from the registry's `ComponentType`
|
|
21
|
+
* because the overlay is drawn over whatever the app spread the attribute
|
|
22
|
+
* onto, which is not always the element the declaration describes — a label
|
|
23
|
+
* carrying the props for the input beside it, for instance.
|
|
24
|
+
*/
|
|
25
|
+
function activates(element) {
|
|
26
|
+
if (!element)
|
|
27
|
+
return false;
|
|
28
|
+
if (element.closest("button, a[href], [role='button'], [role='link']"))
|
|
29
|
+
return true;
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
export function findComponent(componentKey) {
|
|
33
|
+
return document.querySelector(`[${COMPONENT_ATTRIBUTE}="${CSS.escape(componentKey)}"]`);
|
|
34
|
+
}
|
|
35
|
+
export class HighlightEngine {
|
|
36
|
+
overlay = null;
|
|
37
|
+
caption = null;
|
|
38
|
+
target = null;
|
|
39
|
+
tracking = false;
|
|
40
|
+
observer = null;
|
|
41
|
+
frame = 0;
|
|
42
|
+
/** Draw attention to a component. Returns false if it is not on the page. */
|
|
43
|
+
highlight(componentKey, message) {
|
|
44
|
+
const target = findComponent(componentKey);
|
|
45
|
+
if (!target)
|
|
46
|
+
return false;
|
|
47
|
+
this.target = target;
|
|
48
|
+
this.ensureOverlay();
|
|
49
|
+
this.setCaption(message);
|
|
50
|
+
this.position();
|
|
51
|
+
this.startTracking();
|
|
52
|
+
target.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
/** Move keyboard focus into a component, highlighting it too. */
|
|
56
|
+
focus(componentKey, message) {
|
|
57
|
+
const target = findComponent(componentKey);
|
|
58
|
+
if (!target)
|
|
59
|
+
return false;
|
|
60
|
+
this.highlight(componentKey, message);
|
|
61
|
+
// A wrapper may be registered rather than the input itself; focus the
|
|
62
|
+
// first focusable descendant when the element cannot take focus.
|
|
63
|
+
const focusable = target.matches("input, textarea, select, button, [tabindex]")
|
|
64
|
+
? target
|
|
65
|
+
: target.querySelector("input, textarea, select, button, [tabindex]");
|
|
66
|
+
focusable?.focus();
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
scrollTo(componentKey) {
|
|
70
|
+
const target = findComponent(componentKey);
|
|
71
|
+
if (!target)
|
|
72
|
+
return false;
|
|
73
|
+
target.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
clear() {
|
|
77
|
+
this.stopTracking();
|
|
78
|
+
this.overlay?.remove();
|
|
79
|
+
this.overlay = null;
|
|
80
|
+
this.caption = null;
|
|
81
|
+
this.target = null;
|
|
82
|
+
}
|
|
83
|
+
ensureOverlay() {
|
|
84
|
+
if (this.overlay)
|
|
85
|
+
return;
|
|
86
|
+
const overlay = document.createElement("div");
|
|
87
|
+
overlay.id = OVERLAY_ID;
|
|
88
|
+
// `pointer-events: none` is load-bearing: the highlight must never
|
|
89
|
+
// intercept the click it is asking the user to make.
|
|
90
|
+
Object.assign(overlay.style, {
|
|
91
|
+
position: "fixed",
|
|
92
|
+
zIndex: "2147483000",
|
|
93
|
+
pointerEvents: "none",
|
|
94
|
+
border: "2px solid #4f7cff",
|
|
95
|
+
borderRadius: "8px",
|
|
96
|
+
boxShadow: "0 0 0 9999px rgba(15, 23, 42, 0.45)",
|
|
97
|
+
transition: "top 120ms ease, left 120ms ease, width 120ms ease, height 120ms ease",
|
|
98
|
+
});
|
|
99
|
+
const caption = document.createElement("div");
|
|
100
|
+
Object.assign(caption.style, {
|
|
101
|
+
position: "absolute",
|
|
102
|
+
left: "0",
|
|
103
|
+
top: "100%",
|
|
104
|
+
marginTop: "8px",
|
|
105
|
+
maxWidth: "260px",
|
|
106
|
+
padding: "8px 10px",
|
|
107
|
+
borderRadius: "8px",
|
|
108
|
+
background: "#0f172a",
|
|
109
|
+
color: "#f8fafc",
|
|
110
|
+
font: "500 13px/1.4 system-ui, -apple-system, sans-serif",
|
|
111
|
+
display: "none",
|
|
112
|
+
});
|
|
113
|
+
overlay.appendChild(caption);
|
|
114
|
+
document.body.appendChild(overlay);
|
|
115
|
+
this.overlay = overlay;
|
|
116
|
+
this.caption = caption;
|
|
117
|
+
}
|
|
118
|
+
setCaption(message) {
|
|
119
|
+
if (!this.caption)
|
|
120
|
+
return;
|
|
121
|
+
if (message) {
|
|
122
|
+
this.caption.textContent = message;
|
|
123
|
+
this.caption.style.display = "block";
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.caption.textContent = "";
|
|
127
|
+
this.caption.style.display = "none";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
position = () => {
|
|
131
|
+
if (!this.overlay || !this.target)
|
|
132
|
+
return;
|
|
133
|
+
// The element may have unmounted since the highlight was drawn.
|
|
134
|
+
if (!this.target.isConnected) {
|
|
135
|
+
this.clear();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const rect = this.target.getBoundingClientRect();
|
|
139
|
+
Object.assign(this.overlay.style, {
|
|
140
|
+
top: `${rect.top - PADDING}px`,
|
|
141
|
+
left: `${rect.left - PADDING}px`,
|
|
142
|
+
width: `${rect.width + PADDING * 2}px`,
|
|
143
|
+
height: `${rect.height + PADDING * 2}px`,
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
/** Coalesced, because a MutationObserver can fire many times per render. */
|
|
147
|
+
reposition = () => {
|
|
148
|
+
if (this.frame)
|
|
149
|
+
return;
|
|
150
|
+
this.frame = requestAnimationFrame(() => {
|
|
151
|
+
this.frame = 0;
|
|
152
|
+
this.position();
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
/** Escape is the universal "get this off my screen". */
|
|
156
|
+
onKeyDown = (event) => {
|
|
157
|
+
if (event.key === "Escape")
|
|
158
|
+
this.clear();
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Any click outside the target dismisses.
|
|
162
|
+
*
|
|
163
|
+
* The overlay dims the whole page, so it reads as a modal — but it is
|
|
164
|
+
* `pointer-events: none`, so clicks reach the app underneath. Without this
|
|
165
|
+
* the user clicks away, the app responds, and the dim stays: it looks
|
|
166
|
+
* dismissible and is not. Clicks on the target itself are left alone, since
|
|
167
|
+
* that is the click the highlight is asking for and the app's own handler
|
|
168
|
+
* usually removes the highlight's reason for existing anyway.
|
|
169
|
+
*/
|
|
170
|
+
/**
|
|
171
|
+
* A click ends the highlight, with one exception that has an exception.
|
|
172
|
+
*
|
|
173
|
+
* Clicking away dismisses it: the user has moved on and a ring around
|
|
174
|
+
* something they are no longer looking at is clutter.
|
|
175
|
+
*
|
|
176
|
+
* Clicking *inside* the target does not, because the target is often an
|
|
177
|
+
* input the user has just been asked to fill — losing the marker the moment
|
|
178
|
+
* they click into the field would undo the pointing.
|
|
179
|
+
*
|
|
180
|
+
* But if the target is something clicking *activates* — a button, a link —
|
|
181
|
+
* then the click was the action, and the highlight has done its job. Without
|
|
182
|
+
* this the ring survives the thing it pointed at: the assistant highlighted
|
|
183
|
+
* "Receive Stock", the user clicked, the form opened, and the outline stayed
|
|
184
|
+
* behind the dialog pointing at a button nobody needed any more.
|
|
185
|
+
*/
|
|
186
|
+
onPointerDown = (event) => {
|
|
187
|
+
const node = event.target;
|
|
188
|
+
const inside = node instanceof Node && this.target?.contains(node);
|
|
189
|
+
if (inside && !activates(this.target))
|
|
190
|
+
return;
|
|
191
|
+
this.clear();
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Keep the overlay glued to its target, and remove it when the target goes.
|
|
195
|
+
*
|
|
196
|
+
* Scroll and resize are listened to rather than polled; `capture: true` on
|
|
197
|
+
* scroll catches scrolling inside containers, not just the window.
|
|
198
|
+
*
|
|
199
|
+
* The MutationObserver is what makes the overlay mortal. `position` already
|
|
200
|
+
* clears when the target has left the DOM, but it only ran on scroll and
|
|
201
|
+
* resize — so a highlighted element that unmounted while the page sat still
|
|
202
|
+
* (a form closing after submit, say) left the overlay stranded over the page
|
|
203
|
+
* with no way to dismiss it.
|
|
204
|
+
*/
|
|
205
|
+
startTracking() {
|
|
206
|
+
if (this.tracking)
|
|
207
|
+
return;
|
|
208
|
+
this.tracking = true;
|
|
209
|
+
window.addEventListener("scroll", this.position, { passive: true, capture: true });
|
|
210
|
+
window.addEventListener("resize", this.position, { passive: true });
|
|
211
|
+
window.addEventListener("keydown", this.onKeyDown);
|
|
212
|
+
// Capture, so the app's own handlers cannot stop it from reaching us.
|
|
213
|
+
window.addEventListener("pointerdown", this.onPointerDown, { capture: true });
|
|
214
|
+
this.observer = new MutationObserver(this.reposition);
|
|
215
|
+
this.observer.observe(document.body, { childList: true, subtree: true });
|
|
216
|
+
}
|
|
217
|
+
stopTracking() {
|
|
218
|
+
if (!this.tracking)
|
|
219
|
+
return;
|
|
220
|
+
this.tracking = false;
|
|
221
|
+
window.removeEventListener("scroll", this.position, { capture: true });
|
|
222
|
+
window.removeEventListener("resize", this.position);
|
|
223
|
+
window.removeEventListener("keydown", this.onKeyDown);
|
|
224
|
+
window.removeEventListener("pointerdown", this.onPointerDown, { capture: true });
|
|
225
|
+
this.observer?.disconnect();
|
|
226
|
+
this.observer = null;
|
|
227
|
+
if (this.frame) {
|
|
228
|
+
cancelAnimationFrame(this.frame);
|
|
229
|
+
this.frame = 0;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=highlight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight.js","sourceRoot":"","sources":["../../../js/src/highlight.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mihe-dev/js — an app-aware AI assistant for any web app (doc 08).
|
|
3
|
+
*
|
|
4
|
+
* Three things to wire up:
|
|
5
|
+
*
|
|
6
|
+
* 1. `createMihe({ url, publicKey, getUserToken, navigate })` once, at boot.
|
|
7
|
+
* 2. `mihe.setScreen(…)` on each page so the assistant knows where the user
|
|
8
|
+
* is, keeping the returned function for when they leave.
|
|
9
|
+
* 3. `mihe.registerComponent(…)` on the elements it should be able to point
|
|
10
|
+
* at, and `mihe.registerAction(…)` for anything it should be able to run.
|
|
11
|
+
*
|
|
12
|
+
* Then `mountWidget(mihe)` for the orb, or draw your own UI from
|
|
13
|
+
* `mihe.getState()`.
|
|
14
|
+
*
|
|
15
|
+
* The assistant reasons; your app executes. It can only navigate to screens
|
|
16
|
+
* you registered, point at components you declared, and run actions you
|
|
17
|
+
* handled — there is no path by which it drives your UI directly.
|
|
18
|
+
*/
|
|
19
|
+
export { Mihe, createMihe, SDK_VERSION, ASSISTANT_PANEL_ID } from "./mihe.js";
|
|
20
|
+
export type { ChatMessage, MiheOptions, MiheState, VoiceControls } from "./mihe.js";
|
|
21
|
+
export { chartDeclaration, chartSignature, tableDeclaration, tableSignature, tabsDeclaration, tabsSignature, } from "./declarations.js";
|
|
22
|
+
export type { AssistantChart, AssistantQueryParam, AssistantTable, AssistantTableColumn, AssistantTableQuery, AssistantTabs, } from "./declarations.js";
|
|
23
|
+
export { mountWidget, defineMiheAssistant, ELEMENT_NAME } from "./widget/element.js";
|
|
24
|
+
export type { MiheAssistantElement, MountedWidget, WidgetOptions } from "./widget/element.js";
|
|
25
|
+
export { formatValue, humanizeKey } from "./widget/format.js";
|
|
26
|
+
export { appView, fillSummary, formatField, hintedView, DESCRIBE_TIMEOUT_MS } from "./card-view.js";
|
|
27
|
+
export type { CardLine, CardView, DescribeProposal, ProposalDescription } from "./card-view.js";
|
|
28
|
+
export { VoiceSession, voiceUrl } from "./voice.js";
|
|
29
|
+
export type { VoiceEvent, VoiceState, VoiceSessionOptions } from "./voice.js";
|
|
30
|
+
export { MicrophoneCapture, SpeakerQueue, toPcm16, fromPcm16 } from "./audio.js";
|
|
31
|
+
export { AssistantStore } from "./store.js";
|
|
32
|
+
export type { ActionHandler, ComponentDeclaration, ScreenDeclaration, ChartDeclaration, TableDeclaration, TableRow, ViewControlDeclaration, } from "./store.js";
|
|
33
|
+
export { AssistantClient } from "./client.js";
|
|
34
|
+
export type { ClientEvent, ClientOptions, ConnectionState, ProposalPayload, } from "./client.js";
|
|
35
|
+
export { executeCommand } from "./commands.js";
|
|
36
|
+
export type { CommandContext, CommandResult } from "./commands.js";
|
|
37
|
+
export { formatContextReport } from "./debug.js";
|
|
38
|
+
export type { ContextReport } from "./debug.js";
|
|
39
|
+
export { HighlightEngine, COMPONENT_ATTRIBUTE } from "./highlight.js";
|
|
40
|
+
export { PROTOCOL_VERSION, VOICE_SAMPLE_RATE } from "@mihe-dev/protocol";
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../js/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC3E,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEjF,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,GACd,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAClF,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACjG,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAE7F,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE3E,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,sBAAsB,GACvB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,YAAY,EACV,WAAW,EACX,aAAa,EACb,eAAe,EACf,eAAe,GAChB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mihe-dev/js — an app-aware AI assistant for any web app (doc 08).
|
|
3
|
+
*
|
|
4
|
+
* Three things to wire up:
|
|
5
|
+
*
|
|
6
|
+
* 1. `createMihe({ url, publicKey, getUserToken, navigate })` once, at boot.
|
|
7
|
+
* 2. `mihe.setScreen(…)` on each page so the assistant knows where the user
|
|
8
|
+
* is, keeping the returned function for when they leave.
|
|
9
|
+
* 3. `mihe.registerComponent(…)` on the elements it should be able to point
|
|
10
|
+
* at, and `mihe.registerAction(…)` for anything it should be able to run.
|
|
11
|
+
*
|
|
12
|
+
* Then `mountWidget(mihe)` for the orb, or draw your own UI from
|
|
13
|
+
* `mihe.getState()`.
|
|
14
|
+
*
|
|
15
|
+
* The assistant reasons; your app executes. It can only navigate to screens
|
|
16
|
+
* you registered, point at components you declared, and run actions you
|
|
17
|
+
* handled — there is no path by which it drives your UI directly.
|
|
18
|
+
*/
|
|
19
|
+
export { Mihe, createMihe, SDK_VERSION, ASSISTANT_PANEL_ID } from "./mihe.js";
|
|
20
|
+
export { chartDeclaration, chartSignature, tableDeclaration, tableSignature, tabsDeclaration, tabsSignature, } from "./declarations.js";
|
|
21
|
+
export { mountWidget, defineMiheAssistant, ELEMENT_NAME } from "./widget/element.js";
|
|
22
|
+
export { formatValue, humanizeKey } from "./widget/format.js";
|
|
23
|
+
export { appView, fillSummary, formatField, hintedView, DESCRIBE_TIMEOUT_MS } from "./card-view.js";
|
|
24
|
+
export { VoiceSession, voiceUrl } from "./voice.js";
|
|
25
|
+
export { MicrophoneCapture, SpeakerQueue, toPcm16, fromPcm16 } from "./audio.js";
|
|
26
|
+
export { AssistantStore } from "./store.js";
|
|
27
|
+
export { AssistantClient } from "./client.js";
|
|
28
|
+
export { executeCommand } from "./commands.js";
|
|
29
|
+
export { formatContextReport } from "./debug.js";
|
|
30
|
+
export { HighlightEngine, COMPONENT_ATTRIBUTE } from "./highlight.js";
|
|
31
|
+
export { PROTOCOL_VERSION, VOICE_SAMPLE_RATE } from "@mihe-dev/protocol";
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../js/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAG3E,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,aAAa,GACd,MAAM,gBAAgB,CAAC;AAUxB,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAElF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGjG,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGjD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9E,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAWzC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAQ3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|