@djvlc/runtime-host-vue 1.0.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,489 @@
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
+ DJVPlugin: () => DJVPlugin,
24
+ DJVProvider: () => DJVProvider,
25
+ DJVRenderer: () => DJVRenderer,
26
+ RuntimeContextKey: () => RuntimeContextKey,
27
+ createVueRuntime: () => createVueRuntime,
28
+ injectRuntime: () => injectRuntime,
29
+ provideRuntime: () => provideRuntime,
30
+ useAction: () => useAction,
31
+ useDJVRuntime: () => useDJVRuntime,
32
+ useData: () => useData,
33
+ useHostApi: () => useHostApi,
34
+ useQuery: () => useQuery,
35
+ useRuntimeEvent: () => useRuntimeEvent,
36
+ useRuntimeState: () => useRuntimeState,
37
+ useRuntimeStateWritable: () => useRuntimeStateWritable
38
+ });
39
+ module.exports = __toCommonJS(index_exports);
40
+
41
+ // src/vue-runtime.ts
42
+ var import_vue = require("vue");
43
+ var import_runtime_core = require("@djvlc/runtime-core");
44
+ function createVueRuntime(options) {
45
+ const runtime = (0, import_vue.shallowRef)(null);
46
+ const loading = (0, import_vue.ref)(true);
47
+ const phase = (0, import_vue.ref)("idle");
48
+ const page = (0, import_vue.shallowRef)(null);
49
+ const error = (0, import_vue.shallowRef)(null);
50
+ const hostApi = (0, import_vue.shallowRef)(null);
51
+ const init = async () => {
52
+ const container = options.containerRef?.value;
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
+ error.value = err;
61
+ options.onError?.(err);
62
+ },
63
+ onEvent: (event) => {
64
+ options.onEvent?.(event);
65
+ }
66
+ });
67
+ runtime.value = runtimeInstance;
68
+ runtimeInstance.onStateChange((state) => {
69
+ phase.value = state.phase;
70
+ loading.value = state.phase !== "ready" && state.phase !== "error";
71
+ if (state.page) {
72
+ page.value = state.page;
73
+ }
74
+ if (state.error) {
75
+ error.value = state.error;
76
+ }
77
+ });
78
+ await runtimeInstance.init();
79
+ hostApi.value = runtimeInstance.getHostApi();
80
+ };
81
+ const load = async () => {
82
+ if (!runtime.value) {
83
+ throw new Error("Runtime not initialized");
84
+ }
85
+ const result = await runtime.value.load();
86
+ page.value = result;
87
+ hostApi.value = runtime.value.getHostApi();
88
+ return result;
89
+ };
90
+ const render = async () => {
91
+ if (!runtime.value) {
92
+ throw new Error("Runtime not initialized");
93
+ }
94
+ await runtime.value.render();
95
+ loading.value = false;
96
+ };
97
+ const destroy = () => {
98
+ runtime.value?.destroy();
99
+ runtime.value = null;
100
+ hostApi.value = null;
101
+ page.value = null;
102
+ error.value = null;
103
+ phase.value = "idle";
104
+ loading.value = true;
105
+ };
106
+ const setVariable = (key, value) => {
107
+ runtime.value?.setVariable(key, value);
108
+ };
109
+ const refreshData = async (queryId) => {
110
+ await runtime.value?.refreshData(queryId);
111
+ };
112
+ return {
113
+ runtime,
114
+ loading: (0, import_vue.readonly)(loading),
115
+ phase: (0, import_vue.readonly)(phase),
116
+ page,
117
+ error,
118
+ hostApi,
119
+ init,
120
+ load,
121
+ render,
122
+ destroy,
123
+ setVariable,
124
+ refreshData
125
+ };
126
+ }
127
+
128
+ // src/components/DJVRenderer.ts
129
+ var import_vue3 = require("vue");
130
+
131
+ // src/composables/useRuntime.ts
132
+ var import_vue2 = require("vue");
133
+ var RuntimeContextKey = /* @__PURE__ */ Symbol("DJVRuntime");
134
+ function provideRuntime(value) {
135
+ (0, import_vue2.provide)(RuntimeContextKey, value);
136
+ }
137
+ function injectRuntime() {
138
+ const context = (0, import_vue2.inject)(RuntimeContextKey);
139
+ if (!context) {
140
+ throw new Error("useDJVRuntime must be used within a DJVProvider");
141
+ }
142
+ return context;
143
+ }
144
+ function useDJVRuntime() {
145
+ const context = injectRuntime();
146
+ return {
147
+ runtime: (0, import_vue2.computed)(() => context.value.runtime),
148
+ state: (0, import_vue2.computed)(() => context.value.state),
149
+ loading: (0, import_vue2.computed)(() => {
150
+ const phase = context.value.state.phase;
151
+ return phase !== "ready" && phase !== "error";
152
+ }),
153
+ phase: (0, import_vue2.computed)(() => context.value.state.phase),
154
+ error: (0, import_vue2.computed)(() => context.value.state.error),
155
+ page: (0, import_vue2.computed)(() => context.value.state.page)
156
+ };
157
+ }
158
+ function useHostApi() {
159
+ const context = injectRuntime();
160
+ const hostApi = context.value.hostApi;
161
+ if (!hostApi) {
162
+ throw new Error("HostAPI not available. Make sure runtime is initialized.");
163
+ }
164
+ return hostApi;
165
+ }
166
+ function useRuntimeState(key) {
167
+ const context = injectRuntime();
168
+ return (0, import_vue2.computed)(() => {
169
+ return context.value.state.variables[key];
170
+ });
171
+ }
172
+ function useRuntimeStateWritable(key, defaultValue) {
173
+ const context = injectRuntime();
174
+ const value = (0, import_vue2.computed)(() => {
175
+ return context.value.state.variables[key] ?? defaultValue;
176
+ });
177
+ const setValue = (newValue) => {
178
+ context.value.runtime?.setVariable(key, newValue);
179
+ };
180
+ return [value, setValue];
181
+ }
182
+ function useQuery(queryId) {
183
+ const context = injectRuntime();
184
+ const loading = (0, import_vue2.ref)(false);
185
+ const error = (0, import_vue2.ref)(null);
186
+ const data = (0, import_vue2.computed)(() => {
187
+ return context.value.state.queries[queryId];
188
+ });
189
+ const refetch = async () => {
190
+ loading.value = true;
191
+ error.value = null;
192
+ try {
193
+ await context.value.runtime?.refreshData(queryId);
194
+ } catch (e) {
195
+ error.value = e;
196
+ } finally {
197
+ loading.value = false;
198
+ }
199
+ };
200
+ return {
201
+ data,
202
+ loading,
203
+ error,
204
+ refetch
205
+ };
206
+ }
207
+ function useAction(actionType) {
208
+ const context = injectRuntime();
209
+ const loading = (0, import_vue2.ref)(false);
210
+ const result = (0, import_vue2.ref)();
211
+ const error = (0, import_vue2.ref)(null);
212
+ const execute = async (params) => {
213
+ const hostApi = context.value.hostApi;
214
+ if (!hostApi) {
215
+ throw new Error("HostAPI not available");
216
+ }
217
+ loading.value = true;
218
+ error.value = null;
219
+ try {
220
+ const response = await hostApi.executeAction(actionType, params);
221
+ if (response.success) {
222
+ result.value = response.data;
223
+ return response.data;
224
+ } else {
225
+ throw new Error(response.message || "Action failed");
226
+ }
227
+ } catch (e) {
228
+ error.value = e;
229
+ throw e;
230
+ } finally {
231
+ loading.value = false;
232
+ }
233
+ };
234
+ return {
235
+ execute,
236
+ loading,
237
+ result,
238
+ error
239
+ };
240
+ }
241
+ function useData(queryId, params, options) {
242
+ const context = injectRuntime();
243
+ const data = (0, import_vue2.ref)();
244
+ const loading = (0, import_vue2.ref)(false);
245
+ const error = (0, import_vue2.ref)(null);
246
+ const refetch = async (newParams) => {
247
+ const hostApi = context.value.hostApi;
248
+ if (!hostApi) {
249
+ throw new Error("HostAPI not available");
250
+ }
251
+ loading.value = true;
252
+ error.value = null;
253
+ try {
254
+ const response = await hostApi.requestData(
255
+ queryId,
256
+ newParams || params
257
+ );
258
+ if (response.success) {
259
+ data.value = response.data;
260
+ } else {
261
+ throw new Error(response.message || "Query failed");
262
+ }
263
+ } catch (e) {
264
+ error.value = e;
265
+ } finally {
266
+ loading.value = false;
267
+ }
268
+ };
269
+ if (options?.immediate !== false) {
270
+ refetch();
271
+ }
272
+ return {
273
+ data,
274
+ loading,
275
+ error,
276
+ refetch
277
+ };
278
+ }
279
+ function useRuntimeEvent(eventType, handler) {
280
+ const context = injectRuntime();
281
+ const unsubscribe = context.value.runtime?.on(eventType, (event) => {
282
+ handler(event.data);
283
+ });
284
+ (0, import_vue2.onUnmounted)(() => {
285
+ unsubscribe?.();
286
+ });
287
+ }
288
+
289
+ // src/components/DJVRenderer.ts
290
+ var DJVRenderer = (0, import_vue3.defineComponent)({
291
+ name: "DJVRenderer",
292
+ props: {
293
+ pageUid: {
294
+ type: String,
295
+ required: true
296
+ },
297
+ apiBaseUrl: {
298
+ type: String,
299
+ required: true
300
+ },
301
+ cdnBaseUrl: {
302
+ type: String,
303
+ required: true
304
+ },
305
+ channel: {
306
+ type: String,
307
+ default: "prod"
308
+ },
309
+ userId: String,
310
+ deviceId: String,
311
+ authToken: String,
312
+ previewToken: String,
313
+ debug: {
314
+ type: Boolean,
315
+ default: false
316
+ },
317
+ enableSRI: {
318
+ type: Boolean,
319
+ default: true
320
+ }
321
+ },
322
+ emits: ["load", "error", "ready"],
323
+ setup(props, { emit, slots }) {
324
+ const containerRef = (0, import_vue3.ref)(null);
325
+ const contextValue = (0, import_vue3.shallowRef)({
326
+ runtime: null,
327
+ state: {
328
+ phase: "idle",
329
+ page: null,
330
+ variables: {},
331
+ queries: {},
332
+ components: /* @__PURE__ */ new Map(),
333
+ error: null,
334
+ destroyed: false
335
+ },
336
+ hostApi: null
337
+ });
338
+ provideRuntime(contextValue);
339
+ let vueRuntime = null;
340
+ const initAndLoad = async () => {
341
+ if (!containerRef.value) return;
342
+ const options = {
343
+ pageUid: props.pageUid,
344
+ apiBaseUrl: props.apiBaseUrl,
345
+ cdnBaseUrl: props.cdnBaseUrl,
346
+ channel: props.channel,
347
+ userId: props.userId,
348
+ deviceId: props.deviceId,
349
+ authToken: props.authToken,
350
+ previewToken: props.previewToken,
351
+ debug: props.debug,
352
+ enableSRI: props.enableSRI,
353
+ containerRef,
354
+ onError: (error) => {
355
+ emit("error", error);
356
+ }
357
+ };
358
+ vueRuntime = createVueRuntime(options);
359
+ try {
360
+ await vueRuntime.init();
361
+ contextValue.value = {
362
+ runtime: vueRuntime.runtime.value,
363
+ state: vueRuntime.runtime.value?.getState() || contextValue.value.state,
364
+ hostApi: vueRuntime.hostApi.value
365
+ };
366
+ const page = await vueRuntime.load();
367
+ emit("load", page);
368
+ contextValue.value = {
369
+ ...contextValue.value,
370
+ state: vueRuntime.runtime.value?.getState() || contextValue.value.state,
371
+ hostApi: vueRuntime.hostApi.value
372
+ };
373
+ await vueRuntime.render();
374
+ emit("ready");
375
+ vueRuntime.runtime.value?.onStateChange((state) => {
376
+ contextValue.value = {
377
+ ...contextValue.value,
378
+ state
379
+ };
380
+ });
381
+ } catch (error) {
382
+ emit("error", error);
383
+ }
384
+ };
385
+ (0, import_vue3.onMounted)(() => {
386
+ initAndLoad();
387
+ });
388
+ (0, import_vue3.onUnmounted)(() => {
389
+ vueRuntime?.destroy();
390
+ });
391
+ (0, import_vue3.watch)(
392
+ () => props.pageUid,
393
+ () => {
394
+ vueRuntime?.destroy();
395
+ initAndLoad();
396
+ }
397
+ );
398
+ return () => {
399
+ return (0, import_vue3.h)(
400
+ "div",
401
+ {
402
+ ref: containerRef,
403
+ class: "djvlc-renderer"
404
+ },
405
+ [
406
+ // 加载中插槽
407
+ vueRuntime?.loading.value && slots.loading?.(),
408
+ // 错误插槽
409
+ vueRuntime?.error.value && slots.error?.({ error: vueRuntime.error.value }),
410
+ // 默认插槽(额外内容)
411
+ slots.default?.()
412
+ ]
413
+ );
414
+ };
415
+ }
416
+ });
417
+
418
+ // src/components/DJVProvider.ts
419
+ var import_vue4 = require("vue");
420
+ var DJVProvider = (0, import_vue4.defineComponent)({
421
+ name: "DJVProvider",
422
+ props: {
423
+ runtime: {
424
+ type: Object,
425
+ default: null
426
+ },
427
+ hostApi: {
428
+ type: Object,
429
+ default: null
430
+ }
431
+ },
432
+ setup(props, { slots }) {
433
+ const contextValue = (0, import_vue4.shallowRef)({
434
+ runtime: props.runtime,
435
+ state: props.runtime?.getState() || {
436
+ phase: "idle",
437
+ page: null,
438
+ variables: {},
439
+ queries: {},
440
+ components: /* @__PURE__ */ new Map(),
441
+ error: null,
442
+ destroyed: false
443
+ },
444
+ hostApi: props.hostApi
445
+ });
446
+ provideRuntime(contextValue);
447
+ if (props.runtime) {
448
+ props.runtime.onStateChange((state) => {
449
+ contextValue.value = {
450
+ ...contextValue.value,
451
+ state
452
+ };
453
+ });
454
+ }
455
+ return () => (0, import_vue4.h)("div", { class: "djvlc-provider" }, slots.default?.());
456
+ }
457
+ });
458
+
459
+ // src/plugin.ts
460
+ var DJVPlugin = {
461
+ install(app, options = {}) {
462
+ if (options.registerComponents !== false) {
463
+ app.component("DJVRenderer", DJVRenderer);
464
+ app.component("DJVProvider", DJVProvider);
465
+ }
466
+ app.provide("djvlc-config", {
467
+ apiBaseUrl: options.defaultApiBaseUrl,
468
+ cdnBaseUrl: options.defaultCdnBaseUrl
469
+ });
470
+ }
471
+ };
472
+ // Annotate the CommonJS export names for ESM import in node:
473
+ 0 && (module.exports = {
474
+ DJVPlugin,
475
+ DJVProvider,
476
+ DJVRenderer,
477
+ RuntimeContextKey,
478
+ createVueRuntime,
479
+ injectRuntime,
480
+ provideRuntime,
481
+ useAction,
482
+ useDJVRuntime,
483
+ useData,
484
+ useHostApi,
485
+ useQuery,
486
+ useRuntimeEvent,
487
+ useRuntimeState,
488
+ useRuntimeStateWritable
489
+ });