@djvlc/runtime-host-react 1.1.5 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.cjs +1 -1
  2. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";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]),I=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]),A=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 I()},[E,I]),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:I,destroy:A,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({pageId: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:I=3,retryDelay:A=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}),k={pageId: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:q,loading:B,phase:D,page:M,error:U,hostApi:V,init:z,load:L,render:H,destroy:O}=o(k);e.useEffect(()=>{y?.(D)},[D,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,q&&q.onStateChange(e=>{R.current&&S(e)}))})(),e])}catch(e){if(!R.current)return;C.current<I&&(C.current++,setTimeout(()=>{R.current&&J()},A))}},[z,L,H,q,h,w,N,I,A,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:q,state:P,hostApi:V,children:n.jsxs("div",{ref:j,className:`djvlc-renderer ${b||""}`,style:E,"data-phase":D,"data-page-id":r,children:[B?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,"/",I]})]}):null,U?"function"==typeof g?g(U,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:["加载失败:",U.message]}),n.jsx("button",{className:"djvlc-error-retry-btn",onClick:F,type:"button",children:"重试"})]}):null,B||U||M||"ready"!==D||M?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(()=>({pageId:r?.pageId,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}};
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]),I=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]),A=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 I()},[E,I]),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:I,destroy:A,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({pageId: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:I=3,retryDelay:A=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}),k={pageId: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:q,loading:B,phase:D,page:M,error:U,hostApi:V,init:z,load:L,render:H,destroy:O}=o(k);e.useEffect(()=>{y?.(D)},[D,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,q&&q.onStateChange(e=>{R.current&&S(e)}))})(),e])}catch(e){if(!R.current)return;C.current<I&&(C.current++,setTimeout(()=>{R.current&&J()},A))}},[z,L,H,q,h,w,N,I,A,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:q,state:P,hostApi:V,children:n.jsxs("div",{ref:j,className:`djvlc-renderer ${b||""}`,style:E,"data-phase":D,"data-page-id":r,children:[B?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,"/",I]})]}):null,U?"function"==typeof g?g(U,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:["加载失败:",U.message]}),n.jsx("button",{className:"djvlc-error-retry-btn",onClick:F,type:"button",children:"重试"})]}):null,B||U||M||"ready"!==D||M?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(()=>({pageId:r?.pageId,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}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djvlc/runtime-host-react",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "DJV 低代码平台 React 宿主适配器",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -26,7 +26,7 @@
26
26
  "clean": "rimraf dist"
27
27
  },
28
28
  "dependencies": {
29
- "@djvlc/runtime-core": "1.0.3"
29
+ "@djvlc/runtime-core": "1.1.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "^20.10.0",