@hxdhxd/harmony-flow-ui 0.3.0 → 0.4.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.
Files changed (56) hide show
  1. package/README.md +25 -1
  2. package/dist/index.cjs +1535 -1319
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.css +325 -103
  5. package/dist/index.css.map +1 -1
  6. package/dist/index.d.cts +12 -9
  7. package/dist/index.d.ts +12 -9
  8. package/dist/index.js +1520 -1304
  9. package/dist/index.js.map +1 -1
  10. package/dist/monaco-assets/LICENSE.monaco.txt +21 -0
  11. package/dist/monaco-assets/ThirdPartyNotices.txt +448 -0
  12. package/dist/monaco-assets/chunks/chunk-2KWDR4W3.js +1 -0
  13. package/dist/monaco-assets/chunks/chunk-2KWDR4W3.js.gz +0 -0
  14. package/dist/monaco-assets/chunks/chunk-6CWAYXCI.js +870 -0
  15. package/dist/monaco-assets/chunks/chunk-6CWAYXCI.js.gz +0 -0
  16. package/dist/monaco-assets/chunks/chunk-AD5KIREA.js +61 -0
  17. package/dist/monaco-assets/chunks/chunk-AD5KIREA.js.gz +0 -0
  18. package/dist/monaco-assets/chunks/chunk-NYAGVHXV.js +1 -0
  19. package/dist/monaco-assets/chunks/chunk-NYAGVHXV.js.gz +0 -0
  20. package/dist/monaco-assets/chunks/javascript-Q5O4BLC5.css +1 -0
  21. package/dist/monaco-assets/chunks/javascript-Q5O4BLC5.css.gz +0 -0
  22. package/dist/monaco-assets/chunks/javascript-R6AQIXSX.js +1 -0
  23. package/dist/monaco-assets/chunks/javascript-R6AQIXSX.js.gz +0 -0
  24. package/dist/monaco-assets/chunks/jsonMode-I4YAYKCC.css +1 -0
  25. package/dist/monaco-assets/chunks/jsonMode-I4YAYKCC.css.gz +0 -0
  26. package/dist/monaco-assets/chunks/jsonMode-PVXHFVY4.js +10 -0
  27. package/dist/monaco-assets/chunks/jsonMode-PVXHFVY4.js.gz +0 -0
  28. package/dist/monaco-assets/chunks/tsMode-4CIG5YX5.js +11 -0
  29. package/dist/monaco-assets/chunks/tsMode-4CIG5YX5.js.gz +0 -0
  30. package/dist/monaco-assets/chunks/tsMode-LEY4YWTP.css +1 -0
  31. package/dist/monaco-assets/chunks/tsMode-LEY4YWTP.css.gz +0 -0
  32. package/dist/monaco-assets/chunks/typescript-DYIPN6WN.js +1 -0
  33. package/dist/monaco-assets/chunks/typescript-DYIPN6WN.js.gz +0 -0
  34. package/dist/monaco-assets/chunks/typescript-Z6MD7EEQ.css +1 -0
  35. package/dist/monaco-assets/chunks/typescript-Z6MD7EEQ.css.gz +0 -0
  36. package/dist/monaco-assets/editor.worker.js +30 -0
  37. package/dist/monaco-assets/editor.worker.js.gz +0 -0
  38. package/dist/monaco-assets/fonts/codicon-KP4OV2OO.ttf +0 -0
  39. package/dist/monaco-assets/json.worker.js +62 -0
  40. package/dist/monaco-assets/json.worker.js.gz +0 -0
  41. package/dist/monaco-assets/manifest.json +5 -0
  42. package/dist/monaco-assets/runtime.css +1 -0
  43. package/dist/monaco-assets/runtime.css.gz +0 -0
  44. package/dist/monaco-assets/runtime.js +1 -0
  45. package/dist/monaco-assets/runtime.js.gz +0 -0
  46. package/dist/monaco-assets/typescript.worker.js +67740 -0
  47. package/dist/monaco-assets/typescript.worker.js.gz +0 -0
  48. package/dist/monaco.cjs +521 -0
  49. package/dist/monaco.cjs.map +1 -0
  50. package/dist/monaco.css +35 -0
  51. package/dist/monaco.css.map +1 -0
  52. package/dist/monaco.d.cts +22 -0
  53. package/dist/monaco.d.ts +22 -0
  54. package/dist/monaco.js +494 -0
  55. package/dist/monaco.js.map +1 -0
  56. package/package.json +11 -3
@@ -0,0 +1,521 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/monaco/index.ts
21
+ var monaco_exports = {};
22
+ __export(monaco_exports, {
23
+ MonacoCodeEditor: () => MonacoCodeEditor
24
+ });
25
+ module.exports = __toCommonJS(monaco_exports);
26
+
27
+ // src/monaco/MonacoCodeEditor.tsx
28
+ var import_react3 = require("react");
29
+
30
+ // src/components/CodeEditor.tsx
31
+ var import_react2 = require("react");
32
+
33
+ // src/foundations/Icon.tsx
34
+ var import_jsx_runtime = require("react/jsx-runtime");
35
+ var paths = {
36
+ check: "M5 12.5 9.2 17 19 7",
37
+ close: "m7 7 10 10M17 7 7 17",
38
+ info: "M12 11v6M12 7.5h.01",
39
+ warning: "M12 4 3.5 19h17L12 4Zm0 5v4.5m0 2.5h.01",
40
+ error: "M8 8l8 8m0-8-8 8",
41
+ search: "m20 20-4.5-4.5m2.5-4A7 7 0 1 1 4 11a7 7 0 0 1 14 0Z",
42
+ "chevron-down": "m7 10 5 5 5-5",
43
+ "arrow-right": "M5 12h14m-5-5 5 5-5 5",
44
+ user: "M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm7 8a7 7 0 0 0-14 0",
45
+ inbox: "M4 5h16v13H4V5Zm0 9h4l2 2h4l2-2h4"
46
+ };
47
+ function Icon({ name, size = 20, label, className = "", ...props }) {
48
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: `hf-icon ${className}`, width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", role: label ? "img" : void 0, "aria-label": label, "aria-hidden": label ? void 0 : true, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: paths[name] }) });
49
+ }
50
+
51
+ // src/components/useCodeEditor.ts
52
+ var import_react = require("react");
53
+ function useCodeEditor(value, onChange, readOnly) {
54
+ const input = (0, import_react.useRef)(null);
55
+ const gutter = (0, import_react.useRef)(null);
56
+ const search = (0, import_react.useRef)(null);
57
+ const pending = (0, import_react.useRef)(void 0);
58
+ const escapeTab = (0, import_react.useRef)(false);
59
+ const [selection, setSelection] = (0, import_react.useState)({ start: 0, end: 0 });
60
+ const [finding, setFinding] = (0, import_react.useState)(false);
61
+ const [query, setQuery] = (0, import_react.useState)("");
62
+ const [copyStatus, setCopyStatus] = (0, import_react.useState)("");
63
+ const line = value.slice(0, Math.min(selection.start, value.length)).split("\n");
64
+ const position = { line: line.length, column: (line.at(-1)?.length ?? 0) + 1 };
65
+ const matches = [];
66
+ if (query) {
67
+ let offset = value.indexOf(query);
68
+ while (offset !== -1) {
69
+ matches.push(offset);
70
+ offset = value.indexOf(query, offset + query.length);
71
+ }
72
+ }
73
+ (0, import_react.useEffect)(() => () => {
74
+ if (pending.current !== void 0) cancelAnimationFrame(pending.current);
75
+ }, []);
76
+ (0, import_react.useEffect)(() => {
77
+ setCopyStatus("");
78
+ }, [value]);
79
+ function syncSelection() {
80
+ if (input.current) setSelection({ start: input.current.selectionStart, end: input.current.selectionEnd });
81
+ }
82
+ function openFind() {
83
+ setFinding(true);
84
+ requestAnimationFrame(() => search.current?.focus());
85
+ }
86
+ function closeFind() {
87
+ setFinding(false);
88
+ input.current?.focus();
89
+ }
90
+ function find(direction = 1) {
91
+ if (!matches.length || !input.current) return;
92
+ const start = input.current.selectionStart;
93
+ const end = input.current.selectionEnd;
94
+ const next = direction > 0 ? matches.find((offset) => offset >= (end > start ? end : start)) ?? matches[0] : [...matches].reverse().find((offset) => offset < start) ?? matches.at(-1);
95
+ input.current.focus();
96
+ input.current.setSelectionRange(next, next + query.length);
97
+ const row = value.slice(0, next).split("\n").length - 1;
98
+ input.current.scrollTop = Math.max(0, row * 22 - input.current.clientHeight / 2);
99
+ if (gutter.current) gutter.current.scrollTop = input.current.scrollTop;
100
+ syncSelection();
101
+ }
102
+ async function copy() {
103
+ try {
104
+ await navigator.clipboard.writeText(value);
105
+ setCopyStatus("\u5DF2\u590D\u5236");
106
+ } catch {
107
+ setCopyStatus("\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u9009\u4E2D\u6587\u672C\u540E\u590D\u5236");
108
+ }
109
+ }
110
+ function keyDown(event) {
111
+ if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "f") {
112
+ event.preventDefault();
113
+ openFind();
114
+ return;
115
+ }
116
+ if (event.key === "Escape") {
117
+ escapeTab.current = true;
118
+ if (finding) closeFind();
119
+ return;
120
+ }
121
+ if (event.key === "Tab") {
122
+ if (escapeTab.current || event.shiftKey || readOnly) {
123
+ escapeTab.current = false;
124
+ return;
125
+ }
126
+ if (event.nativeEvent.isComposing) return;
127
+ event.preventDefault();
128
+ const start = event.currentTarget.selectionStart;
129
+ const end = event.currentTarget.selectionEnd;
130
+ onChange(`${value.slice(0, start)} ${value.slice(end)}`);
131
+ pending.current = requestAnimationFrame(() => {
132
+ input.current?.setSelectionRange(start + 2, start + 2);
133
+ syncSelection();
134
+ });
135
+ } else escapeTab.current = false;
136
+ }
137
+ return {
138
+ input,
139
+ gutter,
140
+ search,
141
+ selection,
142
+ position,
143
+ finding,
144
+ query,
145
+ setQuery,
146
+ matches,
147
+ copyStatus,
148
+ syncSelection,
149
+ openFind,
150
+ closeFind,
151
+ find,
152
+ copy,
153
+ keyDown
154
+ };
155
+ }
156
+
157
+ // src/components/CodeEditor.tsx
158
+ var import_jsx_runtime2 = require("react/jsx-runtime");
159
+ function CodeEditor({ value, onChange, language = "text", label = "\u4EE3\u7801\u7F16\u8F91\u5668", readOnly, height = 260 }) {
160
+ const editor = useCodeEditor(value, onChange, readOnly);
161
+ const helpId = (0, import_react2.useId)();
162
+ const lines = value.split("\n").length;
163
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `hf-code-editor${readOnly ? " is-readonly" : ""}`, children: [
164
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("header", { className: "hf-code-editor__header", children: [
165
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hf-code-editor__title", children: [
166
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { "aria-hidden": "true", children: "</>" }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: label })
168
+ ] }),
169
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hf-code-editor__tools", children: [
170
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", "aria-label": "\u67E5\u627E\u4EE3\u7801", "aria-expanded": editor.finding, onClick: editor.openFind, children: [
171
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { name: "search", size: 16 }),
172
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u67E5\u627E" })
173
+ ] }),
174
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", onClick: editor.copy, children: "\u590D\u5236" })
175
+ ] })
176
+ ] }),
177
+ editor.finding && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hf-code-editor__find", role: "search", "aria-label": "\u4EE3\u7801\u67E5\u627E", children: [
178
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
179
+ "input",
180
+ {
181
+ ref: editor.search,
182
+ "aria-label": "\u67E5\u627E\u5185\u5BB9",
183
+ placeholder: "\u67E5\u627E\u6587\u672C\uFF08\u533A\u5206\u5927\u5C0F\u5199\uFF09",
184
+ value: editor.query,
185
+ onChange: (event) => editor.setQuery(event.target.value),
186
+ onKeyDown: (event) => {
187
+ if (event.key === "Enter") {
188
+ event.preventDefault();
189
+ editor.find(event.shiftKey ? -1 : 1);
190
+ } else if (event.key === "Escape") editor.closeFind();
191
+ }
192
+ }
193
+ ),
194
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { role: "status", children: editor.query ? `${editor.matches.length} \u4E2A\u5339\u914D` : "\u8F93\u5165\u5173\u952E\u8BCD" }),
195
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", "aria-label": "\u4E0A\u4E00\u4E2A\u5339\u914D", disabled: !editor.matches.length, onClick: () => editor.find(-1), children: "\u2191" }),
196
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", "aria-label": "\u4E0B\u4E00\u4E2A\u5339\u914D", disabled: !editor.matches.length, onClick: () => editor.find(1), children: "\u2193" }),
197
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", "aria-label": "\u5173\u95ED\u67E5\u627E", onClick: editor.closeFind, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Icon, { name: "close", size: 14 }) })
198
+ ] }),
199
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hf-code-editor__body", style: { height }, children: [
200
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { ref: editor.gutter, className: "hf-code-editor__gutter", "aria-hidden": "true", children: Array.from({ length: lines }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: editor.position.line === index + 1 ? "is-active" : "", children: [
201
+ index + 1,
202
+ "\n"
203
+ ] }, index)) }),
204
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
205
+ "textarea",
206
+ {
207
+ ref: editor.input,
208
+ spellCheck: false,
209
+ autoCapitalize: "off",
210
+ autoCorrect: "off",
211
+ wrap: "off",
212
+ readOnly,
213
+ "aria-label": label,
214
+ "aria-describedby": helpId,
215
+ value,
216
+ onChange: (event) => onChange(event.target.value),
217
+ onSelect: editor.syncSelection,
218
+ onKeyDown: editor.keyDown,
219
+ onScroll: (event) => {
220
+ if (editor.gutter.current) editor.gutter.current.scrollTop = event.currentTarget.scrollTop;
221
+ }
222
+ }
223
+ )
224
+ ] }),
225
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("footer", { className: "hf-code-editor__status", children: [
226
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: readOnly ? "\u53EA\u8BFB" : "\u53EF\u7F16\u8F91" }),
227
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
228
+ "\u884C ",
229
+ editor.position.line,
230
+ "\uFF0C\u5217 ",
231
+ editor.position.column
232
+ ] }),
233
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: editor.selection.end > editor.selection.start ? `\u5DF2\u9009 ${editor.selection.end - editor.selection.start} \u5B57\u7B26` : `${lines} \u884C \xB7 ${value.length} \u5B57\u7B26` }),
234
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "hf-code-editor__language", children: language })
235
+ ] }),
236
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "hf-code-editor__sr", id: helpId, children: "Tab \u63D2\u5165\u4E24\u4E2A\u7A7A\u683C\uFF1B\u6309 Escape \u540E\u518D\u6309 Tab \u79BB\u5F00\u7F16\u8F91\u5668\uFF0CShift+Tab \u8FD4\u56DE\u4E0A\u4E00\u4E2A\u63A7\u4EF6\u3002" }),
237
+ editor.copyStatus && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "hf-code-editor__message", role: "status", children: editor.copyStatus })
238
+ ] });
239
+ }
240
+
241
+ // src/monaco/loadRuntime.ts
242
+ var requests = /* @__PURE__ */ new Map();
243
+ function withTimeout(promise, milliseconds = 2e4) {
244
+ return new Promise((resolve, reject) => {
245
+ const timer = setTimeout(() => reject(new Error("Monaco \u8D44\u6E90\u6216 Worker \u52A0\u8F7D\u8D85\u65F6")), milliseconds);
246
+ promise.then((value) => {
247
+ clearTimeout(timer);
248
+ resolve(value);
249
+ }, (error) => {
250
+ clearTimeout(timer);
251
+ reject(error);
252
+ });
253
+ });
254
+ }
255
+ function loadRuntime(assetsUrl, retry) {
256
+ const base = new URL(assetsUrl.endsWith("/") ? assetsUrl : `${assetsUrl}/`, document.baseURI);
257
+ if (base.origin !== location.origin) return Promise.reject(new Error("Monaco \u8D44\u6E90\u5FC5\u987B\u4E0E\u9875\u9762\u540C\u6E90"));
258
+ const key = base.href;
259
+ const existing = requests.get(key);
260
+ if (existing) return existing;
261
+ const link = document.createElement("link");
262
+ link.rel = "stylesheet";
263
+ link.href = new URL("runtime.css", base).href;
264
+ const css = new Promise((resolve, reject) => {
265
+ link.onload = () => resolve();
266
+ link.onerror = () => reject(new Error("Monaco \u6837\u5F0F\u52A0\u8F7D\u5931\u8D25"));
267
+ document.head.append(link);
268
+ });
269
+ const script = new URL("runtime.js", base);
270
+ if (retry) script.searchParams.set("retry", String(retry));
271
+ const request = withTimeout(Promise.all([import(script.href), css])).then(([runtime]) => runtime).catch((error) => {
272
+ link.remove();
273
+ requests.delete(key);
274
+ throw error;
275
+ });
276
+ requests.set(key, request);
277
+ return request;
278
+ }
279
+ function prefersLightEditor() {
280
+ return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent) || navigator.maxTouchPoints > 1 && /Macintosh/i.test(navigator.userAgent);
281
+ }
282
+
283
+ // src/monaco/theme.ts
284
+ function observeTheme(runtime, host) {
285
+ const themeRoot = host.closest(".hf-theme") ?? document.documentElement;
286
+ const apply = () => {
287
+ const style = getComputedStyle(host);
288
+ const color = (token, fallback) => {
289
+ const value = style.getPropertyValue(token).trim();
290
+ if (/^#[\da-f]{3,8}$/i.test(value)) return value;
291
+ if (!value || !CSS.supports("color", value)) return fallback;
292
+ const canvas = document.createElement("canvas").getContext("2d");
293
+ if (!canvas) return fallback;
294
+ canvas.fillStyle = value;
295
+ canvas.fillRect(0, 0, 1, 1);
296
+ return "#" + Array.from(canvas.getImageData(0, 0, 1, 1).data, (channel) => channel.toString(16).padStart(2, "0")).join("");
297
+ };
298
+ const highContrast = themeRoot.classList.contains("hf-theme--high-contrast");
299
+ const dark = themeRoot.classList.contains("hf-theme--dark");
300
+ runtime.monaco.editor.defineTheme("harmony-flow", {
301
+ base: highContrast ? "hc-light" : dark ? "vs-dark" : "vs",
302
+ inherit: true,
303
+ rules: [],
304
+ colors: {
305
+ "editor.background": color("--hf-color-surface", dark ? "#172235" : "#ffffff"),
306
+ "editor.foreground": color("--hf-color-text", dark ? "#f2f6fc" : "#142033"),
307
+ "editorLineNumber.foreground": color("--hf-color-text-muted", "#66758c"),
308
+ "editorLineNumber.activeForeground": color("--hf-color-primary", "#0a7cff"),
309
+ "editorCursor.foreground": color("--hf-color-primary", "#0a7cff"),
310
+ "editorWidget.background": color("--hf-color-surface", "#ffffff"),
311
+ "editorWidget.border": color("--hf-color-border", "#dce9f7"),
312
+ "editorSuggestWidget.background": color("--hf-color-surface", "#ffffff"),
313
+ "editorSuggestWidget.foreground": color("--hf-color-text", "#142033"),
314
+ "focusBorder": color("--hf-color-primary", "#0a7cff")
315
+ }
316
+ });
317
+ runtime.monaco.editor.setTheme("harmony-flow");
318
+ };
319
+ apply();
320
+ const observer = new MutationObserver(apply);
321
+ for (let node = themeRoot; node; node = node.parentElement) {
322
+ observer.observe(node, { attributes: true, attributeFilter: ["class", "style"] });
323
+ }
324
+ return () => observer.disconnect();
325
+ }
326
+
327
+ // src/monaco/session.ts
328
+ var instance = 0;
329
+ function createSession(runtime, host, options, onChange, onPosition) {
330
+ const { monaco } = runtime;
331
+ const id = ++instance;
332
+ const models = /* @__PURE__ */ new Map();
333
+ let path = "";
334
+ let syncing = false;
335
+ const stopTheme = observeTheme(runtime, host);
336
+ const editor = monaco.editor.create(host, {
337
+ model: null,
338
+ automaticLayout: true,
339
+ minimap: { enabled: false },
340
+ fontSize: 13,
341
+ lineHeight: 22,
342
+ fontFamily: 'Consolas, "SFMono-Regular", Menlo, Monaco, "Liberation Mono", monospace',
343
+ fontLigatures: false,
344
+ padding: { top: 12, bottom: 12 },
345
+ scrollBeyondLastLine: false,
346
+ tabSize: 2,
347
+ insertSpaces: true,
348
+ detectIndentation: false,
349
+ renderLineHighlight: "line",
350
+ overviewRulerBorder: false,
351
+ hideCursorInOverviewRuler: true,
352
+ fixedOverflowWidgets: false,
353
+ accessibilitySupport: "auto",
354
+ stickyScroll: { enabled: false },
355
+ tabFocusMode: true
356
+ });
357
+ const changed = editor.onDidChangeModelContent(() => {
358
+ if (!syncing) onChange(editor.getValue());
359
+ });
360
+ const positioned = editor.onDidChangeCursorPosition((event) => onPosition(event.position.lineNumber, event.position.column));
361
+ function update(next) {
362
+ const nextPath = next.path ?? "untitled";
363
+ const language = ["typescript", "javascript", "json"].includes(next.language ?? "") ? next.language : "plaintext";
364
+ if (path !== nextPath || !editor.getModel()) {
365
+ const previous = models.get(path);
366
+ if (previous) previous.view = editor.saveViewState();
367
+ let entry = models.get(nextPath);
368
+ if (!entry) {
369
+ const uri = monaco.Uri.parse(`file:///harmony-${id}/${nextPath.split("/").map(encodeURIComponent).join("/")}`);
370
+ entry = { model: monaco.editor.createModel(next.value, language, uri), view: null };
371
+ }
372
+ models.delete(nextPath);
373
+ models.set(nextPath, entry);
374
+ path = nextPath;
375
+ editor.setModel(entry.model);
376
+ if (entry.view) editor.restoreViewState(entry.view);
377
+ if (models.size > 20) {
378
+ const oldest = models.keys().next().value;
379
+ models.get(oldest).model.dispose();
380
+ models.delete(oldest);
381
+ }
382
+ }
383
+ const model = editor.getModel();
384
+ model.updateOptions({ tabSize: 2, insertSpaces: true });
385
+ if (model.getLanguageId() !== language) monaco.editor.setModelLanguage(model, language);
386
+ if (model.getValue() !== next.value) {
387
+ syncing = true;
388
+ try {
389
+ model.setValue(next.value);
390
+ } finally {
391
+ syncing = false;
392
+ }
393
+ }
394
+ editor.updateOptions({ readOnly: !!next.readOnly, ariaLabel: next.label ?? "\u4EE3\u7801\u7F16\u8F91\u5668" });
395
+ return model;
396
+ }
397
+ update(options);
398
+ return {
399
+ editor,
400
+ update,
401
+ dispose() {
402
+ changed.dispose();
403
+ positioned.dispose();
404
+ stopTheme();
405
+ editor.dispose();
406
+ models.forEach(({ model }) => model.dispose());
407
+ models.clear();
408
+ }
409
+ };
410
+ }
411
+
412
+ // src/monaco/MonacoCodeEditor.tsx
413
+ var import_jsx_runtime3 = require("react/jsx-runtime");
414
+ function MonacoCodeEditor(props) {
415
+ const { assetsUrl = "/monaco/", lightweight = false, height = 260, label = "\u4EE3\u7801\u7F16\u8F91\u5668" } = props;
416
+ const host = (0, import_react3.useRef)(null);
417
+ const current = (0, import_react3.useRef)(props);
418
+ current.current = props;
419
+ const session = (0, import_react3.useRef)(null);
420
+ const [status, setStatus] = (0, import_react3.useState)("loading");
421
+ const [retry, setRetry] = (0, import_react3.useState)(0);
422
+ const [position, setPosition] = (0, import_react3.useState)({ line: 1, column: 1 });
423
+ const [message, setMessage] = (0, import_react3.useState)("");
424
+ (0, import_react3.useEffect)(() => {
425
+ if (lightweight || prefersLightEditor()) {
426
+ setStatus("fallback");
427
+ return;
428
+ }
429
+ let disposed = false;
430
+ let stopErrors;
431
+ let owned;
432
+ const fail = (error) => {
433
+ if (disposed) return;
434
+ console.error("[Harmony Flow Monaco]", error);
435
+ stopErrors?.();
436
+ owned?.dispose();
437
+ owned = void 0;
438
+ session.current = null;
439
+ setStatus("error");
440
+ };
441
+ setStatus("loading");
442
+ loadRuntime(assetsUrl, retry).then(async (runtime) => {
443
+ if (disposed || !host.current) return;
444
+ if (retry) runtime.restartWorkers();
445
+ stopErrors = runtime.onWorkerError(() => fail(new Error("Monaco Worker \u52A0\u8F7D\u5931\u8D25")));
446
+ owned = createSession(
447
+ runtime,
448
+ host.current,
449
+ current.current,
450
+ (value) => current.current.onChange(value),
451
+ (line, column) => setPosition({ line, column })
452
+ );
453
+ session.current = owned;
454
+ await withTimeout(runtime.verifyWorker(owned.editor.getModel()));
455
+ if (!disposed && owned) {
456
+ owned.update(current.current);
457
+ setStatus("ready");
458
+ }
459
+ }).catch(fail);
460
+ return () => {
461
+ disposed = true;
462
+ stopErrors?.();
463
+ owned?.dispose();
464
+ session.current = null;
465
+ };
466
+ }, [assetsUrl, lightweight, retry]);
467
+ (0, import_react3.useEffect)(() => {
468
+ session.current?.update(props);
469
+ }, [props.value, props.path, props.language, props.readOnly, props.label]);
470
+ const copy = async () => {
471
+ try {
472
+ await navigator.clipboard.writeText(current.current.value);
473
+ setMessage("\u5DF2\u590D\u5236");
474
+ } catch {
475
+ setMessage("\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u9009\u4E2D\u4EE3\u7801\u540E\u590D\u5236");
476
+ }
477
+ };
478
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hf-monaco", "data-editor-state": status, children: [
479
+ status !== "ready" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
480
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hf-monaco__notice", role: "status", children: [
481
+ status === "loading" ? "\u6B63\u5728\u52A0\u8F7D\u589E\u5F3A\u7F16\u8F91\u5668\uFF0C\u53EF\u5148\u7EE7\u7EED\u7F16\u8F91" : status === "error" ? "\u589E\u5F3A\u7F16\u8F91\u5668\u52A0\u8F7D\u5931\u8D25\uFF0C\u5DF2\u4F7F\u7528\u8F7B\u91CF\u6A21\u5F0F" : "\u8F7B\u91CF\u7F16\u8F91\u6A21\u5F0F",
482
+ status === "error" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", onClick: () => setRetry((value) => value + 1), children: "\u91CD\u8BD5\u52A0\u8F7D" })
483
+ ] }),
484
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CodeEditor, { ...props })
485
+ ] }),
486
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hf-code-editor hf-monaco__enhanced", hidden: status !== "ready", children: [
487
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "hf-code-editor__header", children: [
488
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hf-code-editor__title", children: [
489
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": "true", children: "</>" }),
490
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: label })
491
+ ] }),
492
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "hf-code-editor__tools", children: [
493
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", onClick: () => {
494
+ session.current?.editor.focus();
495
+ void session.current?.editor.getAction("actions.find")?.run();
496
+ }, children: "\u67E5\u627E" }),
497
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", onClick: copy, children: "\u590D\u5236" })
498
+ ] })
499
+ ] }),
500
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: host, className: "hf-monaco__canvas", style: { height } }),
501
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("footer", { className: "hf-code-editor__status", children: [
502
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: props.readOnly ? "\u53EA\u8BFB" : "\u53EF\u7F16\u8F91" }),
503
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
504
+ "\u884C ",
505
+ position.line,
506
+ "\uFF0C\u5217 ",
507
+ position.column
508
+ ] }),
509
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "UTF-8 \xB7 Monaco" }),
510
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hf-code-editor__language", children: props.language ?? "text" })
511
+ ] }),
512
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "hf-code-editor__sr", children: "Tab \u79BB\u5F00\u7F16\u8F91\u5668\uFF1BCtrl+M \u5207\u6362 Tab \u7F29\u8FDB\u6A21\u5F0F\u3002" }),
513
+ message && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hf-code-editor__message", role: "status", children: message })
514
+ ] })
515
+ ] });
516
+ }
517
+ // Annotate the CommonJS export names for ESM import in node:
518
+ 0 && (module.exports = {
519
+ MonacoCodeEditor
520
+ });
521
+ //# sourceMappingURL=monaco.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/monaco/index.ts","../../src/monaco/MonacoCodeEditor.tsx","../../src/components/CodeEditor.tsx","../../src/foundations/Icon.tsx","../../src/components/useCodeEditor.ts","../../src/monaco/loadRuntime.ts","../../src/monaco/theme.ts","../../src/monaco/session.ts"],"sourcesContent":["export { MonacoCodeEditor, type MonacoCodeEditorProps } from './MonacoCodeEditor';\n","import { useEffect, useRef, useState } from 'react';\nimport { CodeEditor, type CodeEditorProps } from '../components/CodeEditor';\nimport { loadRuntime, prefersLightEditor, withTimeout } from './loadRuntime';\nimport { createSession } from './session';\nimport './style.css';\n\nexport interface MonacoCodeEditorProps extends CodeEditorProps {\n /** Stable file identity. Up to 20 recently opened models retain undo and view state. */\n path?: string;\n /** Same-origin directory containing the prebuilt monaco-assets files. Default: /monaco/. */\n assetsUrl?: string;\n /** Force the lightweight editor, e.g. for low-memory devices. Mobile uses it automatically. */\n lightweight?: boolean;\n}\n\nexport function MonacoCodeEditor(props: MonacoCodeEditorProps) {\n const { assetsUrl = '/monaco/', lightweight = false, height = 260, label = '代码编辑器' } = props;\n const host = useRef<HTMLDivElement>(null);\n const current = useRef(props);\n current.current = props;\n const session = useRef<ReturnType<typeof createSession> | null>(null);\n const [status, setStatus] = useState<'loading' | 'ready' | 'fallback' | 'error'>('loading');\n const [retry, setRetry] = useState(0);\n const [position, setPosition] = useState({ line: 1, column: 1 });\n const [message, setMessage] = useState('');\n\n useEffect(() => {\n if (lightweight || prefersLightEditor()) { setStatus('fallback'); return; }\n let disposed = false;\n let stopErrors: (() => void) | undefined;\n let owned: ReturnType<typeof createSession> | undefined;\n const fail = (error: unknown) => {\n if (disposed) return;\n console.error('[Harmony Flow Monaco]', error);\n stopErrors?.(); owned?.dispose(); owned = undefined; session.current = null;\n setStatus('error');\n };\n setStatus('loading');\n loadRuntime(assetsUrl, retry).then(async runtime => {\n if (disposed || !host.current) return;\n if (retry) runtime.restartWorkers();\n stopErrors = runtime.onWorkerError(() => fail(new Error('Monaco Worker 加载失败')));\n owned = createSession(runtime, host.current, current.current,\n value => current.current.onChange(value), (line, column) => setPosition({ line, column }));\n session.current = owned;\n await withTimeout(runtime.verifyWorker(owned.editor.getModel()!));\n if (!disposed && owned) { owned.update(current.current); setStatus('ready'); }\n }).catch(fail);\n return () => { disposed = true; stopErrors?.(); owned?.dispose(); session.current = null; };\n }, [assetsUrl, lightweight, retry]);\n\n useEffect(() => { session.current?.update(props); }, [props.value, props.path, props.language, props.readOnly, props.label]);\n\n const copy = async () => {\n try { await navigator.clipboard.writeText(current.current.value); setMessage('已复制'); }\n catch { setMessage('复制失败,请选中代码后复制'); }\n };\n return <div className=\"hf-monaco\" data-editor-state={status}>\n {status !== 'ready' && <>\n <div className=\"hf-monaco__notice\" role=\"status\">\n {status === 'loading' ? '正在加载增强编辑器,可先继续编辑' : status === 'error' ? '增强编辑器加载失败,已使用轻量模式' : '轻量编辑模式'}\n {status === 'error' && <button type=\"button\" onClick={() => setRetry(value => value + 1)}>重试加载</button>}\n </div>\n <CodeEditor {...props} />\n </>}\n <div className=\"hf-code-editor hf-monaco__enhanced\" hidden={status !== 'ready'}>\n <header className=\"hf-code-editor__header\">\n <div className=\"hf-code-editor__title\"><span aria-hidden=\"true\">{'</>'}</span><strong>{label}</strong></div>\n <div className=\"hf-code-editor__tools\">\n <button type=\"button\" onClick={() => { session.current?.editor.focus(); void session.current?.editor.getAction('actions.find')?.run(); }}>查找</button>\n <button type=\"button\" onClick={copy}>复制</button>\n </div>\n </header>\n <div ref={host} className=\"hf-monaco__canvas\" style={{ height }} />\n <footer className=\"hf-code-editor__status\">\n <span>{props.readOnly ? '只读' : '可编辑'}</span><span>行 {position.line},列 {position.column}</span>\n <span>UTF-8 · Monaco</span><span className=\"hf-code-editor__language\">{props.language ?? 'text'}</span>\n </footer>\n <span className=\"hf-code-editor__sr\">Tab 离开编辑器;Ctrl+M 切换 Tab 缩进模式。</span>\n {message && <div className=\"hf-code-editor__message\" role=\"status\">{message}</div>}\n </div>\n </div>;\n}\n","import { useId } from 'react';\nimport { Icon } from '../foundations/Icon';\nimport { useCodeEditor } from './useCodeEditor';\n\nexport interface CodeEditorProps {\n value: string;\n onChange: (value: string) => void;\n language?: string;\n label?: string;\n readOnly?: boolean;\n height?: number;\n}\n\nexport function CodeEditor({ value, onChange, language = 'text', label = '代码编辑器', readOnly, height = 260 }: CodeEditorProps) {\n const editor = useCodeEditor(value, onChange, readOnly);\n const helpId = useId();\n const lines = value.split('\\n').length;\n return <div className={`hf-code-editor${readOnly ? ' is-readonly' : ''}`}>\n <header className=\"hf-code-editor__header\">\n <div className=\"hf-code-editor__title\"><span aria-hidden=\"true\">{'</>'}</span><strong>{label}</strong></div>\n <div className=\"hf-code-editor__tools\">\n <button type=\"button\" aria-label=\"查找代码\" aria-expanded={editor.finding} onClick={editor.openFind}><Icon name=\"search\" size={16} /><span>查找</span></button>\n <button type=\"button\" onClick={editor.copy}>复制</button>\n </div>\n </header>\n {editor.finding && <div className=\"hf-code-editor__find\" role=\"search\" aria-label=\"代码查找\">\n <input ref={editor.search} aria-label=\"查找内容\" placeholder=\"查找文本(区分大小写)\" value={editor.query}\n onChange={(event) => editor.setQuery(event.target.value)}\n onKeyDown={(event) => { if (event.key === 'Enter') { event.preventDefault(); editor.find(event.shiftKey ? -1 : 1); } else if (event.key === 'Escape') editor.closeFind(); }} />\n <span role=\"status\">{editor.query ? `${editor.matches.length} 个匹配` : '输入关键词'}</span>\n <button type=\"button\" aria-label=\"上一个匹配\" disabled={!editor.matches.length} onClick={() => editor.find(-1)}>↑</button>\n <button type=\"button\" aria-label=\"下一个匹配\" disabled={!editor.matches.length} onClick={() => editor.find(1)}>↓</button>\n <button type=\"button\" aria-label=\"关闭查找\" onClick={editor.closeFind}><Icon name=\"close\" size={14} /></button>\n </div>}\n <div className=\"hf-code-editor__body\" style={{ height }}>\n <pre ref={editor.gutter} className=\"hf-code-editor__gutter\" aria-hidden=\"true\">\n {Array.from({ length: lines }, (_, index) => <span className={editor.position.line === index + 1 ? 'is-active' : ''} key={index}>{index + 1}{'\\n'}</span>)}\n </pre>\n <textarea ref={editor.input} spellCheck={false} autoCapitalize=\"off\" autoCorrect=\"off\" wrap=\"off\"\n readOnly={readOnly} aria-label={label} aria-describedby={helpId} value={value}\n onChange={(event) => onChange(event.target.value)} onSelect={editor.syncSelection} onKeyDown={editor.keyDown}\n onScroll={(event) => { if (editor.gutter.current) editor.gutter.current.scrollTop = event.currentTarget.scrollTop; }} />\n </div>\n <footer className=\"hf-code-editor__status\">\n <span>{readOnly ? '只读' : '可编辑'}</span><span>行 {editor.position.line},列 {editor.position.column}</span>\n <span>{editor.selection.end > editor.selection.start ? `已选 ${editor.selection.end - editor.selection.start} 字符` : `${lines} 行 · ${value.length} 字符`}</span>\n <span className=\"hf-code-editor__language\">{language}</span>\n </footer>\n <span className=\"hf-code-editor__sr\" id={helpId}>Tab 插入两个空格;按 Escape 后再按 Tab 离开编辑器,Shift+Tab 返回上一个控件。</span>\n {editor.copyStatus && <div className=\"hf-code-editor__message\" role=\"status\">{editor.copyStatus}</div>}\n </div>;\n}\n","import type { SVGAttributes } from 'react';\n\nexport type IconName = 'check' | 'close' | 'info' | 'warning' | 'error' | 'search' | 'chevron-down' | 'arrow-right' | 'user' | 'inbox';\nexport interface IconProps extends Omit<SVGAttributes<SVGSVGElement>, 'children'> { name: IconName; size?: number; label?: string; }\n\nconst paths: Record<IconName, string> = {\n check: 'M5 12.5 9.2 17 19 7', close: 'm7 7 10 10M17 7 7 17', info: 'M12 11v6M12 7.5h.01',\n warning: 'M12 4 3.5 19h17L12 4Zm0 5v4.5m0 2.5h.01', error: 'M8 8l8 8m0-8-8 8',\n search: 'm20 20-4.5-4.5m2.5-4A7 7 0 1 1 4 11a7 7 0 0 1 14 0Z', 'chevron-down': 'm7 10 5 5 5-5',\n 'arrow-right': 'M5 12h14m-5-5 5 5-5 5', user: 'M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm7 8a7 7 0 0 0-14 0',\n inbox: 'M4 5h16v13H4V5Zm0 9h4l2 2h4l2-2h4',\n};\n\nexport function Icon({ name, size = 20, label, className = '', ...props }: IconProps) {\n return <svg className={`hf-icon ${className}`} width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\" role={label ? 'img' : undefined} aria-label={label} aria-hidden={label ? undefined : true} {...props}><path d={paths[name]} /></svg>;\n}\n","import { useEffect, useRef, useState, type KeyboardEvent } from 'react';\r\n\r\nexport function useCodeEditor(value: string, onChange: (value: string) => void, readOnly?: boolean) {\r\n const input = useRef<HTMLTextAreaElement>(null);\r\n const gutter = useRef<HTMLPreElement>(null);\r\n const search = useRef<HTMLInputElement>(null);\r\n const pending = useRef<number | undefined>(undefined);\r\n const escapeTab = useRef(false);\r\n const [selection, setSelection] = useState({ start: 0, end: 0 });\r\n const [finding, setFinding] = useState(false);\r\n const [query, setQuery] = useState('');\r\n const [copyStatus, setCopyStatus] = useState('');\r\n const line = value.slice(0, Math.min(selection.start, value.length)).split('\\n');\r\n const position = { line: line.length, column: (line.at(-1)?.length ?? 0) + 1 };\r\n const matches: number[] = [];\r\n if (query) {\r\n let offset = value.indexOf(query);\r\n while (offset !== -1) { matches.push(offset); offset = value.indexOf(query, offset + query.length); }\r\n }\r\n useEffect(() => () => { if (pending.current !== undefined) cancelAnimationFrame(pending.current); }, []);\r\n useEffect(() => { setCopyStatus(''); }, [value]);\r\n function syncSelection() {\r\n if (input.current) setSelection({ start: input.current.selectionStart, end: input.current.selectionEnd });\r\n }\r\n function openFind() { setFinding(true); requestAnimationFrame(() => search.current?.focus()); }\r\n function closeFind() { setFinding(false); input.current?.focus(); }\r\n function find(direction = 1) {\r\n if (!matches.length || !input.current) return;\r\n const start = input.current.selectionStart;\r\n const end = input.current.selectionEnd;\r\n const next = direction > 0\r\n ? matches.find((offset) => offset >= (end > start ? end : start)) ?? matches[0]!\r\n : [...matches].reverse().find((offset) => offset < start) ?? matches.at(-1)!;\r\n input.current.focus();\r\n input.current.setSelectionRange(next, next + query.length);\r\n const row = value.slice(0, next).split('\\n').length - 1;\r\n input.current.scrollTop = Math.max(0, row * 22 - input.current.clientHeight / 2);\r\n if (gutter.current) gutter.current.scrollTop = input.current.scrollTop;\r\n syncSelection();\r\n }\r\n async function copy() {\r\n try { await navigator.clipboard.writeText(value); setCopyStatus('已复制'); }\r\n catch { setCopyStatus('复制失败,请选中文本后复制'); }\r\n }\r\n function keyDown(event: KeyboardEvent<HTMLTextAreaElement>) {\r\n if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === 'f') { event.preventDefault(); openFind(); return; }\r\n if (event.key === 'Escape') { escapeTab.current = true; if (finding) closeFind(); return; }\r\n if (event.key === 'Tab') {\r\n if (escapeTab.current || event.shiftKey || readOnly) { escapeTab.current = false; return; }\r\n if (event.nativeEvent.isComposing) return;\r\n event.preventDefault();\r\n const start = event.currentTarget.selectionStart;\r\n const end = event.currentTarget.selectionEnd;\r\n onChange(`${value.slice(0, start)} ${value.slice(end)}`);\r\n pending.current = requestAnimationFrame(() => { input.current?.setSelectionRange(start + 2, start + 2); syncSelection(); });\r\n } else escapeTab.current = false;\r\n }\r\n return { input, gutter, search, selection, position, finding, query, setQuery, matches, copyStatus,\r\n syncSelection, openFind, closeFind, find, copy, keyDown };\r\n}\r\n","export type Runtime = typeof import('./runtime-entry');\r\nconst requests = new Map<string, Promise<Runtime>>();\r\n\r\nexport function withTimeout<T>(promise: Promise<T>, milliseconds = 20000): Promise<T> {\r\n return new Promise((resolve, reject) => {\r\n const timer = setTimeout(() => reject(new Error('Monaco 资源或 Worker 加载超时')), milliseconds);\r\n promise.then(value => { clearTimeout(timer); resolve(value); }, error => { clearTimeout(timer); reject(error); });\r\n });\r\n}\r\n\r\n/** Assets are explicitly self-hosted. Never silently switch to a public CDN. */\r\nexport function loadRuntime(assetsUrl: string, retry: number): Promise<Runtime> {\r\n const base = new URL(assetsUrl.endsWith('/') ? assetsUrl : `${assetsUrl}/`, document.baseURI);\r\n if (base.origin !== location.origin) return Promise.reject(new Error('Monaco 资源必须与页面同源'));\r\n const key = base.href;\r\n const existing = requests.get(key);\r\n if (existing) return existing;\r\n const link = document.createElement('link');\r\n link.rel = 'stylesheet';\r\n link.href = new URL('runtime.css', base).href;\r\n const css = new Promise<void>((resolve, reject) => {\r\n link.onload = () => resolve();\r\n link.onerror = () => reject(new Error('Monaco 样式加载失败'));\r\n document.head.append(link);\r\n });\r\n const script = new URL('runtime.js', base);\r\n if (retry) script.searchParams.set('retry', String(retry));\r\n const request = withTimeout(Promise.all([import(script.href) as Promise<Runtime>, css]))\r\n .then(([runtime]) => runtime)\r\n .catch(error => { link.remove(); requests.delete(key); throw error; });\r\n requests.set(key, request);\r\n return request;\r\n}\r\n\r\nexport function prefersLightEditor() {\r\n return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent)\r\n || (navigator.maxTouchPoints > 1 && /Macintosh/i.test(navigator.userAgent));\r\n}\r\n","import type { Runtime } from './loadRuntime';\r\n\r\n/** Monaco's theme service is shared: all enhanced editors follow the page theme. */\r\nexport function observeTheme(runtime: Runtime, host: HTMLElement) {\r\n const themeRoot = host.closest('.hf-theme') ?? document.documentElement;\r\n const apply = () => {\r\n const style = getComputedStyle(host);\r\n const color = (token: string, fallback: string) => {\r\n const value = style.getPropertyValue(token).trim();\r\n if (/^#[\\da-f]{3,8}$/i.test(value)) return value;\r\n if (!value || !CSS.supports('color', value)) return fallback;\r\n const canvas = document.createElement('canvas').getContext('2d');\n if (!canvas) return fallback;\n canvas.fillStyle = value;\n canvas.fillRect(0, 0, 1, 1);\n return '#' + Array.from(canvas.getImageData(0, 0, 1, 1).data, channel => channel.toString(16).padStart(2, '0')).join('');\n };\r\n const highContrast = themeRoot.classList.contains('hf-theme--high-contrast');\r\n const dark = themeRoot.classList.contains('hf-theme--dark');\r\n runtime.monaco.editor.defineTheme('harmony-flow', {\r\n base: highContrast ? 'hc-light' : dark ? 'vs-dark' : 'vs', inherit: true, rules: [],\r\n colors: {\r\n 'editor.background': color('--hf-color-surface', dark ? '#172235' : '#ffffff'),\r\n 'editor.foreground': color('--hf-color-text', dark ? '#f2f6fc' : '#142033'),\r\n 'editorLineNumber.foreground': color('--hf-color-text-muted', '#66758c'),\r\n 'editorLineNumber.activeForeground': color('--hf-color-primary', '#0a7cff'),\r\n 'editorCursor.foreground': color('--hf-color-primary', '#0a7cff'),\r\n 'editorWidget.background': color('--hf-color-surface', '#ffffff'),\r\n 'editorWidget.border': color('--hf-color-border', '#dce9f7'),\r\n 'editorSuggestWidget.background': color('--hf-color-surface', '#ffffff'),\r\n 'editorSuggestWidget.foreground': color('--hf-color-text', '#142033'),\r\n 'focusBorder': color('--hf-color-primary', '#0a7cff'),\r\n },\r\n });\r\n runtime.monaco.editor.setTheme('harmony-flow');\r\n };\r\n apply();\r\n const observer = new MutationObserver(apply);\r\n for (let node: Element | null = themeRoot; node; node = node.parentElement) {\r\n observer.observe(node, { attributes: true, attributeFilter: ['class', 'style'] });\r\n }\r\n return () => observer.disconnect();\r\n}\r\n","import type { CodeEditorProps } from '../components/CodeEditor';\nimport type { Runtime } from './loadRuntime';\nimport { observeTheme } from './theme';\n\ntype Editor = import('monaco-editor').editor.IStandaloneCodeEditor;\ntype Model = import('monaco-editor').editor.ITextModel;\ntype View = import('monaco-editor').editor.ICodeEditorViewState;\ntype Options = CodeEditorProps & { path?: string };\nlet instance = 0;\n\nexport function createSession(runtime: Runtime, host: HTMLElement, options: Options, onChange: (value: string) => void,\n onPosition: (line: number, column: number) => void) {\n const { monaco } = runtime;\n const id = ++instance;\n const models = new Map<string, { model: Model; view: View | null }>();\n let path = '';\n let syncing = false;\n const stopTheme = observeTheme(runtime, host);\n const editor: Editor = monaco.editor.create(host, {\n model: null, automaticLayout: true, minimap: { enabled: false }, fontSize: 13, lineHeight: 22,\n fontFamily: 'Consolas, \"SFMono-Regular\", Menlo, Monaco, \"Liberation Mono\", monospace',\n fontLigatures: false, padding: { top: 12, bottom: 12 }, scrollBeyondLastLine: false,\n tabSize: 2, insertSpaces: true, detectIndentation: false, renderLineHighlight: 'line',\n overviewRulerBorder: false, hideCursorInOverviewRuler: true, fixedOverflowWidgets: false,\n accessibilitySupport: 'auto', stickyScroll: { enabled: false }, tabFocusMode: true,\n });\n const changed = editor.onDidChangeModelContent(() => { if (!syncing) onChange(editor.getValue()); });\n const positioned = editor.onDidChangeCursorPosition(event => onPosition(event.position.lineNumber, event.position.column));\n\n function update(next: Options) {\n const nextPath = next.path ?? 'untitled';\n const language = ['typescript', 'javascript', 'json'].includes(next.language ?? '') ? next.language! : 'plaintext';\n if (path !== nextPath || !editor.getModel()) {\n const previous = models.get(path);\n if (previous) previous.view = editor.saveViewState();\n let entry = models.get(nextPath);\n if (!entry) {\n const uri = monaco.Uri.parse(`file:///harmony-${id}/${nextPath.split('/').map(encodeURIComponent).join('/')}`);\n entry = { model: monaco.editor.createModel(next.value, language, uri), view: null };\n }\n models.delete(nextPath);\n models.set(nextPath, entry);\n path = nextPath;\n editor.setModel(entry.model);\n if (entry.view) editor.restoreViewState(entry.view);\n if (models.size > 20) {\n const oldest = models.keys().next().value!;\n models.get(oldest)!.model.dispose();\n models.delete(oldest);\n }\n }\n const model = editor.getModel()!;\n model.updateOptions({ tabSize: 2, insertSpaces: true });\n if (model.getLanguageId() !== language) monaco.editor.setModelLanguage(model, language);\n if (model.getValue() !== next.value) {\n syncing = true;\n try { model.setValue(next.value); } finally { syncing = false; }\n }\n editor.updateOptions({ readOnly: !!next.readOnly, ariaLabel: next.label ?? '代码编辑器' });\n return model;\n }\n update(options);\n return {\n editor, update,\n dispose() {\n changed.dispose(); positioned.dispose(); stopTheme(); editor.dispose();\n models.forEach(({ model }) => model.dispose()); models.clear();\n },\n };\n}\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime","import_jsx_runtime"]}
@@ -0,0 +1,35 @@
1
+ /* src/monaco/style.css */
2
+ .hf-monaco {
3
+ min-width: 0;
4
+ width: 100%;
5
+ }
6
+ .hf-monaco__enhanced[hidden] {
7
+ display: none;
8
+ }
9
+ .hf-monaco__canvas {
10
+ min-width: 0;
11
+ width: 100%;
12
+ text-align: left;
13
+ }
14
+ .hf-monaco__notice {
15
+ display: flex;
16
+ align-items: center;
17
+ justify-content: space-between;
18
+ gap: 12px;
19
+ margin-bottom: 8px;
20
+ color: var(--hf-color-text-muted);
21
+ font-size: 12px;
22
+ }
23
+ .hf-monaco__notice button {
24
+ border: 1px solid var(--hf-color-border);
25
+ border-radius: var(--hf-radius-control, 6px);
26
+ padding: 4px 10px;
27
+ color: var(--hf-color-primary);
28
+ background: var(--hf-color-surface);
29
+ cursor: pointer;
30
+ }
31
+ .hf-monaco__notice button:focus-visible {
32
+ outline: 2px solid var(--hf-color-primary);
33
+ outline-offset: 2px;
34
+ }
35
+ /*# sourceMappingURL=monaco.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/monaco/style.css"],"sourcesContent":[".hf-monaco { min-width: 0; width: 100%; }\r\n.hf-monaco__enhanced[hidden] { display: none; }\r\n.hf-monaco__canvas { min-width: 0; width: 100%; text-align: left; }\r\n.hf-monaco__notice {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n margin-bottom: 8px;\r\n color: var(--hf-color-text-muted);\r\n font-size: 12px;\r\n}\r\n.hf-monaco__notice button {\r\n border: 1px solid var(--hf-color-border);\r\n border-radius: var(--hf-radius-control, 6px);\r\n padding: 4px 10px;\r\n color: var(--hf-color-primary);\r\n background: var(--hf-color-surface);\r\n cursor: pointer;\r\n}\r\n.hf-monaco__notice button:focus-visible { outline: 2px solid var(--hf-color-primary); outline-offset: 2px; }\r\n"],"mappings":";AAAA,CAAC;AAAY,aAAW;AAAG,SAAO;AAAM;AACxC,CAAC,mBAAmB,CAAC;AAAU,WAAS;AAAM;AAC9C,CAAC;AAAoB,aAAW;AAAG,SAAO;AAAM,cAAY;AAAM;AAClE,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,OAAK;AACL,iBAAe;AACf,SAAO,IAAI;AACX,aAAW;AACb;AACA,CATC,kBASkB;AACjB,UAAQ,IAAI,MAAM,IAAI;AACtB,iBAAe,IAAI,mBAAmB,EAAE;AACxC,WAAS,IAAI;AACb,SAAO,IAAI;AACX,cAAY,IAAI;AAChB,UAAQ;AACV;AACA,CAjBC,kBAiBkB,MAAM;AAAiB,WAAS,IAAI,MAAM,IAAI;AAAqB,kBAAgB;AAAK;","names":[]}