@design.estate/dees-catalog 12.0.0 → 12.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/dist_bundle/bundle.js +1712 -1223
- package/dist_bundle/bundle.js.map +1 -1
- package/dist_ts_web/00_commitinfo_data.js +3 -3
- package/dist_ts_web/elements/00group-harness/dees-harness-session-sidebar/dees-harness-session-sidebar.js +3 -107
- package/dist_ts_web/elements/00group-harness/dees-harness-sidebar/dees-harness-sidebar.d.ts +70 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-sidebar/dees-harness-sidebar.demo.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-sidebar/dees-harness-sidebar.demo.js +78 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-sidebar/dees-harness-sidebar.js +261 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-sidebar/index.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-sidebar/index.js +2 -0
- package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.d.ts +101 -7
- package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.demo.js +38 -7
- package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.js +252 -22
- package/dist_ts_web/elements/00group-harness/harness.styles.d.ts +10 -0
- package/dist_ts_web/elements/00group-harness/harness.styles.js +116 -1
- package/dist_ts_web/elements/00group-harness/index.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/index.js +2 -1
- package/package.json +3 -3
- package/readme.md +49 -1
- package/ts_web/00_commitinfo_data.ts +3 -3
- package/ts_web/elements/00group-harness/dees-harness-session-sidebar/dees-harness-session-sidebar.ts +2 -106
- package/ts_web/elements/00group-harness/dees-harness-sidebar/dees-harness-sidebar.demo.ts +87 -0
- package/ts_web/elements/00group-harness/dees-harness-sidebar/dees-harness-sidebar.ts +245 -0
- package/ts_web/elements/00group-harness/dees-harness-sidebar/index.ts +1 -0
- package/ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.demo.ts +48 -12
- package/ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.ts +283 -22
- package/ts_web/elements/00group-harness/harness.styles.ts +116 -0
- package/ts_web/elements/00group-harness/index.ts +1 -0
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { demoFunc } from './dees-harness-sidebar.demo.js';
|
|
36
|
+
import { DeesElement, html, css, customElement, property, state, cssManager, directives, } from '@design.estate/dees-element';
|
|
37
|
+
import { themeDefaultStyles } from '../../00theme.js';
|
|
38
|
+
import { harnessSidebarStyles } from '../harness.styles.js';
|
|
39
|
+
import '../../00group-utility/dees-icon/dees-icon.js';
|
|
40
|
+
const { repeat } = directives;
|
|
41
|
+
/** Every section body arrives through `slot="section-<key>"`. */
|
|
42
|
+
const sectionSlotPrefix = 'section-';
|
|
43
|
+
const sectionSlotName = (keyArg) => `${sectionSlotPrefix}${keyArg}`;
|
|
44
|
+
const sameKeys = (leftArg, rightArg) => leftArg.size === rightArg.size && [...leftArg].every((keyArg) => rightArg.has(keyArg));
|
|
45
|
+
/**
|
|
46
|
+
* Sidebar shell: the panel chrome of `dees-harness-session-sidebar` with
|
|
47
|
+
* host-declared sections instead of session-specific ones. It owns the
|
|
48
|
+
* single-open accordion and nothing else — every section body is slotted
|
|
49
|
+
* content, so the host keeps its own state, updates, and presentation. A
|
|
50
|
+
* section whose slot holds no content is not offered at all, and the host
|
|
51
|
+
* mounts and unmounts the element to show or hide the panel.
|
|
52
|
+
*/
|
|
53
|
+
let DeesHarnessSidebar = (() => {
|
|
54
|
+
let _classDecorators = [customElement('dees-harness-sidebar')];
|
|
55
|
+
let _classDescriptor;
|
|
56
|
+
let _classExtraInitializers = [];
|
|
57
|
+
let _classThis;
|
|
58
|
+
let _classSuper = DeesElement;
|
|
59
|
+
let _sections_decorators;
|
|
60
|
+
let _sections_initializers = [];
|
|
61
|
+
let _sections_extraInitializers = [];
|
|
62
|
+
let _expandedSection_decorators;
|
|
63
|
+
let _expandedSection_initializers = [];
|
|
64
|
+
let _expandedSection_extraInitializers = [];
|
|
65
|
+
let _disabled_decorators;
|
|
66
|
+
let _disabled_initializers = [];
|
|
67
|
+
let _disabled_extraInitializers = [];
|
|
68
|
+
let _populatedSections_decorators;
|
|
69
|
+
let _populatedSections_initializers = [];
|
|
70
|
+
let _populatedSections_extraInitializers = [];
|
|
71
|
+
var DeesHarnessSidebar = class extends _classSuper {
|
|
72
|
+
static { _classThis = this; }
|
|
73
|
+
static {
|
|
74
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
75
|
+
_sections_decorators = [property({ attribute: false })];
|
|
76
|
+
_expandedSection_decorators = [property()];
|
|
77
|
+
_disabled_decorators = [property({ type: Boolean })];
|
|
78
|
+
_populatedSections_decorators = [state()];
|
|
79
|
+
__esDecorate(this, null, _sections_decorators, { kind: "accessor", name: "sections", static: false, private: false, access: { has: obj => "sections" in obj, get: obj => obj.sections, set: (obj, value) => { obj.sections = value; } }, metadata: _metadata }, _sections_initializers, _sections_extraInitializers);
|
|
80
|
+
__esDecorate(this, null, _expandedSection_decorators, { kind: "accessor", name: "expandedSection", static: false, private: false, access: { has: obj => "expandedSection" in obj, get: obj => obj.expandedSection, set: (obj, value) => { obj.expandedSection = value; } }, metadata: _metadata }, _expandedSection_initializers, _expandedSection_extraInitializers);
|
|
81
|
+
__esDecorate(this, null, _disabled_decorators, { kind: "accessor", name: "disabled", static: false, private: false, access: { has: obj => "disabled" in obj, get: obj => obj.disabled, set: (obj, value) => { obj.disabled = value; } }, metadata: _metadata }, _disabled_initializers, _disabled_extraInitializers);
|
|
82
|
+
__esDecorate(this, null, _populatedSections_decorators, { kind: "accessor", name: "populatedSections", static: false, private: false, access: { has: obj => "populatedSections" in obj, get: obj => obj.populatedSections, set: (obj, value) => { obj.populatedSections = value; } }, metadata: _metadata }, _populatedSections_initializers, _populatedSections_extraInitializers);
|
|
83
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
84
|
+
DeesHarnessSidebar = _classThis = _classDescriptor.value;
|
|
85
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
86
|
+
}
|
|
87
|
+
static demo = demoFunc;
|
|
88
|
+
static demoGroups = ['Agent Chat'];
|
|
89
|
+
#sections_accessor_storage = __runInitializers(this, _sections_initializers, []);
|
|
90
|
+
/** Sections in render order; each one's body is slotted as `section-<key>`. */
|
|
91
|
+
get sections() { return this.#sections_accessor_storage; }
|
|
92
|
+
set sections(value) { this.#sections_accessor_storage = value; }
|
|
93
|
+
#expandedSection_accessor_storage = (__runInitializers(this, _sections_extraInitializers), __runInitializers(this, _expandedSection_initializers, undefined));
|
|
94
|
+
/**
|
|
95
|
+
* Key of the open section. Host-settable and kept in sync with what the user
|
|
96
|
+
* opens; it defaults to the first section that has content, and `undefined`
|
|
97
|
+
* leaves the panel collapsed once a section has been opened. A declared
|
|
98
|
+
* section without content renders collapsed and opens as soon as its content
|
|
99
|
+
* arrives, so the key survives an asynchronous body.
|
|
100
|
+
*/
|
|
101
|
+
get expandedSection() { return this.#expandedSection_accessor_storage; }
|
|
102
|
+
set expandedSection(value) { this.#expandedSection_accessor_storage = value; }
|
|
103
|
+
#disabled_accessor_storage = (__runInitializers(this, _expandedSection_extraInitializers), __runInitializers(this, _disabled_initializers, false));
|
|
104
|
+
/** Freezes the accordion: headings stay visible but cannot be toggled. */
|
|
105
|
+
get disabled() { return this.#disabled_accessor_storage; }
|
|
106
|
+
set disabled(value) { this.#disabled_accessor_storage = value; }
|
|
107
|
+
#populatedSections_accessor_storage = (__runInitializers(this, _disabled_extraInitializers), __runInitializers(this, _populatedSections_initializers, new Set()));
|
|
108
|
+
get populatedSections() { return this.#populatedSections_accessor_storage; }
|
|
109
|
+
set populatedSections(value) { this.#populatedSections_accessor_storage = value; }
|
|
110
|
+
sectionStateInitialized = (__runInitializers(this, _populatedSections_extraInitializers), false);
|
|
111
|
+
static styles = [
|
|
112
|
+
themeDefaultStyles,
|
|
113
|
+
cssManager.defaultStyles,
|
|
114
|
+
harnessSidebarStyles,
|
|
115
|
+
css `
|
|
116
|
+
:host {
|
|
117
|
+
background: var(--dees-color-bg-canvas);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* A section without content is not offered at all: the hidden attribute
|
|
121
|
+
alone would still be laid out, because the shared chrome's display
|
|
122
|
+
declaration wins over the user-agent rule. The divider then follows the
|
|
123
|
+
last visible section instead of the last declared one. */
|
|
124
|
+
.section[hidden] {
|
|
125
|
+
display: none;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.section:not(:has(~ .section:not([hidden]))) {
|
|
129
|
+
border-bottom: 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Section bodies stay as compact as the session panel's; slotted content
|
|
133
|
+
inherits this and can override it per element. */
|
|
134
|
+
.sectionContent {
|
|
135
|
+
font-size: var(--dees-font-caption1-size, 11px);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.sectionHeading:disabled {
|
|
139
|
+
opacity: 0.62;
|
|
140
|
+
cursor: default;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.sectionHeading:disabled:hover {
|
|
144
|
+
background: var(--dees-color-bg-canvas);
|
|
145
|
+
}
|
|
146
|
+
`,
|
|
147
|
+
];
|
|
148
|
+
willUpdate(changedPropertiesArg) {
|
|
149
|
+
if (changedPropertiesArg.has('expandedSection'))
|
|
150
|
+
this.sectionStateInitialized = true;
|
|
151
|
+
const populated = this.populatedSectionsInOrder;
|
|
152
|
+
// Slot assignment is only known after the first render, so an empty panel
|
|
153
|
+
// never overrides a host-set section.
|
|
154
|
+
if (populated.length === 0)
|
|
155
|
+
return;
|
|
156
|
+
if (!this.sectionStateInitialized) {
|
|
157
|
+
this.expandedSection = populated[0].key;
|
|
158
|
+
this.sectionStateInitialized = true;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const open = this.expandedSection;
|
|
162
|
+
// A section the host withdrew from `sections` can never open again, so the
|
|
163
|
+
// panel moves on. A declared section whose content is momentarily missing
|
|
164
|
+
// keeps the key and renders collapsed until the content is back, so an
|
|
165
|
+
// asynchronous body never costs the host or the user their choice.
|
|
166
|
+
if (open !== undefined && !this.sections.some((section) => section.key === open)) {
|
|
167
|
+
this.expandedSection = populated[0].key;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
render() {
|
|
171
|
+
return html `
|
|
172
|
+
<div class="sidebar">
|
|
173
|
+
${repeat(this.sections, (section) => section.key, (section) => this.renderSection(section))}
|
|
174
|
+
</div>
|
|
175
|
+
`;
|
|
176
|
+
}
|
|
177
|
+
/** Declared sections that currently have slotted content, in render order. */
|
|
178
|
+
get populatedSectionsInOrder() {
|
|
179
|
+
return this.sections.filter((section) => this.populatedSections.has(section.key));
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* The heading row is the element's own; the body is the host's, and it stays
|
|
183
|
+
* mounted while collapsed so it keeps its state and scroll position.
|
|
184
|
+
*/
|
|
185
|
+
renderSection(sectionArg) {
|
|
186
|
+
const populated = this.populatedSections.has(sectionArg.key);
|
|
187
|
+
const expanded = populated && this.expandedSection === sectionArg.key;
|
|
188
|
+
const contentId = `harness-sidebar-section-${sectionArg.key}`;
|
|
189
|
+
return html `
|
|
190
|
+
<section
|
|
191
|
+
class=${`section ${expanded ? 'expanded' : ''}`}
|
|
192
|
+
data-section=${sectionArg.key}
|
|
193
|
+
?hidden=${!populated}
|
|
194
|
+
>
|
|
195
|
+
${populated ? html `
|
|
196
|
+
<button
|
|
197
|
+
class="sectionHeading"
|
|
198
|
+
type="button"
|
|
199
|
+
aria-expanded=${String(expanded)}
|
|
200
|
+
aria-controls=${contentId}
|
|
201
|
+
?disabled=${this.disabled}
|
|
202
|
+
@click=${() => this.toggleSection(sectionArg.key)}
|
|
203
|
+
>
|
|
204
|
+
<dees-icon
|
|
205
|
+
icon=${expanded ? 'lucide:ChevronDown' : 'lucide:ChevronRight'}
|
|
206
|
+
iconSize="13"
|
|
207
|
+
></dees-icon>
|
|
208
|
+
${sectionArg.icon ? html `<dees-icon icon=${sectionArg.icon} iconSize="13"></dees-icon>` : ''}
|
|
209
|
+
<span class="sectionHeadingText">${sectionArg.label}</span>
|
|
210
|
+
${sectionArg.badge ? html `<span class="sectionSummary">${sectionArg.badge}</span>` : ''}
|
|
211
|
+
</button>
|
|
212
|
+
` : ''}
|
|
213
|
+
<div
|
|
214
|
+
id=${contentId}
|
|
215
|
+
class="sectionContent"
|
|
216
|
+
role="region"
|
|
217
|
+
aria-label=${sectionArg.label}
|
|
218
|
+
aria-hidden=${String(!expanded)}
|
|
219
|
+
?hidden=${!expanded}
|
|
220
|
+
>
|
|
221
|
+
<slot
|
|
222
|
+
name=${sectionSlotName(sectionArg.key)}
|
|
223
|
+
@slotchange=${this.handleSectionSlotChange}
|
|
224
|
+
></slot>
|
|
225
|
+
</div>
|
|
226
|
+
</section>
|
|
227
|
+
`;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* A section is offered only while its slot holds content, so the panel
|
|
231
|
+
* recomputes from its live slots whenever the host fills or empties one.
|
|
232
|
+
*/
|
|
233
|
+
handleSectionSlotChange = () => {
|
|
234
|
+
const populated = new Set();
|
|
235
|
+
const sectionSlots = this.renderRoot.querySelectorAll(`slot[name^="${sectionSlotPrefix}"]`);
|
|
236
|
+
for (const slot of sectionSlots) {
|
|
237
|
+
if (slot.assignedElements({ flatten: true }).length > 0) {
|
|
238
|
+
populated.add(slot.name.slice(sectionSlotPrefix.length));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
if (sameKeys(this.populatedSections, populated))
|
|
242
|
+
return;
|
|
243
|
+
this.populatedSections = populated;
|
|
244
|
+
};
|
|
245
|
+
toggleSection(keyArg) {
|
|
246
|
+
if (this.disabled)
|
|
247
|
+
return;
|
|
248
|
+
const expandedSection = this.expandedSection === keyArg ? undefined : keyArg;
|
|
249
|
+
this.sectionStateInitialized = true;
|
|
250
|
+
this.expandedSection = expandedSection;
|
|
251
|
+
const detail = { expandedSection };
|
|
252
|
+
this.dispatchEvent(new CustomEvent('harness-sidebar-section-change', { detail, bubbles: true, composed: true }));
|
|
253
|
+
}
|
|
254
|
+
static {
|
|
255
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
return DeesHarnessSidebar = _classThis;
|
|
259
|
+
})();
|
|
260
|
+
export { DeesHarnessSidebar };
|
|
261
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVlcy1oYXJuZXNzLXNpZGViYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90c193ZWIvZWxlbWVudHMvMDBncm91cC1oYXJuZXNzL2RlZXMtaGFybmVzcy1zaWRlYmFyL2RlZXMtaGFybmVzcy1zaWRlYmFyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDMUQsT0FBTyxFQUNMLFdBQVcsRUFDWCxJQUFJLEVBQ0osR0FBRyxFQUNILGFBQWEsRUFFYixRQUFRLEVBQ1IsS0FBSyxFQUNMLFVBQVUsRUFDVixVQUFVLEdBQ1gsTUFBTSw2QkFBNkIsQ0FBQztBQUNyQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RCxPQUFPLDhDQUE4QyxDQUFDO0FBRXRELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxVQUFVLENBQUM7QUFFOUIsaUVBQWlFO0FBQ2pFLE1BQU0saUJBQWlCLEdBQUcsVUFBVSxDQUFDO0FBQ3JDLE1BQU0sZUFBZSxHQUFHLENBQUMsTUFBYyxFQUFVLEVBQUUsQ0FBQyxHQUFHLGlCQUFpQixHQUFHLE1BQU0sRUFBRSxDQUFDO0FBRXBGLE1BQU0sUUFBUSxHQUFHLENBQUMsT0FBNEIsRUFBRSxRQUE2QixFQUFXLEVBQUUsQ0FDeEYsT0FBTyxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztBQStCekY7Ozs7Ozs7R0FPRztJQUVVLGtCQUFrQjs0QkFEOUIsYUFBYSxDQUFD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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dees-harness-sidebar.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export * from './dees-harness-sidebar.js';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90c193ZWIvZWxlbWVudHMvMDBncm91cC1oYXJuZXNzL2RlZXMtaGFybmVzcy1zaWRlYmFyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsMkJBQTJCLENBQUMifQ==
|
|
@@ -8,7 +8,10 @@ declare global {
|
|
|
8
8
|
export interface ITerminalInputDetail {
|
|
9
9
|
data: string;
|
|
10
10
|
}
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* A terminal grid size. It is the detail of `terminal-resize`, fired after the
|
|
13
|
+
* terminal refits its container, and the size `restore()` paints a snapshot at.
|
|
14
|
+
*/
|
|
12
15
|
export interface ITerminalResizeDetail {
|
|
13
16
|
rows: number;
|
|
14
17
|
cols: number;
|
|
@@ -35,9 +38,10 @@ export declare const maxPendingWriteBytes: number;
|
|
|
35
38
|
* every refit so the host can negotiate a PTY size. Output that arrives while
|
|
36
39
|
* no terminal is live is buffered up to `maxPendingWriteBytes` and replayed in
|
|
37
40
|
* order on the next connection, so a replay may start before the element is
|
|
38
|
-
* ready and survives being detached.
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
+
* ready and survives being detached. `restore()` paints a serialized snapshot
|
|
42
|
+
* invisibly at the grid it was taken at, then fits it to the container. xterm
|
|
43
|
+
* loads through DeesServiceLibLoader; CSP-locked hosts can pre-register
|
|
44
|
+
* bundled modules with `provideXtermModules()` to avoid the CDN.
|
|
41
45
|
*/
|
|
42
46
|
export declare class DeesTerminalView extends DeesElement {
|
|
43
47
|
static demo: () => TemplateResult<1>;
|
|
@@ -50,10 +54,21 @@ export declare class DeesTerminalView extends DeesElement {
|
|
|
50
54
|
private resizeObserver;
|
|
51
55
|
private inputDisposable;
|
|
52
56
|
private lastReportedSize;
|
|
57
|
+
private pendingRestore;
|
|
53
58
|
private pendingWrites;
|
|
54
59
|
private pendingWriteBytes;
|
|
55
60
|
private pendingWritesDropped;
|
|
56
61
|
private setupPromise;
|
|
62
|
+
/**
|
|
63
|
+
* The restore handed to the live terminal whose snapshot is not parsed yet. While it is set the
|
|
64
|
+
* grid belongs to the snapshot: the terminal stays invisible and nothing refits it.
|
|
65
|
+
*/
|
|
66
|
+
private activeRestore;
|
|
67
|
+
/**
|
|
68
|
+
* Set only by an explicit `focus()` that arrived before the terminal existed. Nothing else sets
|
|
69
|
+
* it, so a re-render, a write, or a resize can never move the caret into this element.
|
|
70
|
+
*/
|
|
71
|
+
private focusWhenReady;
|
|
57
72
|
private readyPending;
|
|
58
73
|
private readyResolve;
|
|
59
74
|
private readyReject;
|
|
@@ -70,17 +85,96 @@ export declare class DeesTerminalView extends DeesElement {
|
|
|
70
85
|
connectedCallback(): Promise<void>;
|
|
71
86
|
/** Feed remote output into the terminal; safe to call before setup finishes. */
|
|
72
87
|
write(dataArg: string | Uint8Array): void;
|
|
73
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Reset the screen and scrollback, e.g. before a full replay. Before the terminal exists it also
|
|
90
|
+
* replaces a buffered `restore()`, whose promise then resolves as superseded.
|
|
91
|
+
*/
|
|
74
92
|
clear(): void;
|
|
75
|
-
|
|
76
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Replace the terminal state with a serialized snapshot, e.g. from xterm's serialize addon, and
|
|
95
|
+
* show it only once it is complete. A snapshot is exact only in a grid of the size it was
|
|
96
|
+
* serialized at, so the terminal is fully reset (screen, scrollback, modes, alternate buffer),
|
|
97
|
+
* set to `sizeArg`, fed `dataArg` while invisible, then fitted to its container and revealed.
|
|
98
|
+
* `terminal-resize` fires at the end when the fitted grid differs from `sizeArg`, which is the
|
|
99
|
+
* host's cue to resize the PTY so the application redraws at the new size. Until then
|
|
100
|
+
* `currentSize` reports `sizeArg`, so the closing event, or this promise, is what a host
|
|
101
|
+
* negotiates a PTY size on.
|
|
102
|
+
*
|
|
103
|
+
* The restore is part of the output stream: writes issued after it are applied after the
|
|
104
|
+
* snapshot, in order, at the fitted size. Like `write()` it is safe before the terminal exists
|
|
105
|
+
* and while the element is detached; a buffered restore replaces everything buffered before
|
|
106
|
+
* it. The terminal keeps its focus and keeps forwarding input while the restore runs.
|
|
107
|
+
*
|
|
108
|
+
* The promise resolves once the snapshot is on screen, and also, without revealing anything,
|
|
109
|
+
* when a newer `restore()` supersedes this one or `clear()` replaces it while it is buffered.
|
|
110
|
+
* It rejects, without ever surfacing as an unhandled rejection, when the element is
|
|
111
|
+
* disconnected while the snapshot is being parsed (the terminal is disposed with it, as with
|
|
112
|
+
* any live output), when output buffered after it pushes it out of `maxPendingWriteBytes`, and
|
|
113
|
+
* when xterm refuses the data (`terminal-error` carries the same error). Buffered output is
|
|
114
|
+
* dropped oldest first and the restore is the oldest entry, so a buffered snapshot that alone
|
|
115
|
+
* exceeds the bound is dropped by the next buffered write of any size. An invalid size is a
|
|
116
|
+
* programming error: the promise rejects with a `RangeError` and nothing changes; unlike the
|
|
117
|
+
* reasons above this one is not pre-handled, so a `restore()` nobody observes reports it as an
|
|
118
|
+
* unhandled rejection.
|
|
119
|
+
*
|
|
120
|
+
* There is a fourth outcome: a restore that is still buffered when the element is disconnected
|
|
121
|
+
* stays pending, because the snapshot survives the move like buffered output and is applied on
|
|
122
|
+
* the next connection. A host that discards the element instead of reattaching it must not await
|
|
123
|
+
* that promise.
|
|
124
|
+
*
|
|
125
|
+
* @param dataArg The serialized terminal state.
|
|
126
|
+
* @param sizeArg The grid the snapshot was serialized at: integer `cols` in [2, 65535] and
|
|
127
|
+
* `rows` in [1, 65535].
|
|
128
|
+
*/
|
|
129
|
+
restore(dataArg: string | Uint8Array, sizeArg: ITerminalResizeDetail): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Moves the caret into the terminal's input surface, so the next keystroke goes to the pty
|
|
132
|
+
* rather than to whatever the page focused last. This is the call a host makes when the user
|
|
133
|
+
* selects a terminal in a list.
|
|
134
|
+
*
|
|
135
|
+
* The terminal is created asynchronously — the xterm modules are loaded on first connection —
|
|
136
|
+
* so a call that arrives before it exists is remembered and applied once it is ready, exactly
|
|
137
|
+
* once. The same applies to an element that is focused while detached and then reattached: the
|
|
138
|
+
* pending request is dropped on disconnect, because by then the user's intent has expired, and
|
|
139
|
+
* a fresh `focus()` after the move is what a host should issue.
|
|
140
|
+
*
|
|
141
|
+
* Only this method arms that behaviour; re-renders, buffered output and background updates
|
|
142
|
+
* never steal focus.
|
|
143
|
+
*/
|
|
144
|
+
focus(optionsArg?: FocusOptions): void;
|
|
145
|
+
/** True while an explicit `focus()` is waiting for the terminal to come up. */
|
|
146
|
+
get focusPending(): boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Current grid size, or undefined while no terminal is live. While a snapshot is being parsed
|
|
149
|
+
* this is the grid the snapshot was serialized at; the closing `terminal-resize`, or the promise
|
|
150
|
+
* `restore()` returned, is the grid to negotiate a PTY size on.
|
|
151
|
+
*/
|
|
77
152
|
get currentSize(): ITerminalResizeDetail | undefined;
|
|
78
153
|
private createReadyPromise;
|
|
79
154
|
private bufferWrite;
|
|
155
|
+
/** Hands the buffered output over and leaves the buffer empty. */
|
|
156
|
+
private takePendingOutput;
|
|
157
|
+
/** Empties the buffer ahead of a reset; a buffered restore is superseded by it. */
|
|
158
|
+
private discardPendingOutput;
|
|
80
159
|
private flushPendingWrites;
|
|
160
|
+
/**
|
|
161
|
+
* Queues a restore into xterm's write stream. Resetting and resizing happen in the callback of
|
|
162
|
+
* the reset, so they take effect exactly at the restore's position in the stream, and the
|
|
163
|
+
* restore ends in the callback of its snapshot, before xterm parses the next chunk.
|
|
164
|
+
*/
|
|
165
|
+
private startRestore;
|
|
166
|
+
private applyRestoreSize;
|
|
167
|
+
private finishRestore;
|
|
168
|
+
/**
|
|
169
|
+
* Hands the grid back to the container: one refit, then the terminal is revealed. The refit
|
|
170
|
+
* dispatches `terminal-resize` synchronously, and a restore its listener starts keeps the
|
|
171
|
+
* terminal hidden.
|
|
172
|
+
*/
|
|
173
|
+
private endRestore;
|
|
81
174
|
/** xterm throws at its own flow-control watermark; that has to reach the host. */
|
|
82
175
|
private writeToTerminal;
|
|
83
176
|
private reportError;
|
|
177
|
+
private get terminalHost();
|
|
84
178
|
private ensureTerminal;
|
|
85
179
|
private setupTerminal;
|
|
86
180
|
private createTerminal;
|
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
import { html } from '@design.estate/dees-element';
|
|
2
2
|
import { demoPage } from '../../../demos/templates.js';
|
|
3
|
+
// A serialized terminal state as a host would receive it on reattach, e.g. from xterm's
|
|
4
|
+
// serialize addon: styled rows at the grid the PTY had when it was taken.
|
|
5
|
+
const sampleSnapshotSize = { cols: 64, rows: 12 };
|
|
6
|
+
const samplePrompt = '\x1b[1;32m➜\x1b[0m \x1b[36mdees-catalog\x1b[0m ';
|
|
7
|
+
const sampleSnapshot = [
|
|
8
|
+
`${samplePrompt}pnpm build`,
|
|
9
|
+
'\x1b[2mtsbuild \x1b[0m compiled the web folder',
|
|
10
|
+
'\x1b[2mtsbundle\x1b[0m wrote dist_bundle/bundle.js',
|
|
11
|
+
'',
|
|
12
|
+
`${samplePrompt}pnpm test`,
|
|
13
|
+
' \x1b[32m✔\x1b[0m restore() sizes, parses, fits and reveals',
|
|
14
|
+
' \x1b[32m✔\x1b[0m writes during a restore follow the snapshot',
|
|
15
|
+
' \x1b[32m✔\x1b[0m a newer restore supersedes an older one',
|
|
16
|
+
'',
|
|
17
|
+
samplePrompt,
|
|
18
|
+
].join('\r\n');
|
|
19
|
+
const restoreSample = (event) => {
|
|
20
|
+
const view = event.currentTarget
|
|
21
|
+
.closest('.terminalDemoStack')
|
|
22
|
+
?.querySelector('dees-terminal-view');
|
|
23
|
+
if (!view)
|
|
24
|
+
return;
|
|
25
|
+
// A click handler's promise is dropped by the DOM, so both outcomes are settled here: leaving
|
|
26
|
+
// the demo page mid-restore rejects, and nobody would be left to observe it.
|
|
27
|
+
view.restore(sampleSnapshot, sampleSnapshotSize).then(() => view.focus(), () => undefined);
|
|
28
|
+
};
|
|
3
29
|
// A loopback demo: keystrokes echo straight back into the terminal so the
|
|
4
30
|
// component is explorable without a live PTY behind it.
|
|
5
|
-
export const demoFunc = () => demoPage('Terminal', 'A terminal surface with local keyboard echo. Type to try the input and resize behavior.', html `
|
|
31
|
+
export const demoFunc = () => demoPage('Terminal', 'A terminal surface with local keyboard echo. Type to try the input and resize behavior, or restore a serialized snapshot: it is painted invisibly at its own grid and appears fitted, in one step.', html `
|
|
6
32
|
<style>
|
|
7
33
|
.terminalDemo {
|
|
8
34
|
height: 380px;
|
|
@@ -11,17 +37,22 @@ export const demoFunc = () => demoPage('Terminal', 'A terminal surface with loca
|
|
|
11
37
|
overflow: hidden;
|
|
12
38
|
}
|
|
13
39
|
</style>
|
|
14
|
-
<div class="
|
|
15
|
-
<dees-
|
|
16
|
-
@
|
|
40
|
+
<div class="terminalDemoStack dees-demo-stack">
|
|
41
|
+
<div class="dees-demo-row">
|
|
42
|
+
<dees-button @clicked=${restoreSample}>Restore a snapshot</dees-button>
|
|
43
|
+
</div>
|
|
44
|
+
<div class="terminalDemo">
|
|
45
|
+
<dees-terminal-view
|
|
46
|
+
@terminal-input=${(event) => {
|
|
17
47
|
const view = event.currentTarget;
|
|
18
48
|
const data = event.detail.data;
|
|
19
49
|
view.write(data === '\r' ? '\r\n' : data);
|
|
20
50
|
}}
|
|
21
|
-
|
|
51
|
+
@terminal-resize=${(event) => {
|
|
22
52
|
console.log('terminal size', event.detail);
|
|
23
53
|
}}
|
|
24
|
-
|
|
54
|
+
></dees-terminal-view>
|
|
55
|
+
</div>
|
|
25
56
|
</div>
|
|
26
57
|
`);
|
|
27
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVlcy10ZXJtaW5hbC12aWV3LmRlbW8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90c193ZWIvZWxlbWVudHMvMDBncm91cC1oYXJuZXNzL2RlZXMtdGVybWluYWwtdmlldy9kZWVzLXRlcm1pbmFsLXZpZXcuZGVtby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDbkQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBR3ZELHdGQUF3RjtBQUN4RiwwRUFBMEU7QUFDMUUsTUFBTSxrQkFBa0IsR0FBMEIsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUN6RSxNQUFNLFlBQVksR0FBRyxpREFBaUQsQ0FBQztBQUN2RSxNQUFNLGNBQWMsR0FBRztJQUNyQixHQUFHLFlBQVksWUFBWTtJQUMzQixnREFBZ0Q7SUFDaEQsb0RBQW9EO0lBQ3BELEVBQUU7SUFDRixHQUFHLFlBQVksV0FBVztJQUMxQiw2REFBNkQ7SUFDN0QsK0RBQStEO0lBQy9ELDJEQUEyRDtJQUMzRCxFQUFFO0lBQ0YsWUFBWTtDQUNiLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBRWYsTUFBTSxhQUFhLEdBQUcsQ0FBQyxLQUFZLEVBQVEsRUFBRTtJQUMzQyxNQUFNLElBQUksR0FBSSxLQUFLLENBQUMsYUFBNkI7U0FDOUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDO1FBQzlCLEVBQUUsYUFBYSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDeEMsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPO0lBQ2xCLDhGQUE4RjtJQUM5Riw2RUFBNkU7SUFDN0UsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxJQUFJLENBQ25ELEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFDbEIsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUNoQixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBRUYsMEVBQTBFO0FBQzFFLHdEQUF3RDtBQUN4RCxNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxvTUFBb00sRUFBRSxJQUFJLENBQUE7Ozs7Ozs7Ozs7OzhCQVcvTixhQUFhOzs7OzBCQUlqQixDQUFDLEtBQW9DLEVBQUUsRUFBRTtJQUN6RCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsYUFBNEQsQ0FBQztJQUNoRixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUMvQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUMsQ0FBQzsyQkFDa0IsQ0FBQyxLQUF5QyxFQUFFLEVBQUU7SUFDL0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzdDLENBQUM7Ozs7Q0FJUixDQUFDLENBQUMifQ==
|