@djvlc/runtime-host-react 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,485 @@
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/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ DJVProvider: () => DJVProvider,
24
+ DJVRenderer: () => DJVRenderer,
25
+ RuntimeContext: () => RuntimeContext,
26
+ RuntimeProvider: () => RuntimeProvider,
27
+ useAction: () => useAction,
28
+ useDJVRuntime: () => useDJVRuntime,
29
+ useData: () => useData,
30
+ useHostApi: () => useHostApi,
31
+ useQuery: () => useQuery,
32
+ useReactRuntime: () => useReactRuntime,
33
+ useRuntimeContext: () => useRuntimeContext,
34
+ useRuntimeEvent: () => useRuntimeEvent,
35
+ useRuntimeState: () => useRuntimeState,
36
+ useRuntimeStateWritable: () => useRuntimeStateWritable
37
+ });
38
+ module.exports = __toCommonJS(index_exports);
39
+
40
+ // src/react-runtime.ts
41
+ var import_react = require("react");
42
+ var import_runtime_core = require("@djvlc/runtime-core");
43
+ function useReactRuntime(options) {
44
+ const [runtime, setRuntime] = (0, import_react.useState)(null);
45
+ const [loading, setLoading] = (0, import_react.useState)(true);
46
+ const [phase, setPhase] = (0, import_react.useState)("idle");
47
+ const [page, setPage] = (0, import_react.useState)(null);
48
+ const [error, setError] = (0, import_react.useState)(null);
49
+ const [hostApi, setHostApi] = (0, import_react.useState)(null);
50
+ const runtimeRef = (0, import_react.useRef)(null);
51
+ const init = (0, import_react.useCallback)(async () => {
52
+ const container = options.containerRef?.current;
53
+ if (!container) {
54
+ throw new Error("Container element not found");
55
+ }
56
+ const runtimeInstance = (0, import_runtime_core.createRuntime)({
57
+ ...options,
58
+ container,
59
+ onError: (err) => {
60
+ setError(err);
61
+ options.onError?.(err);
62
+ },
63
+ onEvent: (event) => {
64
+ options.onEvent?.(event);
65
+ }
66
+ });
67
+ runtimeRef.current = runtimeInstance;
68
+ setRuntime(runtimeInstance);
69
+ runtimeInstance.onStateChange((state) => {
70
+ setPhase(state.phase);
71
+ setLoading(state.phase !== "ready" && state.phase !== "error");
72
+ if (state.page) {
73
+ setPage(state.page);
74
+ }
75
+ if (state.error) {
76
+ setError(state.error);
77
+ }
78
+ });
79
+ await runtimeInstance.init();
80
+ setHostApi(runtimeInstance.getHostApi());
81
+ }, [options]);
82
+ const load = (0, import_react.useCallback)(async () => {
83
+ if (!runtimeRef.current) {
84
+ throw new Error("Runtime not initialized");
85
+ }
86
+ const result = await runtimeRef.current.load();
87
+ setPage(result);
88
+ setHostApi(runtimeRef.current.getHostApi());
89
+ return result;
90
+ }, []);
91
+ const render = (0, import_react.useCallback)(async () => {
92
+ if (!runtimeRef.current) {
93
+ throw new Error("Runtime not initialized");
94
+ }
95
+ await runtimeRef.current.render();
96
+ setLoading(false);
97
+ }, []);
98
+ const destroy = (0, import_react.useCallback)(() => {
99
+ runtimeRef.current?.destroy();
100
+ runtimeRef.current = null;
101
+ setRuntime(null);
102
+ setHostApi(null);
103
+ setPage(null);
104
+ setError(null);
105
+ setPhase("idle");
106
+ setLoading(true);
107
+ }, []);
108
+ const setVariable = (0, import_react.useCallback)((key, value) => {
109
+ runtimeRef.current?.setVariable(key, value);
110
+ }, []);
111
+ const refreshData = (0, import_react.useCallback)(async (queryId) => {
112
+ await runtimeRef.current?.refreshData(queryId);
113
+ }, []);
114
+ return {
115
+ runtime,
116
+ loading,
117
+ phase,
118
+ page,
119
+ error,
120
+ hostApi,
121
+ init,
122
+ load,
123
+ render,
124
+ destroy,
125
+ setVariable,
126
+ refreshData
127
+ };
128
+ }
129
+
130
+ // src/context.tsx
131
+ var import_react2 = require("react");
132
+ var import_jsx_runtime = require("react/jsx-runtime");
133
+ var defaultState = {
134
+ phase: "idle",
135
+ page: null,
136
+ variables: {},
137
+ queries: {},
138
+ components: /* @__PURE__ */ new Map(),
139
+ error: null,
140
+ destroyed: false
141
+ };
142
+ var RuntimeContext = (0, import_react2.createContext)({
143
+ runtime: null,
144
+ state: defaultState,
145
+ hostApi: null
146
+ });
147
+ function RuntimeProvider({
148
+ runtime,
149
+ state,
150
+ hostApi,
151
+ children
152
+ }) {
153
+ const value = {
154
+ runtime,
155
+ state,
156
+ hostApi
157
+ };
158
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RuntimeContext.Provider, { value, children });
159
+ }
160
+ function useRuntimeContext() {
161
+ const context = (0, import_react2.useContext)(RuntimeContext);
162
+ return context;
163
+ }
164
+
165
+ // src/components/DJVRenderer.tsx
166
+ var import_react3 = require("react");
167
+ var import_jsx_runtime2 = require("react/jsx-runtime");
168
+ function DJVRenderer({
169
+ pageUid,
170
+ apiBaseUrl,
171
+ cdnBaseUrl,
172
+ channel = "prod",
173
+ userId,
174
+ deviceId,
175
+ authToken,
176
+ previewToken,
177
+ debug = false,
178
+ enableSRI = true,
179
+ onLoad,
180
+ onError,
181
+ onReady,
182
+ loadingComponent,
183
+ errorComponent,
184
+ children,
185
+ className,
186
+ style
187
+ }) {
188
+ const containerRef = (0, import_react3.useRef)(null);
189
+ const [state, setState] = (0, import_react3.useState)({
190
+ phase: "idle",
191
+ page: null,
192
+ variables: {},
193
+ queries: {},
194
+ components: /* @__PURE__ */ new Map(),
195
+ error: null,
196
+ destroyed: false
197
+ });
198
+ const options = {
199
+ pageUid,
200
+ apiBaseUrl,
201
+ cdnBaseUrl,
202
+ channel,
203
+ userId,
204
+ deviceId,
205
+ authToken,
206
+ previewToken,
207
+ debug,
208
+ enableSRI,
209
+ containerRef,
210
+ onError: (error2) => {
211
+ onError?.(error2);
212
+ }
213
+ };
214
+ const {
215
+ runtime,
216
+ loading,
217
+ phase: _phase,
218
+ page: _page,
219
+ error,
220
+ hostApi,
221
+ init,
222
+ load,
223
+ render,
224
+ destroy
225
+ } = useReactRuntime(options);
226
+ void _phase;
227
+ void _page;
228
+ const initAndLoad = (0, import_react3.useCallback)(async () => {
229
+ if (!containerRef.current) return;
230
+ try {
231
+ await init();
232
+ const pageData = await load();
233
+ onLoad?.(pageData);
234
+ await render();
235
+ onReady?.();
236
+ if (runtime) {
237
+ runtime.onStateChange((newState) => {
238
+ setState(newState);
239
+ });
240
+ }
241
+ } catch (err) {
242
+ }
243
+ }, [init, load, render, runtime, onLoad, onReady]);
244
+ (0, import_react3.useEffect)(() => {
245
+ initAndLoad();
246
+ return () => {
247
+ destroy();
248
+ };
249
+ }, [pageUid]);
250
+ const renderLoading = () => {
251
+ if (!loading) return null;
252
+ return loadingComponent || /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "djvlc-loading", children: [
253
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "djvlc-loading-spinner" }),
254
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u52A0\u8F7D\u4E2D..." })
255
+ ] });
256
+ };
257
+ const renderError = () => {
258
+ if (!error) return null;
259
+ if (typeof errorComponent === "function") {
260
+ return errorComponent(error);
261
+ }
262
+ return errorComponent || /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "djvlc-error", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
263
+ "\u52A0\u8F7D\u5931\u8D25\uFF1A",
264
+ error.message
265
+ ] }) });
266
+ };
267
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(RuntimeProvider, { runtime, state, hostApi, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
268
+ "div",
269
+ {
270
+ ref: containerRef,
271
+ className: `djvlc-renderer ${className || ""}`,
272
+ style,
273
+ children: [
274
+ renderLoading(),
275
+ renderError(),
276
+ children
277
+ ]
278
+ }
279
+ ) });
280
+ }
281
+
282
+ // src/components/DJVProvider.tsx
283
+ var import_react4 = require("react");
284
+ var import_jsx_runtime3 = require("react/jsx-runtime");
285
+ function DJVProvider({
286
+ runtime,
287
+ hostApi,
288
+ children
289
+ }) {
290
+ const [state, setState] = (0, import_react4.useState)(
291
+ runtime?.getState() || {
292
+ phase: "idle",
293
+ page: null,
294
+ variables: {},
295
+ queries: {},
296
+ components: /* @__PURE__ */ new Map(),
297
+ error: null,
298
+ destroyed: false
299
+ }
300
+ );
301
+ (0, import_react4.useEffect)(() => {
302
+ if (!runtime) return;
303
+ const unsubscribe = runtime.onStateChange((newState) => {
304
+ setState(newState);
305
+ });
306
+ return () => {
307
+ unsubscribe();
308
+ };
309
+ }, [runtime]);
310
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(RuntimeProvider, { runtime, state, hostApi, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "djvlc-provider", children }) });
311
+ }
312
+
313
+ // src/hooks/useDJVRuntime.ts
314
+ var import_react5 = require("react");
315
+ function useDJVRuntime() {
316
+ const context = useRuntimeContext();
317
+ const loading = (0, import_react5.useMemo)(() => {
318
+ const phase = context.state.phase;
319
+ return phase !== "ready" && phase !== "error";
320
+ }, [context.state.phase]);
321
+ return {
322
+ runtime: context.runtime,
323
+ state: context.state,
324
+ loading,
325
+ phase: context.state.phase,
326
+ error: context.state.error,
327
+ page: context.state.page
328
+ };
329
+ }
330
+ function useHostApi() {
331
+ const context = useRuntimeContext();
332
+ if (!context.hostApi) {
333
+ throw new Error("HostAPI not available. Make sure runtime is initialized.");
334
+ }
335
+ return context.hostApi;
336
+ }
337
+ function useRuntimeState(key) {
338
+ const context = useRuntimeContext();
339
+ return context.state.variables[key];
340
+ }
341
+ function useRuntimeStateWritable(key, defaultValue) {
342
+ const context = useRuntimeContext();
343
+ const value = context.state.variables[key] ?? defaultValue;
344
+ const setValue = (0, import_react5.useCallback)(
345
+ (newValue) => {
346
+ context.runtime?.setVariable(key, newValue);
347
+ },
348
+ [context.runtime, key]
349
+ );
350
+ return [value, setValue];
351
+ }
352
+ function useQuery(queryId) {
353
+ const context = useRuntimeContext();
354
+ const [loading, setLoading] = (0, import_react5.useState)(false);
355
+ const [error, setError] = (0, import_react5.useState)(null);
356
+ const data = context.state.queries[queryId];
357
+ const refetch = (0, import_react5.useCallback)(async () => {
358
+ setLoading(true);
359
+ setError(null);
360
+ try {
361
+ await context.runtime?.refreshData(queryId);
362
+ } catch (e) {
363
+ setError(e);
364
+ } finally {
365
+ setLoading(false);
366
+ }
367
+ }, [context.runtime, queryId]);
368
+ return {
369
+ data,
370
+ loading,
371
+ error,
372
+ refetch
373
+ };
374
+ }
375
+ function useAction(actionType) {
376
+ const context = useRuntimeContext();
377
+ const [loading, setLoading] = (0, import_react5.useState)(false);
378
+ const [result, setResult] = (0, import_react5.useState)();
379
+ const [error, setError] = (0, import_react5.useState)(null);
380
+ const execute = (0, import_react5.useCallback)(
381
+ async (params) => {
382
+ const hostApi = context.hostApi;
383
+ if (!hostApi) {
384
+ throw new Error("HostAPI not available");
385
+ }
386
+ setLoading(true);
387
+ setError(null);
388
+ try {
389
+ const response = await hostApi.executeAction(
390
+ actionType,
391
+ params
392
+ );
393
+ if (response.success) {
394
+ setResult(response.data);
395
+ return response.data;
396
+ } else {
397
+ throw new Error(response.message || "Action failed");
398
+ }
399
+ } catch (e) {
400
+ setError(e);
401
+ throw e;
402
+ } finally {
403
+ setLoading(false);
404
+ }
405
+ },
406
+ [context.hostApi, actionType]
407
+ );
408
+ return {
409
+ execute,
410
+ loading,
411
+ result,
412
+ error
413
+ };
414
+ }
415
+ function useData(queryId, params, options) {
416
+ const context = useRuntimeContext();
417
+ const [data, setData] = (0, import_react5.useState)();
418
+ const [loading, setLoading] = (0, import_react5.useState)(false);
419
+ const [error, setError] = (0, import_react5.useState)(null);
420
+ const refetch = (0, import_react5.useCallback)(
421
+ async (newParams) => {
422
+ const hostApi = context.hostApi;
423
+ if (!hostApi) {
424
+ throw new Error("HostAPI not available");
425
+ }
426
+ setLoading(true);
427
+ setError(null);
428
+ try {
429
+ const response = await hostApi.requestData(
430
+ queryId,
431
+ newParams || params
432
+ );
433
+ if (response.success) {
434
+ setData(response.data);
435
+ } else {
436
+ throw new Error(response.message || "Query failed");
437
+ }
438
+ } catch (e) {
439
+ setError(e);
440
+ } finally {
441
+ setLoading(false);
442
+ }
443
+ },
444
+ [context.hostApi, queryId, params]
445
+ );
446
+ (0, import_react5.useEffect)(() => {
447
+ if (options?.immediate !== false && context.hostApi) {
448
+ refetch();
449
+ }
450
+ }, [context.hostApi]);
451
+ return {
452
+ data,
453
+ loading,
454
+ error,
455
+ refetch
456
+ };
457
+ }
458
+ function useRuntimeEvent(eventType, handler) {
459
+ const context = useRuntimeContext();
460
+ (0, import_react5.useEffect)(() => {
461
+ const unsubscribe = context.runtime?.on(eventType, (event) => {
462
+ handler(event.data);
463
+ });
464
+ return () => {
465
+ unsubscribe?.();
466
+ };
467
+ }, [context.runtime, eventType, handler]);
468
+ }
469
+ // Annotate the CommonJS export names for ESM import in node:
470
+ 0 && (module.exports = {
471
+ DJVProvider,
472
+ DJVRenderer,
473
+ RuntimeContext,
474
+ RuntimeProvider,
475
+ useAction,
476
+ useDJVRuntime,
477
+ useData,
478
+ useHostApi,
479
+ useQuery,
480
+ useReactRuntime,
481
+ useRuntimeContext,
482
+ useRuntimeEvent,
483
+ useRuntimeState,
484
+ useRuntimeStateWritable
485
+ });
@@ -0,0 +1,221 @@
1
+ import { RuntimeOptions, DjvlcRuntime, RuntimePhase, PageResolveResult, RuntimeError, HostAPI, RuntimeState } from '@djvlc/runtime-core';
2
+ export { HostAPI, PageResolveResult, RuntimeError, RuntimeOptions, RuntimePhase, RuntimeState } from '@djvlc/runtime-core';
3
+ import * as react from 'react';
4
+ import react__default, { ReactNode } from 'react';
5
+
6
+ /**
7
+ * React 运行时封装
8
+ * 将核心运行时封装为 React 友好的 API
9
+ */
10
+
11
+ /**
12
+ * React 运行时选项
13
+ */
14
+ interface ReactRuntimeOptions extends Omit<RuntimeOptions, 'container'> {
15
+ /** 容器元素引用 */
16
+ containerRef?: React.RefObject<HTMLElement>;
17
+ }
18
+ /**
19
+ * React 运行时返回值
20
+ */
21
+ interface ReactRuntimeReturn {
22
+ /** 运行时实例 */
23
+ runtime: DjvlcRuntime | null;
24
+ /** 加载状态 */
25
+ loading: boolean;
26
+ /** 当前阶段 */
27
+ phase: RuntimePhase;
28
+ /** 页面数据 */
29
+ page: PageResolveResult | null;
30
+ /** 错误信息 */
31
+ error: RuntimeError | null;
32
+ /** Host API */
33
+ hostApi: HostAPI | null;
34
+ /** 初始化 */
35
+ init: () => Promise<void>;
36
+ /** 加载页面 */
37
+ load: () => Promise<PageResolveResult>;
38
+ /** 渲染页面 */
39
+ render: () => Promise<void>;
40
+ /** 销毁 */
41
+ destroy: () => void;
42
+ /** 设置变量 */
43
+ setVariable: (key: string, value: unknown) => void;
44
+ /** 刷新数据 */
45
+ refreshData: (queryId: string) => Promise<void>;
46
+ }
47
+ /**
48
+ * 使用 React 运行时 Hook
49
+ */
50
+ declare function useReactRuntime(options: ReactRuntimeOptions): ReactRuntimeReturn;
51
+
52
+ /**
53
+ * 运行时上下文值
54
+ */
55
+ interface RuntimeContextValue {
56
+ runtime: DjvlcRuntime | null;
57
+ state: RuntimeState;
58
+ hostApi: HostAPI | null;
59
+ }
60
+ /**
61
+ * 运行时上下文
62
+ */
63
+ declare const RuntimeContext: react.Context<RuntimeContextValue>;
64
+ /**
65
+ * Runtime Provider Props
66
+ */
67
+ interface RuntimeProviderProps {
68
+ /** 运行时实例 */
69
+ runtime: DjvlcRuntime | null;
70
+ /** 运行时状态 */
71
+ state: RuntimeState;
72
+ /** Host API */
73
+ hostApi: HostAPI | null;
74
+ /** 子元素 */
75
+ children: ReactNode;
76
+ }
77
+ /**
78
+ * Runtime Provider 组件
79
+ */
80
+ declare function RuntimeProvider({ runtime, state, hostApi, children, }: RuntimeProviderProps): JSX.Element;
81
+ /**
82
+ * 使用运行时上下文
83
+ */
84
+ declare function useRuntimeContext(): RuntimeContextValue;
85
+
86
+ /**
87
+ * DJV 渲染器组件
88
+ * React 组件,用于渲染低代码页面
89
+ */
90
+
91
+ /**
92
+ * DJV 渲染器 Props
93
+ */
94
+ interface DJVRendererProps {
95
+ /** 页面 UID */
96
+ pageUid: string;
97
+ /** API 基础 URL */
98
+ apiBaseUrl: string;
99
+ /** CDN 基础 URL */
100
+ cdnBaseUrl: string;
101
+ /** 渠道 */
102
+ channel?: 'preview' | 'prod' | 'gray';
103
+ /** 用户 ID */
104
+ userId?: string;
105
+ /** 设备 ID */
106
+ deviceId?: string;
107
+ /** 认证 Token */
108
+ authToken?: string;
109
+ /** 预览 Token */
110
+ previewToken?: string;
111
+ /** 调试模式 */
112
+ debug?: boolean;
113
+ /** 是否启用 SRI */
114
+ enableSRI?: boolean;
115
+ /** 加载完成回调 */
116
+ onLoad?: (page: PageResolveResult) => void;
117
+ /** 错误回调 */
118
+ onError?: (error: RuntimeError) => void;
119
+ /** 就绪回调 */
120
+ onReady?: () => void;
121
+ /** 加载中显示 */
122
+ loadingComponent?: ReactNode;
123
+ /** 错误显示 */
124
+ errorComponent?: ReactNode | ((error: RuntimeError) => ReactNode);
125
+ /** 子元素 */
126
+ children?: ReactNode;
127
+ /** 容器类名 */
128
+ className?: string;
129
+ /** 容器样式 */
130
+ style?: react__default.CSSProperties;
131
+ }
132
+ /**
133
+ * DJV 渲染器组件
134
+ */
135
+ declare function DJVRenderer({ pageUid, apiBaseUrl, cdnBaseUrl, channel, userId, deviceId, authToken, previewToken, debug, enableSRI, onLoad, onError, onReady, loadingComponent, errorComponent, children, className, style, }: DJVRendererProps): JSX.Element;
136
+
137
+ /**
138
+ * DJV Provider 组件
139
+ * 提供运行时上下文给子组件
140
+ */
141
+
142
+ /**
143
+ * DJV Provider Props
144
+ */
145
+ interface DJVProviderProps {
146
+ /** 运行时实例 */
147
+ runtime: DjvlcRuntime | null;
148
+ /** Host API */
149
+ hostApi: HostAPI | null;
150
+ /** 子元素 */
151
+ children: ReactNode;
152
+ }
153
+ /**
154
+ * DJV Provider 组件
155
+ * 用于手动控制运行时时使用
156
+ */
157
+ declare function DJVProvider({ runtime, hostApi, children, }: DJVProviderProps): JSX.Element;
158
+
159
+ /**
160
+ * React Hooks
161
+ * 运行时相关的 React Hooks
162
+ */
163
+
164
+ /**
165
+ * 使用 DJV 运行时
166
+ */
167
+ declare function useDJVRuntime(): {
168
+ runtime: RuntimeContextValue['runtime'];
169
+ state: RuntimeContextValue['state'];
170
+ loading: boolean;
171
+ phase: RuntimePhase;
172
+ error: RuntimeError | null;
173
+ page: PageResolveResult | null;
174
+ };
175
+ /**
176
+ * 使用 Host API
177
+ */
178
+ declare function useHostApi(): HostAPI;
179
+ /**
180
+ * 使用运行时状态
181
+ */
182
+ declare function useRuntimeState<T = unknown>(key: string): T | undefined;
183
+ /**
184
+ * 使用可写状态
185
+ */
186
+ declare function useRuntimeStateWritable<T = unknown>(key: string, defaultValue?: T): [T, (value: T) => void];
187
+ /**
188
+ * 使用查询结果
189
+ */
190
+ declare function useQuery<T = unknown>(queryId: string): {
191
+ data: T | undefined;
192
+ loading: boolean;
193
+ error: Error | null;
194
+ refetch: () => Promise<void>;
195
+ };
196
+ /**
197
+ * 使用动作
198
+ */
199
+ declare function useAction<T = unknown, P = Record<string, unknown>>(actionType: string): {
200
+ execute: (params?: P) => Promise<T | undefined>;
201
+ loading: boolean;
202
+ result: T | undefined;
203
+ error: Error | null;
204
+ };
205
+ /**
206
+ * 使用数据请求
207
+ */
208
+ declare function useData<T = unknown, P = Record<string, unknown>>(queryId: string, params?: P, options?: {
209
+ immediate?: boolean;
210
+ }): {
211
+ data: T | undefined;
212
+ loading: boolean;
213
+ error: Error | null;
214
+ refetch: (newParams?: P) => Promise<void>;
215
+ };
216
+ /**
217
+ * 使用事件监听
218
+ */
219
+ declare function useRuntimeEvent<T = unknown>(eventType: string, handler: (data: T) => void): void;
220
+
221
+ export { DJVProvider, type DJVProviderProps, DJVRenderer, type DJVRendererProps, type ReactRuntimeOptions, type ReactRuntimeReturn, RuntimeContext, type RuntimeContextValue, RuntimeProvider, type RuntimeProviderProps, useAction, useDJVRuntime, useData, useHostApi, useQuery, useReactRuntime, useRuntimeContext, useRuntimeEvent, useRuntimeState, useRuntimeStateWritable };
@@ -0,0 +1,221 @@
1
+ import { RuntimeOptions, DjvlcRuntime, RuntimePhase, PageResolveResult, RuntimeError, HostAPI, RuntimeState } from '@djvlc/runtime-core';
2
+ export { HostAPI, PageResolveResult, RuntimeError, RuntimeOptions, RuntimePhase, RuntimeState } from '@djvlc/runtime-core';
3
+ import * as react from 'react';
4
+ import react__default, { ReactNode } from 'react';
5
+
6
+ /**
7
+ * React 运行时封装
8
+ * 将核心运行时封装为 React 友好的 API
9
+ */
10
+
11
+ /**
12
+ * React 运行时选项
13
+ */
14
+ interface ReactRuntimeOptions extends Omit<RuntimeOptions, 'container'> {
15
+ /** 容器元素引用 */
16
+ containerRef?: React.RefObject<HTMLElement>;
17
+ }
18
+ /**
19
+ * React 运行时返回值
20
+ */
21
+ interface ReactRuntimeReturn {
22
+ /** 运行时实例 */
23
+ runtime: DjvlcRuntime | null;
24
+ /** 加载状态 */
25
+ loading: boolean;
26
+ /** 当前阶段 */
27
+ phase: RuntimePhase;
28
+ /** 页面数据 */
29
+ page: PageResolveResult | null;
30
+ /** 错误信息 */
31
+ error: RuntimeError | null;
32
+ /** Host API */
33
+ hostApi: HostAPI | null;
34
+ /** 初始化 */
35
+ init: () => Promise<void>;
36
+ /** 加载页面 */
37
+ load: () => Promise<PageResolveResult>;
38
+ /** 渲染页面 */
39
+ render: () => Promise<void>;
40
+ /** 销毁 */
41
+ destroy: () => void;
42
+ /** 设置变量 */
43
+ setVariable: (key: string, value: unknown) => void;
44
+ /** 刷新数据 */
45
+ refreshData: (queryId: string) => Promise<void>;
46
+ }
47
+ /**
48
+ * 使用 React 运行时 Hook
49
+ */
50
+ declare function useReactRuntime(options: ReactRuntimeOptions): ReactRuntimeReturn;
51
+
52
+ /**
53
+ * 运行时上下文值
54
+ */
55
+ interface RuntimeContextValue {
56
+ runtime: DjvlcRuntime | null;
57
+ state: RuntimeState;
58
+ hostApi: HostAPI | null;
59
+ }
60
+ /**
61
+ * 运行时上下文
62
+ */
63
+ declare const RuntimeContext: react.Context<RuntimeContextValue>;
64
+ /**
65
+ * Runtime Provider Props
66
+ */
67
+ interface RuntimeProviderProps {
68
+ /** 运行时实例 */
69
+ runtime: DjvlcRuntime | null;
70
+ /** 运行时状态 */
71
+ state: RuntimeState;
72
+ /** Host API */
73
+ hostApi: HostAPI | null;
74
+ /** 子元素 */
75
+ children: ReactNode;
76
+ }
77
+ /**
78
+ * Runtime Provider 组件
79
+ */
80
+ declare function RuntimeProvider({ runtime, state, hostApi, children, }: RuntimeProviderProps): JSX.Element;
81
+ /**
82
+ * 使用运行时上下文
83
+ */
84
+ declare function useRuntimeContext(): RuntimeContextValue;
85
+
86
+ /**
87
+ * DJV 渲染器组件
88
+ * React 组件,用于渲染低代码页面
89
+ */
90
+
91
+ /**
92
+ * DJV 渲染器 Props
93
+ */
94
+ interface DJVRendererProps {
95
+ /** 页面 UID */
96
+ pageUid: string;
97
+ /** API 基础 URL */
98
+ apiBaseUrl: string;
99
+ /** CDN 基础 URL */
100
+ cdnBaseUrl: string;
101
+ /** 渠道 */
102
+ channel?: 'preview' | 'prod' | 'gray';
103
+ /** 用户 ID */
104
+ userId?: string;
105
+ /** 设备 ID */
106
+ deviceId?: string;
107
+ /** 认证 Token */
108
+ authToken?: string;
109
+ /** 预览 Token */
110
+ previewToken?: string;
111
+ /** 调试模式 */
112
+ debug?: boolean;
113
+ /** 是否启用 SRI */
114
+ enableSRI?: boolean;
115
+ /** 加载完成回调 */
116
+ onLoad?: (page: PageResolveResult) => void;
117
+ /** 错误回调 */
118
+ onError?: (error: RuntimeError) => void;
119
+ /** 就绪回调 */
120
+ onReady?: () => void;
121
+ /** 加载中显示 */
122
+ loadingComponent?: ReactNode;
123
+ /** 错误显示 */
124
+ errorComponent?: ReactNode | ((error: RuntimeError) => ReactNode);
125
+ /** 子元素 */
126
+ children?: ReactNode;
127
+ /** 容器类名 */
128
+ className?: string;
129
+ /** 容器样式 */
130
+ style?: react__default.CSSProperties;
131
+ }
132
+ /**
133
+ * DJV 渲染器组件
134
+ */
135
+ declare function DJVRenderer({ pageUid, apiBaseUrl, cdnBaseUrl, channel, userId, deviceId, authToken, previewToken, debug, enableSRI, onLoad, onError, onReady, loadingComponent, errorComponent, children, className, style, }: DJVRendererProps): JSX.Element;
136
+
137
+ /**
138
+ * DJV Provider 组件
139
+ * 提供运行时上下文给子组件
140
+ */
141
+
142
+ /**
143
+ * DJV Provider Props
144
+ */
145
+ interface DJVProviderProps {
146
+ /** 运行时实例 */
147
+ runtime: DjvlcRuntime | null;
148
+ /** Host API */
149
+ hostApi: HostAPI | null;
150
+ /** 子元素 */
151
+ children: ReactNode;
152
+ }
153
+ /**
154
+ * DJV Provider 组件
155
+ * 用于手动控制运行时时使用
156
+ */
157
+ declare function DJVProvider({ runtime, hostApi, children, }: DJVProviderProps): JSX.Element;
158
+
159
+ /**
160
+ * React Hooks
161
+ * 运行时相关的 React Hooks
162
+ */
163
+
164
+ /**
165
+ * 使用 DJV 运行时
166
+ */
167
+ declare function useDJVRuntime(): {
168
+ runtime: RuntimeContextValue['runtime'];
169
+ state: RuntimeContextValue['state'];
170
+ loading: boolean;
171
+ phase: RuntimePhase;
172
+ error: RuntimeError | null;
173
+ page: PageResolveResult | null;
174
+ };
175
+ /**
176
+ * 使用 Host API
177
+ */
178
+ declare function useHostApi(): HostAPI;
179
+ /**
180
+ * 使用运行时状态
181
+ */
182
+ declare function useRuntimeState<T = unknown>(key: string): T | undefined;
183
+ /**
184
+ * 使用可写状态
185
+ */
186
+ declare function useRuntimeStateWritable<T = unknown>(key: string, defaultValue?: T): [T, (value: T) => void];
187
+ /**
188
+ * 使用查询结果
189
+ */
190
+ declare function useQuery<T = unknown>(queryId: string): {
191
+ data: T | undefined;
192
+ loading: boolean;
193
+ error: Error | null;
194
+ refetch: () => Promise<void>;
195
+ };
196
+ /**
197
+ * 使用动作
198
+ */
199
+ declare function useAction<T = unknown, P = Record<string, unknown>>(actionType: string): {
200
+ execute: (params?: P) => Promise<T | undefined>;
201
+ loading: boolean;
202
+ result: T | undefined;
203
+ error: Error | null;
204
+ };
205
+ /**
206
+ * 使用数据请求
207
+ */
208
+ declare function useData<T = unknown, P = Record<string, unknown>>(queryId: string, params?: P, options?: {
209
+ immediate?: boolean;
210
+ }): {
211
+ data: T | undefined;
212
+ loading: boolean;
213
+ error: Error | null;
214
+ refetch: (newParams?: P) => Promise<void>;
215
+ };
216
+ /**
217
+ * 使用事件监听
218
+ */
219
+ declare function useRuntimeEvent<T = unknown>(eventType: string, handler: (data: T) => void): void;
220
+
221
+ export { DJVProvider, type DJVProviderProps, DJVRenderer, type DJVRendererProps, type ReactRuntimeOptions, type ReactRuntimeReturn, RuntimeContext, type RuntimeContextValue, RuntimeProvider, type RuntimeProviderProps, useAction, useDJVRuntime, useData, useHostApi, useQuery, useReactRuntime, useRuntimeContext, useRuntimeEvent, useRuntimeState, useRuntimeStateWritable };
package/dist/index.js ADDED
@@ -0,0 +1,447 @@
1
+ // src/react-runtime.ts
2
+ import { useState, useCallback, useRef } from "react";
3
+ import {
4
+ createRuntime
5
+ } from "@djvlc/runtime-core";
6
+ function useReactRuntime(options) {
7
+ const [runtime, setRuntime] = useState(null);
8
+ const [loading, setLoading] = useState(true);
9
+ const [phase, setPhase] = useState("idle");
10
+ const [page, setPage] = useState(null);
11
+ const [error, setError] = useState(null);
12
+ const [hostApi, setHostApi] = useState(null);
13
+ const runtimeRef = useRef(null);
14
+ const init = useCallback(async () => {
15
+ const container = options.containerRef?.current;
16
+ if (!container) {
17
+ throw new Error("Container element not found");
18
+ }
19
+ const runtimeInstance = createRuntime({
20
+ ...options,
21
+ container,
22
+ onError: (err) => {
23
+ setError(err);
24
+ options.onError?.(err);
25
+ },
26
+ onEvent: (event) => {
27
+ options.onEvent?.(event);
28
+ }
29
+ });
30
+ runtimeRef.current = runtimeInstance;
31
+ setRuntime(runtimeInstance);
32
+ runtimeInstance.onStateChange((state) => {
33
+ setPhase(state.phase);
34
+ setLoading(state.phase !== "ready" && state.phase !== "error");
35
+ if (state.page) {
36
+ setPage(state.page);
37
+ }
38
+ if (state.error) {
39
+ setError(state.error);
40
+ }
41
+ });
42
+ await runtimeInstance.init();
43
+ setHostApi(runtimeInstance.getHostApi());
44
+ }, [options]);
45
+ const load = useCallback(async () => {
46
+ if (!runtimeRef.current) {
47
+ throw new Error("Runtime not initialized");
48
+ }
49
+ const result = await runtimeRef.current.load();
50
+ setPage(result);
51
+ setHostApi(runtimeRef.current.getHostApi());
52
+ return result;
53
+ }, []);
54
+ const render = useCallback(async () => {
55
+ if (!runtimeRef.current) {
56
+ throw new Error("Runtime not initialized");
57
+ }
58
+ await runtimeRef.current.render();
59
+ setLoading(false);
60
+ }, []);
61
+ const destroy = useCallback(() => {
62
+ runtimeRef.current?.destroy();
63
+ runtimeRef.current = null;
64
+ setRuntime(null);
65
+ setHostApi(null);
66
+ setPage(null);
67
+ setError(null);
68
+ setPhase("idle");
69
+ setLoading(true);
70
+ }, []);
71
+ const setVariable = useCallback((key, value) => {
72
+ runtimeRef.current?.setVariable(key, value);
73
+ }, []);
74
+ const refreshData = useCallback(async (queryId) => {
75
+ await runtimeRef.current?.refreshData(queryId);
76
+ }, []);
77
+ return {
78
+ runtime,
79
+ loading,
80
+ phase,
81
+ page,
82
+ error,
83
+ hostApi,
84
+ init,
85
+ load,
86
+ render,
87
+ destroy,
88
+ setVariable,
89
+ refreshData
90
+ };
91
+ }
92
+
93
+ // src/context.tsx
94
+ import { createContext, useContext } from "react";
95
+ import { jsx } from "react/jsx-runtime";
96
+ var defaultState = {
97
+ phase: "idle",
98
+ page: null,
99
+ variables: {},
100
+ queries: {},
101
+ components: /* @__PURE__ */ new Map(),
102
+ error: null,
103
+ destroyed: false
104
+ };
105
+ var RuntimeContext = createContext({
106
+ runtime: null,
107
+ state: defaultState,
108
+ hostApi: null
109
+ });
110
+ function RuntimeProvider({
111
+ runtime,
112
+ state,
113
+ hostApi,
114
+ children
115
+ }) {
116
+ const value = {
117
+ runtime,
118
+ state,
119
+ hostApi
120
+ };
121
+ return /* @__PURE__ */ jsx(RuntimeContext.Provider, { value, children });
122
+ }
123
+ function useRuntimeContext() {
124
+ const context = useContext(RuntimeContext);
125
+ return context;
126
+ }
127
+
128
+ // src/components/DJVRenderer.tsx
129
+ import { useRef as useRef2, useEffect, useState as useState2, useCallback as useCallback2 } from "react";
130
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
131
+ function DJVRenderer({
132
+ pageUid,
133
+ apiBaseUrl,
134
+ cdnBaseUrl,
135
+ channel = "prod",
136
+ userId,
137
+ deviceId,
138
+ authToken,
139
+ previewToken,
140
+ debug = false,
141
+ enableSRI = true,
142
+ onLoad,
143
+ onError,
144
+ onReady,
145
+ loadingComponent,
146
+ errorComponent,
147
+ children,
148
+ className,
149
+ style
150
+ }) {
151
+ const containerRef = useRef2(null);
152
+ const [state, setState] = useState2({
153
+ phase: "idle",
154
+ page: null,
155
+ variables: {},
156
+ queries: {},
157
+ components: /* @__PURE__ */ new Map(),
158
+ error: null,
159
+ destroyed: false
160
+ });
161
+ const options = {
162
+ pageUid,
163
+ apiBaseUrl,
164
+ cdnBaseUrl,
165
+ channel,
166
+ userId,
167
+ deviceId,
168
+ authToken,
169
+ previewToken,
170
+ debug,
171
+ enableSRI,
172
+ containerRef,
173
+ onError: (error2) => {
174
+ onError?.(error2);
175
+ }
176
+ };
177
+ const {
178
+ runtime,
179
+ loading,
180
+ phase: _phase,
181
+ page: _page,
182
+ error,
183
+ hostApi,
184
+ init,
185
+ load,
186
+ render,
187
+ destroy
188
+ } = useReactRuntime(options);
189
+ void _phase;
190
+ void _page;
191
+ const initAndLoad = useCallback2(async () => {
192
+ if (!containerRef.current) return;
193
+ try {
194
+ await init();
195
+ const pageData = await load();
196
+ onLoad?.(pageData);
197
+ await render();
198
+ onReady?.();
199
+ if (runtime) {
200
+ runtime.onStateChange((newState) => {
201
+ setState(newState);
202
+ });
203
+ }
204
+ } catch (err) {
205
+ }
206
+ }, [init, load, render, runtime, onLoad, onReady]);
207
+ useEffect(() => {
208
+ initAndLoad();
209
+ return () => {
210
+ destroy();
211
+ };
212
+ }, [pageUid]);
213
+ const renderLoading = () => {
214
+ if (!loading) return null;
215
+ return loadingComponent || /* @__PURE__ */ jsxs("div", { className: "djvlc-loading", children: [
216
+ /* @__PURE__ */ jsx2("div", { className: "djvlc-loading-spinner" }),
217
+ /* @__PURE__ */ jsx2("span", { children: "\u52A0\u8F7D\u4E2D..." })
218
+ ] });
219
+ };
220
+ const renderError = () => {
221
+ if (!error) return null;
222
+ if (typeof errorComponent === "function") {
223
+ return errorComponent(error);
224
+ }
225
+ return errorComponent || /* @__PURE__ */ jsx2("div", { className: "djvlc-error", children: /* @__PURE__ */ jsxs("span", { children: [
226
+ "\u52A0\u8F7D\u5931\u8D25\uFF1A",
227
+ error.message
228
+ ] }) });
229
+ };
230
+ return /* @__PURE__ */ jsx2(RuntimeProvider, { runtime, state, hostApi, children: /* @__PURE__ */ jsxs(
231
+ "div",
232
+ {
233
+ ref: containerRef,
234
+ className: `djvlc-renderer ${className || ""}`,
235
+ style,
236
+ children: [
237
+ renderLoading(),
238
+ renderError(),
239
+ children
240
+ ]
241
+ }
242
+ ) });
243
+ }
244
+
245
+ // src/components/DJVProvider.tsx
246
+ import { useState as useState3, useEffect as useEffect2 } from "react";
247
+ import { jsx as jsx3 } from "react/jsx-runtime";
248
+ function DJVProvider({
249
+ runtime,
250
+ hostApi,
251
+ children
252
+ }) {
253
+ const [state, setState] = useState3(
254
+ runtime?.getState() || {
255
+ phase: "idle",
256
+ page: null,
257
+ variables: {},
258
+ queries: {},
259
+ components: /* @__PURE__ */ new Map(),
260
+ error: null,
261
+ destroyed: false
262
+ }
263
+ );
264
+ useEffect2(() => {
265
+ if (!runtime) return;
266
+ const unsubscribe = runtime.onStateChange((newState) => {
267
+ setState(newState);
268
+ });
269
+ return () => {
270
+ unsubscribe();
271
+ };
272
+ }, [runtime]);
273
+ return /* @__PURE__ */ jsx3(RuntimeProvider, { runtime, state, hostApi, children: /* @__PURE__ */ jsx3("div", { className: "djvlc-provider", children }) });
274
+ }
275
+
276
+ // src/hooks/useDJVRuntime.ts
277
+ import { useCallback as useCallback3, useState as useState4, useEffect as useEffect3, useMemo } from "react";
278
+ function useDJVRuntime() {
279
+ const context = useRuntimeContext();
280
+ const loading = useMemo(() => {
281
+ const phase = context.state.phase;
282
+ return phase !== "ready" && phase !== "error";
283
+ }, [context.state.phase]);
284
+ return {
285
+ runtime: context.runtime,
286
+ state: context.state,
287
+ loading,
288
+ phase: context.state.phase,
289
+ error: context.state.error,
290
+ page: context.state.page
291
+ };
292
+ }
293
+ function useHostApi() {
294
+ const context = useRuntimeContext();
295
+ if (!context.hostApi) {
296
+ throw new Error("HostAPI not available. Make sure runtime is initialized.");
297
+ }
298
+ return context.hostApi;
299
+ }
300
+ function useRuntimeState(key) {
301
+ const context = useRuntimeContext();
302
+ return context.state.variables[key];
303
+ }
304
+ function useRuntimeStateWritable(key, defaultValue) {
305
+ const context = useRuntimeContext();
306
+ const value = context.state.variables[key] ?? defaultValue;
307
+ const setValue = useCallback3(
308
+ (newValue) => {
309
+ context.runtime?.setVariable(key, newValue);
310
+ },
311
+ [context.runtime, key]
312
+ );
313
+ return [value, setValue];
314
+ }
315
+ function useQuery(queryId) {
316
+ const context = useRuntimeContext();
317
+ const [loading, setLoading] = useState4(false);
318
+ const [error, setError] = useState4(null);
319
+ const data = context.state.queries[queryId];
320
+ const refetch = useCallback3(async () => {
321
+ setLoading(true);
322
+ setError(null);
323
+ try {
324
+ await context.runtime?.refreshData(queryId);
325
+ } catch (e) {
326
+ setError(e);
327
+ } finally {
328
+ setLoading(false);
329
+ }
330
+ }, [context.runtime, queryId]);
331
+ return {
332
+ data,
333
+ loading,
334
+ error,
335
+ refetch
336
+ };
337
+ }
338
+ function useAction(actionType) {
339
+ const context = useRuntimeContext();
340
+ const [loading, setLoading] = useState4(false);
341
+ const [result, setResult] = useState4();
342
+ const [error, setError] = useState4(null);
343
+ const execute = useCallback3(
344
+ async (params) => {
345
+ const hostApi = context.hostApi;
346
+ if (!hostApi) {
347
+ throw new Error("HostAPI not available");
348
+ }
349
+ setLoading(true);
350
+ setError(null);
351
+ try {
352
+ const response = await hostApi.executeAction(
353
+ actionType,
354
+ params
355
+ );
356
+ if (response.success) {
357
+ setResult(response.data);
358
+ return response.data;
359
+ } else {
360
+ throw new Error(response.message || "Action failed");
361
+ }
362
+ } catch (e) {
363
+ setError(e);
364
+ throw e;
365
+ } finally {
366
+ setLoading(false);
367
+ }
368
+ },
369
+ [context.hostApi, actionType]
370
+ );
371
+ return {
372
+ execute,
373
+ loading,
374
+ result,
375
+ error
376
+ };
377
+ }
378
+ function useData(queryId, params, options) {
379
+ const context = useRuntimeContext();
380
+ const [data, setData] = useState4();
381
+ const [loading, setLoading] = useState4(false);
382
+ const [error, setError] = useState4(null);
383
+ const refetch = useCallback3(
384
+ async (newParams) => {
385
+ const hostApi = context.hostApi;
386
+ if (!hostApi) {
387
+ throw new Error("HostAPI not available");
388
+ }
389
+ setLoading(true);
390
+ setError(null);
391
+ try {
392
+ const response = await hostApi.requestData(
393
+ queryId,
394
+ newParams || params
395
+ );
396
+ if (response.success) {
397
+ setData(response.data);
398
+ } else {
399
+ throw new Error(response.message || "Query failed");
400
+ }
401
+ } catch (e) {
402
+ setError(e);
403
+ } finally {
404
+ setLoading(false);
405
+ }
406
+ },
407
+ [context.hostApi, queryId, params]
408
+ );
409
+ useEffect3(() => {
410
+ if (options?.immediate !== false && context.hostApi) {
411
+ refetch();
412
+ }
413
+ }, [context.hostApi]);
414
+ return {
415
+ data,
416
+ loading,
417
+ error,
418
+ refetch
419
+ };
420
+ }
421
+ function useRuntimeEvent(eventType, handler) {
422
+ const context = useRuntimeContext();
423
+ useEffect3(() => {
424
+ const unsubscribe = context.runtime?.on(eventType, (event) => {
425
+ handler(event.data);
426
+ });
427
+ return () => {
428
+ unsubscribe?.();
429
+ };
430
+ }, [context.runtime, eventType, handler]);
431
+ }
432
+ export {
433
+ DJVProvider,
434
+ DJVRenderer,
435
+ RuntimeContext,
436
+ RuntimeProvider,
437
+ useAction,
438
+ useDJVRuntime,
439
+ useData,
440
+ useHostApi,
441
+ useQuery,
442
+ useReactRuntime,
443
+ useRuntimeContext,
444
+ useRuntimeEvent,
445
+ useRuntimeState,
446
+ useRuntimeStateWritable
447
+ };
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@djvlc/runtime-host-react",
3
+ "version": "1.1.0",
4
+ "description": "DJV 低代码平台 React 宿主适配器",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format esm,cjs --dts --clean --external react",
21
+ "dev": "tsup src/index.ts --format esm,cjs --dts --watch --external react",
22
+ "test": "vitest run --passWithNoTests",
23
+ "test:watch": "vitest",
24
+ "lint": "eslint src --ext .ts,.tsx",
25
+ "typecheck": "tsc --noEmit",
26
+ "clean": "rimraf dist"
27
+ },
28
+ "dependencies": {
29
+ "@djvlc/runtime-core": "1.0.0",
30
+ "@djvlc/contracts-types": "^1.4.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^20.10.0",
34
+ "@types/react": "^18.2.0",
35
+ "eslint": "^8.55.0",
36
+ "rimraf": "^5.0.5",
37
+ "tsup": "^8.0.0",
38
+ "typescript": "^5.3.0",
39
+ "vitest": "^1.0.0"
40
+ },
41
+ "peerDependencies": {
42
+ "react": "^18.0.0"
43
+ },
44
+ "keywords": [
45
+ "lowcode",
46
+ "runtime",
47
+ "react",
48
+ "djv"
49
+ ],
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "license": "MIT"
54
+ }