@django-bridge/react 0.6.0-rc.1 → 0.6.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.d.ts CHANGED
@@ -74,6 +74,7 @@ type DjangoBridgeResponse = ReloadResponse | RedirectResponse | RenderResponse |
74
74
  type ShouldReloadCallback = (newPath: string, newProps: Record<string, unknown>) => boolean;
75
75
  interface Frame<Props = Record<string, unknown>> {
76
76
  id: number;
77
+ originalId: number;
77
78
  path: string;
78
79
  metadata: Metadata;
79
80
  view: string;
@@ -100,6 +101,7 @@ interface OverlayContextType {
100
101
  declare const OverlayContext: React.Context<OverlayContextType>;
101
102
  interface Navigation {
102
103
  frameId: number;
104
+ originalFrameId: number;
103
105
  path: string;
104
106
  props: Record<string, unknown>;
105
107
  context: Record<string, unknown>;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var Fe=Object.create;var Y=Object.defineProperty;var be=Object.getOwnPropertyDescriptor;var Me=Object.getOwnPropertyNames;var Ee=Object.getPrototypeOf,Ne=Object.prototype.hasOwnProperty;var Se=(n,e)=>{for(var t in e)Y(n,t,{get:e[t],enumerable:!0})},ye=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Me(e))!Ne.call(n,o)&&o!==t&&Y(n,o,{get:()=>e[o],enumerable:!(r=be(e,o))||r.enumerable});return n};var N=(n,e,t)=>(t=n!=null?Fe(Ee(n)):{},ye(e||!n||!n.__esModule?Y(t,"default",{value:n,enumerable:!0}):t,n)),Oe=n=>ye(Y({},"__esModule",{value:!0}),n);var _e={};Se(_e,{App:()=>Te,BuildLinkElement:()=>ue,Config:()=>X,DirtyFormContext:()=>b,DirtyFormMarker:()=>z,Form:()=>fe,FormSubmissionStatus:()=>ee,FormWidgetChangeNotificationContext:()=>Z,Link:()=>Ce,MessagesContext:()=>T,NavigationContext:()=>P,OverlayContext:()=>Q,RenderFrame:()=>te,buildLinkElement:()=>de,useAutoRefresh:()=>xe,useShouldReloadCallback:()=>we});module.exports=Oe(_e);var E=N(require("react"));var I=class{constructors;constructor(){this.constructors={}}register(e,t){this.constructors[e]=t}unpack(e){let t={};this.scanForIds(e,t);let r={};return this.unpackWithRefs(e,t,r)}scanForIds(e,t){if(e===null||typeof e!="object")return;if(Array.isArray(e)){e.forEach(o=>this.scanForIds(o,t));return}let r=!1;if("_id"in e&&(r=!0,t[e._id]=e),("_type"in e||"_val"in e||"_ref"in e)&&(r=!0),"_list"in e&&(r=!0,e._list.forEach(o=>this.scanForIds(o,t))),"_args"in e&&(r=!0,e._args.forEach(o=>this.scanForIds(o,t))),"_dict"in e){r=!0;for(let[o,i]of Object.entries(e._dict))this.scanForIds(i,t)}if(!r)for(let[o,i]of Object.entries(e))this.scanForIds(i,t)}unpackWithRefs(e,t,r){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(i=>this.unpackWithRefs(i,t,r));let o;if("_ref"in e)e._ref in r?o=r[e._ref]:o=this.unpackWithRefs(t[e._ref],t,r);else if("_val"in e)o=e._val;else if("_list"in e)o=e._list.map(i=>this.unpackWithRefs(i,t,r));else if("_dict"in e){o={};for(let[i,c]of Object.entries(e._dict))o[i]=this.unpackWithRefs(c,t,r)}else if("_type"in e){let i=e._type,c=this.constructors[i];if(typeof c!="function")throw new Error(`telepath encountered unknown object type ${i}`);let f=e._args.map(d=>this.unpackWithRefs(d,t,r));o=new c(...f)}else{if("_id"in e)throw new Error("telepath encountered object with _id but no type specified");o={};for(let[i,c]of Object.entries(e))o[i]=this.unpackWithRefs(c,t,r);return o}return"_id"in e&&(r[e._id]=o),o}};var W=class{views;telepathRegistry;constructor(){this.views=new Map,this.telepathRegistry=new I,this.addAdapter("Date",Date)}addView=(e,t)=>(this.views.set(e,t),this);addAdapter=(e,t)=>(this.telepathRegistry.register(e,t),this);unpack=e=>this.telepathRegistry.unpack(e)};async function L(n,e){let t,r={"X-Requested-With":"DjangoBridge"};e&&(r["X-DjangoBridge-Overlay"]="true");try{t=await fetch(n,{headers:r})}catch{return{action:"network-error"}}return t.status===500?{action:"server-error"}:t.headers.get("X-DjangoBridge-Action")?t.json():{action:"reload"}}async function se(n,e,t){let r,o={"X-Requested-With":"DjangoBridge"};t&&(o["X-DjangoBridge-Overlay"]="true");try{r=await fetch(n,{method:"post",headers:o,body:e})}catch{return{action:"network-error"}}return r.status===500?{action:"server-error"}:r.headers.get("X-DjangoBridge-Action")?r.json():{action:"reload"}}var g=require("react");var J=1;function K(n,e,t,r,o={}){J+=1;let[i,c]=(0,g.useState)({id:J,path:r,metadata:{title:"Loading"},view:"loading",props:{},context:{}}),[f,d]=(0,g.useState)(!1),v=(0,g.useCallback)((a,y,k,F,D,S,ie=!0,q=!0)=>{let $=i.id,pe=k!==i.view||q;if(pe&&(J+=1,$=J),!n&&(document.title=y.title,ie)){let ve=0,ke=window.scrollY,he=window.history?.state;he?.prevPath===a&&(ve=he.prevScrollPosition??0),window.history.pushState({prevPath:window.location.pathname,prevScrollPosition:ke},"",a),window.scrollTo(0,ve)}let ge={id:$,path:a,metadata:y,view:k,props:F,context:D};c(ge),o.onNavigation&&o.onNavigation(ge,pe,S)},[o,i.id,i.view,n]),[u,h]=(0,g.useState)(null),C=(0,g.useCallback)((a,y,k=!0,F=!1,D=!1)=>{if(a.action==="reload")if(!n)window.location.href=y;else return n.handleResponse(a,y);else{if(a.action==="redirect")return h(a.path),Promise.resolve();if(a.action==="render"){if(n&&!a.overlay){D&&console.warn(`openOverlay('${y}') returned a response that couldn't be rendered in an overlay.`);let $=n.handleResponse(a,y);return o.onEscalate&&o.onEscalate(),$}let S=e(a.props),ie=e(a.context),q=!F;q&&a.view===i.view&&i.shouldReloadCallback&&(q=i.shouldReloadCallback(y,S)),v(y,a.metadata,a.view,S,ie,a.messages,k,q)}else if(a.action==="close-overlay")o.onOverlayClose&&o.onOverlayClose(a.messages);else{if(a.action==="server-error")return o.onServerError&&o.onServerError("server"),Promise.reject();if(a.action==="network-error")return o.onServerError&&o.onServerError("network"),Promise.reject()}}return Promise.resolve()},[o,i,n,v,e]),m=(0,g.useRef)(1),l=(0,g.useRef)(1),R=(0,g.useRef)(!1),s=(0,g.useCallback)(async(a,y,k,F=!1)=>{m.current+=1;let D=m.current;R.current=!0;let S=await a();D<l.current||(l.current=D,S!==null&&(await C(S,y,k,F),R.current=!1))},[C]),p=(0,g.useCallback)((a,y=!0)=>{let k=a;if(!a.startsWith("/")){let F=new URL(a);if(F.origin!==window.location.origin)return window.location.href=a,Promise.resolve();k=F.pathname+F.search}return d(!0),s(()=>L(k,!!n),k,y).finally(()=>{d(!1)})},[s,n]),w=(0,g.useCallback)((a,y)=>{a===i.id&&(i.path=y,n||history.replaceState({},"",i.path))},[i,n]),ne=(0,g.useCallback)((a,y)=>s(()=>se(a,y,!!n),a,!0),[s,n]),Pe=(0,g.useCallback)(()=>R.current?Promise.resolve():s(()=>L(i.path,!!n),i.path,!1,!0),[i.path,s,n]);return(0,g.useEffect)(()=>{C(t,r,!1,!1,!0)},[]),(0,g.useEffect)(()=>{u&&(h(null),p(u))},[p,u]),{parent:n,currentFrame:i,isLoading:i.view==="loading",handleResponse:C,navigate:p,replacePath:w,submitForm:ne,refreshProps:Pe,isNavigating:f,setIsNavigating:d}}var x=N(require("react")),j=require("react/jsx-runtime"),ae=x.default.createContext(()=>{}),b=x.default.createContext({isDirty:!1,requestUnload:()=>Promise.resolve(),unloadRequested:!1,unloadBlocked:!1,confirmUnload:()=>{},cancelUnload:()=>{},unloadConfirmed:!1});function le({handleBrowserUnload:n=!1,children:e}){let[t,r]=x.default.useState(!1),[o,i]=x.default.useState({cb:()=>{}}),[c,f]=x.default.useState(!1),[d,v]=x.default.useState(!1),u=x.default.useRef(null),h=()=>u.current&&!!u.current.querySelector("div.dirty-form-marker")||!1;x.default.useEffect(()=>{if(n&&d){let R="This page has unsaved changes.",s=p=>h()?(p.returnValue=R,R):"";return window.addEventListener("beforeunload",s),()=>{window.removeEventListener("beforeunload",s)}}return()=>{}},[n,d]);let C=x.default.useContext(ae),m=x.default.useCallback(()=>{v(h()),C()},[C]),l=x.default.useMemo(()=>({isDirty:d,requestUnload:()=>d&&h()?(r(!0),new Promise(R=>{i({cb:R})})):Promise.resolve(),unloadRequested:t,unloadBlocked:d&&t,confirmUnload:()=>{t&&(f(!0),o.cb(),r(!1),i({cb:()=>{}}))},cancelUnload:()=>{t&&(r(!1),i({cb:()=>{}}))},unloadConfirmed:c}),[d,o,c,t]);return(0,j.jsx)("div",{ref:u,children:(0,j.jsx)(ae.Provider,{value:m,children:(0,j.jsx)(b.Provider,{value:l,children:e})})})}function z(){let n=x.default.useContext(ae);return x.default.useEffect(n),(0,j.jsx)("div",{className:"dirty-form-marker",style:{display:"none"}})}var ce=N(require("react"));var B=N(require("react")),Q=B.default.createContext({overlay:!1,closeRequested:!1,requestClose:()=>{console.error("OverlayContext.requestClose() called from outside an overlay")},onCloseCompleted:()=>{console.error("OverlayContext.onCloseCompleted() called from outside an overlay")}}),P=B.default.createContext({frameId:0,path:"/",props:{},context:{},navigate:()=>(console.error("navigate() called from outside a Django Bridge Browser"),Promise.resolve()),replacePath:()=>{console.error("replacePath() called from outside a Django Bridge Browser")},submitForm:()=>(console.error("submitForm() called from outside a Django Bridge Browser"),Promise.resolve()),openOverlay:()=>{throw console.error("openOverlay() called from outside a Django Bridge Browser"),new Error("Modal cannot be opened here")},refreshProps:()=>(console.error("refreshProps() called from outside a Django Bridge Browser"),Promise.resolve()),isNavigating:!1,setShouldReloadCallback:()=>{}}),Z=B.default.createContext(()=>{}),ee=B.default.createContext(!1),T=B.default.createContext({messages:[],pushMessage:()=>{}});var _=require("react/jsx-runtime");function De({config:n,frame:e}){let t=n.views.get(e.view);if(!t)return(0,_.jsxs)("p",{children:["Unknown view '",e.view,"'"]});let r=(0,_.jsx)(t,{...e.props});return n.contextProviders.forEach((o,i)=>{r=(0,_.jsx)(o.Provider,{value:e.context[i],children:r})}),(0,_.jsx)("div",{children:r},e.id)}var te=De;var oe=require("react/jsx-runtime");function Le({config:n,navigationController:e,openOverlay:t}){let{currentFrame:r,navigate:o,replacePath:i,submitForm:c,refreshProps:f,isNavigating:d}=e,{isDirty:v,requestUnload:u,cancelUnload:h}=ce.default.useContext(b),C=ce.default.useMemo(()=>({frameId:r.id,path:r.path,props:r.props,context:r.context,navigate:(m,l={})=>!v||l.skipDirtyFormCheck===!0?(l.skipDirtyFormCheck===!0&&h(),o(m,l.pushState)):u().then(()=>o(m,l.pushState)),replacePath:i,submitForm:c,openOverlay:t,refreshProps:f,isNavigating:d,setShouldReloadCallback:m=>{r.shouldReloadCallback=m}}),[r,i,c,t,v,u,h,o,f,d]);return(0,oe.jsx)(P.Provider,{value:C,children:(0,oe.jsx)("div",{children:(0,oe.jsx)(te,{config:n,frame:r})},r.id)})}var re=Le;var V=N(require("react"));var Re=require("react/jsx-runtime");function de({children:n,href:e,skipDirtyFormCheck:t=!1,...r},{navigate:o},i){return(0,Re.jsx)("a",{onClick:f=>{e&&(f.preventDefault(),o(e,{skipDirtyFormCheck:t}))},href:e||"#",ref:i,...r,children:n})}var ue=V.default.createContext(de),Be=V.default.forwardRef((n,e)=>{let t=V.default.useContext(P);return V.default.useContext(ue)(n,t,e)}),Ce=Be;var X=class extends W{contextProviders;constructor(){super(),this.contextProviders=new Map}addContextProvider=(e,t)=>(this.contextProviders.set(e,t),this)};var A=N(require("react"));var U=require("react/jsx-runtime");function fe({children:n,onSubmit:e,isDirty:t=!1,disableDirtyCheck:r=!1,...o}){let{submitForm:i,navigate:c}=A.default.useContext(P),[f,d]=A.default.useState(!1),[v,u]=A.default.useState(t),{cancelUnload:h}=A.default.useContext(b),C=l=>{if(v&&h(),!(e&&(e(l),l.defaultPrevented))&&l.target instanceof HTMLFormElement){if(f){l.preventDefault();return}let R=new FormData(l.target);if(l.nativeEvent instanceof SubmitEvent&&l.nativeEvent.submitter){let{submitter:s}=l.nativeEvent;(s instanceof HTMLButtonElement||s instanceof HTMLInputElement)&&s.name&&s.value&&R.set(s.name,s.value)}if(l.target.method==="post")l.preventDefault(),d(!0),i(l.target.action,R).catch(()=>d(!1));else if(l.target.method==="get"){l.preventDefault();let s=Array.from(R.entries()).map(w=>`${encodeURIComponent(w[0])}=${encodeURIComponent(w[1])}`).join("&"),p=l.target.action+(l.target.action.indexOf("?")===-1?"?":"&")+s;d(!0),c(p).catch(()=>d(!1))}}},m=A.default.useCallback(()=>{u(!0)},[]);return(0,U.jsxs)("form",{onSubmit:C,...o,children:[v&&!r&&(0,U.jsx)(z,{}),(0,U.jsx)(ee.Provider,{value:f,children:(0,U.jsx)(Z.Provider,{value:m,children:n})})]})}var G=N(require("react"));var H=require("react/jsx-runtime");function me({config:n,initialResponse:e,initialPath:t,parentNavigationController:r,render:o,requestClose:i,closeRequested:c,onCloseCompleted:f,onServerError:d}){let{pushMessage:v}=G.default.useContext(T),u=K(r,n.unpack,e,t,{onNavigation:(l,R,s)=>{s.forEach(v)},onEscalate:()=>{f()},onOverlayClose:l=>{l.forEach(v),i()},onServerError:d}),h=G.default.useContext(b),C=G.default.useCallback(({skipDirtyFormCheck:l=!1}={})=>{!l&&h.isDirty?h.requestUnload().then(()=>i()):i()},[h,i]),m=G.default.useMemo(()=>({overlay:!0,closeRequested:c,requestClose:C,onCloseCompleted:f}),[c,f,C]);return u.isLoading?(0,H.jsx)(H.Fragment,{}):(0,H.jsx)(Q.Provider,{value:m,children:o((0,H.jsx)(re,{config:n,navigationController:u,openOverlay:()=>{}}))})}var M=N(require("react"));function xe(n,e){let{refreshProps:t}=M.default.useContext(P);M.default.useEffect(()=>{if(!n)return()=>{};let r=null,o=()=>{r=setTimeout(()=>{t(),o()},e)};return o(),()=>{r&&clearTimeout(r)}},[n,e,t])}function we(n,e){let t=(0,M.useCallback)(n,e),{setShouldReloadCallback:r}=(0,M.useContext)(P);(0,M.useEffect)(()=>r(t),[t,r])}var O=require("react/jsx-runtime");function Te({config:n,initialResponse:e}){let[t,r]=E.default.useReducer((s,p)=>{switch(p.action){case"push":return s.concat([p.message]);case"clear":return[];default:return s}},[]),o=E.default.useCallback(s=>{r({action:"push",message:s})},[r]),i=E.default.useCallback(s=>{s==="server"?o({level:"error",text:"A server error occurred. Please try again later."}):s==="network"&&o({level:"error",text:"A network error occurred. Please check your internet connection or try again later."})},[o]),[c,f]=E.default.useState(null),[d,v]=E.default.useState(!1),u=E.default.useRef(null),h=(s,p,w)=>{p&&(v(!0),u.current=null),p&&r({action:"clear"}),w.forEach(o)},C=window.location.pathname+window.location.search+window.location.hash,m=K(null,n.unpack,e,C,{onNavigation:h,onServerError:i});E.default.useEffect(()=>{let s=document.querySelector(".django-bridge-load");s instanceof HTMLElement&&(s.classList.add("django-bridge-load--hidden"),setTimeout(()=>{s.remove()},200));let p=()=>{m.navigate(document.location.pathname,!1)};return window.addEventListener("popstate",p),()=>{window.removeEventListener("popstate",p)}},[]);let l=async(s,p,{onClose:w}={})=>{if(c){console.error("Unable to open overlay as an overlay is already open.");return}m.setIsNavigating(!0);let ne=await L(s,!0);w&&(u.current=w),v(!1),f({render:p,initialResponse:ne,initialPath:s}),m.setIsNavigating(!1)},R=E.default.useMemo(()=>({messages:t,pushMessage:o}),[t,o]);return(0,O.jsx)(le,{handleBrowserUnload:!0,children:(0,O.jsxs)(T.Provider,{value:R,children:[c&&(0,O.jsx)(le,{children:(0,O.jsx)(me,{config:n,initialResponse:c.initialResponse,initialPath:c.initialPath,parentNavigationController:m,render:s=>c.render(s),requestClose:()=>v(!0),closeRequested:d,onCloseCompleted:()=>{f(null),v(!1),u.current&&(u.current(),u.current=null)},onServerError:i})}),!m.isLoading&&(0,O.jsx)(re,{config:n,navigationController:m,openOverlay:(s,p,w)=>{l(s,p,w)}})]})})}0&&(module.exports={App,BuildLinkElement,Config,DirtyFormContext,DirtyFormMarker,Form,FormSubmissionStatus,FormWidgetChangeNotificationContext,Link,MessagesContext,NavigationContext,OverlayContext,RenderFrame,buildLinkElement,useAutoRefresh,useShouldReloadCallback});
1
+ "use strict";var be=Object.create;var Y=Object.defineProperty;var Me=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var Ne=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty;var Oe=(n,e)=>{for(var t in e)Y(n,t,{get:e[t],enumerable:!0})},ye=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Ee(e))!Se.call(n,o)&&o!==t&&Y(n,o,{get:()=>e[o],enumerable:!(r=Me(e,o))||r.enumerable});return n};var N=(n,e,t)=>(t=n!=null?be(Ne(n)):{},ye(e||!n||!n.__esModule?Y(t,"default",{value:n,enumerable:!0}):t,n)),De=n=>ye(Y({},"__esModule",{value:!0}),n);var _e={};Oe(_e,{App:()=>Ie,BuildLinkElement:()=>ue,Config:()=>X,DirtyFormContext:()=>b,DirtyFormMarker:()=>z,Form:()=>me,FormSubmissionStatus:()=>ee,FormWidgetChangeNotificationContext:()=>Z,Link:()=>Re,MessagesContext:()=>T,NavigationContext:()=>P,OverlayContext:()=>Q,RenderFrame:()=>te,buildLinkElement:()=>de,useAutoRefresh:()=>we,useShouldReloadCallback:()=>Pe});module.exports=De(_e);var E=N(require("react"));var q=class{constructors;constructor(){this.constructors={}}register(e,t){this.constructors[e]=t}unpack(e){let t={};this.scanForIds(e,t);let r={};return this.unpackWithRefs(e,t,r)}scanForIds(e,t){if(e===null||typeof e!="object")return;if(Array.isArray(e)){e.forEach(o=>this.scanForIds(o,t));return}let r=!1;if("_id"in e&&(r=!0,t[e._id]=e),("_type"in e||"_val"in e||"_ref"in e)&&(r=!0),"_list"in e&&(r=!0,e._list.forEach(o=>this.scanForIds(o,t))),"_args"in e&&(r=!0,e._args.forEach(o=>this.scanForIds(o,t))),"_dict"in e){r=!0;for(let[o,i]of Object.entries(e._dict))this.scanForIds(i,t)}if(!r)for(let[o,i]of Object.entries(e))this.scanForIds(i,t)}unpackWithRefs(e,t,r){if(e===null||typeof e!="object")return e;if(Array.isArray(e))return e.map(i=>this.unpackWithRefs(i,t,r));let o;if("_ref"in e)e._ref in r?o=r[e._ref]:o=this.unpackWithRefs(t[e._ref],t,r);else if("_val"in e)o=e._val;else if("_list"in e)o=e._list.map(i=>this.unpackWithRefs(i,t,r));else if("_dict"in e){o={};for(let[i,c]of Object.entries(e._dict))o[i]=this.unpackWithRefs(c,t,r)}else if("_type"in e){let i=e._type,c=this.constructors[i];if(typeof c!="function")throw new Error(`telepath encountered unknown object type ${i}`);let m=e._args.map(d=>this.unpackWithRefs(d,t,r));o=new c(...m)}else{if("_id"in e)throw new Error("telepath encountered object with _id but no type specified");o={};for(let[i,c]of Object.entries(e))o[i]=this.unpackWithRefs(c,t,r);return o}return"_id"in e&&(r[e._id]=o),o}};var W=class{views;telepathRegistry;constructor(){this.views=new Map,this.telepathRegistry=new q,this.addAdapter("Date",Date)}addView=(e,t)=>(this.views.set(e,t),this);addAdapter=(e,t)=>(this.telepathRegistry.register(e,t),this);unpack=e=>this.telepathRegistry.unpack(e)};async function L(n,e){let t,r={"X-Requested-With":"DjangoBridge"};e&&(r["X-DjangoBridge-Overlay"]="true");try{t=await fetch(n,{headers:r})}catch{return{action:"network-error"}}return t.status===500?{action:"server-error"}:t.headers.get("X-DjangoBridge-Action")?t.json():{action:"reload"}}async function ie(n,e,t){let r,o={"X-Requested-With":"DjangoBridge"};t&&(o["X-DjangoBridge-Overlay"]="true");try{r=await fetch(n,{method:"post",headers:o,body:e})}catch{return{action:"network-error"}}return r.status===500?{action:"server-error"}:r.headers.get("X-DjangoBridge-Action")?r.json():{action:"reload"}}var g=require("react");var J=1;function K(n,e,t,r,o={}){let[i,c]=(0,g.useState)({id:J,originalId:J,path:r,metadata:{title:"Loading"},view:"loading",props:{},context:{}}),[m,d]=(0,g.useState)(!1),v=(0,g.useCallback)((a,C,k,F,D,S,ne=!0,H=!0)=>{J+=1;let $=J,pe=i.originalId,ge=k!==i.view||H;if(ge&&(pe=$),!n&&(document.title=C.title,ne)){let he=0,Fe=window.scrollY,Ce=window.history?.state;Ce?.prevPath===a&&(he=Ce.prevScrollPosition??0),window.history.pushState({prevPath:window.location.pathname,prevScrollPosition:Fe},"",a),window.scrollTo(0,he)}let ve={id:$,originalId:pe,path:a,metadata:C,view:k,props:F,context:D};c(ve),o.onNavigation&&o.onNavigation(ve,ge,S)},[o,i.originalId,i.view,n]),[u,h]=(0,g.useState)(null),y=(0,g.useCallback)((a,C,k=!0,F=!1,D=!1)=>{if(a.action==="reload")if(!n)window.location.href=C;else return n.handleResponse(a,C);else{if(a.action==="redirect")return h(a.path),Promise.resolve();if(a.action==="render"){if(n&&!a.overlay){D&&console.warn(`openOverlay('${C}') returned a response that couldn't be rendered in an overlay.`);let $=n.handleResponse(a,C);return o.onEscalate&&o.onEscalate(),$}let S=e(a.props),ne=e(a.context),H=!F;H&&a.view===i.view&&i.shouldReloadCallback&&(H=i.shouldReloadCallback(C,S)),v(C,a.metadata,a.view,S,ne,a.messages,k,H)}else if(a.action==="close-overlay")o.onOverlayClose&&o.onOverlayClose(a.messages);else{if(a.action==="server-error")return o.onServerError&&o.onServerError("server"),Promise.reject();if(a.action==="network-error")return o.onServerError&&o.onServerError("network"),Promise.reject()}}return Promise.resolve()},[o,i,n,v,e]),f=(0,g.useRef)(1),l=(0,g.useRef)(1),R=(0,g.useRef)(!1),s=(0,g.useCallback)(async(a,C,k,F=!1)=>{f.current+=1;let D=f.current;R.current=!0;let S=await a();D<l.current||(l.current=D,S!==null&&(await y(S,C,k,F),R.current=!1))},[y]),p=(0,g.useCallback)((a,C=!0)=>{let k=a;if(!a.startsWith("/")){let F=new URL(a);if(F.origin!==window.location.origin)return window.location.href=a,Promise.resolve();k=F.pathname+F.search}return d(!0),s(()=>L(k,!!n),k,C).finally(()=>{d(!1)})},[s,n]),w=(0,g.useCallback)((a,C)=>{a===i.id&&(i.path=C,n||history.replaceState({},"",i.path))},[i,n]),re=(0,g.useCallback)((a,C)=>s(()=>ie(a,C,!!n),a,!0),[s,n]),ke=(0,g.useCallback)(()=>R.current?Promise.resolve():s(()=>L(i.path,!!n),i.path,!1,!0),[i.path,s,n]);return(0,g.useEffect)(()=>{y(t,r,!1,!1,!0)},[]),(0,g.useEffect)(()=>{u&&(h(null),p(u))},[p,u]),{parent:n,currentFrame:i,isLoading:i.view==="loading",handleResponse:y,navigate:p,replacePath:w,submitForm:re,refreshProps:ke,isNavigating:m,setIsNavigating:d}}var x=N(require("react")),j=require("react/jsx-runtime"),se=x.default.createContext(()=>{}),b=x.default.createContext({isDirty:!1,requestUnload:()=>Promise.resolve(),unloadRequested:!1,unloadBlocked:!1,confirmUnload:()=>{},cancelUnload:()=>{},unloadConfirmed:!1});function ae({handleBrowserUnload:n=!1,children:e}){let[t,r]=x.default.useState(!1),[o,i]=x.default.useState({cb:()=>{}}),[c,m]=x.default.useState(!1),[d,v]=x.default.useState(!1),u=x.default.useRef(null),h=()=>u.current&&!!u.current.querySelector("div.dirty-form-marker")||!1;x.default.useEffect(()=>{if(n&&d){let R="This page has unsaved changes.",s=p=>h()?(p.returnValue=R,R):"";return window.addEventListener("beforeunload",s),()=>{window.removeEventListener("beforeunload",s)}}return()=>{}},[n,d]);let y=x.default.useContext(se),f=x.default.useCallback(()=>{v(h()),y()},[y]),l=x.default.useMemo(()=>({isDirty:d,requestUnload:()=>d&&h()?(r(!0),new Promise(R=>{i({cb:R})})):Promise.resolve(),unloadRequested:t,unloadBlocked:d&&t,confirmUnload:()=>{t&&(m(!0),o.cb(),r(!1),i({cb:()=>{}}))},cancelUnload:()=>{t&&(r(!1),i({cb:()=>{}}))},unloadConfirmed:c}),[d,o,c,t]);return(0,j.jsx)("div",{ref:u,children:(0,j.jsx)(se.Provider,{value:f,children:(0,j.jsx)(b.Provider,{value:l,children:e})})})}function z(){let n=x.default.useContext(se);return x.default.useEffect(n),(0,j.jsx)("div",{className:"dirty-form-marker",style:{display:"none"}})}var le=N(require("react"));var B=N(require("react")),Q=B.default.createContext({overlay:!1,closeRequested:!1,requestClose:()=>{console.error("OverlayContext.requestClose() called from outside an overlay")},onCloseCompleted:()=>{console.error("OverlayContext.onCloseCompleted() called from outside an overlay")}}),P=B.default.createContext({frameId:0,originalFrameId:0,path:"/",props:{},context:{},navigate:()=>(console.error("navigate() called from outside a Django Bridge Browser"),Promise.resolve()),replacePath:()=>{console.error("replacePath() called from outside a Django Bridge Browser")},submitForm:()=>(console.error("submitForm() called from outside a Django Bridge Browser"),Promise.resolve()),openOverlay:()=>{throw console.error("openOverlay() called from outside a Django Bridge Browser"),new Error("Modal cannot be opened here")},refreshProps:()=>(console.error("refreshProps() called from outside a Django Bridge Browser"),Promise.resolve()),isNavigating:!1,setShouldReloadCallback:()=>{}}),Z=B.default.createContext(()=>{}),ee=B.default.createContext(!1),T=B.default.createContext({messages:[],pushMessage:()=>{}});var I=require("react/jsx-runtime");function Le({config:n,frame:e}){let t=n.views.get(e.view);if(!t)return(0,I.jsxs)("p",{children:["Unknown view '",e.view,"'"]});let r=(0,I.jsx)(t,{...e.props});return n.contextProviders.forEach((o,i)=>{i in e.context&&(r=(0,I.jsx)(o.Provider,{value:e.context[i],children:r}))}),(0,I.jsx)("div",{children:r},e.originalId)}var te=Le;var ce=require("react/jsx-runtime");function Be({config:n,navigationController:e,openOverlay:t}){let{currentFrame:r,navigate:o,replacePath:i,submitForm:c,refreshProps:m,isNavigating:d}=e,{isDirty:v,requestUnload:u,cancelUnload:h}=le.default.useContext(b),y=le.default.useMemo(()=>({originalFrameId:r.originalId,frameId:r.id,path:r.path,props:r.props,context:r.context,navigate:(f,l={})=>!v||l.skipDirtyFormCheck===!0?(l.skipDirtyFormCheck===!0&&h(),o(f,l.pushState)):u().then(()=>o(f,l.pushState)),replacePath:i,submitForm:c,openOverlay:t,refreshProps:m,isNavigating:d,setShouldReloadCallback:f=>{r.shouldReloadCallback=f}}),[r,i,c,t,v,u,h,o,m,d]);return(0,ce.jsx)(P.Provider,{value:y,children:(0,ce.jsx)(te,{config:n,frame:r})})}var oe=Be;var V=N(require("react"));var xe=require("react/jsx-runtime");function de({children:n,href:e,skipDirtyFormCheck:t=!1,...r},{navigate:o},i){return(0,xe.jsx)("a",{onClick:m=>{e&&(m.preventDefault(),o(e,{skipDirtyFormCheck:t}))},href:e||"#",ref:i,...r,children:n})}var ue=V.default.createContext(de),Te=V.default.forwardRef((n,e)=>{let t=V.default.useContext(P);return V.default.useContext(ue)(n,t,e)}),Re=Te;var X=class extends W{contextProviders;constructor(){super(),this.contextProviders=new Map}addContextProvider=(e,t)=>(this.contextProviders.set(e,t),this)};var _=N(require("react"));var A=require("react/jsx-runtime");function me({children:n,onSubmit:e,isDirty:t=!1,disableDirtyCheck:r=!1,...o}){let{submitForm:i,navigate:c}=_.default.useContext(P),[m,d]=_.default.useState(!1),[v,u]=_.default.useState(t),{cancelUnload:h}=_.default.useContext(b),y=l=>{if(v&&h(),!(e&&(e(l),l.defaultPrevented))&&l.target instanceof HTMLFormElement){if(m){l.preventDefault();return}let R=new FormData(l.target);if(l.nativeEvent instanceof SubmitEvent&&l.nativeEvent.submitter){let{submitter:s}=l.nativeEvent;(s instanceof HTMLButtonElement||s instanceof HTMLInputElement)&&s.name&&s.value&&R.set(s.name,s.value)}if(l.target.method==="post")l.preventDefault(),d(!0),i(l.target.action,R).catch(()=>d(!1));else if(l.target.method==="get"){l.preventDefault();let s=Array.from(R.entries()).map(w=>`${encodeURIComponent(w[0])}=${encodeURIComponent(w[1])}`).join("&"),p=l.target.action+(l.target.action.indexOf("?")===-1?"?":"&")+s;d(!0),c(p).catch(()=>d(!1))}}},f=_.default.useCallback(()=>{u(!0)},[]);return(0,A.jsxs)("form",{onSubmit:y,...o,children:[v&&!r&&(0,A.jsx)(z,{}),(0,A.jsx)(ee.Provider,{value:m,children:(0,A.jsx)(Z.Provider,{value:f,children:n})})]})}var G=N(require("react"));var U=require("react/jsx-runtime");function fe({config:n,initialResponse:e,initialPath:t,parentNavigationController:r,render:o,requestClose:i,closeRequested:c,onCloseCompleted:m,onServerError:d}){let{pushMessage:v}=G.default.useContext(T),u=K(r,n.unpack,e,t,{onNavigation:(l,R,s)=>{s.forEach(v)},onEscalate:()=>{m()},onOverlayClose:l=>{l.forEach(v),i()},onServerError:d}),h=G.default.useContext(b),y=G.default.useCallback(({skipDirtyFormCheck:l=!1}={})=>{!l&&h.isDirty?h.requestUnload().then(()=>i()):i()},[h,i]),f=G.default.useMemo(()=>({overlay:!0,closeRequested:c,requestClose:y,onCloseCompleted:m}),[c,m,y]);return u.isLoading?(0,U.jsx)(U.Fragment,{}):(0,U.jsx)(Q.Provider,{value:f,children:o((0,U.jsx)(oe,{config:n,navigationController:u,openOverlay:()=>{}}))})}var M=N(require("react"));function we(n,e){let{refreshProps:t}=M.default.useContext(P);M.default.useEffect(()=>{if(!n)return()=>{};let r=null,o=()=>{r=setTimeout(()=>{t(),o()},e)};return o(),()=>{r&&clearTimeout(r)}},[n,e,t])}function Pe(n,e){let t=(0,M.useCallback)(n,e),{setShouldReloadCallback:r}=(0,M.useContext)(P);(0,M.useEffect)(()=>r(t),[t,r])}var O=require("react/jsx-runtime");function Ie({config:n,initialResponse:e}){let[t,r]=E.default.useReducer((s,p)=>{switch(p.action){case"push":return s.concat([p.message]);case"clear":return[];default:return s}},[]),o=E.default.useCallback(s=>{r({action:"push",message:s})},[r]),i=E.default.useCallback(s=>{s==="server"?o({level:"error",text:"A server error occurred. Please try again later."}):s==="network"&&o({level:"error",text:"A network error occurred. Please check your internet connection or try again later."})},[o]),[c,m]=E.default.useState(null),[d,v]=E.default.useState(!1),u=E.default.useRef(null),h=(s,p,w)=>{p&&(v(!0),u.current=null),p&&r({action:"clear"}),w.forEach(o)},y=window.location.pathname+window.location.search+window.location.hash,f=K(null,n.unpack,e,y,{onNavigation:h,onServerError:i});E.default.useEffect(()=>{let s=document.querySelector(".django-bridge-load");s instanceof HTMLElement&&(s.classList.add("django-bridge-load--hidden"),setTimeout(()=>{s.remove()},200));let p=()=>{f.navigate(document.location.pathname,!1)};return window.addEventListener("popstate",p),()=>{window.removeEventListener("popstate",p)}},[]);let l=async(s,p,{onClose:w}={})=>{if(c){console.error("Unable to open overlay as an overlay is already open.");return}f.setIsNavigating(!0);let re=await L(s,!0);w&&(u.current=w),v(!1),m({render:p,initialResponse:re,initialPath:s}),f.setIsNavigating(!1)},R=E.default.useMemo(()=>({messages:t,pushMessage:o}),[t,o]);return(0,O.jsx)(ae,{handleBrowserUnload:!0,children:(0,O.jsxs)(T.Provider,{value:R,children:[c&&(0,O.jsx)(ae,{children:(0,O.jsx)(fe,{config:n,initialResponse:c.initialResponse,initialPath:c.initialPath,parentNavigationController:f,render:s=>c.render(s),requestClose:()=>v(!0),closeRequested:d,onCloseCompleted:()=>{m(null),v(!1),u.current&&(u.current(),u.current=null)},onServerError:i})}),!f.isLoading&&(0,O.jsx)(oe,{config:n,navigationController:f,openOverlay:(s,p,w)=>{l(s,p,w)}})]})})}0&&(module.exports={App,BuildLinkElement,Config,DirtyFormContext,DirtyFormMarker,Form,FormSubmissionStatus,FormWidgetChangeNotificationContext,Link,MessagesContext,NavigationContext,OverlayContext,RenderFrame,buildLinkElement,useAutoRefresh,useShouldReloadCallback});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@django-bridge/react",
3
- "version": "0.6.0-rc.1",
3
+ "version": "0.6.0",
4
4
  "description": "The simple way to build Django applications with modern React frontends",
5
5
  "repository": "https://github.com/django-bridge/django-bridge",
6
6
  "license": "BSD-3-Clause",