@djvlc/runtime-host-react 1.1.2 → 1.1.4
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 +1 -485
- package/dist/index.d.cts +188 -11
- package/dist/index.d.ts +188 -11
- package/dist/index.js +1 -447
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -1,485 +1 @@
|
|
|
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
|
-
});
|
|
1
|
+
var e=require("react"),r=require("@djvlc/runtime-core"),n=require("react/jsx-runtime"),t={initTime:0,loadTime:0,renderTime:0,totalTime:0,initTimestamp:null,readyTimestamp:null};function o(n){const[o,a]=e.useState(null),[i,l]=e.useState(!0),[s,c]=e.useState("idle"),[u,d]=e.useState(null),[p,m]=e.useState(null),[h,f]=e.useState(null),[w,y]=e.useState(t),v=e.useRef(null),g=e.useRef({startTime:0,initStartTime:0,loadStartTime:0,renderStartTime:0}),x=e.useMemo(()=>"ready"===s,[s]),T=e.useMemo(()=>"error"===s||null!==p,[s,p]),b=e.useCallback(async()=>{const e=n.containerRef?.current;if(!e)throw new Error("Container element not found");g.current.startTime=performance.now(),g.current.initStartTime=g.current.startTime,n.enableMetrics&&y(e=>({...e,initTimestamp:Date.now()}));const t=r.createRuntime({...n,container:e,onError:e=>{m(e),n.onError?.(e)},onEvent:e=>{n.onEvent?.(e)}});v.current=t,a(t),t.onStateChange(e=>{c(e.phase),l("ready"!==e.phase&&"error"!==e.phase),e.page&&d(e.page),e.error&&m(e.error)}),await t.init(),f(t.getHostApi()),n.enableMetrics&&y(e=>({...e,initTime:performance.now()-g.current.initStartTime}))},[n]),E=e.useCallback(async()=>{if(!v.current)throw new Error("Runtime not initialized");g.current.loadStartTime=performance.now();const e=await v.current.load();return d(e),f(v.current.getHostApi()),n.enableMetrics&&y(e=>({...e,loadTime:performance.now()-g.current.loadStartTime})),e},[n.enableMetrics]),A=e.useCallback(async()=>{if(!v.current)throw new Error("Runtime not initialized");if(g.current.renderStartTime=performance.now(),await v.current.render(),l(!1),n.enableMetrics){const e=performance.now();y(r=>({...r,renderTime:e-g.current.renderStartTime,totalTime:e-g.current.startTime,readyTimestamp:Date.now()}))}},[n.enableMetrics]),I=e.useCallback(()=>{v.current?.destroy(),v.current=null,a(null),f(null),d(null),m(null),c("idle"),l(!0),y(t)},[]),N=e.useCallback(async()=>{if(!v.current)throw new Error("Runtime not initialized");m(null),l(!0),await E(),await A()},[E,A]),j=e.useCallback((e,r)=>{v.current?.setVariable(e,r)},[]),R=e.useCallback(e=>{v.current&&Object.entries(e).forEach(([e,r])=>{v.current?.setVariable(e,r)})},[]),C=e.useCallback(e=>v.current?.getState().variables[e],[]),P=e.useCallback(async e=>{await(v.current?.refreshData(e))},[]),S=e.useCallback(async(e,r)=>{const n=h;if(!n)throw new Error("HostAPI not available");const t=await n.executeAction(e,r||{});if(t.success)return t.data;throw new Error(t.errorMessage||"Action failed")},[h]);return{runtime:o,loading:i,phase:s,page:u,error:p,hostApi:h,isReady:x,hasError:T,metrics:w,init:b,load:E,render:A,destroy:I,reload:N,setVariable:j,setVariables:R,getVariable:C,refreshData:P,executeAction:S}}var a={phase:"idle",page:null,variables:{},queries:{},components:new Map,error:null,destroyed:!1},i=e.createContext({runtime:null,state:a,hostApi:null});function l({runtime:e,state:r,hostApi:t,children:o}){const a={runtime:e,state:r,hostApi:t};return n.jsx(i.Provider,{value:a,children:o})}function s(){return e.useContext(i)}var c={phase:"idle",page:null,variables:{},queries:{},components:new Map,error:null,destroyed:!1};function u(r,n){const t=s(),[o,a]=e.useState(!1),[i,l]=e.useState(),[c,u]=e.useState(null),[d,p]=e.useState(0),m=e.useRef(!0);e.useEffect(()=>(m.current=!0,()=>{m.current=!1}),[]);const h=e.useCallback(()=>{l(void 0),u(null),p(0)},[]),f=e.useCallback(async(e,o)=>{const a=t.hostApi;if(!a)throw new Error("HostAPI not available");try{const n=await a.executeAction(r,e);if(n.success)return n.data;throw new Error(n.errorMessage||"Action failed")}catch(r){if(o>0)return await new Promise(e=>setTimeout(e,n?.retryDelay||1e3)),f(e,o-1);throw r}},[t.hostApi,r,n?.retryDelay]);return{execute:e.useCallback(async e=>{if(m.current){a(!0),u(null),p(e=>e+1);try{const r=await f(e,n?.retryCount||0);return m.current&&(l(r),n?.onSuccess?.(r)),r}catch(e){const r=e;throw m.current&&(u(r),n?.onError?.(r)),e}finally{m.current&&a(!1)}}},[f,n]),loading:o,result:i,error:c,reset:h,executionCount:d}}exports.DJVProvider=function({runtime:r,hostApi:t,children:o,className:a,debug:i=!1,onStateChange:s,onPhaseChange:u,onError:d}){const[p,m]=e.useState(r?.getState()||c),h=e.useRef(p.phase);return e.useEffect(()=>{if(!r)return void m(c);m(r.getState());const e=r.onStateChange(e=>{m(e),s?.(e),e.phase!==h.current&&(u?.(e.phase),h.current=e.phase),e.error&&d?.(e.error)});return()=>{e()}},[r,s,u,d,i]),e.useEffect(()=>{},[t]),n.jsx(l,{runtime:r,state:p,hostApi:t,children:n.jsx("div",{className:["djvlc-provider",a].filter(Boolean).join(" "),"data-phase":p.phase,children:o})})},exports.DJVRenderer=function({pageUid:r,apiBaseUrl:t,cdnBaseUrl:a,channel:i="prod",userId:s,deviceId:c,authToken:u,previewToken:d,debug:p=!1,enableSRI:m=!0,onLoad:h,onError:f,onReady:w,onPhaseChange:y,loadingComponent:v,errorComponent:g,emptyComponent:x,children:T,className:b,style:E,retryCount:A=3,retryDelay:I=1e3,timeout:N=3e4}){const j=e.useRef(null),R=e.useRef(!0),C=e.useRef(0),[P,S]=e.useState({phase:"idle",page:null,variables:{},queries:{},components:new Map,error:null,destroyed:!1}),U={pageUid:r,apiBaseUrl:t,cdnBaseUrl:a,channel:i,userId:s,deviceId:c,authToken:u,previewToken:d,debug:p,enableSRI:m,containerRef:j,onError:e=>{f?.(e)}},{runtime:k,loading:q,phase:B,page:D,error:M,hostApi:V,init:z,load:L,render:H,destroy:O}=o(U);e.useEffect(()=>{y?.(B)},[B,y]);const J=e.useCallback(async()=>{if(!j.current||!R.current)return;const e=new Promise((e,r)=>{setTimeout(()=>r(new Error("加载超时")),N)});try{await Promise.race([(async()=>{await z();const e=await L();R.current&&h?.(e),await H(),R.current&&(w?.(),C.current=0,k&&k.onStateChange(e=>{R.current&&S(e)}))})(),e])}catch(e){if(!R.current)return;C.current<A&&(C.current++,setTimeout(()=>{R.current&&J()},I))}},[z,L,H,k,h,w,N,A,I,p]),F=e.useCallback(()=>{C.current=0,J()},[J]);return e.useEffect(()=>(R.current=!0,J(),()=>{R.current=!1,O()}),[r]),n.jsx(l,{runtime:k,state:P,hostApi:V,children:n.jsxs("div",{ref:j,className:`djvlc-renderer ${b||""}`,style:E,"data-phase":B,"data-page-uid":r,children:[q?v||n.jsxs("div",{className:"djvlc-loading",children:[n.jsx("div",{className:"djvlc-loading-spinner"}),n.jsx("span",{children:"加载中..."}),C.current>0&&n.jsxs("span",{className:"djvlc-loading-retry",children:["重试 ",C.current,"/",A]})]}):null,M?"function"==typeof g?g(M,F):g||n.jsxs("div",{className:"djvlc-error",children:[n.jsx("div",{className:"djvlc-error-icon",children:"⚠️"}),n.jsxs("span",{className:"djvlc-error-message",children:["加载失败:",M.message]}),n.jsx("button",{className:"djvlc-error-retry-btn",onClick:F,type:"button",children:"重试"})]}):null,q||M||D||"ready"!==B||D?null:x||n.jsx("div",{className:"djvlc-empty",children:n.jsx("span",{children:"暂无内容"})}),T]})})},exports.RuntimeContext=i,exports.RuntimeProvider=l,exports.useAction=u,exports.useAsync=function(r,n=[],t){const[o,a]=e.useState(),[i,l]=e.useState(!1),[s,c]=e.useState(null),u=e.useRef(!0);e.useEffect(()=>(u.current=!0,()=>{u.current=!1}),[]);const d=e.useCallback(async()=>{if(u.current){l(!0),c(null);try{const e=await r();return u.current&&(a(e),t?.onSuccess?.(e)),e}catch(e){const r=e;return void(u.current&&(c(r),t?.onError?.(r)))}finally{u.current&&l(!1)}}},[r,...n]);return e.useEffect(()=>{!1!==t?.immediate&&d()},[]),{data:o,loading:i,error:s,execute:d}},exports.useComponentState=function(r){const n=s().state.components.get(r);return e.useMemo(()=>({isLoaded:"loaded"===n?.status,isLoading:"loading"===n?.status,hasError:"failed"===n?.status,loadTime:n?.loadTime,info:n}),[n])},exports.useDJVRuntime=function(){const r=s(),n=e.useMemo(()=>{const e=r.state.phase;return"ready"!==e&&"error"!==e},[r.state.phase]),t="ready"===r.state.phase,o="error"===r.state.phase||null!==r.state.error,a=e.useCallback(async()=>{if(!r.runtime)throw new Error("Runtime not available");await r.runtime.load(),await r.runtime.render()},[r.runtime]);return{runtime:r.runtime,state:r.state,loading:n,phase:r.state.phase,error:r.state.error,page:r.state.page,isReady:t,hasError:o,reload:a}},exports.useData=function(r,n,t){const o=s(),[a,i]=e.useState(),[l,c]=e.useState(!1),[u,d]=e.useState(null),[p,m]=e.useState(!1),h=e.useRef(!0),f=e.useRef(n);e.useEffect(()=>(h.current=!0,()=>{h.current=!1}),[]);const w=e.useCallback(async e=>{const n=o.hostApi;if(n&&h.current){c(!0),d(null);try{const o=await n.requestData(r,e||f.current);if(!h.current)return;i(o),m(!0),t?.onSuccess?.(o)}catch(e){if(h.current){const r=e;d(r),t?.onError?.(r)}}finally{h.current&&c(!1)}}},[o.hostApi,r,t]);return e.useEffect(()=>{const e=f.current;f.current=n,!1!==t?.refreshOnParamsChange&&o.hostApi&&p&&JSON.stringify(e)!==JSON.stringify(n)&&w()},[n,o.hostApi,t?.refreshOnParamsChange,p,w]),e.useEffect(()=>{!1!==t?.immediate&&o.hostApi&&w()},[o.hostApi]),e.useEffect(()=>{if(!t?.refreshInterval||t.refreshInterval<=0)return;const e=setInterval(()=>{w()},t.refreshInterval);return()=>clearInterval(e)},[t?.refreshInterval,w]),{data:a,loading:l,error:u,refetch:w,isFetched:p}},exports.useDebouncedAction=function(r,n=300){const{execute:t,loading:o,result:a,error:i}=u(r),l=e.useRef(null),s=e.useRef(!0);return e.useEffect(()=>(s.current=!0,()=>{s.current=!1,l.current&&clearTimeout(l.current)}),[]),{execute:e.useCallback(e=>{l.current&&clearTimeout(l.current),l.current=setTimeout(()=>{s.current&&t(e).catch(()=>{})},n)},[t,n]),loading:o,result:a,error:i,cancel:e.useCallback(()=>{l.current&&(clearTimeout(l.current),l.current=null)},[])}},exports.useHostApi=function(){const e=s();if(!e.hostApi)throw new Error("HostAPI not available. Make sure runtime is initialized.");return e.hostApi},exports.useLifecycle=function(r){const n=s(),[t,o]=e.useState(!1),[a,i]=e.useState(!1),l=e.useRef(n.state.phase),c=e.useRef(!0);return e.useEffect(()=>(c.current=!0,()=>{c.current=!1}),[]),e.useEffect(()=>{const e=n.state.phase;e!==l.current&&(r?.onPhaseChange?.(e),l.current=e),t||"idle"===e||(o(!0),Promise.resolve(r?.onMounted?.()).catch(e=>{r?.onError?.(e)})),a||"ready"!==e||(i(!0),Promise.resolve(r?.onReady?.()).catch(e=>{r?.onError?.(e)})),"error"===e&&n.state.error&&r?.onError?.(n.state.error)},[n.state.phase,n.state.error,t,a,r]),{phase:n.state.phase,hasMounted:t,hasReady:a}},exports.usePageInfo=function(){const r=s().state.page;return e.useMemo(()=>({pageUid:r?.pageUid,pageVersionId:r?.pageVersionId,schemaVersion:r?.pageJson?.schemaVersion,title:r?.title,config:r?.config,isLoaded:null!==r}),[r])},exports.usePrevious=function(r){const n=e.useRef();return e.useEffect(()=>{n.current=r},[r]),n.current},exports.useQuery=function(r,n){const t=s(),[o,a]=e.useState(!1),[i,l]=e.useState(null),[c,u]=e.useState(null),d=e.useRef(!0),p=t.state.queries[r],m=e.useCallback(async()=>{if(d.current){a(!0),l(null);try{await(t.runtime?.refreshData(r)),d.current&&u(Date.now())}catch(e){d.current&&l(e)}finally{d.current&&a(!1)}}},[t.runtime,r]);return e.useEffect(()=>(d.current=!0,n?.refreshOnMount&&t.runtime&&m(),()=>{d.current=!1}),[]),e.useEffect(()=>{if(!n?.refreshInterval||n.refreshInterval<=0)return;const e=setInterval(()=>{m()},n.refreshInterval);return()=>clearInterval(e)},[n?.refreshInterval,m]),e.useEffect(()=>{if(!n?.refreshOnFocus)return;const e=()=>{m()};return window.addEventListener("focus",e),()=>window.removeEventListener("focus",e)},[n?.refreshOnFocus,m]),{data:p,loading:o,error:i,refetch:m,lastUpdated:c}},exports.useReactRuntime=o,exports.useRuntimeContext=s,exports.useRuntimeEvent=function(r,n){const t=s();e.useEffect(()=>{const e=t.runtime?.on(r,e=>{n(e.data)});return()=>{e?.()}},[t.runtime,r,n])},exports.useRuntimeState=function(e){return s().state.variables[e]},exports.useRuntimeStateWritable=function(r,n){const t=s();return[t.state.variables[r]??n,e.useCallback(e=>{t.runtime?.setVariable(r,e)},[t.runtime,r])]},exports.useWhen=function(r,n,t){const[o,a]=e.useState(!1),{once:i=!0}=t||{};return e.useEffect(()=>{!r||i&&o||(a(!0),n())},[r,n,i,o]),{executed:o}};
|