UNPKG

@donverduyn/react-runtime

Version:
3 lines (2 loc) 9.11 kB
import{jsx as e}from"react/jsx-runtime";import*as t from"react";import{v4 as n}from"uuid";import{Effect as s,ManagedRuntime as i,pipe as r,Stream as o,Scope as c,Exit as u,identity as a}from"effect";function d(e){return"object"==typeof e&&null!==e&&Object.getPrototypeOf(e)===Object.prototype}function l(e,t,n={}){if(e===t)return!0;if(d(e)&&d(t)){const s=Object.keys(e),i=Object.keys(t);if(s.length!==i.length)return!1;for(const r of s){if(!i.includes(r))return!1;if(!l(e[r],t[r],n))return!1}return!0}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(let s=0;s<e.length;s++)if(!l(e[s],t[s],n))return!1;return!0}return!1}function f(e){return d(e)&&t.isValidElement(e.Provider)&&t.isValidElement(e.Consumer)}const h=e=>d(e)&&e.$$typeof===t.createContext(null).$$typeof,p=(e,t)=>{const n=e?.type?.name,s=e&&(e.displayName||e.name||n)||"Component";return t?`${t}(${s})`:s},m={$$typeof:!0,compare:!0,displayName:!0,render:!0,type:!0};function g(e,t){Object.keys(e).forEach((function(n){m[n]||Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))}))}const y=(t,n)=>t?e(t,{...n}):null,v=e=>Object.getOwnPropertyNames(e).filter((()=>{const e=Object.getOwnPropertyNames((()=>{}));return t=>!e.includes(t)})()).reduce(((t,n)=>Object.assign(t,{[n]:e[n]})),{}),x=(e,t)=>s.isEffect(e)?t:Array.isArray(e)?e:t,b=(e,n,s)=>{const r=h(e)?e!==n?t.use(e):s.get(e):i.isManagedRuntime(e)?e:s.get(n);if(void 0===r)throw new Error("No runtime available. \n Did you forget to wrap your component using WithRuntime?\n ");return r},w=(e,t)=>s.isEffect(e)&&!i.isManagedRuntime(e)?e:s.isEffect(t)?t:s.void;class E{constructor(){this.listeners=[],this.resolvers=new Map,this.eventQueue=[],this.emit=(...e)=>{const t=n();let s;const i=new Promise((e=>{s=e}));return this.eventQueue.push({data:e,eventId:t}),this.notifyListeners(),this.resolvers.set(t,s),i}}subscribe(e){this.listeners.push(e),this.notifyListeners()}notifyListeners(){for(;this.eventQueue.length>0&&this.listeners.length>0;){const e=this.eventQueue.shift();this.listeners.forEach((t=>t(e.data,e.eventId)))}}resolve(e){return t=>{const n=this.resolvers.get(e);n&&(n(t),this.resolvers.delete(e))}}async waitForEvent(){return this.eventQueue.length>0?Promise.resolve(this.eventQueue.shift()):new Promise((e=>{const t=(n,s)=>{e({data:n,eventId:s}),this.listeners=this.listeners.filter((e=>e!==t))};this.subscribe(t)}))}}const T=(e,n)=>(a,d,l=[])=>{const f=x(d,l),p=((e,t)=>i.isManagedRuntime(e)||s.isEffect(e)||h(e)?"function"==typeof t?t:()=>s.void:e)(a,d),m=b(a,e,n),g=t.useRef(p);t.useEffect((()=>{g.current=p}),[n,m,p,...f]);const y=t.useMemo((()=>new E),[n,m,...f]),v=t.useMemo((()=>r(o.fromAsyncIterable(async function*(e){for(;;)yield await e.waitForEvent()}(y),(()=>{})),o.mapEffect((({data:e,eventId:t})=>r(g.current(...e),s.tap((e=>y.resolve(t)(e)))))),o.runDrain)),[n,m,...f]);return t.useEffect((()=>{const e=s.runSync(c.make());return m.runFork(v.pipe(s.forkScoped,c.extend(e))),()=>{m.runFork(c.close(e,u.void))}}),[n,m,y,...f]),y.emit},I=(e,n)=>(i,r,o=[])=>{const a=x(r,o),d=w(i,r),l=b(i,e,n),f=t.useRef(!1),h=t.useRef(null);f.current||(h.current=s.runSync(c.make()),l.runFork(d.pipe(s.forkScoped,c.extend(h.current))),f.current=!0),t.useEffect((()=>(f.current||(h.current=s.runSync(c.make()),l.runFork(d.pipe(s.forkScoped,c.extend(h.current)))),()=>{l.runFork(c.close(h.current,u.void)),f.current=!1})),[n,l,...a])};class O{constructor(){this.instances=new Map,this.contextToId=new Map,this.disposalTimeouts=new Map,this.listeners=new Map,this.loggers=new Map}static of(){return new O}log(e,t){e.debug}updateTimeout(e){const t=this.disposalTimeouts.get(e.id);t&&(clearTimeout(t),this.disposalTimeouts.delete(e.id),this.log(e,`cleared disposal timeout for ${e.id}`))}createTimeout(e,t){const n=setTimeout((()=>{t.dispose(),this.disposalTimeouts.delete(e.id),this.log(e,`disposed runtime after TTL for ${e.id}`)}),t.config.postUnmountTTL);this.disposalTimeouts.set(e.id,n)}createInstance(e,t){return this.log(t,`instantiating runtime ${t.id}`),Object.assign(i.make(e),{id:t.id,config:t})}onMount(e,t,n={notify:!0,update:!1}){const s=this.contextToId.get(e);if(this.updateTimeout(t),s&&s!==t.id){const i=this.instances.get(s);if(t.fresh&&i&&!i.isDisposed){this.log(t,`creating runtime with fresh:true for ${t.id}, replacing ${s}`);const r=this.createInstance(e.layer,t);n.notify&&this.notifyById(t.id),"dispose"===t.disposeStrategy&&(setTimeout((()=>{i.dispose(),i.isDisposed=!0}),0),this.instances.set(t.id,r),this.contextToId.set(e,t.id),this.log(t,`disposed previous instance ${s}`))}else n.update&&(this.log(t,`reused existing runtime for ${s}`),this.updateInstance(t.id,t))}if(!this.instances.has(t.id)){this.log(t,`creating new runtime for ${t.id}`);const n=this.createInstance(e.layer,t);this.instances.set(t.id,n),this.contextToId.set(e,t.id)}}onUnmount(e,t){const n=this.instances.get(t.id);n&&(this.log(t,`scheduled disposal for ${t.id}`),this.createTimeout(t,n))}updateInstance(e,t){const n=this.instances.get(e);n&&(n.config=t,this.log(t,`updated config for ${e}`))}subscribe(e,t){return this.instances.get(t.id)||this.onMount(e,t,{notify:!1}),e=>(this.log(t,`subscribed ${t.id}`),this.listeners.set(t.id,e),()=>{this.listeners.delete(t.id),this.log(t,`unsubscribed ${t.id}`)})}getSnapshot(e){return()=>this.instances.get(e)}getByInstanceId(e){return this.instances.get(e)}getByRuntimeCtx(e){const t=this.contextToId.get(e);return t?this.instances.get(t):void 0}notifyById(e){const t=this.listeners.get(e);t&&t()}notifyAll(){this.listeners.forEach((e=>e()))}disposeAll(){this.instances.forEach((e=>{e.dispose()})),this.instances.clear(),this.contextToId.clear(),this.listeners.clear(),this.disposalTimeouts.forEach(clearTimeout),this.disposalTimeouts.clear()}}const $=O.of(),j=(e,n)=>{const s=t.useRef(n),i=t.useRef(!1);if(!$)throw new Error("[useRuntimeInstance] Store is not initialized.");t.useEffect((()=>(i.current&&($.onMount(e,n,{notify:!0,update:!1}),i.current=!1),()=>{$.onUnmount(e,n),i.current=!0})),[e]),l(s.current,n)||($.updateInstance(n.id,n),s.current=n);const r=t.useSyncExternalStore($.subscribe(e,s.current),$.getSnapshot(s.current.id));if(!r)throw new Error(`[useRuntimeInstance] Runtime for ID "${n.id}" could not be initialized.`);return r},R="__runtimes",M="__component",S="__props",k="__upstream",P={componentName:"Runtime",debug:!1,postUnmountTTL:1e3,env:"production"===process.env.NODE_ENV?"prod":"dev",disposeStrategy:"unmount",fresh:!1,id:n()},F=e=>e[R]??[];const N=(s,i)=>function(r,o){return c=>{const u=c[M]??c;const a=F(c),d=n(),l={context:r,configFn:o,id:d,type:s},f=v(c),h=t.memo((n=>{const s=function(e,t){const n=[],s=new Set;return function i(r,o){if(s.has(r))return;s.add(r);const c=F(r);(r===e?c.concat(t):c).forEach(((e,s)=>{n.push(Object.assign({},e,{level:o,index:s}));const r=e.context!==t.context?e.context.reference():void 0;r&&i(r,o+1)}))}(e,0),n.sort(((e,t)=>e.level!==t.level?t.level-e.level:e.index-t.index))}(c,l),r=new Map,o=new Map;s.filter((e=>"runtime"===e.type&&0!==e.level)).forEach((({context:e})=>{const n=t.use(e.context);n&&(o.set(e.context,n),r.set(e.context,n))}));let a={},d=0;s.filter((e=>!o.has(e.context.context))).forEach((e=>{const{context:s,configFn:o,type:c}=e;e.level<d&&(a={}),d=e.level;const l=Object.assign({},P,{...e.context.context.config,componentName:p(u,"Runtime"),id:0===e.level?n.id??e.id:e.id}),f=n=>{const i=Object.assign({},l,n??{}),o=j(e.context.context,i);return r.set(s.context,o),{runtime:o,use:(c=s.context,u=r,(e,n,s=[])=>{const i=x(n,s),r=w(e,n),o=b(e,c,u);return t.useMemo((()=>o.runSync(r)),[u,o,...i])}),useFn:T(s.context,r),useRun:I(s.context,r)};var c,u};if("upstream"===c&&"prod"!==l.env){if(!r.get(s.context)){const t=j(e.context.context,l);r.set(s.context,t)}}if(o){const t=new Proxy({},{get(e,t){if("configure"===t)return f;if("runtime"===t)return f();throw new Error(function(e,t){return`[${e}] Invalid destructure "${String(t)}". Use "runtime" or "configure".`}(i,t))}}),s=Object.assign({},a,0===e.level?n:{}),r=new Proxy(s,{get:(e,t)=>e[t]}),c=o(t,r);0===e.level&&c&&Object.assign(a,c)}else"runtime"===c&&f()}));const f=Object.assign(a,n),h=y(u,f)??n.children??null;return s.filter((e=>"runtime"===e.type)).reduceRight(((t,{context:{context:n}})=>o.get(n)?t:e(n.Provider,{value:r.get(n),children:t})),h)}));return h.displayName=p(c,i),g(f,h),((e,t)=>{e[M]=t})(h,u),((e,t)=>{e[R]=t})(h,a.concat(l)),h}};const A=N("runtime","withRuntime");function _(e,t){return A(e,t)}const D=N("upstream","withUpstream");function C(e,t){return D(e,t)}function L(e){return t=>(g(e,t),t)}const Q=e=>n=>({context:t.createContext(void 0),layer:n,...e(n)}),U=e=>n=>{const s=t.createContext(void 0);return Object.assign(s,{layer:n,config:e})},B=(e,t=a)=>r(e,s.andThen(t));export{M as COMPONENT_PROP,S as PROPS_PROP,R as RUNTIME_PROP,k as UPSTREAM_PROP,g as copyStaticProperties,y as createElement,U as createRuntimeContext,Q as createRuntimeContext2,v as extractMeta,B as fromLayer,p as getDisplayName,h as isReactContext,f as isReactContext2,_ as withRuntime,L as withStatic,C as withUpstream}; //# sourceMappingURL=index.esm.min.js.map