@linxin666/dsh-remote-web-ui 0.2.0 → 0.2.2
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/README.i18n.yaml +2 -2
- package/README.md +17 -8
- package/README.zh.md +5 -5
- package/lib/client.js +259 -43
- package/lib/client.js.map +1 -1
- package/lib/index.js +26 -7
- package/lib/mobile.js +209 -39
- package/lib/mobile.js.map +1 -1
- package/lib/types/client/PluginSettingsCard.d.ts +22 -0
- package/lib/types/client/PluginSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PluginSettingsCard.js +142 -3
- package/lib/types/client/RemoteEntry.d.ts.map +1 -1
- package/lib/types/client/RemoteEntry.js +11 -0
- package/lib/types/client/RemoteSettingsCard.d.ts +2 -2
- package/lib/types/client/UpdateEntry.d.ts.map +1 -1
- package/lib/types/client/UpdateEntry.js +8 -5
- package/lib/types/client/UpdatePanel.d.ts +3 -1
- package/lib/types/client/UpdatePanel.d.ts.map +1 -1
- package/lib/types/client/UpdatePanel.js +3 -3
- package/lib/types/client/locales.d.ts +4 -0
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +8 -4
- package/lib/types/client/pair-api.d.ts +1 -6
- package/lib/types/client/pair-api.d.ts.map +1 -1
- package/lib/types/client/pair-api.js +1 -10
- package/lib/types/gate.d.ts.map +1 -1
- package/lib/types/gate.js +2 -0
- package/lib/types/mobile/api.d.ts +10 -0
- package/lib/types/mobile/api.d.ts.map +1 -1
- package/lib/types/mobile/api.js +4 -0
- package/lib/types/mobile/messages.d.ts +24 -0
- package/lib/types/mobile/messages.d.ts.map +1 -1
- package/lib/types/mobile/messages.js +60 -23
- package/lib/types/mobile/messages.test.js +49 -1
- package/lib/types/mobile/mobile-styles.d.ts +1 -1
- package/lib/types/mobile/mobile-styles.d.ts.map +1 -1
- package/lib/types/mobile/mobile-styles.js +38 -0
- package/lib/types/mobile/views/ChatView.d.ts.map +1 -1
- package/lib/types/mobile/views/ChatView.js +34 -11
- package/lib/types/mobile/views/SessionListView.d.ts.map +1 -1
- package/lib/types/mobile/views/SessionListView.js +30 -4
- package/lib/types/mobile/views/SessionListView.test.js +58 -1
- package/lib/types/mobile/views/WorkspaceView.d.ts.map +1 -1
- package/lib/types/mobile/views/WorkspaceView.js +4 -2
- package/lib/types/mobile-api.d.ts.map +1 -1
- package/lib/types/mobile-api.js +10 -1
- package/lib/types/routes.d.ts.map +1 -1
- package/lib/types/routes.js +22 -2
- package/lib/types/tunnel.d.ts +1 -0
- package/lib/types/tunnel.d.ts.map +1 -1
- package/lib/types/tunnel.js +7 -2
- package/lib/types/update.d.ts +1 -1
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +1 -1
- package/package.json +1 -2
- package/src/client/PluginSettingsCard.tsx +219 -18
- package/src/client/RemoteEntry.tsx +10 -0
- package/src/client/RemoteSettingsCard.tsx +2 -2
- package/src/client/UpdateEntry.tsx +9 -5
- package/src/client/UpdatePanel.tsx +12 -1
- package/src/client/locales.ts +8 -4
- package/src/client/pair-api.ts +1 -10
- package/src/client/settings-card.module.css +90 -1
- package/src/gate.ts +2 -0
- package/src/mobile/api.ts +14 -1
- package/src/mobile/messages.test.ts +52 -1
- package/src/mobile/messages.ts +65 -22
- package/src/mobile/mobile-styles.ts +38 -0
- package/src/mobile/mobile-theme.test.ts +1 -1
- package/src/mobile/views/ChatView.tsx +33 -10
- package/src/mobile/views/SessionListView.test.tsx +69 -1
- package/src/mobile/views/SessionListView.tsx +58 -5
- package/src/mobile/views/WorkspaceView.tsx +4 -2
- package/src/mobile-api.ts +9 -1
- package/src/routes.ts +22 -2
- package/src/tunnel.ts +7 -2
- package/src/update.ts +2 -2
|
@@ -88,6 +88,27 @@ export declare function ValueField(props: FieldProps & {
|
|
|
88
88
|
/** Placeholder shown while the draft is empty. */
|
|
89
89
|
placeholder?: string;
|
|
90
90
|
}): import("react").JSX.Element;
|
|
91
|
+
interface SelectOption {
|
|
92
|
+
value: string;
|
|
93
|
+
label: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The shared dual-mode select control. While an appearance skin is active it
|
|
97
|
+
* renders the legacy native `<select>` untouched, so element-level skin
|
|
98
|
+
* selectors keep working; under the default appearance it renders a
|
|
99
|
+
* self-drawn `role="listbox"` popup whose open/close is transition-animated.
|
|
100
|
+
* Staged cards reach it through BooleanField/ChoiceField; immediate-apply
|
|
101
|
+
* editors (the side-card prefs) bind it directly through onEdit.
|
|
102
|
+
* 双模式下拉框:皮肤激活时用原生 select,默认外观用自绘动画弹层。
|
|
103
|
+
*/
|
|
104
|
+
export declare function SelectField(props: {
|
|
105
|
+
id: string;
|
|
106
|
+
options: ReadonlyArray<SelectOption>;
|
|
107
|
+
value: string;
|
|
108
|
+
disabled: boolean;
|
|
109
|
+
invalid: boolean;
|
|
110
|
+
onEdit: (text: string) => void;
|
|
111
|
+
}): import("react").JSX.Element;
|
|
91
112
|
/** A staged boolean field: 继承 / 开 / 关. */
|
|
92
113
|
export declare function BooleanField(props: FieldProps & {
|
|
93
114
|
/** Copy for the inherit option. */
|
|
@@ -107,4 +128,5 @@ export declare function ChoiceField(props: FieldProps & {
|
|
|
107
128
|
label: string;
|
|
108
129
|
}>;
|
|
109
130
|
}): import("react").JSX.Element;
|
|
131
|
+
export {};
|
|
110
132
|
//# sourceMappingURL=PluginSettingsCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PluginSettingsCard.tsx"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"PluginSettingsCard.d.ts","sourceRoot":"","sources":["../../../src/client/PluginSettingsCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
* it. Inlined into each consumer's client bundle; mirrors the official
|
|
9
9
|
* ui-plugin-config PluginCard in a self-contained slice.
|
|
10
10
|
*/
|
|
11
|
-
import { useState } from 'react';
|
|
11
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
12
12
|
import css from './settings-card.module.css';
|
|
13
13
|
/** Copy keys the card chrome itself reads; every consumer locale carries this shared vocabulary. */
|
|
14
14
|
export const CARD_COPY_KEYS = [
|
|
@@ -65,15 +65,154 @@ export function ValueField(props) {
|
|
|
65
65
|
? (_jsxs("span", { className: css.badges, children: [_jsx("span", { className: css.badge, children: props.overriddenLabel }), _jsx("button", { type: "button", className: css.reset, disabled: props.disabled, onClick: props.onReset, children: props.resetLabel })] }))
|
|
66
66
|
: null] }), _jsx("input", { id: props.id, className: props.invalid ? css.inputInvalid : css.input, type: "text", ...props.numeric === true ? { inputMode: 'numeric' } : {}, ...props.invalid ? { 'aria-invalid': true } : {}, value: props.text, placeholder: props.placeholder ?? '', disabled: props.disabled, onChange: (event) => { props.onEdit(event.target.value); } }), _jsx("p", { className: props.invalid ? css.invalid : css.hint, children: props.invalid ? props.invalidLabel : props.hint })] }));
|
|
67
67
|
}
|
|
68
|
+
const NON_SKIN_BODY_MARKERS = new Set(['dshSkinCenter', 'dshSidebarCollapsed']);
|
|
69
|
+
// 检测使用使用皮肤,用了皮肤退回原生select样式,防止样式冲突。默认外观下使用优化后的select样式。
|
|
70
|
+
function isSkinActive() {
|
|
71
|
+
const datasetList = Object.keys(document.body.dataset);
|
|
72
|
+
const isActive = datasetList.some(key => key.startsWith('dsh') && !NON_SKIN_BODY_MARKERS.has(key));
|
|
73
|
+
return isActive;
|
|
74
|
+
}
|
|
75
|
+
const SELECT_CLOSE_MS = 100;
|
|
76
|
+
/**
|
|
77
|
+
* The shared dual-mode select control. While an appearance skin is active it
|
|
78
|
+
* renders the legacy native `<select>` untouched, so element-level skin
|
|
79
|
+
* selectors keep working; under the default appearance it renders a
|
|
80
|
+
* self-drawn `role="listbox"` popup whose open/close is transition-animated.
|
|
81
|
+
* Staged cards reach it through BooleanField/ChoiceField; immediate-apply
|
|
82
|
+
* editors (the side-card prefs) bind it directly through onEdit.
|
|
83
|
+
* 双模式下拉框:皮肤激活时用原生 select,默认外观用自绘动画弹层。
|
|
84
|
+
*/
|
|
85
|
+
export function SelectField(props) {
|
|
86
|
+
const { id, options, value } = props;
|
|
87
|
+
const [open, setOpen] = useState(false);
|
|
88
|
+
const [closing, setClosing] = useState(false);
|
|
89
|
+
const [phase, setPhase] = useState('initial');
|
|
90
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
91
|
+
const closeTimer = useRef(undefined);
|
|
92
|
+
const wrapRef = useRef(null);
|
|
93
|
+
const popupRef = useRef(null);
|
|
94
|
+
const currentIndex = () => {
|
|
95
|
+
const index = options.findIndex(option => option.value === value);
|
|
96
|
+
return index >= 0 ? index : 0;
|
|
97
|
+
};
|
|
98
|
+
const close = useCallback(() => {
|
|
99
|
+
if (closeTimer.current !== undefined)
|
|
100
|
+
clearTimeout(closeTimer.current);
|
|
101
|
+
setClosing(true);
|
|
102
|
+
closeTimer.current = setTimeout(() => {
|
|
103
|
+
setClosing(false);
|
|
104
|
+
setOpen(false);
|
|
105
|
+
}, SELECT_CLOSE_MS);
|
|
106
|
+
}, []);
|
|
107
|
+
const openPopup = () => {
|
|
108
|
+
if (closeTimer.current !== undefined)
|
|
109
|
+
clearTimeout(closeTimer.current);
|
|
110
|
+
setActiveIndex(currentIndex());
|
|
111
|
+
setPhase('initial');
|
|
112
|
+
setClosing(false);
|
|
113
|
+
setOpen(true);
|
|
114
|
+
};
|
|
115
|
+
const commit = (index) => {
|
|
116
|
+
const option = options[index];
|
|
117
|
+
if (option)
|
|
118
|
+
props.onEdit(option.value);
|
|
119
|
+
close();
|
|
120
|
+
};
|
|
121
|
+
const onTriggerClick = () => {
|
|
122
|
+
if (props.disabled)
|
|
123
|
+
return;
|
|
124
|
+
if (open && !closing)
|
|
125
|
+
close();
|
|
126
|
+
else
|
|
127
|
+
openPopup();
|
|
128
|
+
};
|
|
129
|
+
const onKeyDown = (event) => {
|
|
130
|
+
if (props.disabled)
|
|
131
|
+
return;
|
|
132
|
+
const count = options.length;
|
|
133
|
+
switch (event.key) {
|
|
134
|
+
case 'ArrowDown':
|
|
135
|
+
case 'ArrowUp':
|
|
136
|
+
case 'Enter':
|
|
137
|
+
case ' ':
|
|
138
|
+
event.preventDefault();
|
|
139
|
+
if (!open) {
|
|
140
|
+
openPopup();
|
|
141
|
+
}
|
|
142
|
+
else if (!closing) {
|
|
143
|
+
if (event.key === 'ArrowDown')
|
|
144
|
+
setActiveIndex(index => (index + 1) % count);
|
|
145
|
+
else if (event.key === 'ArrowUp')
|
|
146
|
+
setActiveIndex(index => (index - 1 + count) % count);
|
|
147
|
+
else
|
|
148
|
+
commit(activeIndex);
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
case 'Escape':
|
|
152
|
+
if (open) {
|
|
153
|
+
event.preventDefault();
|
|
154
|
+
event.stopPropagation();
|
|
155
|
+
close();
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
158
|
+
case 'Tab':
|
|
159
|
+
if (open)
|
|
160
|
+
close();
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
useEffect(() => () => {
|
|
165
|
+
if (closeTimer.current !== undefined)
|
|
166
|
+
clearTimeout(closeTimer.current);
|
|
167
|
+
}, []);
|
|
168
|
+
useLayoutEffect(() => {
|
|
169
|
+
if (open && !closing && phase === 'initial') {
|
|
170
|
+
void popupRef.current?.offsetHeight;
|
|
171
|
+
setPhase('open');
|
|
172
|
+
}
|
|
173
|
+
}, [open, closing, phase]);
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
if (!open)
|
|
176
|
+
return;
|
|
177
|
+
const onPointerDown = (event) => {
|
|
178
|
+
const target = event.target;
|
|
179
|
+
if (target instanceof Node && !wrapRef.current?.contains(target))
|
|
180
|
+
close();
|
|
181
|
+
};
|
|
182
|
+
document.addEventListener('pointerdown', onPointerDown);
|
|
183
|
+
return () => document.removeEventListener('pointerdown', onPointerDown);
|
|
184
|
+
}, [open, close]);
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
if (props.disabled && open)
|
|
187
|
+
close();
|
|
188
|
+
}, [props.disabled, open, close]);
|
|
189
|
+
// 使用了皮肤则退回原生select样式防止样式冲突。
|
|
190
|
+
if (isSkinActive()) {
|
|
191
|
+
return (_jsx("select", { id: id, className: css.select, value: value, disabled: props.disabled, onChange: (event) => { props.onEdit(event.target.value); }, children: options.map(option => (_jsx("option", { value: option.value, children: option.label }, option.value))) }));
|
|
192
|
+
}
|
|
193
|
+
const label = options.find(option => option.value === value)?.label ?? '';
|
|
194
|
+
const popupClass = closing
|
|
195
|
+
? `${css.selectPopup} ${css.selectPopupClose}`
|
|
196
|
+
: phase === 'open'
|
|
197
|
+
? `${css.selectPopup} ${css.selectPopupOpen}`
|
|
198
|
+
: css.selectPopup;
|
|
199
|
+
return (_jsxs("div", { className: css.selectWrap, ref: wrapRef, children: [_jsxs("button", { type: "button", id: id, className: `${css.select} ${css.selectButton}`, disabled: props.disabled, "aria-haspopup": "listbox", "aria-expanded": open, "aria-activedescendant": open ? `${id}-o${activeIndex}` : undefined, "aria-invalid": props.invalid || undefined, onClick: onTriggerClick, onKeyDown: onKeyDown, children: [_jsx("span", { className: css.selectLabel, children: label }), _jsx("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: open ? `${css.selectChevron} ${css.selectChevronOpen}` : css.selectChevron, "aria-hidden": "true", children: _jsx("path", { d: "M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z", fill: "currentColor" }) })] }), open
|
|
200
|
+
? (_jsx("div", { className: popupClass, role: "listbox", ref: popupRef, children: options.map((option, index) => (_jsx("div", { id: `${id}-o${index}`, role: "option", "aria-selected": option.value === value, className: `${css.selectOption}${option.value === value ? ` ${css.selectOptionSelected}` : ''}${index === activeIndex && !closing ? ` ${css.selectOptionActive}` : ''}`, onClick: () => { commit(index); }, children: option.label }, option.value))) }))
|
|
201
|
+
: null] }));
|
|
202
|
+
}
|
|
68
203
|
/** A staged boolean field: 继承 / 开 / 关. */
|
|
69
204
|
export function BooleanField(props) {
|
|
70
205
|
return (_jsxs("div", { className: css.field, children: [_jsxs("div", { className: css.head, children: [_jsx("label", { className: css.label, htmlFor: props.id, children: props.label }), props.overridden
|
|
71
206
|
? (_jsxs("span", { className: css.badges, children: [_jsx("span", { className: css.badge, children: props.overriddenLabel }), _jsx("button", { type: "button", className: css.reset, disabled: props.disabled, onClick: props.onReset, children: props.resetLabel })] }))
|
|
72
|
-
: null] }),
|
|
207
|
+
: null] }), _jsx(SelectField, { id: props.id, options: [
|
|
208
|
+
{ value: '', label: props.inheritLabel },
|
|
209
|
+
{ value: 'true', label: props.onLabel },
|
|
210
|
+
{ value: 'false', label: props.offLabel },
|
|
211
|
+
], value: props.text, disabled: props.disabled, invalid: props.invalid, onEdit: props.onEdit }), _jsx("p", { className: css.hint, children: props.hint })] }));
|
|
73
212
|
}
|
|
74
213
|
/** A staged enumerated field rendered as a select. */
|
|
75
214
|
export function ChoiceField(props) {
|
|
76
215
|
return (_jsxs("div", { className: css.field, children: [_jsxs("div", { className: css.head, children: [_jsx("label", { className: css.label, htmlFor: props.id, children: props.label }), props.overridden
|
|
77
216
|
? (_jsxs("span", { className: css.badges, children: [_jsx("span", { className: css.badge, children: props.overriddenLabel }), _jsx("button", { type: "button", className: css.reset, disabled: props.disabled, onClick: props.onReset, children: props.resetLabel })] }))
|
|
78
|
-
: null] }),
|
|
217
|
+
: null] }), _jsx(SelectField, { id: props.id, options: [{ value: '', label: props.inheritLabel }, ...props.choices], value: props.text, disabled: props.disabled, invalid: props.invalid, onEdit: props.onEdit }), _jsx("p", { className: props.invalid ? css.invalid : css.hint, children: props.invalid ? props.invalidLabel : props.hint })] }));
|
|
79
218
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoteEntry.d.ts","sourceRoot":"","sources":["../../../src/client/RemoteEntry.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAQjF,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AAwBrF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,gBAAgB,+
|
|
1
|
+
{"version":3,"file":"RemoteEntry.d.ts","sourceRoot":"","sources":["../../../src/client/RemoteEntry.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAQjF,wEAAwE;AACxE,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;AAwBrF;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,gBAAgB,+BAuLvE"}
|
|
@@ -52,6 +52,10 @@ export function RemoteEntry({ wide, useWorkspaces, t }) {
|
|
|
52
52
|
useEffect(() => { stateRef.current = state; }, [state]);
|
|
53
53
|
const [copied, setCopied] = useState(false);
|
|
54
54
|
const eventSource = useRef(undefined);
|
|
55
|
+
// Generation counter for the open flow: closing (or re-opening) the panel
|
|
56
|
+
// bumps it, so an in-flight issue() that resolves after a close does not
|
|
57
|
+
// spawn a stray EventSource.
|
|
58
|
+
const openSeq = useRef(0);
|
|
55
59
|
// The current workspace (the recent-workspace projection the shell's New
|
|
56
60
|
// Session flow targets) — the deep-link target for the phone.
|
|
57
61
|
const workspaceId = useWorkspaces(s => s.recentWorkspaceId);
|
|
@@ -98,8 +102,14 @@ export function RemoteEntry({ wide, useWorkspaces, t }) {
|
|
|
98
102
|
};
|
|
99
103
|
}, [workspaceId]);
|
|
100
104
|
const openPanel = useCallback(async () => {
|
|
105
|
+
const seq = ++openSeq.current;
|
|
101
106
|
setOpen(true);
|
|
102
107
|
const next = await mint();
|
|
108
|
+
// A close (or re-open) during the await invalidates this issue: skip the
|
|
109
|
+
// state write and the stream so a panel closed mid-mint neither leaks an
|
|
110
|
+
// EventSource nor resurrects a stale QR.
|
|
111
|
+
if (seq !== openSeq.current)
|
|
112
|
+
return;
|
|
103
113
|
setState(next);
|
|
104
114
|
// Live status: the desktop panel mirrors the pairing service state. The
|
|
105
115
|
// stream makes sense in the ready state and on the lan-required banner —
|
|
@@ -137,6 +147,7 @@ export function RemoteEntry({ wide, useWorkspaces, t }) {
|
|
|
137
147
|
};
|
|
138
148
|
}, [mint]);
|
|
139
149
|
const closePanel = useCallback(() => {
|
|
150
|
+
openSeq.current += 1;
|
|
140
151
|
closeEventSource();
|
|
141
152
|
setOpen(false);
|
|
142
153
|
}, [closeEventSource]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The remote-control settings card: pairing security and device limits.
|
|
3
|
-
* Registers into the `
|
|
4
|
-
*
|
|
3
|
+
* Registers into the `web-ui.plugin.item` child slot the Web UI plugin group
|
|
4
|
+
* renders, bound to the `remote-web-ui` settings namespace.
|
|
5
5
|
*/
|
|
6
6
|
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
7
7
|
import type { SettingsScope, SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateEntry.d.ts","sourceRoot":"","sources":["../../../src/client/UpdateEntry.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UpdateEntry.d.ts","sourceRoot":"","sources":["../../../src/client/UpdateEntry.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAOnE,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,IAAI,EAAE,OAAO,CAAA;IACb,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;CACzB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,gBAAgB,+BA8GxD"}
|
|
@@ -2,8 +2,9 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
2
2
|
/**
|
|
3
3
|
* The sidebar update seat: the download trigger beside the remote-control
|
|
4
4
|
* trigger plus the update panel modal. Owns the flow — probe the registry
|
|
5
|
-
* on open,
|
|
6
|
-
* outcome (restart hint on success,
|
|
5
|
+
* on open, show the result, and let the user start the update from the
|
|
6
|
+
* result view (#507), then report the outcome (restart hint on success,
|
|
7
|
+
* translated failure on error).
|
|
7
8
|
* Component-local state per the client stack rules.
|
|
8
9
|
*/
|
|
9
10
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -65,9 +66,11 @@ export function UpdateEntry({ wide, t }) {
|
|
|
65
66
|
setView({ kind: "result", status });
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
69
|
+
// Checking never starts an update by itself (#507): the result view
|
|
70
|
+
// carries the confirmation button that calls startUpdate.
|
|
68
71
|
setView({ kind: "result", status });
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
}, [t]);
|
|
73
|
+
const startUpdate = useCallback(async (status) => {
|
|
71
74
|
if (status.mode !== "npm" || !status.outdated)
|
|
72
75
|
return;
|
|
73
76
|
setView({ kind: "updating", status });
|
|
@@ -105,5 +108,5 @@ export function UpdateEntry({ wide, t }) {
|
|
|
105
108
|
};
|
|
106
109
|
}, [probeAvailability]);
|
|
107
110
|
const updateLabel = updateAvailable ? t("update.availableLabel") : t("update.label");
|
|
108
|
-
return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: css.trigger, "data-wide": wide ? undefined : "rail", "data-update-available": updateAvailable ? "true" : undefined, "aria-label": updateLabel, title: updateLabel, onClick: openPanel, children: _jsx(IconDownloadOutline16, { size: wide ? 16 : 18 }) }), open && createPortal((_jsxs("div", { className: css.overlay, role: "presentation", children: [_jsx("div", { className: css.mask, "aria-hidden": "true", onClick: closePanel }), _jsx(UpdatePanel, { t: t, view: view, onClose: closePanel, onRecheck: () => { void check(); } })] })), document.body)] }));
|
|
111
|
+
return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: css.trigger, "data-wide": wide ? undefined : "rail", "data-update-available": updateAvailable ? "true" : undefined, "aria-label": updateLabel, title: updateLabel, onClick: openPanel, children: _jsx(IconDownloadOutline16, { size: wide ? 16 : 18 }) }), open && createPortal((_jsxs("div", { className: css.overlay, role: "presentation", children: [_jsx("div", { className: css.mask, "aria-hidden": "true", onClick: closePanel }), _jsx(UpdatePanel, { t: t, view: view, onClose: closePanel, onRecheck: () => { void check(); }, onStartUpdate: (status) => { void startUpdate(status); } })] })), document.body)] }));
|
|
109
112
|
}
|
|
@@ -30,11 +30,13 @@ export interface UpdatePanelProps {
|
|
|
30
30
|
onClose(): void;
|
|
31
31
|
/** Re-run the check from a terminal state. */
|
|
32
32
|
onRecheck(): void;
|
|
33
|
+
/** Start the update from the result view (the confirmation step, #507). */
|
|
34
|
+
onStartUpdate(status: UpdateStatus): void;
|
|
33
35
|
}
|
|
34
36
|
/**
|
|
35
37
|
* Render the update panel.
|
|
36
38
|
* @param props - copy, view state, and actions.
|
|
37
39
|
* @returns the panel element tree.
|
|
38
40
|
*/
|
|
39
|
-
export declare function UpdatePanel({ t, view, onClose, onRecheck }: UpdatePanelProps): import("react").JSX.Element;
|
|
41
|
+
export declare function UpdatePanel({ t, view, onClose, onRecheck, onStartUpdate }: UpdatePanelProps): import("react").JSX.Element;
|
|
40
42
|
//# sourceMappingURL=UpdatePanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdatePanel.d.ts","sourceRoot":"","sources":["../../../src/client/UpdatePanel.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAEnE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAGjE,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD,qDAAqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IACxB,IAAI,EAAE,UAAU,CAAA;IAChB,OAAO,IAAI,IAAI,CAAA;IACf,8CAA8C;IAC9C,SAAS,IAAI,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"UpdatePanel.d.ts","sourceRoot":"","sources":["../../../src/client/UpdatePanel.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAEnE,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAGjE,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD,qDAAqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;IACxB,IAAI,EAAE,UAAU,CAAA;IAChB,OAAO,IAAI,IAAI,CAAA;IACf,8CAA8C;IAC9C,SAAS,IAAI,IAAI,CAAA;IACjB,2EAA2E;IAC3E,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAA;CAC1C;AAYD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,gBAAgB,+BAiD3F"}
|
|
@@ -14,11 +14,11 @@ function anchorLatest(status) {
|
|
|
14
14
|
* @param props - copy, view state, and actions.
|
|
15
15
|
* @returns the panel element tree.
|
|
16
16
|
*/
|
|
17
|
-
export function UpdatePanel({ t, view, onClose, onRecheck }) {
|
|
17
|
+
export function UpdatePanel({ t, view, onClose, onRecheck, onStartUpdate }) {
|
|
18
18
|
const status = view.kind === "result" || view.kind === "updating" ? view.status : undefined;
|
|
19
19
|
const title = view.kind === "done" && view.result.ok ? t("update.done") : t("update.title");
|
|
20
20
|
const subtitle = subtitleOf(t, view);
|
|
21
|
-
return (_jsxs("div", { className: css.panel, role: "dialog", "aria-modal": "true", "aria-label": title, children: [_jsxs("div", { className: css.header, children: [_jsxs("div", { className: css.heading, children: [_jsx("h2", { className: css.title, children: title }), subtitle !== undefined && _jsx("p", { className: css.subtitle, children: subtitle })] }), _jsx("button", { type: "button", className: css.close, "aria-label": t("update.close"), onClick: onClose, children: _jsx(IconCloseOutline16, {}) })] }), view.kind === "checking" && _jsx("p", { className: css.updateStatus, children: t("update.checking") }), view.kind === "result" && status !== undefined && _jsx(ResultBody, { t: t, status: status }), view.kind === "updating" && status !== undefined && (_jsxs("div", { children: [_jsx("p", { className: css.updateStatus, children: t("update.updating", { name: anchorName(status) ?? "", version: anchorLatest(status) ?? "" }) }), _jsx(PackageList, { status: status })] })), view.kind === "done" && _jsx(DoneBody, { t: t, result: view.result }), view.kind === "error" && (_jsxs("div", { children: [_jsx("p", { className: css.updateError, children: view.message }), view.detail !== undefined && _jsx("pre", { className: css.updateOutput, children: view.detail })] })), (view.kind === "done" || view.kind === "error") && (_jsx("div", { className: css.updateActions, children: _jsxs("button", { type: "button", className: css.updateRetry, onClick: onRecheck, children: [_jsx(IconRefreshOutline16, {}), " ", t("update.retry")] }) }))] }));
|
|
21
|
+
return (_jsxs("div", { className: css.panel, role: "dialog", "aria-modal": "true", "aria-label": title, children: [_jsxs("div", { className: css.header, children: [_jsxs("div", { className: css.heading, children: [_jsx("h2", { className: css.title, children: title }), subtitle !== undefined && _jsx("p", { className: css.subtitle, children: subtitle })] }), _jsx("button", { type: "button", className: css.close, "aria-label": t("update.close"), onClick: onClose, children: _jsx(IconCloseOutline16, {}) })] }), view.kind === "checking" && _jsx("p", { className: css.updateStatus, children: t("update.checking") }), view.kind === "result" && status !== undefined && _jsx(ResultBody, { t: t, status: status }), view.kind === "result" && status !== undefined && status.mode === "npm" && status.outdated && status.error === undefined && (_jsx("div", { className: css.updateActions, children: _jsx("button", { type: "button", className: css.updateRetry, onClick: () => onStartUpdate(status), children: t("update.start") }) })), view.kind === "updating" && status !== undefined && (_jsxs("div", { children: [_jsx("p", { className: css.updateStatus, children: t("update.updating", { name: anchorName(status) ?? "", version: anchorLatest(status) ?? "" }) }), _jsx("p", { className: css.updateDetail, children: t("update.cooldownNotice") }), _jsx(PackageList, { status: status })] })), view.kind === "done" && _jsx(DoneBody, { t: t, result: view.result }), view.kind === "error" && (_jsxs("div", { children: [_jsx("p", { className: css.updateError, children: view.message }), view.detail !== undefined && _jsx("pre", { className: css.updateOutput, children: view.detail })] })), (view.kind === "done" || view.kind === "error") && (_jsx("div", { className: css.updateActions, children: _jsxs("button", { type: "button", className: css.updateRetry, onClick: onRecheck, children: [_jsx(IconRefreshOutline16, {}), " ", t("update.retry")] }) }))] }));
|
|
22
22
|
}
|
|
23
23
|
/** The subtitle copy per view state (absent on plain results). */
|
|
24
24
|
function subtitleOf(t, view) {
|
|
@@ -50,7 +50,7 @@ function ResultBody({ t, status }) {
|
|
|
50
50
|
return (_jsxs("div", { children: [_jsx("p", { className: css.updateStatus, children: t("update.offline") }), _jsx("p", { className: css.updateDetail, children: t("update.offlineDetail") })] }));
|
|
51
51
|
}
|
|
52
52
|
if (status.outdated) {
|
|
53
|
-
return (_jsxs("div", { children: [_jsx("p", { className: css.updateStatus, children: t("update.found") }), _jsx("p", { className: css.updateDetail, children: anchor !== undefined ? t("update.foundDetail", { name: anchor, version: latest ?? "" }) : "" })] }));
|
|
53
|
+
return (_jsxs("div", { children: [_jsx("p", { className: css.updateStatus, children: t("update.found") }), _jsx("p", { className: css.updateDetail, children: anchor !== undefined ? t("update.foundDetail", { name: anchor, version: latest ?? "" }) : "" }), _jsx("p", { className: css.updateDetail, children: t("update.cooldownNotice") })] }));
|
|
54
54
|
}
|
|
55
55
|
return (_jsxs("div", { children: [_jsx("p", { className: css.updateStatus, children: t("update.upToDate") }), anchor !== undefined && latest !== undefined && (_jsx("p", { className: css.updateDetail, children: t("update.upToDateDetail", { name: anchor, version: latest }) })), _jsx(PackageList, { status: status })] }));
|
|
56
56
|
}
|
|
@@ -78,7 +78,9 @@ export declare const zh: {
|
|
|
78
78
|
'update.upToDateDetail': string;
|
|
79
79
|
'update.found': string;
|
|
80
80
|
'update.foundDetail': string;
|
|
81
|
+
'update.start': string;
|
|
81
82
|
'update.updating': string;
|
|
83
|
+
'update.cooldownNotice': string;
|
|
82
84
|
'update.updatingTitle': string;
|
|
83
85
|
'update.done': string;
|
|
84
86
|
'update.doneDetail': string;
|
|
@@ -187,7 +189,9 @@ export declare const en: {
|
|
|
187
189
|
'update.upToDateDetail': string;
|
|
188
190
|
'update.found': string;
|
|
189
191
|
'update.foundDetail': string;
|
|
192
|
+
'update.start': string;
|
|
190
193
|
'update.updating': string;
|
|
194
|
+
'update.cooldownNotice': string;
|
|
191
195
|
'update.updatingTitle': string;
|
|
192
196
|
'update.done': string;
|
|
193
197
|
'update.doneDetail': string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAE/E,mEAAmE;AACnE,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAE/E,mEAAmE;AACnE,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2GmB,CAAA;AAElC,sCAAsC;AACtC,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,EAAE,CAAA;AAEvC,wDAAwD;AACxD,MAAM,MAAM,eAAe,GAAG,SAAS,CAAA;AAEvC,mEAAmE;AACnE,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2GsB,CAAA"}
|
|
@@ -79,9 +79,11 @@ export const zh = {
|
|
|
79
79
|
'update.upToDate': '当前已是最新版本',
|
|
80
80
|
'update.upToDateDetail': '{name} 已是最新版本 v{version}。',
|
|
81
81
|
'update.found': '发现新版本',
|
|
82
|
-
'update.foundDetail': '{name} 有新版本 v{version}
|
|
82
|
+
'update.foundDetail': '{name} 有新版本 v{version}。确认后开始更新。',
|
|
83
|
+
'update.start': '开始更新',
|
|
83
84
|
'update.updating': '正在更新 {name} 至 v{version},可能需要 1-2 分钟…',
|
|
84
|
-
'update.
|
|
85
|
+
'update.cooldownNotice': '本次更新由你主动触发,将跳过 pnpm 的 24 小时发布冷却期(供应链保护)直接安装所选版本。',
|
|
86
|
+
'update.updatingTitle': '正在更新…',
|
|
85
87
|
'update.done': '更新完成',
|
|
86
88
|
'update.doneDetail': '所有组件已更新到最新版本。',
|
|
87
89
|
'update.restartHint': '请重启 dsh web 使新版本生效:在终端按 Ctrl+C 停止后重新运行 dsh web。',
|
|
@@ -186,9 +188,11 @@ export const en = {
|
|
|
186
188
|
'update.upToDate': 'Everything is up to date',
|
|
187
189
|
'update.upToDateDetail': '{name} is at the latest version v{version}.',
|
|
188
190
|
'update.found': 'A new version is available',
|
|
189
|
-
'update.foundDetail': '{name} has a newer release v{version}
|
|
191
|
+
'update.foundDetail': '{name} has a newer release v{version}. Confirm to start the update.',
|
|
192
|
+
'update.start': 'Update now',
|
|
190
193
|
'update.updating': 'Updating {name} to v{version}; this may take 1-2 minutes…',
|
|
191
|
-
'update.
|
|
194
|
+
'update.cooldownNotice': 'This user-initiated update bypasses pnpm\'s 24-hour release cooldown (supply-chain protection) and installs the selected version immediately.',
|
|
195
|
+
'update.updatingTitle': 'Updating…',
|
|
192
196
|
'update.done': 'Update complete',
|
|
193
197
|
'update.doneDetail': 'All components are up to date.',
|
|
194
198
|
'update.restartHint': 'Restart dsh web for the new version to take effect: stop it with Ctrl+C in the terminal, then run dsh web again.',
|
|
@@ -83,12 +83,7 @@ export declare function readPairParams(search: string): {
|
|
|
83
83
|
pair?: string;
|
|
84
84
|
workspace?: string;
|
|
85
85
|
};
|
|
86
|
-
/**
|
|
87
|
-
* Strip one query parameter from the current URL without reloading.
|
|
88
|
-
* @param name - the parameter to remove.
|
|
89
|
-
* @returns the new search string ('' when empty).
|
|
90
|
-
*/
|
|
91
|
-
export declare function stripParam(name: string): string; /** Human-readable expiry clock, e.g. "10:35". */
|
|
86
|
+
/** Human-readable expiry clock, e.g. "10:35". */
|
|
92
87
|
export declare function formatClock(epochMs: number): string;
|
|
93
88
|
/**
|
|
94
89
|
* Copy text to the clipboard with a fallback for insecure contexts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pair-api.d.ts","sourceRoot":"","sources":["../../../src/client/pair-api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wBAAwB;AACxB,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,IAAI,CAAA;IACR,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,cAAc,CAAA;CACrB;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,iBAAiB,CAAA;CACxB;AAED,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,WAAW,CAAA;CAClB;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,qBAAqB,CAAA;AAExG,8BAA8B;AAC9B,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,WAAW,CAAA;CAAE,CAAA;AAEjF,sEAAsE;AACtE,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAA;IACxC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,kCAAkC;AAClC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc,CAAA;IAC5E,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAC3B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAgB9F;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,aAAa,CAAC,CAUrF;AAED,iEAAiE;AACjE,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAG9C;AAED,mFAAmF;AACnF,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnD;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAQpF;AAED
|
|
1
|
+
{"version":3,"file":"pair-api.d.ts","sourceRoot":"","sources":["../../../src/client/pair-api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wBAAwB;AACxB,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,IAAI,CAAA;IACR,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,8DAA8D;IAC9D,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,cAAc,CAAA;CACrB;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,iBAAiB,CAAA;CACxB;AAED,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,KAAK,CAAA;IACT,IAAI,EAAE,WAAW,CAAA;CAClB;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,qBAAqB,CAAA;AAExG,8BAA8B;AAC9B,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,WAAW,CAAA;CAAE,CAAA;AAEjF,sEAAsE;AACtE,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAA;IACxC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,kCAAkC;AAClC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc,CAAA;IAC5E,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAC3B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAgB9F;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,aAAa,CAAC,CAUrF;AAED,iEAAiE;AACjE,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAG9C;AAED,mFAAmF;AACnF,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAEnD;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAQpF;AAED,iDAAiD;AACjD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKnD;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAsB7D"}
|
|
@@ -74,16 +74,7 @@ export function readPairParams(search) {
|
|
|
74
74
|
...(workspace !== null && workspace !== '' ? { workspace } : {}),
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
-
/**
|
|
78
|
-
* Strip one query parameter from the current URL without reloading.
|
|
79
|
-
* @param name - the parameter to remove.
|
|
80
|
-
* @returns the new search string ('' when empty).
|
|
81
|
-
*/
|
|
82
|
-
export function stripParam(name) {
|
|
83
|
-
const url = new URL(window.location.href);
|
|
84
|
-
url.searchParams.delete(name);
|
|
85
|
-
return url.search;
|
|
86
|
-
} /** Human-readable expiry clock, e.g. "10:35". */
|
|
77
|
+
/** Human-readable expiry clock, e.g. "10:35". */
|
|
87
78
|
export function formatClock(epochMs) {
|
|
88
79
|
const date = new Date(epochMs);
|
|
89
80
|
const hours = String(date.getHours()).padStart(2, '0');
|
package/lib/types/gate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAGlD;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASvF;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAQvE;AAED,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAKlE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,cAAc,EACvB,oBAAoB,GAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAQ,EACtD,OAAO,GAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAQ,GACxC,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAGlD;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASvF;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAQvE;AAED,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAKlE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,cAAc,EACvB,oBAAoB,GAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAQ,EACtD,OAAO,GAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAQ,GACxC,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAW9H;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAIhG"}
|
package/lib/types/gate.js
CHANGED
|
@@ -86,6 +86,8 @@ export function makeGateListener(service, requirePairingForLan = true, enabled =
|
|
|
86
86
|
const require = typeof requirePairingForLan === 'function' ? requirePairingForLan() : requirePairingForLan;
|
|
87
87
|
if (!require)
|
|
88
88
|
return next();
|
|
89
|
+
// The paired-device cookie is a full host-API credential: it passes this
|
|
90
|
+
// gate for the whole ApiProxy surface, not just the /m/api allowlist.
|
|
89
91
|
return isPairedDeviceRequest(service, request) ? next() : false;
|
|
90
92
|
};
|
|
91
93
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* rpc/mux layers).
|
|
6
6
|
*/
|
|
7
7
|
import type { WorkspaceView } from '@deepseek-ai/dsh-host-apiproxy/api/workspace';
|
|
8
|
+
import type { AgentPresetEntry } from '@deepseek-ai/dsh-host-apiproxy/api/agent-presets';
|
|
8
9
|
import type { SessionSummary, SessionModels, SessionProjectionsBlock } from '@deepseek-ai/dsh-host-apiproxy/api/sessions';
|
|
9
10
|
/** One session.list page. */
|
|
10
11
|
export interface SessionPage {
|
|
@@ -19,6 +20,12 @@ export interface CreatedSession {
|
|
|
19
20
|
/** The composition the new session runs (echoed so the caller can label it). */
|
|
20
21
|
agentPreset?: string;
|
|
21
22
|
}
|
|
23
|
+
/** Agent presets available when composing a new session. */
|
|
24
|
+
export interface AgentPresetRoster {
|
|
25
|
+
presets: readonly AgentPresetEntry[];
|
|
26
|
+
authorable: boolean;
|
|
27
|
+
hasDocument: boolean;
|
|
28
|
+
}
|
|
22
29
|
/** One history page (already bounded to whole messages by the host). */
|
|
23
30
|
export interface HistoryPage {
|
|
24
31
|
events: import('@deepseek-ai/dsh-host-apiproxy/api/sessions').HistoryEntry[];
|
|
@@ -40,6 +47,8 @@ export declare function listWorkspaces(): Promise<WorkspaceView[]>;
|
|
|
40
47
|
export declare function fetchMobilePreferences(): Promise<MobilePreferences>;
|
|
41
48
|
/** One session.list page; omit the cursor for the first page. */
|
|
42
49
|
export declare function listSessions(cursor?: string): Promise<SessionPage>;
|
|
50
|
+
/** Read the available agent compositions for a new session. */
|
|
51
|
+
export declare function listAgentPresets(): Promise<AgentPresetRoster>;
|
|
43
52
|
/**
|
|
44
53
|
* Create a blank session (entity birth precedes the first message). Name a
|
|
45
54
|
* workspace to attach it there, or a cwd; omitting both uses the host cwd.
|
|
@@ -47,6 +56,7 @@ export declare function listSessions(cursor?: string): Promise<SessionPage>;
|
|
|
47
56
|
export declare function createSession(options?: {
|
|
48
57
|
workspaceId?: string;
|
|
49
58
|
cwd?: string;
|
|
59
|
+
agentPreset?: string;
|
|
50
60
|
}): Promise<CreatedSession>;
|
|
51
61
|
/** One history window; omit beforeSeq for the tail page, pass a signal to abort. */
|
|
52
62
|
export declare function history(sessionId: string, beforeSeq?: number, maxMessages?: number, signal?: AbortSignal): Promise<HistoryPage>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/mobile/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAA;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAA;AAGzH,6BAA6B;AAC7B,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,6CAA6C,EAAE,YAAY,EAAE,CAAA;IAC5E,OAAO,EAAE,OAAO,CAAA;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,uBAAuB,CAAA;CACtC;AAED,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,iBAAiB,EAAE,OAAO,CAAA;CAC3B;AAED,kEAAkE;AAClE,wBAAsB,cAAc,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAG/D;AAED,yFAAyF;AACzF,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAEzE;AAED,iEAAiE;AACjE,wBAAsB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAExE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/mobile/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAA;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAA;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAA;AAGzH,6BAA6B;AAC7B,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,gFAAgF;IAChF,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,4DAA4D;AAC5D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAA;IACpC,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,EAAE,OAAO,CAAA;CACrB;AAED,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,6CAA6C,EAAE,YAAY,EAAE,CAAA;IAC5E,OAAO,EAAE,OAAO,CAAA;IAChB;;;OAGG;IACH,WAAW,CAAC,EAAE,uBAAuB,CAAA;CACtC;AAED,4EAA4E;AAC5E,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,iBAAiB,EAAE,OAAO,CAAA;CAC3B;AAED,kEAAkE;AAClE,wBAAsB,cAAc,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAG/D;AAED,yFAAyF;AACzF,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAEzE;AAED,iEAAiE;AACjE,wBAAsB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAExE;AAED,+DAA+D;AAC/D,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAEnE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACzE,OAAO,CAAC,cAAc,CAAC,CAEzB;AAED,oFAAoF;AACpF,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,WAAW,SAAK,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,WAAW,CAAC,CAMtB;AAED,qEAAqE;AACrE,wBAAsB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3E;AAED,wEAAwE;AACxE,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMnF;AAED,oFAAoF;AACpF,wBAAsB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAEtE;AAED,2FAA2F;AAC3F,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE,OAAO,CAAC;IAAE,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,CAOtF"}
|
package/lib/types/mobile/api.js
CHANGED
|
@@ -18,6 +18,10 @@ export async function fetchMobilePreferences() {
|
|
|
18
18
|
export async function listSessions(cursor) {
|
|
19
19
|
return await callUnary('session.list', cursor === undefined ? {} : { cursor });
|
|
20
20
|
}
|
|
21
|
+
/** Read the available agent compositions for a new session. */
|
|
22
|
+
export async function listAgentPresets() {
|
|
23
|
+
return await callUnary('agentPreset.list', {});
|
|
24
|
+
}
|
|
21
25
|
/**
|
|
22
26
|
* Create a blank session (entity birth precedes the first message). Name a
|
|
23
27
|
* workspace to attach it there, or a cwd; omitting both uses the host cwd.
|
|
@@ -114,4 +114,28 @@ export interface WireEvent {
|
|
|
114
114
|
* @returns messages sorted by seq.
|
|
115
115
|
*/
|
|
116
116
|
export declare function foldEvents(events: readonly WireEvent[], existing?: readonly RenderMessage[]): RenderMessage[];
|
|
117
|
+
/**
|
|
118
|
+
* Incremental folder for one message stream. Live chat folds one event at a
|
|
119
|
+
* time; rebuilding the five index maps by scanning every message per event
|
|
120
|
+
* made that path O(n) per event (O(n * events) per turn). A folder keeps the
|
|
121
|
+
* indexes alive across folds, applies each event in O(1) map operations, and
|
|
122
|
+
* returns the previous snapshot identity unchanged when nothing applied, so
|
|
123
|
+
* React skips the re-render entirely. Replayed events are no-ops: the maxSeq
|
|
124
|
+
* watermark advanced by the first application skips them, which also makes a
|
|
125
|
+
* double-invoked React state updater harmless.
|
|
126
|
+
*/
|
|
127
|
+
export declare class EventFolder {
|
|
128
|
+
private state;
|
|
129
|
+
private snapshotList;
|
|
130
|
+
/** @param initial - seed rows (history tail load); omit for an empty stream. */
|
|
131
|
+
constructor(initial?: readonly RenderMessage[]);
|
|
132
|
+
/** Fold one batch incrementally; returns the current snapshot list. */
|
|
133
|
+
fold(events: readonly WireEvent[]): RenderMessage[];
|
|
134
|
+
/** Replace the whole stream (history reload / session switch). */
|
|
135
|
+
seed(messages: readonly RenderMessage[]): void;
|
|
136
|
+
/** Prepend an older history page (exact seam; no overlapping seqs). */
|
|
137
|
+
prepend(older: readonly RenderMessage[]): void;
|
|
138
|
+
/** Current snapshot list; a fresh copy whenever the folder changed. */
|
|
139
|
+
snapshot(): RenderMessage[];
|
|
140
|
+
}
|
|
117
141
|
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/mobile/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,WAAW,aAAa;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAA;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,sFAAsF;IACtF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;IACzB;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAC1B,CAAA;IACD,sFAAsF;IACtF,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,gEAAgE;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAA;CAC1B;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/mobile/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,WAAW,aAAa;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,EAAE,CAAA;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,kFAAkF;IAClF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;IAC1B,sFAAsF;IACtF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;IACzB;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,MAAM,CAAA;QACpB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAC1B,CAAA;IACD,sFAAsF;IACtF,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,gEAAgE;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAA;CAC1B;AAweD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,GAAG,aAAa,EAAE,CAE7G;AAED;;;;;;;;;GASG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,YAAY,CAA6B;IAEjD,gFAAgF;IAChF,YAAY,OAAO,CAAC,EAAE,SAAS,aAAa,EAAE,EAE7C;IAED,uEAAuE;IACvE,IAAI,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,aAAa,EAAE,CAWlD;IAED,kEAAkE;IAClE,IAAI,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAG7C;IAED,uEAAuE;IACvE,OAAO,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAG7C;IAED,uEAAuE;IACvE,QAAQ,IAAI,aAAa,EAAE,CAI1B;CACF"}
|