@coding-script/script-engine 0.0.1

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 (49) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +23 -0
  3. package/dist/autocomplete/completion-source.d.ts +11 -0
  4. package/dist/autocomplete/completion-source.js +267 -0
  5. package/dist/autocomplete/index.d.ts +2 -0
  6. package/dist/autocomplete/index.js +2 -0
  7. package/dist/autocomplete/resolve.d.ts +15 -0
  8. package/dist/autocomplete/resolve.js +29 -0
  9. package/dist/components/data-types-section.d.ts +10 -0
  10. package/dist/components/data-types-section.js +25 -0
  11. package/dist/components/drag-handle.d.ts +10 -0
  12. package/dist/components/drag-handle.js +39 -0
  13. package/dist/components/expand-sidebar-button.d.ts +8 -0
  14. package/dist/components/expand-sidebar-button.js +27 -0
  15. package/dist/components/field-row.d.ts +8 -0
  16. package/dist/components/field-row.js +46 -0
  17. package/dist/components/function-row.d.ts +8 -0
  18. package/dist/components/function-row.js +47 -0
  19. package/dist/components/index.d.ts +28 -0
  20. package/dist/components/index.js +14 -0
  21. package/dist/components/main-function-section.d.ts +8 -0
  22. package/dist/components/main-function-section.js +40 -0
  23. package/dist/components/panel-header.d.ts +7 -0
  24. package/dist/components/panel-header.js +33 -0
  25. package/dist/components/section-header.d.ts +7 -0
  26. package/dist/components/section-header.js +12 -0
  27. package/dist/components/theme-colors.d.ts +46 -0
  28. package/dist/components/theme-colors.js +47 -0
  29. package/dist/components/toolbar-button.d.ts +11 -0
  30. package/dist/components/toolbar-button.js +26 -0
  31. package/dist/components/toolbar.d.ts +8 -0
  32. package/dist/components/toolbar.js +85 -0
  33. package/dist/components/type-section.d.ts +10 -0
  34. package/dist/components/type-section.js +58 -0
  35. package/dist/components/variable-row.d.ts +9 -0
  36. package/dist/components/variable-row.js +38 -0
  37. package/dist/components/variables-section.d.ts +9 -0
  38. package/dist/components/variables-section.js +23 -0
  39. package/dist/index.d.ts +2 -0
  40. package/dist/index.js +2 -0
  41. package/dist/script-code.d.ts +3 -0
  42. package/dist/script-code.js +307 -0
  43. package/dist/type-panel/index.d.ts +2 -0
  44. package/dist/type-panel/index.js +1 -0
  45. package/dist/type-panel/type-panel.d.ts +12 -0
  46. package/dist/type-panel/type-panel.js +129 -0
  47. package/dist/types/index.d.ts +77 -0
  48. package/dist/types/index.js +0 -0
  49. package/package.json +48 -0
@@ -0,0 +1,23 @@
1
+ import react from "react";
2
+ import { SectionHeader } from "./section-header.js";
3
+ import { VariableRow } from "./variable-row.js";
4
+ const VariablesSection = ({ sortedBinds, sortedRequests, colors })=>{
5
+ if (0 === sortedBinds.length && 0 === sortedRequests.length) return null;
6
+ return /*#__PURE__*/ react.createElement("div", null, /*#__PURE__*/ react.createElement(SectionHeader, {
7
+ colors: colors,
8
+ label: "变量"
9
+ }), sortedBinds.map((bind)=>/*#__PURE__*/ react.createElement(VariableRow, {
10
+ key: bind.name,
11
+ name: bind.name,
12
+ dataType: bind.dataType,
13
+ description: bind.description,
14
+ colors: colors
15
+ })), sortedRequests.map((req)=>/*#__PURE__*/ react.createElement(VariableRow, {
16
+ key: req.name,
17
+ name: req.name,
18
+ dataType: req.dataType,
19
+ description: req.description,
20
+ colors: colors
21
+ })));
22
+ };
23
+ export { VariablesSection };
@@ -0,0 +1,2 @@
1
+ export * from "./script-code";
2
+ export * from "./types";
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./script-code.js";
2
+ export * from "./types/index.js";
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { ScriptCodeEditorProps } from './types';
3
+ export declare const ScriptCodeEditor: React.FC<ScriptCodeEditorProps>;
@@ -0,0 +1,307 @@
1
+ import react, { useEffect, useRef, useState } from "react";
2
+ import { Compartment, EditorState } from "@codemirror/state";
3
+ import { EditorView, crosshairCursor, drawSelection, dropCursor, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, keymap, lineNumbers, placeholder as view_placeholder, rectangularSelection } from "@codemirror/view";
4
+ import { defaultKeymap, history as commands_history, historyKeymap, indentWithTab } from "@codemirror/commands";
5
+ import { HighlightStyle, bracketMatching, defaultHighlightStyle, foldGutter, foldKeymap, indentOnInput, syntaxHighlighting } from "@codemirror/language";
6
+ import { java } from "@codemirror/lang-java";
7
+ import { oneDark } from "@codemirror/theme-one-dark";
8
+ import { tags } from "@lezer/highlight";
9
+ import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
10
+ import { createGroovyCompletionSource, createGroovyKeywordSource } from "./autocomplete/index.js";
11
+ import { TypePanel } from "./type-panel/index.js";
12
+ import { Toolbar } from "./components/toolbar.js";
13
+ import { ExpandSidebarButton } from "./components/expand-sidebar-button.js";
14
+ const darkHighlightStyle = HighlightStyle.define([
15
+ {
16
+ tag: tags.keyword,
17
+ color: '#c678dd'
18
+ },
19
+ {
20
+ tag: tags.operator,
21
+ color: '#56b6c2'
22
+ },
23
+ {
24
+ tag: tags.variableName,
25
+ color: '#e5c07b'
26
+ },
27
+ {
28
+ tag: tags.string,
29
+ color: '#98c379'
30
+ },
31
+ {
32
+ tag: tags.comment,
33
+ color: '#5c6370',
34
+ fontStyle: 'italic'
35
+ },
36
+ {
37
+ tag: tags.number,
38
+ color: '#d19a66'
39
+ },
40
+ {
41
+ tag: tags.bool,
42
+ color: '#d19a66'
43
+ },
44
+ {
45
+ tag: tags["null"],
46
+ color: '#d19a66'
47
+ },
48
+ {
49
+ tag: tags.propertyName,
50
+ color: '#e06c75'
51
+ },
52
+ {
53
+ tag: tags["function"](tags.variableName),
54
+ color: '#61afef'
55
+ },
56
+ {
57
+ tag: tags.definition(tags.variableName),
58
+ color: '#e5c07b'
59
+ },
60
+ {
61
+ tag: tags.typeName,
62
+ color: '#e5c07b'
63
+ },
64
+ {
65
+ tag: tags.className,
66
+ color: '#e5c07b'
67
+ },
68
+ {
69
+ tag: tags.annotation,
70
+ color: '#d19a66'
71
+ }
72
+ ]);
73
+ function buildThemeExtensions(theme) {
74
+ const isDark = 'dark' === theme;
75
+ const exts = [];
76
+ if (isDark) {
77
+ exts.push(oneDark);
78
+ exts.push(syntaxHighlighting(darkHighlightStyle));
79
+ } else exts.push(syntaxHighlighting(defaultHighlightStyle));
80
+ exts.push(EditorView.theme({
81
+ '.cm-tooltip.cm-tooltip-autocomplete': {
82
+ backgroundColor: isDark ? '#21252b' : '#ffffff',
83
+ borderColor: isDark ? '#434343' : '#d9d9d9',
84
+ borderRadius: '4px',
85
+ boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
86
+ overflow: 'hidden'
87
+ },
88
+ '.cm-tooltip-autocomplete > ul > li': {
89
+ padding: '4px 8px',
90
+ color: isDark ? '#abb2bf' : '#333'
91
+ },
92
+ '.cm-tooltip-autocomplete > ul > li[aria-selected]': {
93
+ backgroundColor: isDark ? '#2c313a' : '#e6f4ff',
94
+ color: isDark ? '#fff' : '#000'
95
+ },
96
+ '.cm-completionLabel': {
97
+ fontFamily: 'monospace'
98
+ },
99
+ '.cm-completionDetail': {
100
+ color: isDark ? '#7f848e' : '#888',
101
+ fontStyle: 'normal',
102
+ marginLeft: '8px'
103
+ },
104
+ '.cm-completionInfo': {
105
+ backgroundColor: isDark ? '#282c34' : '#fafafa',
106
+ borderColor: isDark ? '#434343' : '#d9d9d9',
107
+ color: isDark ? '#abb2bf' : '#333',
108
+ padding: '6px 8px'
109
+ },
110
+ '.cm-completionIcon': {
111
+ width: '1.2em',
112
+ fontSize: '0.9em',
113
+ paddingRight: '4px'
114
+ },
115
+ '.cm-completionIcon-property::after': {
116
+ content: '"F"',
117
+ color: '#61afef'
118
+ },
119
+ '.cm-completionIcon-function::after': {
120
+ content: '"M"',
121
+ color: '#c678dd'
122
+ },
123
+ '.cm-completionIcon-variable::after': {
124
+ content: '"V"',
125
+ color: '#e5c07b'
126
+ },
127
+ '.cm-completionIcon-keyword::after': {
128
+ content: '"K"',
129
+ color: '#56b6c2'
130
+ }
131
+ }));
132
+ return exts;
133
+ }
134
+ function buildAutocompleteExt(metadata) {
135
+ return metadata ? autocompletion({
136
+ override: [
137
+ createGroovyCompletionSource(metadata)
138
+ ],
139
+ activateOnTyping: true,
140
+ icons: true
141
+ }) : autocompletion({
142
+ override: [
143
+ createGroovyKeywordSource()
144
+ ],
145
+ activateOnTyping: true,
146
+ icons: true
147
+ });
148
+ }
149
+ const ScriptCodeEditor = (props)=>{
150
+ const { value, readonly = false, onChange, onCompile, onThemeChange, placeholder = '请输入 Groovy 脚本...', theme = 'dark', title, metadata, defaultSidebarOpen, options = {} } = props;
151
+ const { fontSize = 14, minHeight = 300, maxHeight = 300 } = options;
152
+ const editorContainerRef = useRef(null);
153
+ const viewRef = useRef(null);
154
+ const themeCompartmentRef = useRef(new Compartment());
155
+ const autocompleteCompartmentRef = useRef(new Compartment());
156
+ const onChangeRef = useRef(onChange);
157
+ onChangeRef.current = onChange;
158
+ const metadataRef = useRef(metadata);
159
+ metadataRef.current = metadata;
160
+ const [sidebarOpen, setSidebarOpen] = useState(defaultSidebarOpen ?? null != metadata);
161
+ const [panelWidth, setPanelWidth] = useState(300);
162
+ useEffect(()=>{
163
+ if (!editorContainerRef.current) return;
164
+ const themeCompartment = themeCompartmentRef.current;
165
+ const acCompartment = autocompleteCompartmentRef.current;
166
+ const extensions = [
167
+ lineNumbers(),
168
+ highlightActiveLineGutter(),
169
+ highlightSpecialChars(),
170
+ commands_history(),
171
+ foldGutter(),
172
+ drawSelection(),
173
+ dropCursor(),
174
+ EditorState.allowMultipleSelections.of(true),
175
+ indentOnInput(),
176
+ bracketMatching(),
177
+ rectangularSelection(),
178
+ crosshairCursor(),
179
+ highlightActiveLine(),
180
+ keymap.of([
181
+ ...defaultKeymap,
182
+ ...historyKeymap,
183
+ ...foldKeymap,
184
+ ...completionKeymap,
185
+ indentWithTab
186
+ ]),
187
+ java(),
188
+ view_placeholder(placeholder),
189
+ EditorView.updateListener.of((update)=>{
190
+ if (update.docChanged && onChangeRef.current) onChangeRef.current(update.state.doc.toString());
191
+ }),
192
+ EditorView.theme({
193
+ '&': {
194
+ fontSize: `${fontSize}px`
195
+ },
196
+ '.cm-scroller': {
197
+ overflow: 'auto',
198
+ minHeight: `${minHeight}px`,
199
+ maxHeight: `${maxHeight}px`
200
+ },
201
+ '.cm-content': {
202
+ fontFamily: 'monospace',
203
+ minHeight: `${minHeight}px`
204
+ },
205
+ '.cm-gutters': {
206
+ minHeight: `${minHeight}px`
207
+ }
208
+ }),
209
+ themeCompartment.of(buildThemeExtensions(theme)),
210
+ acCompartment.of(buildAutocompleteExt(metadataRef.current))
211
+ ];
212
+ if (readonly) extensions.push(EditorState.readOnly.of(true));
213
+ const state = EditorState.create({
214
+ doc: value,
215
+ extensions
216
+ });
217
+ const view = new EditorView({
218
+ state,
219
+ parent: editorContainerRef.current
220
+ });
221
+ viewRef.current = view;
222
+ return ()=>{
223
+ view.destroy();
224
+ };
225
+ }, [
226
+ fontSize,
227
+ minHeight,
228
+ maxHeight,
229
+ placeholder,
230
+ readonly
231
+ ]);
232
+ useEffect(()=>{
233
+ if (viewRef.current && value !== viewRef.current.state.doc.toString()) viewRef.current.dispatch({
234
+ changes: {
235
+ from: 0,
236
+ to: viewRef.current.state.doc.length,
237
+ insert: value
238
+ }
239
+ });
240
+ }, [
241
+ value
242
+ ]);
243
+ useEffect(()=>{
244
+ if (!viewRef.current) return;
245
+ viewRef.current.dispatch({
246
+ effects: themeCompartmentRef.current.reconfigure(buildThemeExtensions(theme))
247
+ });
248
+ }, [
249
+ theme
250
+ ]);
251
+ useEffect(()=>{
252
+ if (!viewRef.current) return;
253
+ viewRef.current.dispatch({
254
+ effects: autocompleteCompartmentRef.current.reconfigure(buildAutocompleteExt(metadata))
255
+ });
256
+ }, [
257
+ metadata
258
+ ]);
259
+ const isDark = 'dark' === theme;
260
+ const borderColor = isDark ? '#434343' : '#d9d9d9';
261
+ const expandBtnBg = isDark ? '#2c313a' : '#f0f0f0';
262
+ const expandBtnColor = isDark ? '#abb2bf' : '#666';
263
+ const handleCompile = ()=>{
264
+ if (onCompile && viewRef.current) onCompile(viewRef.current.state.doc.toString());
265
+ };
266
+ return /*#__PURE__*/ react.createElement("div", {
267
+ style: {
268
+ display: 'flex',
269
+ flexDirection: 'column'
270
+ }
271
+ }, /*#__PURE__*/ react.createElement(Toolbar, {
272
+ title: title,
273
+ theme: theme,
274
+ onThemeChange: onThemeChange,
275
+ onCompile: onCompile ? handleCompile : void 0
276
+ }), /*#__PURE__*/ react.createElement("div", {
277
+ style: {
278
+ display: 'flex',
279
+ border: `1px solid ${borderColor}`,
280
+ borderTop: 'none',
281
+ borderRadius: '0 0 6px 6px',
282
+ overflow: 'hidden'
283
+ }
284
+ }, /*#__PURE__*/ react.createElement("div", {
285
+ style: {
286
+ flex: 1,
287
+ minWidth: 0,
288
+ position: 'relative'
289
+ }
290
+ }, metadata && !sidebarOpen && /*#__PURE__*/ react.createElement(ExpandSidebarButton, {
291
+ borderColor: borderColor,
292
+ expandBtnColor: expandBtnColor,
293
+ expandBtnBg: expandBtnBg,
294
+ onClick: ()=>setSidebarOpen(true)
295
+ }), /*#__PURE__*/ react.createElement("div", {
296
+ ref: editorContainerRef
297
+ })), metadata && sidebarOpen && /*#__PURE__*/ react.createElement(TypePanel, {
298
+ metadata: metadata,
299
+ theme: theme,
300
+ minHeight: minHeight,
301
+ maxHeight: maxHeight,
302
+ width: panelWidth,
303
+ onWidthChange: setPanelWidth,
304
+ onCollapse: ()=>setSidebarOpen(false)
305
+ })));
306
+ };
307
+ export { ScriptCodeEditor };
@@ -0,0 +1,2 @@
1
+ export { TypePanel } from './type-panel';
2
+ export type { TypePanelProps } from './type-panel';
@@ -0,0 +1 @@
1
+ export { TypePanel } from "./type-panel.js";
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import type { ScriptMetadata } from '../types';
3
+ export interface TypePanelProps {
4
+ metadata: ScriptMetadata;
5
+ theme: 'dark' | 'light';
6
+ minHeight: number;
7
+ maxHeight: number;
8
+ width: number;
9
+ onWidthChange: (width: number) => void;
10
+ onCollapse: () => void;
11
+ }
12
+ export declare const TypePanel: React.FC<TypePanelProps>;
@@ -0,0 +1,129 @@
1
+ import react, { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { SCROLL_CLASS, ensureScrollbarStyle, themes } from "../components/theme-colors.js";
3
+ import { DragHandle } from "../components/drag-handle.js";
4
+ import { PanelHeader } from "../components/panel-header.js";
5
+ import { MainFunctionSection } from "../components/main-function-section.js";
6
+ import { VariablesSection } from "../components/variables-section.js";
7
+ import { DataTypesSection } from "../components/data-types-section.js";
8
+ const DEFAULT_WIDTH = 300;
9
+ const MIN_WIDTH = 180;
10
+ const MAX_WIDTH = 600;
11
+ const TypePanel = ({ metadata, theme, minHeight, maxHeight, width, onWidthChange, onCollapse })=>{
12
+ const colors = themes[theme];
13
+ const [expanded, setExpanded] = useState(()=>new Set());
14
+ const panelRef = useRef(null);
15
+ const [dragging, setDragging] = useState(false);
16
+ const [handleHovered, setHandleHovered] = useState(false);
17
+ const dragStartXRef = useRef(0);
18
+ const dragStartWidthRef = useRef(DEFAULT_WIDTH);
19
+ useEffect(()=>{
20
+ ensureScrollbarStyle();
21
+ }, []);
22
+ useEffect(()=>{
23
+ if (!dragging) return;
24
+ const onMouseMove = (e)=>{
25
+ const delta = dragStartXRef.current - e.clientX;
26
+ const next = Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, dragStartWidthRef.current + delta));
27
+ onWidthChange(next);
28
+ };
29
+ const onMouseUp = ()=>{
30
+ setDragging(false);
31
+ document.body.classList.remove('se-panel-resizing');
32
+ };
33
+ window.addEventListener('mousemove', onMouseMove);
34
+ window.addEventListener('mouseup', onMouseUp);
35
+ return ()=>{
36
+ window.removeEventListener('mousemove', onMouseMove);
37
+ window.removeEventListener('mouseup', onMouseUp);
38
+ };
39
+ }, [
40
+ dragging,
41
+ onWidthChange
42
+ ]);
43
+ const onHandleMouseDown = useCallback((e)=>{
44
+ e.preventDefault();
45
+ dragStartXRef.current = e.clientX;
46
+ dragStartWidthRef.current = width;
47
+ setDragging(true);
48
+ document.body.classList.add('se-panel-resizing');
49
+ }, [
50
+ width
51
+ ]);
52
+ const toggle = useCallback((typeName)=>{
53
+ setExpanded((prev)=>{
54
+ const next = new Set(prev);
55
+ if (next.has(typeName)) next.delete(typeName);
56
+ else next.add(typeName);
57
+ return next;
58
+ });
59
+ }, []);
60
+ const allTypes = useMemo(()=>Object.values(metadata.types).sort((a, b)=>a.dataType.localeCompare(b.dataType)), [
61
+ metadata.types
62
+ ]);
63
+ const sortedBinds = useMemo(()=>[
64
+ ...metadata.binds
65
+ ].sort((a, b)=>a.name.localeCompare(b.name)), [
66
+ metadata.binds
67
+ ]);
68
+ const sortedRequests = useMemo(()=>[
69
+ ...metadata.requests
70
+ ].sort((a, b)=>a.name.localeCompare(b.name)), [
71
+ metadata.requests
72
+ ]);
73
+ return /*#__PURE__*/ react.createElement("div", {
74
+ ref: panelRef,
75
+ style: {
76
+ width,
77
+ flexShrink: 0,
78
+ display: 'flex',
79
+ flexDirection: 'row',
80
+ overflow: 'hidden',
81
+ minHeight: `${minHeight}px`,
82
+ maxHeight: `${maxHeight}px`,
83
+ position: 'relative'
84
+ }
85
+ }, /*#__PURE__*/ react.createElement(DragHandle, {
86
+ colors: colors,
87
+ dragging: dragging,
88
+ handleHovered: handleHovered,
89
+ onMouseDown: onHandleMouseDown,
90
+ onHoverChange: setHandleHovered
91
+ }), /*#__PURE__*/ react.createElement("div", {
92
+ style: {
93
+ flex: 1,
94
+ minWidth: 0,
95
+ borderLeft: `1px solid ${colors.border}`,
96
+ display: 'flex',
97
+ flexDirection: 'column',
98
+ overflow: 'hidden',
99
+ backgroundColor: colors.bg,
100
+ color: colors.text,
101
+ fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
102
+ fontSize: 13
103
+ }
104
+ }, /*#__PURE__*/ react.createElement(PanelHeader, {
105
+ colors: colors,
106
+ onCollapse: onCollapse
107
+ }), /*#__PURE__*/ react.createElement("div", {
108
+ className: SCROLL_CLASS,
109
+ style: {
110
+ flex: 1,
111
+ overflowY: 'auto',
112
+ overflowX: 'hidden',
113
+ minHeight: 0
114
+ }
115
+ }, /*#__PURE__*/ react.createElement(MainFunctionSection, {
116
+ metadata: metadata,
117
+ colors: colors
118
+ }), /*#__PURE__*/ react.createElement(VariablesSection, {
119
+ sortedBinds: sortedBinds,
120
+ sortedRequests: sortedRequests,
121
+ colors: colors
122
+ }), /*#__PURE__*/ react.createElement(DataTypesSection, {
123
+ allTypes: allTypes,
124
+ expanded: expanded,
125
+ onToggle: toggle,
126
+ colors: colors
127
+ }))));
128
+ };
129
+ export { TypePanel };
@@ -0,0 +1,77 @@
1
+ /** 函数参数信息 */
2
+ export interface ScriptParameterInfo {
3
+ dataType: string;
4
+ description?: string;
5
+ name: string;
6
+ }
7
+ /** 函数/方法信息 */
8
+ export interface ScriptFunctionInfo {
9
+ description?: string;
10
+ name: string;
11
+ parameters: ScriptParameterInfo[];
12
+ returnType?: string;
13
+ }
14
+ /** 字段/属性信息 */
15
+ export interface ScriptFieldInfo {
16
+ dataType: string;
17
+ description?: string;
18
+ name: string;
19
+ }
20
+ /** 类型定义 */
21
+ export interface ScriptTypeInfo {
22
+ dataType: string;
23
+ description?: string;
24
+ fields: ScriptFieldInfo[];
25
+ functions: ScriptFunctionInfo[];
26
+ }
27
+ /** 绑定变量信息(如 $request) */
28
+ export interface ScriptBindInfo {
29
+ dataType: string;
30
+ name: string;
31
+ description?: string;
32
+ }
33
+ /** 请求参数信息(如 request) */
34
+ export interface ScriptRequestInfo {
35
+ dataType: string;
36
+ description?: string;
37
+ name: string;
38
+ }
39
+ /** 脚本元数据顶层结构 */
40
+ export interface ScriptMetadata {
41
+ binds: ScriptBindInfo[];
42
+ requests: ScriptRequestInfo[];
43
+ mainMethod: string;
44
+ returnType?: string;
45
+ types: Record<string, ScriptTypeInfo>;
46
+ }
47
+ export interface ScriptCodeEditorProps {
48
+ /** 代码内容 */
49
+ value?: string;
50
+ /** 是否只读 */
51
+ readonly?: boolean;
52
+ /** 代码变化回调 */
53
+ onChange?: (value: string) => void;
54
+ /** 编译/测试脚本回调(后续接入 API) */
55
+ onCompile?: (code: string) => void;
56
+ /** 主题切换回调 */
57
+ onThemeChange?: (theme: 'dark' | 'light') => void;
58
+ /** 占位符 */
59
+ placeholder?: string;
60
+ /** 主题 */
61
+ theme?: 'dark' | 'light';
62
+ /** 标题(可选) */
63
+ title?: string;
64
+ /** 脚本元数据 — 提供后启用类型面板和自动补全 */
65
+ metadata?: ScriptMetadata;
66
+ /** 类型面板侧边栏默认是否展开(默认:提供 metadata 时为 true) */
67
+ defaultSidebarOpen?: boolean;
68
+ /** 其他选项 */
69
+ options?: {
70
+ /** 字体大小 */
71
+ fontSize?: number;
72
+ /** 最小高度 */
73
+ minHeight?: number;
74
+ /** 最大高度 */
75
+ maxHeight?: number;
76
+ };
77
+ }
File without changes
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@coding-script/script-engine",
3
+ "version": "0.0.1",
4
+ "description": "script-engine components",
5
+ "keywords": [
6
+ "coding-script",
7
+ "script-engine"
8
+ ],
9
+ "homepage": "https://github.com/codingapi/script-engine",
10
+ "bugs": {
11
+ "url": "https://github.com/codingapi/script-engine/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/codingapi/script-engine.git"
16
+ },
17
+ "license": "Apache-2.0",
18
+ "author": "1024lorne@gmail.com",
19
+ "type": "module",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js"
24
+ }
25
+ },
26
+ "types": "./dist/index.d.ts",
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "dependencies": {
31
+ "@codemirror/autocomplete": "^6.18.0",
32
+ "@codemirror/commands": "^6.10.2",
33
+ "@codemirror/lang-java": "^6.0.2",
34
+ "@codemirror/language": "^6.12.2",
35
+ "@codemirror/state": "^6.5.4",
36
+ "@codemirror/theme-one-dark": "^6.1.3",
37
+ "@codemirror/view": "^6.39.16"
38
+ },
39
+ "peerDependencies": {
40
+ "react": ">=18",
41
+ "react-dom": ">=18"
42
+ },
43
+ "scripts": {
44
+ "build": "rslib build",
45
+ "dev": "rslib build --watch",
46
+ "push": "pnpm run build && pnpm publish --access public"
47
+ }
48
+ }