flexdesk 0.17.17 → 0.18.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/CHANGELOG.md +70 -0
- package/LICENSE +0 -0
- package/README.md +1 -0
- package/THIRD_PARTY_LICENSES.md +0 -0
- package/canvas.js +0 -0
- package/charts.js +0 -0
- package/core.js +0 -0
- package/css/flexdesk.css +7499 -5851
- package/css/reset.css +1 -1
- package/css/tokens.css +23 -1
- package/dist/canvas.js +0 -0
- package/dist/canvas.js.map +0 -0
- package/dist/charts.js +10 -6
- package/dist/charts.js.map +1 -1
- package/dist/chunk-3PHCPZHT.js +0 -0
- package/dist/chunk-3PHCPZHT.js.map +0 -0
- package/dist/chunk-5W4EEKSK.js +778 -0
- package/dist/chunk-5W4EEKSK.js.map +7 -0
- package/dist/chunk-DNJ3N4T4.js +82 -0
- package/dist/chunk-DNJ3N4T4.js.map +7 -0
- package/dist/chunk-FOOS3T5L.js +0 -0
- package/dist/chunk-FOOS3T5L.js.map +0 -0
- package/dist/chunk-GOQLR5WR.js +0 -0
- package/dist/chunk-GOQLR5WR.js.map +0 -0
- package/dist/{chunk-JKZLNKG6.js → chunk-HKPB6OFA.js} +90 -25
- package/dist/{chunk-JKZLNKG6.js.map → chunk-HKPB6OFA.js.map} +2 -2
- package/dist/chunk-HNU6MM2B.js +0 -0
- package/dist/chunk-HNU6MM2B.js.map +0 -0
- package/dist/{chunk-REJ5HLIM.js → chunk-HYJYYEPK.js} +2 -2
- package/dist/chunk-JYWURG5T.js +0 -0
- package/dist/chunk-JYWURG5T.js.map +0 -0
- package/dist/{chunk-7U4IB65H.js → chunk-LLBJ2SJH.js} +5 -3
- package/dist/{chunk-7U4IB65H.js.map → chunk-LLBJ2SJH.js.map} +1 -1
- package/dist/chunk-N7HC3ADV.js +0 -0
- package/dist/chunk-N7HC3ADV.js.map +0 -0
- package/dist/{chunk-7OL6F2AM.js → chunk-P74F6I6P.js} +6 -4
- package/dist/{chunk-7OL6F2AM.js.map → chunk-P74F6I6P.js.map} +1 -1
- package/dist/chunk-PAI2ZUWV.js +260 -0
- package/dist/chunk-PAI2ZUWV.js.map +7 -0
- package/dist/chunk-Q7BALEPX.js +527 -0
- package/dist/chunk-Q7BALEPX.js.map +7 -0
- package/dist/chunk-QXAOTGCC.js +40 -0
- package/dist/chunk-QXAOTGCC.js.map +7 -0
- package/dist/{chunk-XJNADRGR.js → chunk-RKVYIXDC.js} +664 -91
- package/dist/chunk-RKVYIXDC.js.map +7 -0
- package/dist/{chunk-2Z2ENHR3.js → chunk-U5GKJUOC.js} +3 -3
- package/dist/{chunk-2Z2ENHR3.js.map → chunk-U5GKJUOC.js.map} +1 -1
- package/dist/chunk-UKP22RUG.js +219 -0
- package/dist/chunk-UKP22RUG.js.map +7 -0
- package/dist/chunk-VLOAI3HS.js +43 -0
- package/dist/chunk-VLOAI3HS.js.map +7 -0
- package/dist/{chunk-WUFLGETN.js → chunk-WVFGV5FT.js} +2 -39
- package/dist/{chunk-WUFLGETN.js.map → chunk-WVFGV5FT.js.map} +3 -3
- package/dist/{chunk-PGZ4EHSE.js → chunk-ZL3VKINP.js} +41 -390
- package/dist/chunk-ZL3VKINP.js.map +7 -0
- package/dist/editor.js +3 -2
- package/dist/editor.js.map +1 -1
- package/dist/flexdesk.css +7499 -5851
- package/dist/flow.js +29 -97
- package/dist/flow.js.map +3 -3
- package/dist/git.js +1356 -0
- package/dist/git.js.map +7 -0
- package/dist/host.js +0 -0
- package/dist/host.js.map +0 -0
- package/dist/reset.css +1 -1
- package/dist/tile_registry-6WZPTUZV.js +0 -0
- package/dist/tile_registry-6WZPTUZV.js.map +0 -0
- package/dist/tiles.js +20 -15
- package/dist/tiles.js.map +2 -2
- package/dist/tokens.css +23 -1
- package/dist/widgets.js +3969 -1189
- package/dist/widgets.js.map +4 -4
- package/dist/wm.js +121 -33
- package/dist/wm.js.map +2 -2
- package/docs/README.md +9 -4
- package/docs/best-practices.md +2 -2
- package/docs/components/chat-shell.md +198 -0
- package/docs/components/command-palette.md +0 -0
- package/docs/components/conversation.md +10 -0
- package/docs/components/data-table-grid.md +0 -0
- package/docs/components/data-table.md +0 -0
- package/docs/components/editor.md +0 -0
- package/docs/components/filter-builder.md +246 -0
- package/docs/components/flow-canvas-editor.md +0 -0
- package/docs/components/flow-editors.md +0 -0
- package/docs/components/flow-lane-editor.md +0 -0
- package/docs/components/flow-outline-editor.md +0 -0
- package/docs/components/forms-and-dialogs.md +22 -0
- package/docs/components/git.md +355 -0
- package/docs/components/input-fields.md +167 -2
- package/docs/components/keymap.md +8 -0
- package/docs/components/markdown-and-outline.md +0 -0
- package/docs/components/menus.md +120 -3
- package/docs/components/panels-and-desktops.md +16 -5
- package/docs/components/record-list-and-fact-table.md +0 -0
- package/docs/components/settings-view.md +0 -0
- package/docs/components/shell.md +104 -1
- package/docs/components/wizard.md +0 -0
- package/docs/components/workspace-picker.md +149 -0
- package/docs/concepts/building-and-packaging.md +2 -2
- package/docs/concepts/domain-neutrality.md +0 -0
- package/docs/concepts/host-port.md +0 -0
- package/docs/concepts/packages-and-entry-points.md +14 -13
- package/docs/concepts/peer-dependencies.md +0 -0
- package/docs/concepts/state-guard.md +3 -3
- package/docs/quickstart.md +1 -1
- package/editor.js +0 -0
- package/flow.js +0 -0
- package/git.js +13 -0
- package/host.js +0 -0
- package/package.json +6 -1
- package/src/canvas/canvas_adapter.js +0 -0
- package/src/canvas/edge_router.js +0 -0
- package/src/canvas/graph/connector_router.js +0 -0
- package/src/canvas/graph/history_service.js +0 -0
- package/src/canvas/graph/node_platform.js +0 -0
- package/src/canvas/index.js +0 -0
- package/src/canvas/layered_layout.js +0 -0
- package/src/charts/data_series_plot_window.js +0 -0
- package/src/charts/downsample.js +0 -0
- package/src/charts/plot_config.js +0 -0
- package/src/charts/plotly_wrapper.js +0 -0
- package/src/core/event_bus.js +0 -0
- package/src/core/logging.js +0 -0
- package/src/core/settings.js +0 -0
- package/src/core/state_guard.js +0 -0
- package/src/core/state_machine.js +0 -0
- package/src/editor/editor_pane.js +0 -0
- package/src/editor/monaco_editor_factory.js +0 -0
- package/src/editor/monaco_loader.js +0 -0
- package/src/editor/notebook_search.js +0 -0
- package/src/editor/notebook_undo_manager.js +0 -0
- package/src/editor/split_pane_container.js +0 -0
- package/src/flow/canvas_editor/connections.js +0 -0
- package/src/flow/canvas_editor/editor.js +0 -0
- package/src/flow/canvas_editor/index.js +0 -0
- package/src/flow/canvas_editor/layout.js +0 -0
- package/src/flow/canvas_editor/strings.js +0 -0
- package/src/flow/kit/always_before.js +0 -0
- package/src/flow/kit/catalogue.js +0 -0
- package/src/flow/kit/chip_input.js +0 -0
- package/src/flow/kit/dom.js +28 -119
- package/src/flow/kit/findings.js +0 -0
- package/src/flow/kit/history.js +0 -0
- package/src/flow/kit/index.js +0 -0
- package/src/flow/kit/keys.js +0 -0
- package/src/flow/kit/logic_graph.js +0 -0
- package/src/flow/kit/references.js +0 -0
- package/src/flow/kit/settings_panel.js +0 -0
- package/src/flow/kit/settings_schema.js +0 -0
- package/src/flow/kit/step_picker.js +1 -1
- package/src/flow/kit/strings.js +0 -0
- package/src/flow/kit/value_picker.js +1 -1
- package/src/flow/kit/widgets.js +0 -0
- package/src/flow/lanes/editor.js +0 -0
- package/src/flow/lanes/index.js +0 -0
- package/src/flow/lanes/layout.js +0 -0
- package/src/flow/lanes/pipeline.js +0 -0
- package/src/flow/lanes/preview.js +0 -0
- package/src/flow/lanes/strings.js +0 -0
- package/src/flow/outline/editor.js +0 -0
- package/src/flow/outline/index.js +0 -0
- package/src/flow/outline/mapping.js +0 -0
- package/src/flow/outline/menu.js +1 -1
- package/src/flow/outline/operations.js +0 -0
- package/src/flow/outline/recognise.js +0 -0
- package/src/flow/outline/strings.js +0 -0
- package/src/git/diff_viewer.js +212 -0
- package/src/git/diff_window.js +51 -0
- package/src/git/git_graph.js +401 -0
- package/src/git/git_ops.js +61 -0
- package/src/git/git_panel.js +755 -0
- package/src/git/index.js +9 -0
- package/src/git/line_diff.js +202 -0
- package/src/help/help_modal.js +0 -0
- package/src/help/help_registry.js +0 -0
- package/src/host/external_links.js +0 -0
- package/src/host/file_picker.js +0 -0
- package/src/host/host.js +0 -0
- package/src/host/photino_host.js +0 -0
- package/src/host/photino_host.md +0 -0
- package/src/host/pywebview_host.js +0 -0
- package/src/tiles/chart_tiles.js +0 -0
- package/src/tiles/config_schema.js +0 -0
- package/src/tiles/figure_tile.js +0 -0
- package/src/tiles/layout_persistence.js +0 -0
- package/src/tiles/list_tiles.js +0 -0
- package/src/tiles/scope_picker.js +0 -0
- package/src/tiles/tile_base.js +5 -4
- package/src/tiles/tile_config_form.js +0 -0
- package/src/tiles/tile_registry.js +0 -0
- package/src/tiling/bottom_panel_tabs.js +0 -0
- package/src/tiling/command_palette.js +0 -0
- package/src/tiling/content_registry.js +0 -0
- package/src/tiling/desktops.js +10 -8
- package/src/tiling/entity_sources.js +0 -0
- package/src/tiling/keymap.js +6 -5
- package/src/tiling/kind_taxonomy.js +15 -2
- package/src/tiling/landing_table.js +0 -0
- package/src/tiling/loading_overlay.js +0 -0
- package/src/tiling/nav_panel.js +0 -0
- package/src/tiling/page_factory.js +0 -0
- package/src/tiling/panel_availability.js +0 -0
- package/src/tiling/panel_keys.js +0 -0
- package/src/tiling/shell.js +124 -17
- package/src/tiling/tab_strip.js +0 -0
- package/src/tiling/tile_renderer.js +2 -3
- package/src/tiling/tile_tab_menu.js +0 -0
- package/src/tiling/zoom.js +0 -0
- package/src/ui/base/component_base.js +0 -0
- package/src/ui/base/controller_base.js +0 -0
- package/src/ui/base/page_base.js +0 -0
- package/src/ui/components/about_dialog.js +0 -0
- package/src/ui/components/action_dropdown.js +4 -78
- package/src/ui/components/alert_log.js +0 -0
- package/src/ui/components/alerts_pane.js +0 -0
- package/src/ui/components/anchored_layer.js +255 -0
- package/src/ui/components/attribute_list_editor.js +0 -0
- package/src/ui/components/autocomplete_field.js +0 -0
- package/src/ui/components/cell_editor_host.js +0 -0
- package/src/ui/components/cell_editors.js +0 -0
- package/src/ui/components/cell_grid.js +0 -0
- package/src/ui/components/cell_paste.js +0 -0
- package/src/ui/components/cell_selection.js +0 -0
- package/src/ui/components/chat_shell.js +920 -0
- package/src/ui/components/chat_state_machine.js +223 -0
- package/src/ui/components/choice_controls.js +45 -2
- package/src/ui/components/color_field.js +3 -2
- package/src/ui/components/color_list_field.js +3 -2
- package/src/ui/components/column_fit.js +0 -0
- package/src/ui/components/column_groups.js +0 -0
- package/src/ui/components/column_order.js +0 -0
- package/src/ui/components/combobox.js +422 -0
- package/src/ui/components/conversation_view.js +17 -2
- package/src/ui/components/crosstab.js +0 -0
- package/src/ui/components/data_table.js +2 -2
- package/src/ui/components/detail_header.js +0 -0
- package/src/ui/components/document_outline.js +0 -0
- package/src/ui/components/drag_reorder.js +0 -0
- package/src/ui/components/fact_table.js +0 -0
- package/src/ui/components/fill_handle.js +0 -0
- package/src/ui/components/filter_builder.js +766 -0
- package/src/ui/components/filter_model.js +614 -0
- package/src/ui/components/gallery_picker.js +0 -0
- package/src/ui/components/header_actions.js +0 -0
- package/src/ui/components/inline_renamer.js +0 -0
- package/src/ui/components/job_progress.js +0 -0
- package/src/ui/components/managed_window.js +24 -47
- package/src/ui/components/menu_bar.js +101 -24
- package/src/ui/components/modal.js +79 -109
- package/src/ui/components/option_list.js +160 -0
- package/src/ui/components/popover.js +94 -0
- package/src/ui/components/progress.js +0 -0
- package/src/ui/components/recent_items.js +169 -0
- package/src/ui/components/record_list.js +0 -0
- package/src/ui/components/row_activation.js +0 -0
- package/src/ui/components/section_stack.js +0 -0
- package/src/ui/components/select.js +322 -0
- package/src/ui/components/series.js +0 -0
- package/src/ui/components/settings_view.js +0 -0
- package/src/ui/components/slide_out_panel.js +0 -0
- package/src/ui/components/slider_field.js +0 -0
- package/src/ui/components/sortable_list.js +0 -0
- package/src/ui/components/staged_edits.js +0 -0
- package/src/ui/components/staged_history.js +0 -0
- package/src/ui/components/table_filter_chips.js +0 -0
- package/src/ui/components/table_state_store.js +0 -0
- package/src/ui/components/table_structure.js +0 -0
- package/src/ui/components/table_values.js +0 -0
- package/src/ui/components/tabs.js +0 -0
- package/src/ui/components/tag_input.js +77 -8
- package/src/ui/components/toast.js +0 -0
- package/src/ui/components/toggle_field.js +0 -0
- package/src/ui/components/tsv.js +0 -0
- package/src/ui/components/window_taskbar.js +0 -0
- package/src/ui/components/workspace_picker.js +1155 -0
- package/src/ui/controllers/window_chrome_controller.js +4 -1
- package/src/ui/utils/auto_scrollbars.js +0 -0
- package/src/ui/utils/fire_event.js +17 -0
- package/src/ui/utils/focusable.js +25 -0
- package/src/ui/utils/markdown.js +0 -0
- package/src/ui/utils/modal_host.js +27 -0
- package/src/ui/utils/native_context_menu.js +0 -0
- package/src/ui/utils/overlay_scrollbar.js +0 -0
- package/src/ui/utils/raf_resize_observer.js +0 -0
- package/src/ui/utils/scroll_lock.js +0 -0
- package/src/ui/utils/strip_scroll.js +0 -0
- package/src/ui/utils/tooltip_service.js +0 -0
- package/tiles.js +0 -0
- package/widgets.js +12 -2
- package/wm.js +0 -0
- package/css/base.css +0 -10527
- package/css/overrides.css +0 -2596
- package/dist/chunk-7JI7HHSY.js +0 -107
- package/dist/chunk-7JI7HHSY.js.map +0 -7
- package/dist/chunk-MIW7D6WC.js +0 -526
- package/dist/chunk-MIW7D6WC.js.map +0 -7
- package/dist/chunk-PGZ4EHSE.js.map +0 -7
- package/dist/chunk-XJNADRGR.js.map +0 -7
- /package/dist/{chunk-REJ5HLIM.js.map → chunk-HYJYYEPK.js.map} +0 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ══ THE CONVERSATION STATE MACHINE ════════════════════════════════════════
|
|
3
|
+
*
|
|
4
|
+
* The lifecycle of one assistant conversation, with no view and no transport in
|
|
5
|
+
* it. `mountChatShell` (`./chat_shell.js`) drives one; a chat of your own can
|
|
6
|
+
* too.
|
|
7
|
+
*
|
|
8
|
+
* idle ──send──▶ waiting ──streamStart──▶ streaming ──streamComplete──▶ idle
|
|
9
|
+
* └─ streamComplete ▶ idle ├─ cancel ▶ idle
|
|
10
|
+
* └─ cancel ▶ idle └─ error ▶ error
|
|
11
|
+
* └─ error ▶ error
|
|
12
|
+
* error ──send──▶ waiting error ──reset──▶ idle
|
|
13
|
+
*
|
|
14
|
+
* TRANSITIONS ARE QUEUED. `StateMachine` (`../../core/state_machine.js`) is
|
|
15
|
+
* asynchronous and refuses a transition that arrives during another. Text can
|
|
16
|
+
* arrive in the same tick as the request that asked for it, so every call here
|
|
17
|
+
* waits for the one before it, in call order, and answers a promise of
|
|
18
|
+
* `{ transitioned, reason? }`. `getState()` therefore lags a call by some
|
|
19
|
+
* microtasks; `settled()` resolves when the queue is empty, and `getState()` is
|
|
20
|
+
* `null` until the machine has entered `idle`. A transition the current state
|
|
21
|
+
* does not have is refused, not thrown.
|
|
22
|
+
*
|
|
23
|
+
* OBSERVERS: `onChange({ state, conversationId, mode })` hears every state
|
|
24
|
+
* entered. With an `eventBus`, the same goes out as `CHAT_BUS_EVENTS.STATE_CHANGED`
|
|
25
|
+
* along with the others below.
|
|
26
|
+
*
|
|
27
|
+
* THE MODE is an opaque string of the caller's (`null` for none): it is kept
|
|
28
|
+
* and handed back, and means nothing here.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { StateMachine } from '../../core/state_machine.js';
|
|
32
|
+
|
|
33
|
+
export const CHAT_STATES = Object.freeze({
|
|
34
|
+
IDLE: 'idle',
|
|
35
|
+
WAITING: 'waiting',
|
|
36
|
+
STREAMING: 'streaming',
|
|
37
|
+
ERROR: 'error',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export const CHAT_TRANSITIONS = Object.freeze({
|
|
41
|
+
SEND: 'chat:message:send',
|
|
42
|
+
STREAM_START: 'chat:stream:start',
|
|
43
|
+
STREAM_COMPLETE: 'chat:stream:complete',
|
|
44
|
+
CANCEL: 'chat:cancel',
|
|
45
|
+
ERROR: 'chat:error',
|
|
46
|
+
RESET: 'chat:reset',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export const CHAT_BUS_EVENTS = Object.freeze({
|
|
50
|
+
STATE_CHANGED: 'chat:state:changed',
|
|
51
|
+
MESSAGE_SENT: 'chat:message:sent',
|
|
52
|
+
STREAM_COMPLETE: 'chat:stream:completed',
|
|
53
|
+
MODE_CHANGED: 'chat:mode:changed',
|
|
54
|
+
CONVERSATION_NEW: 'chat:conversation:new',
|
|
55
|
+
CONVERSATION_LOADED: 'chat:conversation:loaded',
|
|
56
|
+
ERROR: 'chat:error:raised',
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export class ChatStateMachine {
|
|
60
|
+
#machine;
|
|
61
|
+
#eventBus;
|
|
62
|
+
#onChange;
|
|
63
|
+
#queue = Promise.resolve();
|
|
64
|
+
#conversationId = null;
|
|
65
|
+
#mode;
|
|
66
|
+
#lastError = null;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @param {object} [deps]
|
|
70
|
+
* @param {object} [deps.eventBus] gets `CHAT_BUS_EVENTS`
|
|
71
|
+
* @param {object} [deps.logger]
|
|
72
|
+
* @param {?string} [deps.mode] the mode to start in
|
|
73
|
+
* @param {Function} [deps.onChange] `({ state, conversationId, mode })` on every state entered
|
|
74
|
+
*/
|
|
75
|
+
constructor({ eventBus = null, logger = null, mode = null, onChange = null } = {}) {
|
|
76
|
+
this.#eventBus = eventBus;
|
|
77
|
+
this.#onChange = onChange;
|
|
78
|
+
this.#mode = mode;
|
|
79
|
+
|
|
80
|
+
const entered = () => this.#entered();
|
|
81
|
+
const send = {
|
|
82
|
+
target: CHAT_STATES.WAITING,
|
|
83
|
+
guard: (ctx) => !!ctx.payload?.message,
|
|
84
|
+
action: (ctx) => this.#messageSent(ctx.payload),
|
|
85
|
+
};
|
|
86
|
+
const inFlight = {
|
|
87
|
+
[CHAT_TRANSITIONS.STREAM_COMPLETE]: {
|
|
88
|
+
target: CHAT_STATES.IDLE,
|
|
89
|
+
action: (ctx) => this.#emit(CHAT_BUS_EVENTS.STREAM_COMPLETE, {
|
|
90
|
+
conversationId: this.#conversationId, ...ctx.payload,
|
|
91
|
+
}),
|
|
92
|
+
},
|
|
93
|
+
[CHAT_TRANSITIONS.CANCEL]: { target: CHAT_STATES.IDLE },
|
|
94
|
+
[CHAT_TRANSITIONS.ERROR]: {
|
|
95
|
+
target: CHAT_STATES.ERROR,
|
|
96
|
+
action: (ctx) => this.#failed(ctx.payload),
|
|
97
|
+
},
|
|
98
|
+
[CHAT_TRANSITIONS.RESET]: { target: CHAT_STATES.IDLE },
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
this.#machine = new StateMachine({
|
|
102
|
+
name: 'chat',
|
|
103
|
+
initialState: CHAT_STATES.IDLE,
|
|
104
|
+
eventBus,
|
|
105
|
+
logger,
|
|
106
|
+
states: {
|
|
107
|
+
[CHAT_STATES.IDLE]: {
|
|
108
|
+
onEnter: () => {
|
|
109
|
+
this.#lastError = null;
|
|
110
|
+
entered();
|
|
111
|
+
},
|
|
112
|
+
transitions: { [CHAT_TRANSITIONS.SEND]: send },
|
|
113
|
+
},
|
|
114
|
+
[CHAT_STATES.WAITING]: {
|
|
115
|
+
onEnter: entered,
|
|
116
|
+
transitions: {
|
|
117
|
+
[CHAT_TRANSITIONS.STREAM_START]: { target: CHAT_STATES.STREAMING },
|
|
118
|
+
...inFlight,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
[CHAT_STATES.STREAMING]: { onEnter: entered, transitions: inFlight },
|
|
122
|
+
[CHAT_STATES.ERROR]: {
|
|
123
|
+
onEnter: entered,
|
|
124
|
+
transitions: {
|
|
125
|
+
[CHAT_TRANSITIONS.RESET]: { target: CHAT_STATES.IDLE },
|
|
126
|
+
[CHAT_TRANSITIONS.SEND]: send,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
getState() { return this.#machine.getState(); }
|
|
134
|
+
|
|
135
|
+
get conversationId() { return this.#conversationId; }
|
|
136
|
+
set conversationId(id) { this.#conversationId = id ?? null; }
|
|
137
|
+
|
|
138
|
+
get mode() { return this.#mode; }
|
|
139
|
+
get lastError() { return this.#lastError; }
|
|
140
|
+
|
|
141
|
+
setMode(mode) {
|
|
142
|
+
this.#mode = mode;
|
|
143
|
+
this.#emit(CHAT_BUS_EVENTS.MODE_CHANGED, { mode });
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** Resolves when every call so far has taken effect. */
|
|
147
|
+
settled() { return this.#queue; }
|
|
148
|
+
|
|
149
|
+
sendMessage(message, conversationId = this.#conversationId) {
|
|
150
|
+
this.#conversationId = conversationId ?? null;
|
|
151
|
+
return this.#transition(CHAT_TRANSITIONS.SEND, { message });
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
streamStart() { return this.#transition(CHAT_TRANSITIONS.STREAM_START); }
|
|
155
|
+
|
|
156
|
+
/** @param {object} [payload] goes out with `CHAT_BUS_EVENTS.STREAM_COMPLETE` */
|
|
157
|
+
streamComplete(payload = {}) { return this.#transition(CHAT_TRANSITIONS.STREAM_COMPLETE, payload); }
|
|
158
|
+
|
|
159
|
+
cancel() { return this.#transition(CHAT_TRANSITIONS.CANCEL); }
|
|
160
|
+
|
|
161
|
+
error(message, detail = null) { return this.#transition(CHAT_TRANSITIONS.ERROR, { message, detail }); }
|
|
162
|
+
|
|
163
|
+
reset() { return this.#transition(CHAT_TRANSITIONS.RESET); }
|
|
164
|
+
|
|
165
|
+
/** Back to idle with no conversation, whatever the state. */
|
|
166
|
+
newConversation() {
|
|
167
|
+
this.#conversationId = null;
|
|
168
|
+
return this.#enqueue(async () => {
|
|
169
|
+
await this.#machine.reset(CHAT_STATES.IDLE);
|
|
170
|
+
this.#emit(CHAT_BUS_EVENTS.CONVERSATION_NEW, {});
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Back to idle on a kept conversation, whatever the state. */
|
|
175
|
+
loadConversation(conversationId) {
|
|
176
|
+
this.#conversationId = conversationId ?? null;
|
|
177
|
+
return this.#enqueue(async () => {
|
|
178
|
+
await this.#machine.reset(CHAT_STATES.IDLE);
|
|
179
|
+
this.#emit(CHAT_BUS_EVENTS.CONVERSATION_LOADED, { conversationId });
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
canSend() {
|
|
184
|
+
const state = this.getState();
|
|
185
|
+
return state === CHAT_STATES.IDLE || state === CHAT_STATES.ERROR;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
isProcessing() {
|
|
189
|
+
const state = this.getState();
|
|
190
|
+
return state === CHAT_STATES.WAITING || state === CHAT_STATES.STREAMING;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
#transition(event, payload) {
|
|
194
|
+
return this.#enqueue(() => this.#machine.transition(event, payload));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** One step after the last; a step that fails rejects its own promise and not the next one's. */
|
|
198
|
+
#enqueue(step) {
|
|
199
|
+
const run = this.#queue.then(step);
|
|
200
|
+
this.#queue = run.then(() => undefined, () => undefined);
|
|
201
|
+
return run;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
#messageSent({ message }) {
|
|
205
|
+
this.#lastError = null;
|
|
206
|
+
this.#emit(CHAT_BUS_EVENTS.MESSAGE_SENT, {
|
|
207
|
+
conversationId: this.#conversationId, text: message, mode: this.#mode,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
#failed({ message, detail }) {
|
|
212
|
+
this.#lastError = message;
|
|
213
|
+
this.#emit(CHAT_BUS_EVENTS.ERROR, { conversationId: this.#conversationId, message, detail });
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
#entered() {
|
|
217
|
+
const change = { state: this.getState(), conversationId: this.#conversationId, mode: this.#mode };
|
|
218
|
+
this.#onChange?.(change);
|
|
219
|
+
this.#emit(CHAT_BUS_EVENTS.STATE_CHANGED, change);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
#emit(name, payload) { this.#eventBus?.emit(name, payload); }
|
|
223
|
+
}
|
|
@@ -47,10 +47,15 @@ function el(tag, className, text) {
|
|
|
47
47
|
|
|
48
48
|
const isGroup = (o) => o !== null && typeof o === 'object' && Array.isArray(o.options) && 'group' in o;
|
|
49
49
|
|
|
50
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* One option, normalised: `{value, label, description, disabled, reason, icon, hint,
|
|
52
|
+
* keywords, source}`. `icon`, `hint` and `keywords` are the DOM-drawn select's and
|
|
53
|
+
* combobox's; `source` is the entry as it was given, handed back when one is chosen.
|
|
54
|
+
*/
|
|
51
55
|
function choiceOption(o) {
|
|
52
56
|
if (o === null || typeof o !== 'object') {
|
|
53
|
-
return { value: o, label: shownValue(o), description: null, disabled: false, reason: null
|
|
57
|
+
return { value: o, label: shownValue(o), description: null, disabled: false, reason: null, icon: null,
|
|
58
|
+
hint: null, keywords: null, source: o };
|
|
54
59
|
}
|
|
55
60
|
return {
|
|
56
61
|
value: o.value,
|
|
@@ -58,6 +63,10 @@ function choiceOption(o) {
|
|
|
58
63
|
description: o.description != null ? String(o.description) : null,
|
|
59
64
|
disabled: Boolean(o.disabled),
|
|
60
65
|
reason: o.reason != null && o.reason !== '' ? String(o.reason) : null,
|
|
66
|
+
icon: o.icon ? String(o.icon) : null,
|
|
67
|
+
hint: o.hint != null && o.hint !== '' ? String(o.hint) : null,
|
|
68
|
+
keywords: o.keywords != null ? String(o.keywords) : null,
|
|
69
|
+
source: o,
|
|
61
70
|
};
|
|
62
71
|
}
|
|
63
72
|
|
|
@@ -71,6 +80,40 @@ export function flatChoices(options) {
|
|
|
71
80
|
return out;
|
|
72
81
|
}
|
|
73
82
|
|
|
83
|
+
/**
|
|
84
|
+
* A list as the sections it draws in, in order: `[{ heading, items }]`, `heading`
|
|
85
|
+
* null for a run of options outside any group, `items` normalised. A group with no
|
|
86
|
+
* options is left out.
|
|
87
|
+
*/
|
|
88
|
+
export function choiceSections(options) {
|
|
89
|
+
const out = [];
|
|
90
|
+
for (const o of options || []) {
|
|
91
|
+
if (isGroup(o)) {
|
|
92
|
+
if (o.options.length) out.push({ heading: String(o.group ?? ''), items: o.options.map(choiceOption) });
|
|
93
|
+
} else if (out.length && out[out.length - 1].heading === null) {
|
|
94
|
+
out[out.length - 1].items.push(choiceOption(o));
|
|
95
|
+
} else {
|
|
96
|
+
out.push({ heading: null, items: [choiceOption(o)] });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Does `text` occur, ignoring case, in the option's label, value, description or keywords? */
|
|
103
|
+
export function optionMatches(option, text) {
|
|
104
|
+
const needle = String(text ?? '').trim().toLowerCase();
|
|
105
|
+
if (!needle) return true;
|
|
106
|
+
return [option.label, shownValue(option.value), option.description, option.keywords]
|
|
107
|
+
.some((part) => String(part ?? '').toLowerCase().includes(needle));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** `sections` with only the options `text` matches; a section left empty goes. */
|
|
111
|
+
export function filterSections(sections, text) {
|
|
112
|
+
return sections
|
|
113
|
+
.map((s) => ({ heading: s.heading, items: s.items.filter((o) => optionMatches(o, text)) }))
|
|
114
|
+
.filter((s) => s.items.length);
|
|
115
|
+
}
|
|
116
|
+
|
|
74
117
|
/**
|
|
75
118
|
* Where the chips and the radio list draw a group heading: the position in
|
|
76
119
|
* the flattened list of each non-empty group's first option, to its heading.
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
* the box's `change` (blur, Enter, a preset, the picker closing) with
|
|
29
29
|
* `commit: true`.
|
|
30
30
|
*/
|
|
31
|
+
import { fireEvent } from '../utils/fire_event.js';
|
|
31
32
|
|
|
32
33
|
const HEX_RE = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
|
|
33
34
|
const RGB_RE = /^rgba?\(\s*([^)]*)\)$/i;
|
|
@@ -197,8 +198,8 @@ export class ColorField {
|
|
|
197
198
|
/** Put `text` in the box and fire the box's own events, as typing would. */
|
|
198
199
|
#writeBox(text, commit) {
|
|
199
200
|
this.hex.value = text;
|
|
200
|
-
this.hex
|
|
201
|
-
if (commit) this.hex
|
|
201
|
+
fireEvent(this.hex, 'input', { bubbles: true });
|
|
202
|
+
if (commit) fireEvent(this.hex, 'change', { bubbles: true });
|
|
202
203
|
}
|
|
203
204
|
|
|
204
205
|
/** Swatch and invalid mark follow the box; `commit === null` is silent. */
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
import { SortableList } from './sortable_list.js';
|
|
29
29
|
import { ColorField, isHexColor, normalizeHex } from './color_field.js';
|
|
30
|
+
import { fireEvent } from '../utils/fire_event.js';
|
|
30
31
|
|
|
31
32
|
let _seq = 0;
|
|
32
33
|
|
|
@@ -202,8 +203,8 @@ export class ColorListField {
|
|
|
202
203
|
#emit(commit) {
|
|
203
204
|
this.#writeInput();
|
|
204
205
|
if (this.input) {
|
|
205
|
-
this.input
|
|
206
|
-
if (commit) this.input
|
|
206
|
+
fireEvent(this.input, 'input', { bubbles: true });
|
|
207
|
+
if (commit) fireEvent(this.input, 'change', { bubbles: true });
|
|
207
208
|
}
|
|
208
209
|
this.onChange?.(this.getValue(), { commit });
|
|
209
210
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|