@vyuh/react-extension-content
Version:
Content extension for the Vyuh Framework
9 lines • 20.6 kB
JavaScript
import {ExtensionDescriptor,useVyuhStore,useVyuh,LayoutConfiguration,ExtensionBuilder,ContentModifierConfiguration,ActionConfiguration,ConditionConfiguration,ContentPlugin}from'@vyuh/react-core';import K,{Component,useState,useEffect,useCallback,Suspense}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {RefreshCcw}from'lucide-react';// @vyuh/react-extension-content - Content extension for the Vyuh Framework
var y=class{constructor(r){this.result=null;this.error=null;this.status="pending";this.promise=null;this.handlePromise(r);}handlePromise(r){this.promise=r.then(e=>(this.status="success",this.result=e,e),e=>{throw this.status="error",this.error=e instanceof Error?e:new Error(String(e)),this.error});}read(){if(this.status==="pending")throw this.promise;if(this.status==="error")throw this.error;if(this.result===null)throw new Error("No Content found");return this.result}dispose(){}isLive(){return false}},T=class{constructor(r){this.result=null;this.error=null;this.status="pending";this.promise=null;this.subscription=null;this.listeners=new Set;this.resolveInitialPromise=null;this.rejectInitialPromise=null;this.handleObservable(r);}handleObservable(r){this.promise=new Promise((e,t)=>{this.resolveInitialPromise=e,this.rejectInitialPromise=t;}),this.subscription=r.subscribe({next:e=>{let t=this.status==="pending";this.status="success",this.result=e,t&&this.resolveInitialPromise?(this.resolveInitialPromise(e),this.resolveInitialPromise=null,this.rejectInitialPromise=null):this.notifyListeners();},error:e=>{let t=e instanceof Error?e:new Error(String(e));this.status="error",this.error=t,this.rejectInitialPromise&&(this.rejectInitialPromise(t),this.resolveInitialPromise=null,this.rejectInitialPromise=null),this.notifyListeners();},complete:()=>{if(this.status==="pending"){let e=new Error("Observable completed without emitting a value");this.status="error",this.error=e,this.rejectInitialPromise&&(this.rejectInitialPromise(e),this.resolveInitialPromise=null,this.rejectInitialPromise=null),this.notifyListeners();}}});}read(){if(this.status==="pending")throw this.promise;if(this.status==="error")throw this.error;if(this.result===null)throw new Error("No Content found");return this.result}subscribe(r){return this.listeners.add(r),()=>{this.listeners.delete(r);}}notifyListeners(){this.listeners.forEach(r=>r());}dispose(){this.subscription&&(this.subscription.unsubscribe(),this.subscription=null),this.listeners.clear(),this.resolveInitialPromise=null,this.rejectInitialPromise=null;}isLive(){return true}};function v(o){return o instanceof Promise?new y(o):new T(o)}var U=({error:o,onRetry:r,title:e})=>{let{components:t}=useVyuh();return t.renderError({title:e,error:o,onRetry:r})},f=class extends Component{constructor(e){super(e);this.invokeRetry=()=>{this.setState({hasError:false,error:null}),this.props.onRetry?.();};this.state={hasError:false,error:null};}static getDerivedStateFromError(e){return {hasError:true,error:e}}componentDidCatch(e,t){let{plugins:n}=useVyuhStore.getState();n.telemetry?.log(this.props.title,"error",{error:e});}render(){if(this.state.hasError&&this.state.error){if(this.props.FallbackComponent){let e=this.props.FallbackComponent;return jsx(e,{error:this.state.error,onRetry:this.props.onRetry?this.invokeRetry:void 0})}return jsx(U,{error:this.state.error,onRetry:this.props.onRetry?this.invokeRetry:void 0,title:this.props.title})}return this.props.children}};function J({resource:o,renderContent:r}){let[,e]=useState({});useEffect(()=>{if(o.isLive())return o.subscribe(()=>{e({});})},[o]);let t=o.read();return jsx(Fragment,{children:t&&r(t)})}function M({fetchContent:o,renderContent:r,errorTitle:e="Failed to load content",onRetry:t}){let{components:n}=useVyuh(),[a,l]=useState(0),c=K.useRef(o),[i,s]=useState(null);useEffect(()=>{let d=v(o());return s(d),()=>{d.dispose();}},[]),useEffect(()=>{if(o===c.current||!i)return;c.current=o;let d=v(o());i.dispose(),s(d),l(h=>h+1);},[o,i]);let u=useCallback(()=>{if(!i)return;let d=v(o());i.dispose(),s(d),l(h=>h+1),t?.();},[o,t,i]);return i?jsx(f,{title:e,onRetry:u,children:jsx(Suspense,{fallback:n.renderContentLoader(),children:jsx(J,{resource:i,renderContent:r})})},a):n.renderContentLoader()}function P({fetchContent:o,renderContent:r,allowRefresh:e=true,errorTitle:t}){let{plugins:n}=useVyuh(),[a,l]=useState(0),c=useCallback(()=>{l(u=>u+1);},[]),i=useCallback(()=>o(),[o,a]),s=useCallback(u=>r?r(u):Array.isArray(u)?u.map((d,h)=>jsx("div",{children:n.content.render(d)},h)):null,[n.content,r]);return jsxs(Fragment,{children:[jsx(M,{fetchContent:i,renderContent:s,errorTitle:t||"Failed to render document",onRetry:c}),e&&jsx("button",{onClick:c,className:"vxc:z-1000 vxc:fixed vxc:bottom-2 vxc:right-2 vxc:flex vxc:h-8 vxc:w-8 vxc:cursor-pointer vxc:items-center vxc:justify-center vxc:rounded-full vxc:bg-gray-600 vxc:text-white vxc:transition-colors vxc:ease-in-out vxc:hover:bg-gray-300 vxc:hover:text-gray-700 vxc:hover:shadow-md",title:"Refresh Document",children:jsx(RefreshCcw,{size:16})})]})}function Pe(o,r){return ()=>{let{plugins:e}=useVyuhStore.getState();if(r?.live){let t=e.content.provider.supportsLive,n=e.content.provider.live;if(!t||!n)throw new Error("Live updates not supported");return n.fetchSingle(o,{params:r?.params,includeDrafts:process.env.NODE_ENV==="development"})}else return e.content.provider.fetchSingle(o,{params:r?.params})}}function Be(o,r){return ()=>{let{plugins:e}=useVyuhStore.getState();if(r?.live){let t=e.content.provider.supportsLive,n=e.content.provider.live;if(!t||!n)throw new Error("Live updates not supported");return n.fetchMultiple(o,{params:r?.params,includeDrafts:process.env.NODE_ENV==="development"})}else return e.content.provider.fetchMultiple(o,{params:r?.params})}}function Fe(o,r){return ()=>{let{plugins:e}=useVyuhStore.getState();if(r?.live){let t=e.content.provider.supportsLive,n=e.content.provider.live;if(!t||!n)throw new Error("Live updates not supported");return n.fetchById(o,{includeDrafts:process.env.NODE_ENV==="development"})}else return e.content.provider.fetchById(o)}}function $e({url:o,routeId:r,allowRefresh:e=true,live:t=false}){let{plugins:n}=useVyuh(),a=useCallback(()=>{if(!o&&!r)throw new Error("Either url or routeId must be provided");if(t){let c=n.content.provider.supportsLive,i=n.content.provider.live;if(!c||!i)throw new Error("Live updates not supported");return i.fetchRoute({path:o,routeId:r,includeDrafts:process.env.NODE_ENV==="development"})}else return n.content.provider.fetchRoute({path:o,routeId:r})},[n.content.provider,o,r,t]),l=useCallback(c=>n.content.render(c),[n.content]);return jsx(P,{allowRefresh:e,fetchContent:a,renderContent:l,errorTitle:`Failed to render route: ${o||r}`})}var p=class{get defaultLayout(){return this._defaultLayout}get defaultLayoutDescriptor(){return this._defaultLayoutDescriptor}get sourceFeature(){return this._sourceFeature}setSourceFeature(r){this._sourceFeature=r;}constructor({schemaType:r,defaultLayout:e,defaultLayoutDescriptor:t}){this.schemaType=r,this._defaultLayout=e,this._defaultLayoutDescriptor=t;}init(r){}getLayout(r){return Array.isArray(r.layout)?r.layout[0]:void 0}render(r,e){let{plugins:t}=useVyuh(),n=t.content,a=t.telemetry;if(e)return e.render(r);let l=this.getLayout(r),c=l?n.provider.schemaType(l):void 0,i=c?n.getItem(LayoutConfiguration,c):void 0;return i?new i.fromJson(l).render(r):(a?.log(`No layout found for ${this.schemaType}. Using default.`,"debug"),this.defaultLayout.render(r))}setDefaultLayout(r){this._defaultLayout=r;}};var F=class o{get sourceFeature(){return this._sourceFeature}constructor({schemaType:r,title:e,layouts:t=[]}){this.schemaType=r,this.title=e,this.layouts=t;}setSourceFeature(r){if(this._sourceFeature=r,this.layouts)for(let e of this.layouts)typeof e.setSourceFeature=="function"&&e.setSourceFeature(r);}static createDefault({schemaType:r,title:e}){return t=>new o({schemaType:r,title:e,layouts:t})}};var m=class m extends ExtensionDescriptor{constructor(e){super(m.extensionType);this.type=m.extensionType;this.contents=e?.contents,this.contentBuilders=e?.contentBuilders,this.actions=e?.actions,this.conditions=e?.conditions,this.contentModifiers=e?.contentModifiers;}setSourceFeature(e){if(super.setSourceFeature(e),this.contents)for(let t of this.contents)typeof t.setSourceFeature=="function"&&t.setSourceFeature(e);if(this.contentBuilders)for(let t of this.contentBuilders)typeof t.setSourceFeature=="function"&&t.setSourceFeature(e);if(this.actions)for(let t of this.actions)typeof t.setSourceFeature=="function"&&t.setSourceFeature(e);if(this.conditions)for(let t of this.conditions)typeof t.setSourceFeature=="function"&&t.setSourceFeature(e);if(this.contentModifiers)for(let t of this.contentModifiers)typeof t.setSourceFeature=="function"&&t.setSourceFeature(e);}};m.extensionType="vyuh.extension.content";var w=m;var C=class extends ExtensionBuilder{constructor(){super({type:w.extensionType});this.typeMap=new Map;}build(e){let t=e,a=useVyuhStore.getState().plugins.telemetry;this.findAndAttachToContentPlugin(),this.initTypeMap(p),this.initTypeMap(ContentModifierConfiguration),this.initTypeMap(ActionConfiguration),this.initTypeMap(ConditionConfiguration),this.initTypeMap(LayoutConfiguration),this.collectItems(t,i=>i.contentBuilders||[],p,"ContentBuilder"),this.collectItems(t,i=>(i.contentBuilders||[]).flatMap(s=>[s.defaultLayoutDescriptor]),LayoutConfiguration,"Default Layouts"),this.collectItems(t,i=>i.contentModifiers||[],ContentModifierConfiguration,"ContentModifier"),this.collectItems(t,i=>i.actions||[],ActionConfiguration,"Action"),this.collectItems(t,i=>i.conditions||[],ConditionConfiguration,"Condition"),this.collectItems(t,i=>(i.contents||[]).flatMap(s=>s.layouts||[]),LayoutConfiguration,"Layout");let l=t.flatMap(i=>i.contents||[]).reduce((i,s)=>{let u=i.get(s.schemaType)||[];return u.push(s),i.set(s.schemaType,u),i},new Map);for(let[i,s]of l.entries())this.getBuilder(i)||a?.reportError(new Error(`Missing ContentBuilder for ContentDescriptor of schemaType: ${i}`),{params:{descriptors:s.length}});let c=this.typeMap.get(p)||new Map;for(let[i,s]of c.entries()){let u=l.get(i)||[];s.init(u);}}registerItem(e,t){this.typeMap.has(e)||this.typeMap.set(e,new Map);let{telemetry:n}=useVyuhStore.getState().plugins,a=this.typeMap.get(e);a.has(t.schemaType)&&n?.log(`Duplicate schemaType: ${t.schemaType} is being registered.`,"warning"),a.set(t.schemaType,t);}getBuilder(e){let n=this.typeMap.get(p)?.get(e);if(!n)throw new Error(`
No ContentBuilder found with schemaType: ${e}.
Make sure you have registered a ContentBuilder for this schema type.
`);return n}getItem(e,t){if(!t)return;let n=this.typeMap.get(e);if(!n?.get(t))throw new Error(`
No Item found with schemaType: ${t}.
Make sure you have registered a TypeDescriptor for this schema type.
`.trim());return n.get(t)}findAndAttachToContentPlugin(){let e=useVyuhStore.getState(),t=e.plugins.telemetry;if(!e){t?.reportError(new Error("Vyuh store not found, cannot attach ContentExtensionBuilder to ContentPlugin"));return}let n=e.plugins;if(!n){t?.reportError(new Error("No plugins found in Vyuh store"));return}let a=n.content;if(!a){t?.reportError(new Error("ContentPlugin not found in Vyuh store"));return}a.attach(this);}collectItems(e,t,n,a){let l=useVyuhStore.getState().plugins.telemetry,c=this.typeMap.get(n)||new Map;e.flatMap(t).forEach(i=>{let s=i.schemaType;if(!s){l?.log(`${a} without schema type found and will be ignored`,"warning");return}c.has(s)&&l?.log(`Duplicate ${a} for schema type: ${s}. The later definition will override the earlier one.`,"warning"),c.set(s,i);}),this.typeMap.set(n,c);}initTypeMap(e){this.typeMap.has(e)||this.typeMap.set(e,new Map);}};var j=class extends ContentPlugin{constructor(r){super("vyuh.plugin.content.default","Default Content Plugin",r);}getItem(r,e){return this.extensionBuilder?.getItem(r,e)}registerItem(r,e){this.extensionBuilder?.registerItem(r,e);}render(r,e){let t=r.schemaType??this.provider.schemaType(r);return jsx(f,{title:`Failed to render: ${t}`,children:jsx(le,{schemaType:t,extensionBuilder:this.extensionBuilder,content:r,layout:e?.layout})})}attach(r){let e=useVyuhStore.getState().plugins.telemetry;if(!(r instanceof C)){e?.log(`For the ${this.constructor.name} to work, there must be one ContentExtensionBuilder in your extension builders. However, you have provided a ${r.constructor.name}`,"warning");return}this.extensionBuilder=r;}async dispose(){return this.provider.dispose()}async init(){return this.provider.init()}};function le({schemaType:o,content:r,extensionBuilder:e,layout:t}){return e?.getBuilder(o)?.render(r,t)}function k(o,{insertAt:r}={}){if(typeof document>"u")return;let e=document.head||document.getElementsByTagName("head")[0],t=document.createElement("style");t.type="text/css",r==="top"&&e.firstChild?e.insertBefore(t,e.firstChild):e.appendChild(t),t.styleSheet?t.styleSheet.cssText=o:t.appendChild(document.createTextNode(o));}k(`/*! tailwindcss v4.1.6 | MIT License | https://tailwindcss.com */ properties{ (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-ease:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}} theme{:root,:host{--vxc-font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--vxc-font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--vxc-color-gray-300:oklch(87.2% .01 258.338);--vxc-color-gray-600:oklch(44.6% .03 256.802);--vxc-color-gray-700:oklch(37.3% .034 259.733);--vxc-color-white:#fff;--vxc-spacing:.25rem;--vxc-ease-in-out:cubic-bezier(.4,0,.2,1);--vxc-default-transition-duration:.15s;--vxc-default-transition-timing-function:cubic-bezier(.4,0,.2,1);--vxc-default-font-family:var(--vxc-font-sans);--vxc-default-mono-font-family:var(--vxc-font-mono)}} base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--vxc-default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--vxc-default-font-feature-settings,normal);font-variation-settings:var(--vxc-default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--vxc-default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--vxc-default-mono-font-feature-settings,normal);font-variation-settings:var(--vxc-default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1} (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor} (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}} components; utilities{.vxc\\:fixed{position:fixed}.vxc\\:right-2{right:calc(var(--vxc-spacing)*2)}.vxc\\:bottom-2{bottom:calc(var(--vxc-spacing)*2)}.vxc\\:z-1000{z-index:1000}.vxc\\:flex{display:flex}.vxc\\:h-8{height:calc(var(--vxc-spacing)*8)}.vxc\\:w-8{width:calc(var(--vxc-spacing)*8)}.vxc\\:cursor-pointer{cursor:pointer}.vxc\\:items-center{align-items:center}.vxc\\:justify-center{justify-content:center}.vxc\\:rounded-full{border-radius:3.40282e38px}.vxc\\:bg-gray-600{background-color:var(--vxc-color-gray-600)}.vxc\\:text-white{color:var(--vxc-color-white)}.vxc\\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--vxc-default-transition-timing-function));transition-duration:var(--tw-duration,var(--vxc-default-transition-duration))}.vxc\\:ease-in-out{--tw-ease:var(--vxc-ease-in-out);transition-timing-function:var(--vxc-ease-in-out)} (hover:hover){.vxc\\:hover\\:bg-gray-300:hover{background-color:var(--vxc-color-gray-300)}.vxc\\:hover\\:text-gray-700:hover{color:var(--vxc-color-gray-700)}.vxc\\:hover\\:shadow-md:hover{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}} --tw-ease{syntax:"*";inherits:false} --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000} --tw-shadow-color{syntax:"*";inherits:false} --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%} --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000} --tw-inset-shadow-color{syntax:"*";inherits:false} --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%} --tw-ring-color{syntax:"*";inherits:false} --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000} --tw-inset-ring-color{syntax:"*";inherits:false} --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000} --tw-ring-inset{syntax:"*";inherits:false} --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0} --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff} --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
`);export{M as AsyncContentContainer,y as AsyncResource,p as ContentBuilder,F as ContentDescriptor,C as ContentExtensionBuilder,w as ContentExtensionDescriptor,j as DefaultContentPlugin,P as DocumentLoader,f as ErrorBoundary,$e as RouteLoader,Be as fetchMultipleWithQuery,Pe as fetchSingleWithQuery,Fe as fetchWithId};