@djvlc/runtime-host-vue 1.0.2 → 1.0.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.js CHANGED
@@ -1,458 +1 @@
1
- // src/vue-runtime.ts
2
- import { ref, shallowRef, readonly } from "vue";
3
- import {
4
- createRuntime
5
- } from "@djvlc/runtime-core";
6
- function createVueRuntime(options) {
7
- const runtime = shallowRef(null);
8
- const loading = ref(true);
9
- const phase = ref("idle");
10
- const page = shallowRef(null);
11
- const error = shallowRef(null);
12
- const hostApi = shallowRef(null);
13
- const init = async () => {
14
- const container = options.containerRef?.value;
15
- if (!container) {
16
- throw new Error("Container element not found");
17
- }
18
- const runtimeInstance = createRuntime({
19
- ...options,
20
- container,
21
- onError: (err) => {
22
- error.value = err;
23
- options.onError?.(err);
24
- },
25
- onEvent: (event) => {
26
- options.onEvent?.(event);
27
- }
28
- });
29
- runtime.value = runtimeInstance;
30
- runtimeInstance.onStateChange((state) => {
31
- phase.value = state.phase;
32
- loading.value = state.phase !== "ready" && state.phase !== "error";
33
- if (state.page) {
34
- page.value = state.page;
35
- }
36
- if (state.error) {
37
- error.value = state.error;
38
- }
39
- });
40
- await runtimeInstance.init();
41
- hostApi.value = runtimeInstance.getHostApi();
42
- };
43
- const load = async () => {
44
- if (!runtime.value) {
45
- throw new Error("Runtime not initialized");
46
- }
47
- const result = await runtime.value.load();
48
- page.value = result;
49
- hostApi.value = runtime.value.getHostApi();
50
- return result;
51
- };
52
- const render = async () => {
53
- if (!runtime.value) {
54
- throw new Error("Runtime not initialized");
55
- }
56
- await runtime.value.render();
57
- loading.value = false;
58
- };
59
- const destroy = () => {
60
- runtime.value?.destroy();
61
- runtime.value = null;
62
- hostApi.value = null;
63
- page.value = null;
64
- error.value = null;
65
- phase.value = "idle";
66
- loading.value = true;
67
- };
68
- const setVariable = (key, value) => {
69
- runtime.value?.setVariable(key, value);
70
- };
71
- const refreshData = async (queryId) => {
72
- await runtime.value?.refreshData(queryId);
73
- };
74
- return {
75
- runtime,
76
- loading: readonly(loading),
77
- phase: readonly(phase),
78
- page,
79
- error,
80
- hostApi,
81
- init,
82
- load,
83
- render,
84
- destroy,
85
- setVariable,
86
- refreshData
87
- };
88
- }
89
-
90
- // src/components/DJVRenderer.ts
91
- import {
92
- defineComponent,
93
- ref as ref3,
94
- shallowRef as shallowRef2,
95
- onMounted,
96
- onUnmounted as onUnmounted2,
97
- watch,
98
- h
99
- } from "vue";
100
-
101
- // src/composables/useRuntime.ts
102
- import { inject, provide, ref as ref2, computed, onUnmounted } from "vue";
103
- var RuntimeContextKey = /* @__PURE__ */ Symbol("DJVRuntime");
104
- function provideRuntime(value) {
105
- provide(RuntimeContextKey, value);
106
- }
107
- function injectRuntime() {
108
- const context = inject(RuntimeContextKey);
109
- if (!context) {
110
- throw new Error("useDJVRuntime must be used within a DJVProvider");
111
- }
112
- return context;
113
- }
114
- function useDJVRuntime() {
115
- const context = injectRuntime();
116
- return {
117
- runtime: computed(() => context.value.runtime),
118
- state: computed(() => context.value.state),
119
- loading: computed(() => {
120
- const phase = context.value.state.phase;
121
- return phase !== "ready" && phase !== "error";
122
- }),
123
- phase: computed(() => context.value.state.phase),
124
- error: computed(() => context.value.state.error),
125
- page: computed(() => context.value.state.page)
126
- };
127
- }
128
- function useHostApi() {
129
- const context = injectRuntime();
130
- const hostApi = context.value.hostApi;
131
- if (!hostApi) {
132
- throw new Error("HostAPI not available. Make sure runtime is initialized.");
133
- }
134
- return hostApi;
135
- }
136
- function useRuntimeState(key) {
137
- const context = injectRuntime();
138
- return computed(() => {
139
- return context.value.state.variables[key];
140
- });
141
- }
142
- function useRuntimeStateWritable(key, defaultValue) {
143
- const context = injectRuntime();
144
- const value = computed(() => {
145
- return context.value.state.variables[key] ?? defaultValue;
146
- });
147
- const setValue = (newValue) => {
148
- context.value.runtime?.setVariable(key, newValue);
149
- };
150
- return [value, setValue];
151
- }
152
- function useQuery(queryId) {
153
- const context = injectRuntime();
154
- const loading = ref2(false);
155
- const error = ref2(null);
156
- const data = computed(() => {
157
- return context.value.state.queries[queryId];
158
- });
159
- const refetch = async () => {
160
- loading.value = true;
161
- error.value = null;
162
- try {
163
- await context.value.runtime?.refreshData(queryId);
164
- } catch (e) {
165
- error.value = e;
166
- } finally {
167
- loading.value = false;
168
- }
169
- };
170
- return {
171
- data,
172
- loading,
173
- error,
174
- refetch
175
- };
176
- }
177
- function useAction(actionType) {
178
- const context = injectRuntime();
179
- const loading = ref2(false);
180
- const result = ref2();
181
- const error = ref2(null);
182
- const execute = async (params) => {
183
- const hostApi = context.value.hostApi;
184
- if (!hostApi) {
185
- throw new Error("HostAPI not available");
186
- }
187
- loading.value = true;
188
- error.value = null;
189
- try {
190
- const response = await hostApi.executeAction(actionType, params);
191
- if (response.success) {
192
- result.value = response.data;
193
- return response.data;
194
- } else {
195
- throw new Error(response.message || "Action failed");
196
- }
197
- } catch (e) {
198
- error.value = e;
199
- throw e;
200
- } finally {
201
- loading.value = false;
202
- }
203
- };
204
- return {
205
- execute,
206
- loading,
207
- result,
208
- error
209
- };
210
- }
211
- function useData(queryId, params, options) {
212
- const context = injectRuntime();
213
- const data = ref2();
214
- const loading = ref2(false);
215
- const error = ref2(null);
216
- const refetch = async (newParams) => {
217
- const hostApi = context.value.hostApi;
218
- if (!hostApi) {
219
- throw new Error("HostAPI not available");
220
- }
221
- loading.value = true;
222
- error.value = null;
223
- try {
224
- const response = await hostApi.requestData(
225
- queryId,
226
- newParams || params
227
- );
228
- if (response.success) {
229
- data.value = response.data;
230
- } else {
231
- throw new Error(response.message || "Query failed");
232
- }
233
- } catch (e) {
234
- error.value = e;
235
- } finally {
236
- loading.value = false;
237
- }
238
- };
239
- if (options?.immediate !== false) {
240
- refetch();
241
- }
242
- return {
243
- data,
244
- loading,
245
- error,
246
- refetch
247
- };
248
- }
249
- function useRuntimeEvent(eventType, handler) {
250
- const context = injectRuntime();
251
- const unsubscribe = context.value.runtime?.on(eventType, (event) => {
252
- handler(event.data);
253
- });
254
- onUnmounted(() => {
255
- unsubscribe?.();
256
- });
257
- }
258
-
259
- // src/components/DJVRenderer.ts
260
- var DJVRenderer = defineComponent({
261
- name: "DJVRenderer",
262
- props: {
263
- pageUid: {
264
- type: String,
265
- required: true
266
- },
267
- apiBaseUrl: {
268
- type: String,
269
- required: true
270
- },
271
- cdnBaseUrl: {
272
- type: String,
273
- required: true
274
- },
275
- channel: {
276
- type: String,
277
- default: "prod"
278
- },
279
- userId: String,
280
- deviceId: String,
281
- authToken: String,
282
- previewToken: String,
283
- debug: {
284
- type: Boolean,
285
- default: false
286
- },
287
- enableSRI: {
288
- type: Boolean,
289
- default: true
290
- }
291
- },
292
- emits: ["load", "error", "ready"],
293
- setup(props, { emit, slots }) {
294
- const containerRef = ref3(null);
295
- const contextValue = shallowRef2({
296
- runtime: null,
297
- state: {
298
- phase: "idle",
299
- page: null,
300
- variables: {},
301
- queries: {},
302
- components: /* @__PURE__ */ new Map(),
303
- error: null,
304
- destroyed: false
305
- },
306
- hostApi: null
307
- });
308
- provideRuntime(contextValue);
309
- let vueRuntime = null;
310
- const initAndLoad = async () => {
311
- if (!containerRef.value) return;
312
- const options = {
313
- pageUid: props.pageUid,
314
- apiBaseUrl: props.apiBaseUrl,
315
- cdnBaseUrl: props.cdnBaseUrl,
316
- channel: props.channel,
317
- userId: props.userId,
318
- deviceId: props.deviceId,
319
- authToken: props.authToken,
320
- previewToken: props.previewToken,
321
- debug: props.debug,
322
- enableSRI: props.enableSRI,
323
- containerRef,
324
- onError: (error) => {
325
- emit("error", error);
326
- }
327
- };
328
- vueRuntime = createVueRuntime(options);
329
- try {
330
- await vueRuntime.init();
331
- contextValue.value = {
332
- runtime: vueRuntime.runtime.value,
333
- state: vueRuntime.runtime.value?.getState() || contextValue.value.state,
334
- hostApi: vueRuntime.hostApi.value
335
- };
336
- const page = await vueRuntime.load();
337
- emit("load", page);
338
- contextValue.value = {
339
- ...contextValue.value,
340
- state: vueRuntime.runtime.value?.getState() || contextValue.value.state,
341
- hostApi: vueRuntime.hostApi.value
342
- };
343
- await vueRuntime.render();
344
- emit("ready");
345
- vueRuntime.runtime.value?.onStateChange((state) => {
346
- contextValue.value = {
347
- ...contextValue.value,
348
- state
349
- };
350
- });
351
- } catch (error) {
352
- emit("error", error);
353
- }
354
- };
355
- onMounted(() => {
356
- initAndLoad();
357
- });
358
- onUnmounted2(() => {
359
- vueRuntime?.destroy();
360
- });
361
- watch(
362
- () => props.pageUid,
363
- () => {
364
- vueRuntime?.destroy();
365
- initAndLoad();
366
- }
367
- );
368
- return () => {
369
- return h(
370
- "div",
371
- {
372
- ref: containerRef,
373
- class: "djvlc-renderer"
374
- },
375
- [
376
- // 加载中插槽
377
- vueRuntime?.loading.value && slots.loading?.(),
378
- // 错误插槽
379
- vueRuntime?.error.value && slots.error?.({ error: vueRuntime.error.value }),
380
- // 默认插槽(额外内容)
381
- slots.default?.()
382
- ]
383
- );
384
- };
385
- }
386
- });
387
-
388
- // src/components/DJVProvider.ts
389
- import { defineComponent as defineComponent2, shallowRef as shallowRef3, h as h2 } from "vue";
390
- var DJVProvider = defineComponent2({
391
- name: "DJVProvider",
392
- props: {
393
- runtime: {
394
- type: Object,
395
- default: null
396
- },
397
- hostApi: {
398
- type: Object,
399
- default: null
400
- }
401
- },
402
- setup(props, { slots }) {
403
- const contextValue = shallowRef3({
404
- runtime: props.runtime,
405
- state: props.runtime?.getState() || {
406
- phase: "idle",
407
- page: null,
408
- variables: {},
409
- queries: {},
410
- components: /* @__PURE__ */ new Map(),
411
- error: null,
412
- destroyed: false
413
- },
414
- hostApi: props.hostApi
415
- });
416
- provideRuntime(contextValue);
417
- if (props.runtime) {
418
- props.runtime.onStateChange((state) => {
419
- contextValue.value = {
420
- ...contextValue.value,
421
- state
422
- };
423
- });
424
- }
425
- return () => h2("div", { class: "djvlc-provider" }, slots.default?.());
426
- }
427
- });
428
-
429
- // src/plugin.ts
430
- var DJVPlugin = {
431
- install(app, options = {}) {
432
- if (options.registerComponents !== false) {
433
- app.component("DJVRenderer", DJVRenderer);
434
- app.component("DJVProvider", DJVProvider);
435
- }
436
- app.provide("djvlc-config", {
437
- apiBaseUrl: options.defaultApiBaseUrl,
438
- cdnBaseUrl: options.defaultCdnBaseUrl
439
- });
440
- }
441
- };
442
- export {
443
- DJVPlugin,
444
- DJVProvider,
445
- DJVRenderer,
446
- RuntimeContextKey,
447
- createVueRuntime,
448
- injectRuntime,
449
- provideRuntime,
450
- useAction,
451
- useDJVRuntime,
452
- useData,
453
- useHostApi,
454
- useQuery,
455
- useRuntimeEvent,
456
- useRuntimeState,
457
- useRuntimeStateWritable
458
- };
1
+ import{defineComponent as e,ref as t,shallowRef as n,onMounted as r,onUnmounted as a,watch as o,h as i,provide as l,computed as s,readonly as c,inject as u}from"vue";import{createRuntime as d}from"@djvlc/runtime-core";function p(e){const r=n(null),a=t(!0),o=t("idle"),i=n(null),l=n(null),u=n(null),p=s(()=>"ready"===o.value),m=s(()=>"error"===o.value||null!==l.value),f=n({initTime:0,loadTime:0,renderTime:0,totalTime:0,initTimestamp:null,readyTimestamp:null});let y=0,h=0,v=0,w=0;const g=async()=>{if(!r.value)throw new Error("Runtime not initialized");v=performance.now();const t=await r.value.load();return i.value=t,u.value=r.value.getHostApi(),e.enableMetrics&&(f.value={...f.value,loadTime:performance.now()-v}),t},b=async()=>{if(!r.value)throw new Error("Runtime not initialized");if(w=performance.now(),await r.value.render(),a.value=!1,e.enableMetrics){const e=performance.now();f.value={...f.value,renderTime:e-w,totalTime:e-y,readyTimestamp:Date.now()}}};return{runtime:r,loading:c(a),phase:c(o),page:i,error:l,hostApi:u,isReady:p,hasError:m,metrics:f,init:async()=>{const t=e.containerRef?.value;if(!t)throw new Error("Container element not found");y=performance.now(),h=y,e.enableMetrics&&(f.value={...f.value,initTimestamp:Date.now()});const n=d({...e,container:t,onError:t=>{l.value=t,e.onError?.(t)},onEvent:t=>{e.onEvent?.(t)}});r.value=n,n.onStateChange(e=>{o.value=e.phase,a.value="ready"!==e.phase&&"error"!==e.phase,e.page&&(i.value=e.page),e.error&&(l.value=e.error)}),await n.init(),u.value=n.getHostApi(),e.enableMetrics&&(f.value={...f.value,initTime:performance.now()-h})},load:g,render:b,destroy:()=>{r.value?.destroy(),r.value=null,u.value=null,i.value=null,l.value=null,o.value="idle",a.value=!0},reload:async()=>{if(!r.value)throw new Error("Runtime not initialized");l.value=null,a.value=!0,await g(),await b()},setVariable:(e,t)=>{r.value?.setVariable(e,t)},setVariables:e=>{r.value&&Object.entries(e).forEach(([e,t])=>{r.value?.setVariable(e,t)})},getVariable:e=>r.value?.getState().variables[e],refreshData:async e=>{await(r.value?.refreshData(e))},executeAction:async(e,t)=>{const n=u.value;if(!n)throw new Error("HostAPI not available");const r=await n.executeAction(e,t||{});if(r.success)return r.data;throw new Error(r.errorMessage||"Action failed")}}}var m=Symbol("DJVRuntime");function f(e){l(m,e)}function y(){const e=u(m);if(!e)throw new Error("useDJVRuntime must be used within a DJVProvider");return e}function h(){const e=y(),t=s(()=>{const t=e.value.state.phase;return"ready"!==t&&"error"!==t}),n=s(()=>"ready"===e.value.state.phase),r=s(()=>"error"===e.value.state.phase||null!==e.value.state.error);return{runtime:s(()=>e.value.runtime),state:s(()=>e.value.state),loading:t,phase:s(()=>e.value.state.phase),error:s(()=>e.value.state.error),page:s(()=>e.value.state.page),isReady:n,hasError:r,reload:async()=>{const t=e.value.runtime;if(!t)throw new Error("Runtime not available");await t.load(),await t.render()}}}function v(){const e=y().value.hostApi;if(!e)throw new Error("HostAPI not available. Make sure runtime is initialized.");return e}function w(e){const t=y();return s(()=>t.value.state.variables[e])}function g(e,t){const n=y();return[s(()=>n.value.state.variables[e]??t),t=>{n.value.runtime?.setVariable(e,t)}]}function b(e,n){const o=y(),i=t(!1),l=t(null),c=t(null);let u=null;const d=s(()=>o.value.state.queries[e]),p=async()=>{i.value=!0,l.value=null;try{await(o.value.runtime?.refreshData(e)),c.value=Date.now()}catch(e){l.value=e}finally{i.value=!1}};return r(()=>{n?.refreshOnMount&&o.value.runtime&&p(),n?.refreshInterval&&n.refreshInterval>0&&(u=setInterval(p,n.refreshInterval)),n?.refreshOnFocus&&window.addEventListener("focus",p)}),a(()=>{u&&clearInterval(u),n?.refreshOnFocus&&window.removeEventListener("focus",p)}),{data:d,loading:i,error:l,refetch:p,lastUpdated:c}}function j(e,r){const a=y(),o=t(!1),i=n(),l=t(null),s=t(0),c=async(t,n)=>{const o=a.value.hostApi;if(!o)throw new Error("HostAPI not available");try{const n=await o.executeAction(e,t);if(n.success)return n.data;throw new Error(n.errorMessage||"Action failed")}catch(e){if(n>0)return await new Promise(e=>setTimeout(e,r?.retryDelay||1e3)),c(t,n-1);throw e}};return{execute:async e=>{o.value=!0,l.value=null,s.value++;try{const t=await c(e,r?.retryCount||0);return i.value=t,r?.onSuccess?.(t),t}catch(e){const t=e;throw l.value=t,r?.onError?.(t),e}finally{o.value=!1}},loading:o,result:i,error:l,reset:()=>{i.value=void 0,l.value=null,s.value=0},executionCount:s}}function T(e,i,l){const s=y(),c=n(),u=t(!1),d=t(null),p=t(!1);let m=null;const f=async t=>{const n=s.value.hostApi;if(!n)throw new Error("HostAPI not available");u.value=!0,d.value=null;try{const r=await n.requestData(e,t||(()=>{if(i)return"object"==typeof i&&"value"in i?i.value:i})());c.value=r,p.value=!0,l?.onSuccess?.(r)}catch(e){const t=e;d.value=t,l?.onError?.(t)}finally{u.value=!1}};return i&&"object"==typeof i&&"value"in i&&!1!==l?.refreshOnParamsChange&&o(i,()=>{p.value&&f()},{deep:!0}),r(()=>{!1!==l?.immediate&&s.value.hostApi&&f(),l?.refreshInterval&&l.refreshInterval>0&&(m=setInterval(f,l.refreshInterval))}),a(()=>{m&&clearInterval(m)}),{data:c,loading:u,error:d,refetch:f,isFetched:p}}function E(e,t){const n=y(),r=n.value.runtime?.on(e,e=>{t(e.data)});a(()=>{r?.()})}function I(){const e=y();return{pageUid:s(()=>e.value.state.page?.pageUid),pageVersionId:s(()=>e.value.state.page?.pageVersionId),schemaVersion:s(()=>e.value.state.page?.pageJson?.schemaVersion),title:s(()=>{const t=e.value.state.page;return t?.title}),config:s(()=>{const t=e.value.state.page;return t?.config}),isLoaded:s(()=>null!==e.value.state.page)}}function k(e){const t=y(),n=s(()=>t.value.state.components.get(e));return{isLoaded:s(()=>"loaded"===n.value?.status),isLoading:s(()=>"loading"===n.value?.status),hasError:s(()=>"failed"===n.value?.status),loadTime:s(()=>n.value?.loadTime),info:n}}function A(e){const n=y(),r=t(!1),a=t(!1);return o(()=>n.value.state.phase,async(t,o)=>{if(e?.onPhaseChange?.(t),!r.value&&"idle"!==t){r.value=!0;try{await(e?.onMounted?.())}catch(t){e?.onError?.(t)}}if(!a.value&&"ready"===t){a.value=!0;try{await(e?.onReady?.())}catch(t){e?.onError?.(t)}}"error"===t&&"error"!==o&&e?.onError?.(n.value.state.error)},{immediate:!0}),{phase:s(()=>n.value.state.phase),hasMounted:c(r),hasReady:c(a)}}function R(e,n,r){const i=t(!1),{once:l=!0,immediate:s=!0}=r||{},u=o(e,async e=>{!e||l&&i.value||(i.value=!0,await n(),l&&u())},{immediate:s});return a(()=>{u()}),{executed:c(i),stop:u}}function D(e,t=300){const{execute:n,loading:r,result:o,error:i}=j(e);let l=null;const s=()=>{l&&(clearTimeout(l),l=null)};return a(()=>{s()}),{execute:e=>{l&&clearTimeout(l),l=setTimeout(()=>{n(e).catch(()=>{})},t)},loading:r,result:o,error:i,cancel:s}}function S(){return u("djvlc-config",{})}var V=e({name:"DJVRenderer",props:{pageUid:{type:String,required:!0},apiBaseUrl:{type:String,required:!0},cdnBaseUrl:{type:String,required:!0},channel:{type:String,default:"prod"},userId:String,deviceId:String,authToken:String,previewToken:String,debug:{type:Boolean,default:!1},enableSRI:{type:Boolean,default:!0},retryCount:{type:Number,default:3},retryDelay:{type:Number,default:1e3},timeout:{type:Number,default:3e4}},emits:["load","error","ready","phase-change"],setup(e,{emit:l,slots:s}){const c=t(null),u=t(!0),d=t(0),m=t("idle"),y=n({runtime:null,state:{phase:"idle",page:null,variables:{},queries:{},components:new Map,error:null,destroyed:!1},hostApi:null});f(y);let h=null;const v=async()=>{if(!c.value||!u.value)return;const t={pageUid:e.pageUid,apiBaseUrl:e.apiBaseUrl,cdnBaseUrl:e.cdnBaseUrl,channel:e.channel,userId:e.userId,deviceId:e.deviceId,authToken:e.authToken,previewToken:e.previewToken,debug:e.debug,enableSRI:e.enableSRI,containerRef:c,onError:e=>{l("error",e)}};h=p(t);try{await(n=(async()=>{if(await h.init(),!u.value)return;m.value="loading",l("phase-change","loading"),y.value={runtime:h.runtime.value,state:h.runtime.value?.getState()||y.value.state,hostApi:h.hostApi.value};const e=await h.load();u.value&&(l("load",e),y.value={...y.value,state:h.runtime.value?.getState()||y.value.state,hostApi:h.hostApi.value},await h.render(),u.value&&(m.value="ready",l("phase-change","ready"),l("ready"),d.value=0,h.runtime.value?.onStateChange(e=>{u.value&&(y.value={...y.value,state:e},m.value=e.phase,l("phase-change",e.phase))})))})(),r=e.timeout,Promise.race([n,new Promise((e,t)=>setTimeout(()=>t(new Error("加载超时")),r))]))}catch(t){if(!u.value)return;d.value<e.retryCount?(d.value++,e.debug,setTimeout(()=>{u.value&&v()},e.retryDelay)):(m.value="error",l("phase-change","error"),l("error",t))}var n,r},w=()=>{d.value=0,v()};return r(()=>{u.value=!0,v()}),a(()=>{u.value=!1,h?.destroy()}),o(()=>e.pageUid,()=>{h?.destroy(),d.value=0,v()}),()=>{const t=h?.loading.value??!1,n=h?.error.value,r=h?.page.value;return i("div",{ref:c,class:"djvlc-renderer","data-phase":m.value,"data-page-uid":e.pageUid},[t&&(s.loading?.()||i("div",{class:"djvlc-loading"},[i("div",{class:"djvlc-loading-spinner"}),i("span",{},"加载中..."),d.value>0&&i("span",{class:"djvlc-loading-retry"},`重试 ${d.value}/${e.retryCount}`)])),n&&(s.error?.({error:n,retry:w})||(a=n,i("div",{class:"djvlc-error"},[i("div",{class:"djvlc-error-icon"},"⚠️"),i("span",{class:"djvlc-error-message"},`加载失败:${a.message}`),i("button",{class:"djvlc-error-retry-btn",onClick:w,type:"button"},"重试")]))),!t&&!n&&!r&&"ready"===m.value&&(s.empty?.()||i("div",{class:"djvlc-empty"},[i("span",{},"暂无内容")])),s.default?.()]);var a}}}),x={phase:"idle",page:null,variables:{},queries:{},components:new Map,error:null,destroyed:!1},B=e({name:"DJVProvider",props:{runtime:{type:Object,default:null},hostApi:{type:Object,default:null},class:{type:String,default:""},debug:{type:Boolean,default:!1}},emits:["state-change","phase-change","error"],setup(e,{slots:t,emit:r}){let l=null;const s=n({runtime:e.runtime,state:e.runtime?.getState()||x,hostApi:e.hostApi});f(s);const c=t=>{l&&(l(),l=null),t&&(l=t.onStateChange(t=>{const n=s.value.state.phase;s.value={...s.value,state:t},r("state-change",t),t.phase!==n&&(r("phase-change",t.phase),e.debug),t.error&&r("error",t.error)}))};return c(e.runtime),o(()=>e.runtime,(t,n)=>{t!==n&&(s.value={runtime:t,state:t?.getState()||x,hostApi:e.hostApi},c(t))}),o(()=>e.hostApi,e=>{s.value={...s.value,hostApi:e}}),a(()=>{l&&(l(),l=null)}),()=>i("div",{class:["djvlc-provider",e.class].filter(Boolean).join(" "),"data-phase":s.value.state.phase},t.default?.())}}),P="djvlc-config";function U(e,t){window.dispatchEvent(new CustomEvent("djvlc:track",{detail:{event:e,data:t,timestamp:Date.now()}}))}function J(e,t){e.style.display=t?"":"none"}function C(e,t,n){let r=n.get(e);t?(r||(r=document.createElement("div"),r.className="djvlc-loading-overlay",r.innerHTML='\n <div class="djvlc-loading-spinner"></div>\n ',r.style.cssText="\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: rgba(255, 255, 255, 0.8);\n z-index: 100;\n ",e.appendChild(r),n.set(e,r)),r.style.display="flex"):r&&(r.style.display="none")}var M={install(e,t={}){const n=t.componentPrefix||"";!1!==t.registerComponents&&(e.component(`${n}DJVRenderer`,V),e.component(`${n}DJVProvider`,B)),!1!==t.registerDirectives&&(e.directive("djv-track",function(){const e=new WeakSet;return{mounted(t,n){const{event:r,data:a={},trigger:o="click"}=n.value;if("click"===o)t.addEventListener("click",()=>{U(r,{...a,element:t.tagName})});else if("view"===o){if(!e.has(t)){e.add(t);const n=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting&&(U(r,{...a,element:t.tagName}),n.unobserve(t))})},{threshold:.5});n.observe(t)}}else"mounted"===o&&U(r,{...a,element:t.tagName})}}}()),e.directive("djv-visible",{mounted(e,t){J(e,t.value)},updated(e,t){J(e,t.value)}}),e.directive("djv-loading",function(){const e=new WeakMap;return{mounted(t,n){t.style.position="relative",C(t,n.value,e)},updated(t,n){C(t,n.value,e)},unmounted(t){const n=e.get(t);n&&(n.remove(),e.delete(t))}}}()));const r={apiBaseUrl:t.apiBaseUrl,cdnBaseUrl:t.cdnBaseUrl,channel:t.channel,debug:t.debug,enableSRI:t.enableSRI,enableMetrics:t.enableMetrics,retryCount:t.retryCount,retryDelay:t.retryDelay,timeout:t.timeout};e.provide(P,r),e.config.globalProperties.$djvlc={config:r,track:U}}};export{P as DJVLC_CONFIG_KEY,M as DJVPlugin,B as DJVProvider,V as DJVRenderer,m as RuntimeContextKey,p as createVueRuntime,y as injectRuntime,f as provideRuntime,j as useAction,k as useComponentState,h as useDJVRuntime,T as useData,D as useDebouncedAction,S as useGlobalConfig,v as useHostApi,A as useLifecycle,I as usePageInfo,b as useQuery,E as useRuntimeEvent,w as useRuntimeState,g as useRuntimeStateWritable,R as useWhen};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djvlc/runtime-host-vue",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "DJV 低代码平台 Vue3 宿主适配器",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -17,8 +17,8 @@
17
17
  "dist"
18
18
  ],
19
19
  "scripts": {
20
- "build": "tsup src/index.ts --format esm,cjs --dts --clean --external vue",
21
- "dev": "tsup src/index.ts --format esm,cjs --dts --watch --external vue",
20
+ "build": "tsup",
21
+ "dev": "tsup --watch",
22
22
  "test": "vitest run --passWithNoTests",
23
23
  "test:watch": "vitest",
24
24
  "lint": "eslint src --ext .ts,.vue",
@@ -26,13 +26,13 @@
26
26
  "clean": "rimraf dist"
27
27
  },
28
28
  "dependencies": {
29
- "@djvlc/runtime-core": "1.0.0",
30
- "@djvlc/contracts-types": "^1.4.0"
29
+ "@djvlc/runtime-core": "1.0.2"
31
30
  },
32
31
  "devDependencies": {
33
32
  "@types/node": "^20.10.0",
34
33
  "eslint": "^8.55.0",
35
34
  "rimraf": "^5.0.5",
35
+ "terser": "^5.44.1",
36
36
  "tsup": "^8.0.0",
37
37
  "typescript": "^5.3.0",
38
38
  "vitest": "^1.0.0",