@jucie.io/engine-message 1.0.10 → 1.0.13
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/README.md +1 -1
- package/dist/main.js +5 -5
- package/dist/main.js.map +4 -4
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ const engine = Engine.create()
|
|
|
46
46
|
Define typed events using the `defineEvents` function:
|
|
47
47
|
|
|
48
48
|
```javascript
|
|
49
|
-
import { defineEvents } from '@
|
|
49
|
+
import { defineEvents } from '@jucie.io/message';
|
|
50
50
|
|
|
51
51
|
const userEvents = defineEvents('user', () => ({
|
|
52
52
|
login: ['String', 'String'], // username, password
|
package/dist/main.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
var M=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var ue=Object.freeze(Object.create(null));function _(r,e,t="value"){if(Array.isArray(e)){for(let s of e)if(L(r,s))return!0;let n=e.map(N).join(" | ");throw new TypeError(`${t} must be one of: ${n}. Got ${N(r)}`)}if(!L(r,e))throw new TypeError(`${t} must be ${N(e)}. Got ${N(r)}`);return!0}function L(r,e){return e===String?typeof r=="string":e===Number?typeof r=="number"&&!isNaN(r):e===Boolean?typeof r=="boolean":e===Symbol?typeof r=="symbol":e===BigInt?typeof r=="bigint":e===Function?typeof r=="function":e===Array?Array.isArray(r):e===Object?r!==null&&typeof r=="object"&&!Array.isArray(r):r instanceof e}function N(r){return r===String?"String":r===Number?"Number":r===Boolean?"Boolean":r===Array?"Array":r===Object?"Object":r===Function?"Function":r===Date?"Date":r===RegExp?"RegExp":r===Promise?"Promise":r===Map?"Map":r===Set?"Set":r===WeakMap?"WeakMap":r===WeakSet?"WeakSet":r===Symbol?"Symbol":r===BigInt?"BigInt":r===Error?"Error":typeof r=="string"?"string":typeof r=="number"?"number":typeof r=="boolean"?"boolean":typeof r=="symbol"?"symbol":typeof r=="bigint"?"bigint":typeof r=="function"?"function":Array.isArray(r)?"Array":r===null?"null":r===void 0?"undefined":typeof r=="object"?r.constructor?.name||"Object":"unknown"}function A(r,e="value"){return t=>_(t,r,e)}var C=new Map,H=new WeakMap;var y=(r,e=[])=>{let t=e.length>0?A(e,"return value"):null;if(C.has(r))return console.warn(`Definition type "${r}" already exists`),C.get(r);let n=(s,i,...a)=>{A(String,"name")(s),A(Function,"factory")(i);let l=(...o)=>{try{let c=[...o,...a],f=i(...c);if(t&&f===void 0)throw new Error(`Factory ${r} must return a value for ${s}`);return t&&t(f),f}catch(c){throw console.error(`Error creating definition "${s}"`,c),c}};return Object.defineProperty(l,"_name",{value:s,enumerable:!1,configurable:!1}),H.set(l,r),l};return C.set(r,n),n};var Q=new Set(["__proto__","prototype","constructor"]),ee=new Set(["use","install","uninstall","relay","state","debug"]),D=64,te=/^[a-zA-Z_$][a-zA-Z_$0-9]*$/;function re(r,e="key"){if(Q.has(r))throw new Error(`Illegal key "${r}" in ${e}`)}function O(r){if(re(r,"namespace"),typeof r!="string")throw new Error(`Namespace must be a string, got ${typeof r}`);if(!te.test(r))throw new Error(`Invalid namespace "${r}". Must be a valid JS identifier`);if(r.length>D)throw new Error(`Namespace "${r}" too long (max ${D} chars)`);if(ee.has(r))throw new Error(`Namespace "${r}" is reserved`);return r}var R=y("MIDDLEWARE",[Function,Array]),$=y("ACTIONS",[Object]),I=y("UNINSTALL"),k=y("INITIALIZE"),j=y("GETTERS",[Object]);var T=class r{static create(e){return new r(e)}#e;#t;#r={MIDDLEWARE:null,GETTERS:null,ACTIONS:null,INITIALIZE:null,UNINSTALL:null};constructor(e){this.#e=e}#n(e,t,n){if(this.#r[e])throw new Error(`${e} already defined for ${this.#e}`);this.#r[e]=n(this.#e,t)}defineMiddleware=e=>this.#n("MIDDLEWARE",e,R);defineGetters=e=>this.#n("GETTERS",e,j);defineActions=e=>this.#n("ACTIONS",e,$);defineInitialize=e=>this.#n("INITIALIZE",e,k);defineUninstall=e=>this.#n("UNINSTALL",e,I);_toArray(){return[this.#r.MIDDLEWARE,this.#r.GETTERS,this.#r.ACTIONS,this.#r.INITIALIZE,this.#r.UNINSTALL].filter(Boolean)}};var E=class r{static#e=new Set;static manifest={name:"base",dependencies:[],version:"1.0.0",description:"Base extension template"};static config=null;static unique=!1;static configure(e={}){return{install:(t,n)=>this.install(t,n),manifest:this.manifest,config:{...this.config||this.manifest.defaults||{},...e},unique:!0,configured:!0}}static install(e,t){try{let{namespace:n}=this.manifest;O(n);let s=new this;r.#e.add(s),Object.defineProperty(s,"config",{value:Object.freeze({...t}),writable:!1,configurable:!1,enumerable:!1}),Object.defineProperty(s,"context",{get:()=>e(),configurable:!1,enumerable:!1}),Object.defineProperty(s,"useContext",{value:(...a)=>e(...a),writable:!1,configurable:!1,enumerable:!1});let i=T.create(n);if(s.setup){let a={defineActions:o=>i.defineActions(()=>o(e,t)),defineMiddleware:o=>i.defineMiddleware(()=>o(e,t)),defineGetters:o=>i.defineGetters(()=>o(e,t)),defineInitialize:o=>i.defineInitialize(()=>o(e,t)),defineUninstall:o=>i.defineUninstall(()=>o(e,t))},l=s.setup(a);return l?.then?l.then(()=>i._toArray()):i._toArray()}return s.middleware&&i.defineMiddleware(()=>s.middleware(e,t)),s.getters&&i.defineGetters(()=>s.getters(e,t)),s.actions&&i.defineActions(()=>s.actions(e,t)),s.initialize&&i.defineInitialize(()=>s.initialize(e,t)),s.uninstall&&i.defineUninstall(()=>s.uninstall(e,t)),i._toArray()}catch(n){throw n}}};var ct=Symbol("jucie.engine");var q=(r,e)=>setTimeout(()=>{r(new Error("Timeout waiting for connect"))},e);import W from"crypto";var z="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var ie=128,g,m,oe=r=>{!g||g.length<r?(g=Buffer.allocUnsafe(r*ie),W.randomFillSync(g),m=0):m+r>g.length&&(W.randomFillSync(g),m=0),m+=r};var S=(r=21)=>{oe(r|=0);let e="";for(let t=m-r;t<m;t++)e+=z[g[t]&63];return e};var b=class r{static get EVENTS(){return{CONNECT:"CONNECT",CONFIRM_CONNECT:"CONFIRM_CONNECT",RESPONSE:"RESPONSE",ENABLE:"ENABLE",ERROR:"ERROR",MESSAGE:"MESSAGE",WARNING:"WARNING",INFO:"INFO",DEBUG:"DEBUG",TRACE:"TRACE"}}static defaultOptions={primary:!1,maxRetries:10,baseDelay:200,maxDelay:2e3,jitter:.2};#e=null;#t=!1;#r=null;#n=new Map;#s=new Map;#i=1e3;get enabled(){return this.#t}static connect({port:e,options:t={}}){t={...r.defaultOptions,...t};let n=S();return new Promise((s,i)=>{let a=0,l=null,o=!1,c=()=>{l&&clearTimeout(l);try{e.onmessage=null}catch{}try{e.onerror=null}catch{}};if(t.primary){if(e.onmessage=f=>{let h=f?.data;if(!Array.isArray(h)||h.length<2)return;let[u,p]=h;if(u===r.EVENTS.CONNECT)try{e.postMessage([r.EVENTS.CONFIRM_CONNECT,{rid:p?.rid,sid:p?.sid}]),o=!0,s(new r(e,p?.sid))}catch(w){c(),i(w)}},e.onerror=f=>{o||(o=!0,c(),i(f))},typeof e.start=="function")try{e.start()}catch{}}else{let f=()=>{if(a>=t.maxRetries){o||(c(),i(new Error("Max retries reached")));return}let u=Math.min(t.baseDelay*2**a,t.maxDelay),p=Math.floor(u*t.jitter*Math.random());l=setTimeout(h,u+p)},h=()=>{a+=1;try{e.postMessage([r.EVENTS.CONNECT,{rid:S(),sid:n}])}catch(u){c(),i(u);return}f()};if(e.onmessage=u=>{let p=u?.data;if(!Array.isArray(p)||p.length<2)return;let[w,x]=p;if(!(!x?.sid||!x?.rid))switch(w){case r.EVENTS.CONFIRM_CONNECT:{if(o)return;o=!0,c(),s(new r(e,x?.sid));break}case r.EVENTS.ERROR:{if(o)return;o=!0,c(),i(new Error("Handshake error"));break}default:break}},e.onerror=u=>{o||(o=!0,c(),i(u))},typeof e.start=="function")try{e.start()}catch{}h()}})}constructor(e,t=S()){if(e){if(typeof e.postMessage!="function")throw new Error("Port must be an object with postMessage");this.#e=e,this.#r=t,this.#e.onmessage=n=>this.#h(n),this.#e.onerror=n=>this.#d(n),this.#t=!0,typeof this.#e.start=="function"&&this.#e.start()}}close(){this.#e&&(this.#e.onmessage=null,this.#e.onerror=null,typeof this.#e.stop=="function"&&this.#e.stop(),typeof this.#e.close=="function"&&this.#e.close());for(let[,e]of this.#n)e.timeout&&clearTimeout(e.timeout),e.reject?.(new Error("Port closed"));this.#n.clear(),this.#e=null,this.#t=!1,this.#s.clear()}emit(e){return this.#e?this.#t?this.#c(e):Promise.resolve(null):Promise.reject(new Error("No port available"))}request(e){return this.#e?this.#t?this.#o(r.EVENTS.MESSAGE,e):Promise.resolve(null):Promise.reject(new Error("No port available"))}async enable(){return this.#e?(this.#t=await this.#o(r.EVENTS.ENABLE,!0),this.#t):Promise.reject(new Error("No port available"))}async disable(){return this.#e?(this.#t=await this.#o(r.EVENTS.ENABLE,!1),this.#t):Promise.reject(new Error("No port available"))}onMessage(e){if(typeof e!="function")throw new Error("Listener must be a function");if(this.#s.has(r.EVENTS.MESSAGE))throw new Error("A listener is already registered. Remove the existing listener before adding a new one.");return this.#s.set(r.EVENTS.MESSAGE,e),()=>{this.#s.get(r.EVENTS.MESSAGE)===e&&this.#s.delete(r.EVENTS.MESSAGE)}}onEnable(e){if(typeof e!="function")throw new Error("Listener must be a function");return this.#s.set(r.EVENTS.ENABLE,e),()=>this.#s.delete(r.EVENTS.ENABLE)}onError(e){if(typeof e!="function")throw new Error("Listener must be a function");if(this.#s.has(r.EVENTS.ERROR))throw new Error("A listener is already registered. Remove the existing listener before adding a new one.");return this.#s.set(r.EVENTS.ERROR,e),()=>this.#s.delete(r.EVENTS.ERROR)}#c(e){try{return this.#a(r.EVENTS.MESSAGE,{sid:this.#r,rid:null,payload:e})}catch(t){return Promise.reject(t)}}#o(e,t){return new Promise((n,s)=>{try{let i=S(),a=q(()=>{this.#n.delete(i),s(new Error("Request timeout"))},this.#i);this.#n.set(i,{resolve:n,reject:s,timeout:a}),this.#a(e,{sid:this.#r,rid:i,payload:t})}catch(i){s(i)}})}#h(e){let t=e?.data;if(!Array.isArray(t)||t.length<2)return;let[n,s]=t||[];if(!(s?.sid&&s.sid!==this.#r))switch(n){case r.EVENTS.RESPONSE:this.#f(s?.rid,s?.payload,"resolve");return;case r.EVENTS.ERROR:let i=s?.payload instanceof Error?s.payload.message:String(s?.payload);this.#f(s?.rid,new Error(i),"reject");return;case r.EVENTS.MESSAGE:this.#l(s?.rid,s?.payload);return;case r.EVENTS.ENABLE:this.#u(s?.rid,s?.payload);return;default:return}}async#l(e,t){try{let n=this.#s.get(r.EVENTS.MESSAGE),s=n?await n(t):null;return e?this.#a(r.EVENTS.RESPONSE,{rid:e,payload:s??null}):void 0}catch(n){let s=n instanceof Error?n.message:String(n);this.#a(r.EVENTS.ERROR,{rid:e,payload:s})}}#f(e,t,n){let s=this.#n.get(e);s&&(s.timeout&&clearTimeout(s.timeout),this.#n.delete(e),n==="resolve"?s.resolve(t):s.reject(t))}#u(e,t){this.#t=t;let n=this.#s.get(r.EVENTS.ENABLE);return n&&n(t),this.#a(r.EVENTS.RESPONSE,{rid:e,payload:t})}#a(e,t){return this.#e?.postMessage?.([e,t]),!0}#d(e){console.error("onerror",e)}};function ae(){return typeof window>"u"&&typeof global<"u"}function Y(){if(ae())try{if(typeof M<"u"){let{MessageChannel:r}=M("worker_threads");return new r}else throw new Error("require not available")}catch{return console.warn("worker_threads not available, falling back to global MessageChannel"),new MessageChannel}else return new MessageChannel}var d={HANDSHAKE:"HANDSHAKE",MESSAGE:"MESSAGE",SUBSCRIBE:"SUBSCRIBE",UNSUBSCRIBE:"UNSUBSCRIBE"};var P=class extends E{#e=new Map;#t=new Map;#r={};#n="development";static manifest={name:"Message Bus",description:"A message bus for the engine",namespace:"messageBus",version:"1.0.0",defaults:{mode:"development",schemas:[]}};initialize(e,t){this.#n=t.mode||"development",this.#r=t.schemas.map(n=>[n._name,n()])}actions(e,t){return{createChannel:(n,s)=>{try{if(!n)throw new Error("Channel name is required");let i=Y();return this.#s(n,i.port1,s),i.port2}catch(i){throw console.error("MessageBus error:",i),i.message==="Channel name is required"?i:new Error("Failed to create port")}},useChannel:(n,s,i)=>{if(!n)throw new Error("Channel name is required");if(!s)throw new Error("Channel port is required");this.#s(n,s,i)},disableChannel:n=>{if(n&&this.#t.has(n))return this.#t.get(n).disable()},enableChannel:n=>{if(n&&this.#t.has(n))return this.#t.get(n).enable()},isChannelActive:n=>{if(n&&this.#t.has(n))return this.#t.get(n).enabled}}}async#s(e,t,n=null){let s=await b.connect({port:t,options:{primary:!0}});return n&&n(),this.#t.set(e,s),s.onMessage(async i=>await this.#i(i,s)),s.onError(i=>this.#c(i,s)),s}async#i(e,t){try{let[n,s,i,a]=e,l=null;for(let[o,c]of this.#t.entries())if(c===t){l=o;break}switch(n){case d.MESSAGE:if(!a||Array.isArray(a)&&a.length===0){let o=[];for(let c of this.#t.values())if(c!==t&&this.#e.get(c)?.has(s)){let f=await c?.request([n,s,i,null,l]);f!==void 0&&o.push(f)}return o.length===0?null:o.length===1?o[0]:o}if(Array.isArray(a)){let o=[];for(let c of a){let f=this.#t.get(c);if(!(!f||f===t)&&this.#e.get(f)?.has(s)){let h=await f?.request([n,s,i,[c],l]);h!==void 0&&o.push(h)}}return o.length===0?null:o.length===1?o[0]:o}break;case d.SUBSCRIBE:this.#e.has(t)||this.#e.set(t,new Set),this.#e.get(t)?.add(s);break;case d.UNSUBSCRIBE:this.#e.get(t)?.delete(s);break}}catch(n){(this.#n==="development"||this.#n!=="test"&&!n.message?.includes("Request timeout"))&&console.error("MessageBus message error:",n)}}#c(e,t){console.error("MessageBus error:",e)}};function V(r,e){let t=new Set;return r.map(n=>{for(let s=0;s<e.length;s++)if(!t.has(s)&&ce(e[s],n))return t.add(s),e[s]})}function ce(r,e){if(r==null)return!1;switch(e){case String:return typeof r=="string"||r instanceof String;case Number:return typeof r=="number"||r instanceof Number;case Boolean:return typeof r=="boolean"||r instanceof Boolean;case Array:return Array.isArray(r);case Object:{let t=Object.getPrototypeOf(r);return t===Object.prototype||t===null}case Function:return typeof r=="function";default:try{return r instanceof e}catch{return!1}}}var le=y("channelContracts",[Object]),B=class extends E{#e=null;#t=null;#r=new Map;#n=[];#s=!1;#i={enable:new Set,disable:new Set,connect:new Set};static manifest={name:"Channel",dependencies:[],version:"1.0.0",namespace:"channel",description:"Channel extension for message passing between systems",defaults:{port:null,subscriptions:[]}};initialize(e,t){if(this.#t=t.port,t.subscriptions&&t.subscriptions.length)for(let n of t.subscriptions)this.#n.push(n)}actions(){let e={ready:()=>this.#s,connect:async(...t)=>{try{let[n,s]=V([MessagePort,Function],t);if(this.#t=n||this.#t,!this.#t)throw new Error("Message port is required");if(s&&typeof s=="function"&&this.#i.connect.add(s),this.#e=await b.connect({port:this.#t}),this.#a("CONNECT",!0,e),this.#s=!0,this.#n.length>0)for(let i of this.#n)this.#c(i);return this.#e.onMessage(async i=>await this.#u(i)),this.#e.onEnable(i=>this.#a("ENABLE",i,e)),this.#e.onError(this.#d),e}catch(n){return console.error("Channel error:",n),!1}},onEnable:t=>{if(typeof t!="function")throw new Error("Listener must be a function");return this.#i.enable.add(t),()=>this.#i.enable.delete(t)},onDisable:t=>{if(typeof t!="function")throw new Error("Listener must be a function");return this.#i.disable.add(t),()=>this.#i.disable.delete(t)},use:(...t)=>{if(this.#s){for(let n of t)this.#c(n);return e}for(let n of t)this.#n.push(n);return e},publish:(t,...n)=>(this.#l(d.MESSAGE,t,n),e),request:(t,...n)=>this.#f(d.MESSAGE,t,n),subscribe:(t,n)=>this.#o(t,void 0,n,!1),subscribeOnce:(t,n)=>this.#o(t,void 0,n,!0),unsubscribe:(t,n)=>this.#h(t,n),to:(...t)=>({publish:(n,...s)=>{this.#l(d.MESSAGE,n,s,t)}}),namespace:t=>({publish:(n,...s)=>{let i=t?`${t}/${n}`:n;return this.#l(d.MESSAGE,i,s),e},request:(n,...s)=>{let i=t?`${t}/${n}`:n;return this.#f(d.MESSAGE,i,s)},subscribe:(n,s)=>{let i=t?`${t}/${n}`:n;return this.#o(i,void 0,s,!1),e},subscribeOnce:(n,s)=>{let i=t?`${t}/${n}`:n;return this.#o(i,void 0,s,!0),e},unsubscribe:(n,s)=>{let i=t?`${t}/${n}`:n;return this.#h(i,s),e}})};return e}#c(e){if(e&&typeof e=="function"){let t=e._name,n=e(this.useContext),s=Object.entries(n);for(let[i,a]of s){let{handler:l,schema:o,namespace:c,once:f}=a,h=c?`${c}/${t}:${i}`:`${t}:${i}`,u=(...p)=>{try{return l(...p)}catch(w){console.error(`Errow with ${h}:`,w)}};this.#o(h,o,u,f)}}}#o(e,t,n,s=!1){this.#r.has(e)||this.#r.set(e,new Set);let i={event:e,schema:t,subscriber:n,once:s};return this.#r.get(e).add(i),this.#e.emit([d.SUBSCRIBE,e]),()=>this.#r.get(e).delete(i)}#h(e,t){if(!this.#r.has(e))return;let n=this.#r.get(e);for(let s of n.values())if(s.subscriber===t)return n.delete(s),t}#l(e,t,n,s=null){this.#e.emit([e,t,n,s])}#f(e,t,n,s=null){return this.#e.request([e,t,n,s])}#u=async([e,t,n,s,i])=>{let a=[];switch(e){case d.MESSAGE:let l=this.#r.get(t);if(l)for(let o of l){if(!this.#p(t,n,o.schema))continue;let c=await o.subscriber(...n);a.push(c),o.once&&this.#r.get(t).delete(o)}break}return a.length===1?a[0]:a.length>1?a:null};#a=(e,t,n)=>{switch(e){case"ENABLE":t===!0?this.#i.enable.forEach(s=>s(n)):this.#i.disable.forEach(s=>s(n));break;case"CONNECT":this.#i.connect.forEach(s=>s(n));break}};#d=e=>{console.error("Channel error:",e)};#p(e,t,n){if(n===void 0||n==="*"||n===null||t===void 0)return!0;if(Array.isArray(n)){if(n.length===1&&n[0]==="*")return!0;let s=n.length,i=t.length;if(s!==i)return console.warn(`
|
|
1
|
+
var N=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});import{ServiceProvider as P}from"@jucie.io/engine";var M=(n,e)=>setTimeout(()=>{n(new Error("Timeout waiting for connect"))},e);import R from"crypto";var C="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var B=128,p,m,V=n=>{!p||p.length<n?(p=Buffer.allocUnsafe(n*B),R.randomFillSync(p),m=0):m+n>p.length&&(R.randomFillSync(p),m=0),m+=n};var w=(n=21)=>{V(n|=0);let e="";for(let t=m-n;t<m;t++)e+=C[p[t]&63];return e};var S=class n{static get EVENTS(){return{CONNECT:"CONNECT",CONFIRM_CONNECT:"CONFIRM_CONNECT",RESPONSE:"RESPONSE",ENABLE:"ENABLE",ERROR:"ERROR",MESSAGE:"MESSAGE",WARNING:"WARNING",INFO:"INFO",DEBUG:"DEBUG",TRACE:"TRACE"}}static defaultOptions={primary:!1,maxRetries:10,baseDelay:200,maxDelay:2e3,jitter:.2};#e=null;#t=!1;#s=null;#n=new Map;#r=new Map;#i=1e3;get enabled(){return this.#t}static connect({port:e,options:t={}}){t={...n.defaultOptions,...t};let r=w();return new Promise((s,i)=>{let u=0,l=null,o=!1,a=()=>{l&&clearTimeout(l);try{e.onmessage=null}catch{}try{e.onerror=null}catch{}};if(t.primary){if(e.onmessage=c=>{let h=c?.data;if(!Array.isArray(h)||h.length<2)return;let[f,d]=h;if(f===n.EVENTS.CONNECT)try{e.postMessage([n.EVENTS.CONFIRM_CONNECT,{rid:d?.rid,sid:d?.sid}]),o=!0,s(new n(e,d?.sid))}catch(b){a(),i(b)}},e.onerror=c=>{o||(o=!0,a(),i(c))},typeof e.start=="function")try{e.start()}catch{}}else{let c=()=>{if(u>=t.maxRetries){o||(a(),i(new Error("Max retries reached")));return}let f=Math.min(t.baseDelay*2**u,t.maxDelay),d=Math.floor(f*t.jitter*Math.random());l=setTimeout(h,f+d)},h=()=>{u+=1;try{e.postMessage([n.EVENTS.CONNECT,{rid:w(),sid:r}])}catch(f){a(),i(f);return}c()};if(e.onmessage=f=>{let d=f?.data;if(!Array.isArray(d)||d.length<2)return;let[b,g]=d;if(!(!g?.sid||!g?.rid))switch(b){case n.EVENTS.CONFIRM_CONNECT:{if(o)return;o=!0,a(),s(new n(e,g?.sid));break}case n.EVENTS.ERROR:{if(o)return;o=!0,a(),i(new Error("Handshake error"));break}default:break}},e.onerror=f=>{o||(o=!0,a(),i(f))},typeof e.start=="function")try{e.start()}catch{}h()}})}constructor(e,t=w()){if(e){if(typeof e.postMessage!="function")throw new Error("Port must be an object with postMessage");this.#e=e,this.#s=t,this.#e.onmessage=r=>this.#h(r),this.#e.onerror=r=>this.#E(r),this.#t=!0,typeof this.#e.start=="function"&&this.#e.start()}}close(){this.#e&&(this.#e.onmessage=null,this.#e.onerror=null,typeof this.#e.stop=="function"&&this.#e.stop(),typeof this.#e.close=="function"&&this.#e.close());for(let[,e]of this.#n)e.timeout&&clearTimeout(e.timeout),e.reject?.(new Error("Port closed"));this.#n.clear(),this.#e=null,this.#t=!1,this.#r.clear()}emit(e){return this.#e?this.#t?this.#u(e):Promise.resolve(null):Promise.reject(new Error("No port available"))}request(e){return this.#e?this.#t?this.#o(n.EVENTS.MESSAGE,e):Promise.resolve(null):Promise.reject(new Error("No port available"))}async enable(){return this.#e?(this.#t=await this.#o(n.EVENTS.ENABLE,!0),this.#t):Promise.reject(new Error("No port available"))}async disable(){return this.#e?(this.#t=await this.#o(n.EVENTS.ENABLE,!1),this.#t):Promise.reject(new Error("No port available"))}onMessage(e){if(typeof e!="function")throw new Error("Listener must be a function");if(this.#r.has(n.EVENTS.MESSAGE))throw new Error("A listener is already registered. Remove the existing listener before adding a new one.");return this.#r.set(n.EVENTS.MESSAGE,e),()=>{this.#r.get(n.EVENTS.MESSAGE)===e&&this.#r.delete(n.EVENTS.MESSAGE)}}onEnable(e){if(typeof e!="function")throw new Error("Listener must be a function");return this.#r.set(n.EVENTS.ENABLE,e),()=>this.#r.delete(n.EVENTS.ENABLE)}onError(e){if(typeof e!="function")throw new Error("Listener must be a function");if(this.#r.has(n.EVENTS.ERROR))throw new Error("A listener is already registered. Remove the existing listener before adding a new one.");return this.#r.set(n.EVENTS.ERROR,e),()=>this.#r.delete(n.EVENTS.ERROR)}#u(e){try{return this.#a(n.EVENTS.MESSAGE,{sid:this.#s,rid:null,payload:e})}catch(t){return Promise.reject(t)}}#o(e,t){return new Promise((r,s)=>{try{let i=w(),u=M(()=>{this.#n.delete(i),s(new Error("Request timeout"))},this.#i);this.#n.set(i,{resolve:r,reject:s,timeout:u}),this.#a(e,{sid:this.#s,rid:i,payload:t})}catch(i){s(i)}})}#h(e){let t=e?.data;if(!Array.isArray(t)||t.length<2)return;let[r,s]=t||[];if(!(s?.sid&&s.sid!==this.#s))switch(r){case n.EVENTS.RESPONSE:this.#c(s?.rid,s?.payload,"resolve");return;case n.EVENTS.ERROR:let i=s?.payload instanceof Error?s.payload.message:String(s?.payload);this.#c(s?.rid,new Error(i),"reject");return;case n.EVENTS.MESSAGE:this.#l(s?.rid,s?.payload);return;case n.EVENTS.ENABLE:this.#f(s?.rid,s?.payload);return;default:return}}async#l(e,t){try{let r=this.#r.get(n.EVENTS.MESSAGE),s=r?await r(t):null;return e?this.#a(n.EVENTS.RESPONSE,{rid:e,payload:s??null}):void 0}catch(r){let s=r instanceof Error?r.message:String(r);this.#a(n.EVENTS.ERROR,{rid:e,payload:s})}}#c(e,t,r){let s=this.#n.get(e);s&&(s.timeout&&clearTimeout(s.timeout),this.#n.delete(e),r==="resolve"?s.resolve(t):s.reject(t))}#f(e,t){this.#t=t;let r=this.#r.get(n.EVENTS.ENABLE);return r&&r(t),this.#a(n.EVENTS.RESPONSE,{rid:e,payload:t})}#a(e,t){return this.#e?.postMessage?.([e,t]),!0}#E(e){console.error("onerror",e)}};function x(){return typeof window>"u"&&typeof global<"u"}function O(){if(x())try{if(typeof N<"u"){let{MessageChannel:n}=N("worker_threads");return new n}else throw new Error("require not available")}catch{return console.warn("worker_threads not available, falling back to global MessageChannel"),new MessageChannel}else return new MessageChannel}var E={HANDSHAKE:"HANDSHAKE",MESSAGE:"MESSAGE",SUBSCRIBE:"SUBSCRIBE",UNSUBSCRIBE:"UNSUBSCRIBE"};var y=class extends P{#e=new Map;#t=new Map;#s={};#n="development";static manifest={name:"Message Bus",description:"A message bus for the engine",namespace:"messageBus",version:"1.0.0",defaults:{mode:"development",schemas:[]}};initialize(e,t){this.#n=t.mode||"development",this.#s=t.schemas.map(r=>[r._name,r()])}actions(e,t){return{createChannel:(r,s)=>{try{if(!r)throw new Error("Channel name is required");let i=O();return this.#r(r,i.port1,s),i.port2}catch(i){throw console.error("MessageBus error:",i),i.message==="Channel name is required"?i:new Error("Failed to create port")}},useChannel:(r,s,i)=>{if(!r)throw new Error("Channel name is required");if(!s)throw new Error("Channel port is required");this.#r(r,s,i)},disableChannel:r=>{if(r&&this.#t.has(r))return this.#t.get(r).disable()},enableChannel:r=>{if(r&&this.#t.has(r))return this.#t.get(r).enable()},isChannelActive:r=>{if(r&&this.#t.has(r))return this.#t.get(r).enabled}}}async#r(e,t,r=null){let s=await S.connect({port:t,options:{primary:!0}});return r&&r(),this.#t.set(e,s),s.onMessage(async i=>await this.#i(i,s)),s.onError(i=>this.#u(i,s)),s}async#i(e,t){try{let[r,s,i,u]=e,l=null;for(let[o,a]of this.#t.entries())if(a===t){l=o;break}switch(r){case E.MESSAGE:if(!u||Array.isArray(u)&&u.length===0){let o=[];for(let a of this.#t.values())if(a!==t&&this.#e.get(a)?.has(s)){let c=await a?.request([r,s,i,null,l]);c!==void 0&&o.push(c)}return o.length===0?null:o.length===1?o[0]:o}if(Array.isArray(u)){let o=[];for(let a of u){let c=this.#t.get(a);if(!(!c||c===t)&&this.#e.get(c)?.has(s)){let h=await c?.request([r,s,i,[a],l]);h!==void 0&&o.push(h)}}return o.length===0?null:o.length===1?o[0]:o}break;case E.SUBSCRIBE:this.#e.has(t)||this.#e.set(t,new Set),this.#e.get(t)?.add(s);break;case E.UNSUBSCRIBE:this.#e.get(t)?.delete(s);break}}catch(r){(this.#n==="development"||this.#n!=="test"&&!r.message?.includes("Request timeout"))&&console.error("MessageBus message error:",r)}}#u(e,t){console.error("MessageBus error:",e)}};import{ServiceProvider as G,createDefinition as k}from"@jucie.io/engine";function A(n,e){let t=new Set;return n.map(r=>{for(let s=0;s<e.length;s++)if(!t.has(s)&&v(e[s],r))return t.add(s),e[s]})}function v(n,e){if(n==null)return!1;switch(e){case String:return typeof n=="string"||n instanceof String;case Number:return typeof n=="number"||n instanceof Number;case Boolean:return typeof n=="boolean"||n instanceof Boolean;case Array:return Array.isArray(n);case Object:{let t=Object.getPrototypeOf(n);return t===Object.prototype||t===null}case Function:return typeof n=="function";default:try{return n instanceof e}catch{return!1}}}var L=k("channelContracts",[Object]),T=class extends G{#e=null;#t=null;#s=new Map;#n=[];#r=!1;#i={enable:new Set,disable:new Set,connect:new Set};static manifest={name:"Channel",dependencies:[],version:"1.0.0",namespace:"channel",description:"Channel extension for message passing between systems",defaults:{port:null,subscriptions:[]}};initialize(e,t){if(this.#t=t.port,t.subscriptions&&t.subscriptions.length)for(let r of t.subscriptions)this.#n.push(r)}actions(){let e={ready:()=>this.#r,connect:async(...t)=>{try{let[r,s]=A([MessagePort,Function],t);if(this.#t=r||this.#t,!this.#t)throw new Error("Message port is required");if(s&&typeof s=="function"&&this.#i.connect.add(s),this.#e=await S.connect({port:this.#t}),this.#a("CONNECT",!0,e),this.#r=!0,this.#n.length>0)for(let i of this.#n)this.#u(i);return this.#e.onMessage(async i=>await this.#f(i)),this.#e.onEnable(i=>this.#a("ENABLE",i,e)),this.#e.onError(this.#E),e}catch(r){return console.error("Channel error:",r),!1}},onEnable:t=>{if(typeof t!="function")throw new Error("Listener must be a function");return this.#i.enable.add(t),()=>this.#i.enable.delete(t)},onDisable:t=>{if(typeof t!="function")throw new Error("Listener must be a function");return this.#i.disable.add(t),()=>this.#i.disable.delete(t)},use:(...t)=>{if(this.#r){for(let r of t)this.#u(r);return e}for(let r of t)this.#n.push(r);return e},publish:(t,...r)=>(this.#l(E.MESSAGE,t,r),e),request:(t,...r)=>this.#c(E.MESSAGE,t,r),subscribe:(t,r)=>this.#o(t,void 0,r,!1),subscribeOnce:(t,r)=>this.#o(t,void 0,r,!0),unsubscribe:(t,r)=>this.#h(t,r),to:(...t)=>({publish:(r,...s)=>{this.#l(E.MESSAGE,r,s,t)}}),namespace:t=>({publish:(r,...s)=>{let i=t?`${t}/${r}`:r;return this.#l(E.MESSAGE,i,s),e},request:(r,...s)=>{let i=t?`${t}/${r}`:r;return this.#c(E.MESSAGE,i,s)},subscribe:(r,s)=>{let i=t?`${t}/${r}`:r;return this.#o(i,void 0,s,!1),e},subscribeOnce:(r,s)=>{let i=t?`${t}/${r}`:r;return this.#o(i,void 0,s,!0),e},unsubscribe:(r,s)=>{let i=t?`${t}/${r}`:r;return this.#h(i,s),e}})};return e}#u(e){if(e&&typeof e=="function"){let t=e._name,r=e(this.useContext),s=Object.entries(r);for(let[i,u]of s){let{handler:l,schema:o,namespace:a,once:c}=u,h=a?`${a}/${t}:${i}`:`${t}:${i}`,f=(...d)=>{try{return l(...d)}catch(b){console.error(`Errow with ${h}:`,b)}};this.#o(h,o,f,c)}}}#o(e,t,r,s=!1){this.#s.has(e)||this.#s.set(e,new Set);let i={event:e,schema:t,subscriber:r,once:s};return this.#s.get(e).add(i),this.#e.emit([E.SUBSCRIBE,e]),()=>this.#s.get(e).delete(i)}#h(e,t){if(!this.#s.has(e))return;let r=this.#s.get(e);for(let s of r.values())if(s.subscriber===t)return r.delete(s),t}#l(e,t,r,s=null){this.#e.emit([e,t,r,s])}#c(e,t,r,s=null){return this.#e.request([e,t,r,s])}#f=async([e,t,r,s,i])=>{let u=[];switch(e){case E.MESSAGE:let l=this.#s.get(t);if(l)for(let o of l){if(!this.#d(t,r,o.schema))continue;let a=await o.subscriber(...r);u.push(a),o.once&&this.#s.get(t).delete(o)}break}return u.length===1?u[0]:u.length>1?u:null};#a=(e,t,r)=>{switch(e){case"ENABLE":t===!0?this.#i.enable.forEach(s=>s(r)):this.#i.disable.forEach(s=>s(r));break;case"CONNECT":this.#i.connect.forEach(s=>s(r));break}};#E=e=>{console.error("Channel error:",e)};#d(e,t,r){if(r===void 0||r==="*"||r===null||t===void 0)return!0;if(Array.isArray(r)){if(r.length===1&&r[0]==="*")return!0;let s=r.length,i=t.length;if(s!==i)return console.warn(`
|
|
2
2
|
Event:`,e,`
|
|
3
|
-
Expected:`,
|
|
4
|
-
Received:`,t.map(
|
|
3
|
+
Expected:`,r,`
|
|
4
|
+
Received:`,t.map(u=>typeof u)),!1;for(let u=0;u<s;u++){let l=r[u],o=t[u],a;if(Array.isArray(o)?a="Array":o===null?a="null":a=Object.prototype.toString.call(o).slice(8,-1),l==="Object"&&a==="Array")return console.warn(`
|
|
5
5
|
Event:`,e,`
|
|
6
|
-
Value:`,o),!1;if(l!==
|
|
6
|
+
Value:`,o),!1;if(l!==a)return console.warn(`
|
|
7
7
|
Event:`,e,`
|
|
8
|
-
Value:`,o),!1}}return!0}};export{
|
|
8
|
+
Value:`,o),!1}}return!0}};export{T as Channel,y as MessageBus,L as defineContracts};
|
|
9
9
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["
|
|
4
|
-
"sourcesContent": ["// Simple, readable relay with wildcard matching and no indexing\n\nconst GLOBAL_NS_OBJ = Object.freeze(Object.create(null));\n\nfunction queueMicrotask(fn) {\n if (globalThis.queueMicrotask && typeof globalThis.queueMicrotask === 'function') {\n globalThis.queueMicrotask(fn);\n return;\n }\n setTimeout(fn, 0);\n}\n\nclass Channel {\n #nsObj; #relay;\n constructor(nsObj, relay) { this.#nsObj = nsObj; this.#relay = relay; }\n\n // Any source -> me\n on(event, handler) {\n return this.#relay.subscribe(event, GLOBAL_NS_OBJ, this.#nsObj, handler);\n }\n\n once(event, handler) {\n return this.#relay.once(event, GLOBAL_NS_OBJ, this.#nsObj, handler);\n }\n\n // Me -> everyone (sender never hears itself)\n broadcast(event, ...payload) {\n this.#relay.publish(event, this.#nsObj, GLOBAL_NS_OBJ, payload);\n }\n\n // Specific source -> me\n from(fromNs) {\n return {\n subscribe: (event, handler) => this.#relay.subscribe(event, fromNs, this.#nsObj, handler),\n once: (event, handler) => this.#relay.once(event, fromNs, this.#nsObj, handler),\n };\n }\n\n // Me -> specific target\n to(toNs) {\n return {\n publish: (event, ...payload) => this.#relay.publish(event, this.#nsObj, toNs, payload),\n publishAsync: (event, ...payload) => this.#relay.publishAsync(event, this.#nsObj, toNs, payload),\n };\n }\n}\n\nexport class Relay {\n #channels = new WeakMap(); // nsObj -> Channel\n #events = new Map(); // eventName -> Set<Listener>\n #onError = null;\n\n static create(config = {}) {\n return new Relay(config);\n }\n\n constructor({ onError = null } = {}) {\n this.#onError = onError;\n this.createChannel(GLOBAL_NS_OBJ);\n }\n\n // Public convenience\n channel(nsObj) { return this.createChannel(nsObj); }\n createChannel(nsObj) {\n if (this.#channels.has(nsObj)) return this.#channels.get(nsObj);\n const ch = new Channel(nsObj, this);\n this.#channels.set(nsObj, ch);\n return ch;\n }\n\n // Internal helpers\n #listeners(event) {\n let set = this.#events.get(event);\n if (!set) { set = new Set(); this.#events.set(event, set); }\n return set;\n }\n\n // Wildcard matcher:\n // - If published `from` is GLOBAL, it matches every listener.from\n // - If listener.from is GLOBAL, it matches every published from\n // Same for `to`. This makes broadcast (to = GLOBAL) hit specific targets too.\n static #matchSide(published, constraint) {\n return published === GLOBAL_NS_OBJ || constraint === GLOBAL_NS_OBJ || published === constraint;\n }\n\n static #matches(publishedFrom, publishedTo, listenerFrom, listenerTo) {\n return Relay.#matchSide(publishedFrom, listenerFrom)\n && Relay.#matchSide(publishedTo, listenerTo);\n }\n\n subscribe(event, from, to, handler) {\n const listener = { from, to, handler };\n this.#listeners(event).add(listener);\n return () => {\n const set = this.#events.get(event);\n if (set) set.delete(listener);\n };\n }\n\n once(event, from, to, handler) {\n let off = null;\n const wrapped = (payload) => {\n try { handler(payload); } finally { off && off(); }\n };\n off = this.subscribe(event, from, to, wrapped);\n return off;\n }\n\n offAllFor(nsObj) {\n for (const set of this.#events.values()) {\n for (const l of Array.from(set)) {\n if (l.from === nsObj || l.to === nsObj) set.delete(l);\n }\n }\n }\n\n listenerCount(event) {\n const set = this.#events.get(event);\n return set ? set.size : 0;\n }\n\n #deliver(event, from, to, payload) {\n const set = this.#events.get(event);\n if (!set || set.size === 0) return;\n\n for (const l of set) {\n // Always skip self-delivery\n if (l.to === from) continue;\n\n if (Relay.#matches(from, to, l.from, l.to)) {\n try { l.handler(...payload); }\n catch (err) { if (this.#onError) this.#onError(err, { event, from, to, listener: l }); }\n }\n }\n }\n\n publish(event, from, to, payload) {\n this.#deliver(event, from, to, payload);\n }\n\n publishAsync(event, from, to, payload) {\n queueMicrotask(() => this.#deliver(event, from, to, payload));\n }\n\n broadcast(event, from, payload) {\n this.publish(event, from, GLOBAL_NS_OBJ, payload);\n }\n}\n", "/**\n * Type Checker Utility\n * \n * Supports syntax like:\n * - createDefinition('action', [Array, Function]) // Array or Function\n * - createDefinition('name', String) // Must be String\n * - createDefinition('items', Array) // Must be Array\n * - createDefinition('callback', Function) // Must be Function\n * - createDefinition('value', [String, Number]) // String or Number\n */\n\n/**\n * Type definitions mapping constructor names to actual constructors\n */\nconst TYPE_MAP = {\n String,\n Number,\n Boolean,\n Array,\n Object,\n Function,\n Date,\n RegExp,\n Promise,\n Map,\n Set,\n WeakMap,\n WeakSet,\n Symbol,\n BigInt,\n Error,\n TypeError,\n RangeError,\n ReferenceError,\n SyntaxError,\n EvalError,\n URIError\n};\n\n/**\n * Checks if a value matches the expected type(s)\n * @param {*} value - The value to check\n * @param {Function|Array<Function>} expectedType - Single type or array of possible types\n * @param {string} name - Name of the parameter for error messages\n * @returns {boolean} - True if value matches expected type(s)\n */\nexport function checkType(value, expectedType, name = 'value') {\n // Handle array of possible types\n if (Array.isArray(expectedType)) {\n for (const type of expectedType) {\n if (matchesType(value, type)) {\n return true;\n }\n }\n \n const typeNames = expectedType.map(getTypeName).join(' | ');\n throw new TypeError(`${name} must be one of: ${typeNames}. Got ${getTypeName(value)}`);\n }\n \n // Handle single type\n if (!matchesType(value, expectedType)) {\n throw new TypeError(`${name} must be ${getTypeName(expectedType)}. Got ${getTypeName(value)}`);\n }\n \n return true;\n}\n\n/**\n * Checks if a value matches a specific type\n * @param {*} value - The value to check\n * @param {Function} type - The expected constructor/type\n * @returns {boolean} - True if value matches the type\n */\nfunction matchesType(value, type) {\n // Handle primitive constructors\n if (type === String) {\n return typeof value === 'string';\n }\n if (type === Number) {\n return typeof value === 'number' && !isNaN(value);\n }\n if (type === Boolean) {\n return typeof value === 'boolean';\n }\n if (type === Symbol) {\n return typeof value === 'symbol';\n }\n if (type === BigInt) {\n return typeof value === 'bigint';\n }\n if (type === Function) {\n return typeof value === 'function';\n }\n \n // Handle object constructors (including Array, Object, Date, etc.)\n if (type === Array) {\n return Array.isArray(value);\n }\n if (type === Object) {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n }\n \n // Handle other constructors (Date, RegExp, Map, Set, etc.)\n return value instanceof type;\n}\n\n/**\n * Gets a human-readable name for a type\n * @param {*} value - The value or constructor to get name for\n * @returns {string} - Human-readable type name\n */\nfunction getTypeName(value) {\n if (value === String) return 'String';\n if (value === Number) return 'Number';\n if (value === Boolean) return 'Boolean';\n if (value === Array) return 'Array';\n if (value === Object) return 'Object';\n if (value === Function) return 'Function';\n if (value === Date) return 'Date';\n if (value === RegExp) return 'RegExp';\n if (value === Promise) return 'Promise';\n if (value === Map) return 'Map';\n if (value === Set) return 'Set';\n if (value === WeakMap) return 'WeakMap';\n if (value === WeakSet) return 'WeakSet';\n if (value === Symbol) return 'Symbol';\n if (value === BigInt) return 'BigInt';\n if (value === Error) return 'Error';\n \n if (typeof value === 'string') return 'string';\n if (typeof value === 'number') return 'number';\n if (typeof value === 'boolean') return 'boolean';\n if (typeof value === 'symbol') return 'symbol';\n if (typeof value === 'bigint') return 'bigint';\n if (typeof value === 'function') return 'function';\n if (Array.isArray(value)) return 'Array';\n if (value === null) return 'null';\n if (value === undefined) return 'undefined';\n if (typeof value === 'object') {\n return value.constructor?.name || 'Object';\n }\n \n return 'unknown';\n}\n\n/**\n * Creates a type checker function for a specific parameter\n * @param {Function|Array<Function>} expectedType - Expected type(s)\n * @param {string} name - Parameter name\n * @returns {Function} - Type checker function\n */\nexport function createTypeChecker(expectedType, name = 'value') {\n return (value) => checkType(value, expectedType, name);\n}\n\n/**\n * Validates an object against a schema\n * @param {Object} obj - Object to validate\n * @param {Object} schema - Schema definition { prop: Type, prop2: [Type1, Type2] }\n * @param {string} objName - Name of the object for error messages\n */\nexport function validateObject(obj, schema, objName = 'object') {\n if (!obj || typeof obj !== 'object') {\n throw new TypeError(`${objName} must be an object`);\n }\n \n for (const [prop, expectedType] of Object.entries(schema)) {\n if (prop in obj) {\n checkType(obj[prop], expectedType, `${objName}.${prop}`);\n }\n }\n}\n\n/**\n * Creates a validator function for an object schema\n * @param {Object} schema - Schema definition\n * @param {string} objName - Name of the object\n * @returns {Function} - Validator function\n */\nexport function createObjectValidator(schema, objName = 'object') {\n return (obj) => validateObject(obj, schema, objName);\n}\n\n// Export the type map for advanced usage\nexport { TYPE_MAP };\n", "const DefinitionTypes = new Map();\nconst Definitions = new WeakMap();\nimport { createTypeChecker } from '../utils/typeChecker.js';\n\n/**\n * Creates a definition type with return type validation\n * @param {string} type - The definition type name\n * @param {Function|Array<Function>} returnTypes - Expected return type(s)\n * @returns {Function} - Definition creator function\n */\n\n\nexport const definitionType = (definition) => {\n if (Definitions.has(definition)) {\n return Definitions.get(definition);\n }\n return undefined;\n}\n\nexport const createDefinition = (type, returnTypes = []) => { \n // Create type checker for return values if returnTypes specified\n const returnTypeChecker = returnTypes.length > 0 ? createTypeChecker(returnTypes, 'return value') : null;\n \n if (DefinitionTypes.has(type)) {\n console.warn(`Definition type \"${type}\" already exists`);\n return DefinitionTypes.get(type);\n }\n\n const definitionType = (name, factory, ...defaultArgs) => {\n // Validate inputs using type checker\n createTypeChecker(String, 'name')(name);\n createTypeChecker(Function, 'factory')(factory);\n\n const definition = (...args) => {\n try {\n const combinedArgs = [...args, ...defaultArgs];\n const res = factory(...combinedArgs);\n \n if (returnTypeChecker && res === undefined) {\n throw new Error(`Factory ${type} must return a value for ${name}`);\n }\n\n // Use type checker to validate return value\n if (returnTypeChecker) {\n returnTypeChecker(res);\n }\n\n return res\n } catch (error) {\n console.error(`Error creating definition \"${name}\"`, error);\n throw error;\n }\n }\n\n Object.defineProperty(definition, '_name', {\n value: name,\n enumerable: false,\n configurable: false\n });\n\n Definitions.set(definition, type);\n\n return definition;\n }\n\n DefinitionTypes.set(type, definitionType);\n\n return definitionType;\n}; ", "// utils/asserts.js\n\nconst BAD_KEYS = new Set(['__proto__', 'prototype', 'constructor']);\nconst RESERVED_NAMESPACES = new Set(['use', 'install', 'uninstall', 'relay', 'state', 'debug']);\n\nconst MAX_NAME_LENGTH = 64;\nconst VALID_NAME = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;\n\n/**\n * Throw if key is unsafe (__proto__, constructor, etc.)\n */\nexport function assertSafeKey(key, where = 'key') {\n if (BAD_KEYS.has(key)) {\n throw new Error(`Illegal key \"${key}\" in ${where}`);\n }\n}\n\n/**\n * Validate a namespace string: format, length, reserved words, proto poisoning.\n */\nexport function assertNamespace(ns) {\n assertSafeKey(ns, 'namespace');\n if (typeof ns !== 'string') {\n throw new Error(`Namespace must be a string, got ${typeof ns}`);\n }\n if (!VALID_NAME.test(ns)) {\n throw new Error(`Invalid namespace \"${ns}\". Must be a valid JS identifier`);\n }\n if (ns.length > MAX_NAME_LENGTH) {\n throw new Error(`Namespace \"${ns}\" too long (max ${MAX_NAME_LENGTH} chars)`);\n }\n if (RESERVED_NAMESPACES.has(ns)) {\n throw new Error(`Namespace \"${ns}\" is reserved`);\n }\n return ns;\n}\n\n/**\n * Validate an action or getter name within a namespace.\n */\nexport function assertMemberName(name, namespace, kind = 'member') {\n assertSafeKey(name, `${kind}:${namespace}`);\n if (typeof name !== 'string') {\n throw new Error(`${kind} name in ${namespace} must be a string`);\n }\n if (!VALID_NAME.test(name)) {\n throw new Error(`Invalid ${kind} name \"${name}\" in ${namespace}`);\n }\n if (name.length > MAX_NAME_LENGTH) {\n throw new Error(\n `${kind} name \"${name}\" in ${namespace} too long (max ${MAX_NAME_LENGTH})`\n );\n }\n return name;\n}\n", "import { createDefinition, definitionType } from './createDefinition.js';\nexport const defineMiddleware = createDefinition('MIDDLEWARE', [Function, Array]);\nexport const defineActions = createDefinition('ACTIONS', [Object]);\nexport const defineUninstall = createDefinition('UNINSTALL');\nexport const defineInitialize = createDefinition('INITIALIZE');\nexport const defineGetters = createDefinition('GETTERS', [Object]);\nexport { createDefinition, definitionType };", "// DefinitionBuilder.js\nimport { defineActions, defineGetters, defineMiddleware, defineInitialize, defineUninstall } from './defaults.js';\n\nexport class DefinitionBuilder {\n static create(namespace) {\n return new DefinitionBuilder(namespace);\n }\n\n #ns; #args;\n #slots = { MIDDLEWARE:null, GETTERS:null, ACTIONS:null, INITIALIZE:null, UNINSTALL:null };\n constructor(namespace) { this.#ns = namespace }\n\n #set(type, factory, creator) {\n if (this.#slots[type]) throw new Error(`${type} already defined for ${this.#ns}`);\n this.#slots[type] = creator(this.#ns, factory);\n }\n\n defineMiddleware = (factory) => this.#set('MIDDLEWARE', factory, defineMiddleware);\n defineGetters = (factory) => this.#set('GETTERS', factory, defineGetters);\n defineActions = (factory) => this.#set('ACTIONS', factory, defineActions);\n defineInitialize = (factory) => this.#set('INITIALIZE', factory, defineInitialize);\n defineUninstall = (factory) => this.#set('UNINSTALL', factory, defineUninstall);\n\n _toArray() {\n return [\n this.#slots.MIDDLEWARE,\n this.#slots.GETTERS,\n this.#slots.ACTIONS,\n this.#slots.INITIALIZE,\n this.#slots.UNINSTALL\n ].filter(Boolean);\n }\n}\n\n", "import { assertNamespace } from './utils/asserts.js';\nimport { DefinitionBuilder } from './definitions/DefinitionBuilder.js';\n\n\nexport class ServiceProvider {\n static #services = new Set();\n\n static manifest = {\n name: 'base',\n dependencies: [],\n version: '1.0.0',\n description: 'Base extension template',\n };\n\n static config = null;\n\n static unique = false;\n\n static configure(options = {}) {\n return {\n install: (useContext, config) => this.install(useContext, config),\n manifest: this.manifest,\n config: { ...(this.config || this.manifest.defaults || {}), ...options },\n unique: true,\n configured: true\n };\n }\n\n static install(useContext, config) { \n try {\n const {namespace} = this.manifest;\n assertNamespace(namespace);\n\n // instantiate\n const instance = new this();\n ServiceProvider.#services.add(instance);\n\n // bind context/config\n // bind config (frozen to avoid accidental mutation)\n Object.defineProperty(instance, 'config', {\n value: Object.freeze({ ...config }),\n writable: false,\n configurable: false,\n enumerable: false,\n });\n\n // expose both a live context getter AND the keyed accessor\n Object.defineProperty(instance, 'context', {\n get: () => useContext(), // always fresh, via your proxy\n configurable: false,\n enumerable: false,\n });\n \n Object.defineProperty(instance, 'useContext', {\n value: (...keys) => useContext(...keys),\n writable: false,\n configurable: false,\n enumerable: false,\n });\n\n const builder = DefinitionBuilder.create(namespace);\n\n if (instance.setup) {\n // Create properly bound context for setup pattern\n const setupContext = {\n defineActions: (factory) => builder.defineActions(() => factory(useContext, config)),\n defineMiddleware: (factory) => builder.defineMiddleware(() => factory(useContext, config)),\n defineGetters: (factory) => builder.defineGetters(() => factory(useContext, config)),\n defineInitialize: (factory) => builder.defineInitialize(() => factory(useContext, config)),\n defineUninstall: (factory) => builder.defineUninstall(() => factory(useContext, config))\n };\n const maybe = instance.setup(setupContext);\n return maybe?.then ? maybe.then(() => builder._toArray()) : builder._toArray();\n }\n\n if (instance.middleware) builder.defineMiddleware(() => instance.middleware(useContext, config));\n if (instance.getters) builder.defineGetters (() => instance.getters(useContext, config));\n if (instance.actions) builder.defineActions (() => instance.actions(useContext, config));\n if (instance.initialize) builder.defineInitialize(() => instance.initialize(useContext, config));\n if (instance.uninstall) builder.defineUninstall (() => instance.uninstall(useContext, config));\n\n return builder._toArray();\n } catch (error) {\n throw error;\n }\n }\n}", "const ENGINE_CONTEXT = Symbol('jucie.engine');\n\n/**\n * Registers the engine globally, but only if no engine has already been set.\n * @param {object} engine \n */\n\nexport function provideEngine(engine) {\n if (!globalThis[ENGINE_CONTEXT]) {\n globalThis[ENGINE_CONTEXT] = engine;\n }\n}\n\nexport function hasEngine() {\n return globalThis[ENGINE_CONTEXT] !== undefined;\n}\n\n/**\n * Forcefully override the engine in the global context.\n * Useful for testing or resetting.\n */\nexport function forceEngine(engine) {\n globalThis[ENGINE_CONTEXT] = engine;\n}\n\n/**\n * Retrieves the globally registered engine.\n */\nexport function getEngine() {\n return globalThis[ENGINE_CONTEXT] || null;\n}\n\n/**\n * Retrieves the globally registered engine.\n */\nexport function useEngine() {\n return getEngine();\n}", "export const requestTimeout = (reject, defaultTimeoutMs) => setTimeout(() => {\n reject(new Error('Timeout waiting for connect'));\n}, defaultTimeoutMs);", "import crypto from 'crypto'\nimport { urlAlphabet } from './url-alphabet/index.js'\nconst POOL_SIZE_MULTIPLIER = 128\nlet pool, poolOffset\nlet fillPool = bytes => {\n if (!pool || pool.length < bytes) {\n pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)\n crypto.randomFillSync(pool)\n poolOffset = 0\n } else if (poolOffset + bytes > pool.length) {\n crypto.randomFillSync(pool)\n poolOffset = 0\n }\n poolOffset += bytes\n}\nlet random = bytes => {\n fillPool((bytes |= 0))\n return pool.subarray(poolOffset - bytes, poolOffset)\n}\nlet customRandom = (alphabet, defaultSize, getRandom) => {\n let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1\n let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)\n return (size = defaultSize) => {\n let id = ''\n while (true) {\n let bytes = getRandom(step)\n let i = step\n while (i--) {\n id += alphabet[bytes[i] & mask] || ''\n if (id.length === size) return id\n }\n }\n }\n}\nlet customAlphabet = (alphabet, size = 21) =>\n customRandom(alphabet, size, random)\nlet nanoid = (size = 21) => {\n fillPool((size |= 0))\n let id = ''\n for (let i = poolOffset - size; i < poolOffset; i++) {\n id += urlAlphabet[pool[i] & 63]\n }\n return id\n}\nexport { nanoid, customAlphabet, customRandom, urlAlphabet, random }\n", "let urlAlphabet =\n 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\nexport { urlAlphabet }\n", "import { requestTimeout } from './utils/requestTimeout.js';\nimport { nanoid } from 'nanoid';\n\nexport class Port {\n static get EVENTS() {\n return {\n CONNECT: 'CONNECT',\n CONFIRM_CONNECT: 'CONFIRM_CONNECT',\n RESPONSE: 'RESPONSE',\n ENABLE: 'ENABLE',\n ERROR: 'ERROR',\n MESSAGE: 'MESSAGE',\n WARNING: 'WARNING',\n INFO: 'INFO',\n DEBUG: 'DEBUG',\n TRACE: 'TRACE',\n }\n }\n\n static defaultOptions = {\n primary: false,\n maxRetries: 10,\n baseDelay: 200,\n maxDelay: 2000,\n jitter: 0.2\n }\n\n #port = null;\n #enabled = false;\n #sid = null;\n // rid -> { resolve, reject, timeout }\n #pendingResponses = new Map();\n\n // Single listener by event name\n #messageListeners = new Map();\n #defaultTimeoutMs = 1000;\n\n get enabled() { return this.#enabled; }\n\n static connect({ port, options = {}}) {\n options = { ...Port.defaultOptions, ...options };\n \n let sid = nanoid();\n \n return new Promise((resolve, reject) => {\n let attempt = 0;\n let timer = null;\n let resolved = false;\n \n const cleanup = () => {\n if (timer) clearTimeout(timer);\n try { port.onmessage = null; } catch {}\n try { port.onerror = null; } catch {}\n };\n\n if (options.primary) {\n // PRIMARY MODE: Listen for connections\n port.onmessage = (e) => {\n const msg = e?.data;\n \n if (!Array.isArray(msg) || msg.length < 2) return;\n\n const [EVENT_TYPE, MSG] = msg;\n if (EVENT_TYPE === Port.EVENTS.CONNECT) {\n // Secondary is trying to connect\n try {\n port.postMessage([\n Port.EVENTS.CONFIRM_CONNECT,\n { rid: MSG?.rid, sid: MSG?.sid }\n ]);\n \n resolved = true;\n resolve(new Port(port, MSG?.sid));\n } catch (err) {\n cleanup();\n reject(err);\n }\n }\n };\n\n port.onerror = (err) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(err);\n };\n\n if (typeof port.start === 'function') {\n try { port.start(); } catch {}\n }\n\n } else {\n // SECONDARY MODE: Initiate connection with retries\n const scheduleNext = () => {\n if (attempt >= options.maxRetries) {\n if (!resolved) {\n cleanup();\n reject(new Error('Max retries reached'));\n }\n return;\n }\n const delay = Math.min(options.baseDelay * (2 ** attempt), options.maxDelay);\n const fuzz = Math.floor(delay * options.jitter * Math.random());\n timer = setTimeout(sendConnect, delay + fuzz);\n };\n\n const sendConnect = () => {\n attempt += 1;\n try {\n port.postMessage([\n Port.EVENTS.CONNECT,\n { rid: nanoid(), sid }\n ]);\n } catch (err) {\n cleanup();\n reject(err);\n return;\n }\n scheduleNext();\n };\n\n port.onmessage = (e) => {\n const msg = e?.data;\n if (!Array.isArray(msg) || msg.length < 2) return;\n const [EVENT_TYPE, MSG] = msg;\n \n if (!MSG?.sid || !MSG?.rid) return;\n\n switch (EVENT_TYPE) {\n case Port.EVENTS.CONFIRM_CONNECT: {\n if (resolved) return;\n resolved = true;\n cleanup();\n \n resolve(new Port(port, MSG?.sid));\n break;\n }\n case Port.EVENTS.ERROR: {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(new Error('Handshake error'));\n break;\n }\n default:\n break;\n }\n };\n\n port.onerror = (err) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(err);\n };\n\n if (typeof port.start === 'function') {\n try { port.start(); } catch {}\n }\n\n // Start connection attempts\n sendConnect();\n }\n });\n }\n\n constructor(port, sid = nanoid()) {\n if (port) {\n if (typeof port.postMessage !== 'function') {\n throw new Error('Port must be an object with postMessage');\n }\n this.#port = port;\n this.#sid = sid;\n this.#port.onmessage = (e) => this.#onmessage(e);\n this.#port.onerror = (err) => this.#onerror(err);\n this.#enabled = true;\n if (typeof this.#port.start === 'function') this.#port.start();\n }\n }\n\n /**\n * Handshake: resolves when the peer responds to CONNECT.\n */\n\n close() {\n if (this.#port) {\n this.#port.onmessage = null;\n this.#port.onerror = null;\n if (typeof this.#port.stop === 'function') this.#port.stop();\n if (typeof this.#port.close === 'function') this.#port.close();\n }\n\n // Reject any in-flight requests and clear timers\n for (const [, entry] of this.#pendingResponses) {\n if (entry.timeout) clearTimeout(entry.timeout);\n entry.reject?.(new Error('Port closed'));\n }\n\n this.#pendingResponses.clear();\n this.#port = null;\n this.#enabled = false;\n this.#messageListeners.clear();\n }\n\n emit(payload) {\n if (!this.#port) return Promise.reject(new Error('No port available'));\n if (!this.#enabled) return Promise.resolve(null);\n return this.#createEmit(payload);\n }\n\n request(payload) {\n if (!this.#port) return Promise.reject(new Error('No port available'));\n if (!this.#enabled) return Promise.resolve(null);\n return this.#createRequest(Port.EVENTS.MESSAGE, payload);\n }\n \n async enable() {\n if (!this.#port) return Promise.reject(new Error('No port available'));\n this.#enabled = await this.#createRequest(Port.EVENTS.ENABLE, true);\n return this.#enabled;\n }\n\n async disable() {\n if (!this.#port) return Promise.reject(new Error('No port available'));\n this.#enabled = await this.#createRequest(Port.EVENTS.ENABLE, false);\n return this.#enabled;\n }\n\n onMessage(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n if (this.#messageListeners.has(Port.EVENTS.MESSAGE)) {\n throw new Error('A listener is already registered. Remove the existing listener before adding a new one.');\n }\n this.#messageListeners.set(Port.EVENTS.MESSAGE, listener);\n return () => {\n // only remove if still same ref\n if (this.#messageListeners.get(Port.EVENTS.MESSAGE) === listener) {\n this.#messageListeners.delete(Port.EVENTS.MESSAGE);\n }\n };\n }\n\n onEnable(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n this.#messageListeners.set(Port.EVENTS.ENABLE, listener);\n return () => this.#messageListeners.delete(Port.EVENTS.ENABLE);\n }\n\n onError(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n if (this.#messageListeners.has(Port.EVENTS.ERROR)) {\n throw new Error('A listener is already registered. Remove the existing listener before adding a new one.');\n }\n this.#messageListeners.set(Port.EVENTS.ERROR, listener);\n return () => this.#messageListeners.delete(Port.EVENTS.ERROR);\n }\n\n #createEmit(payload) {\n try {\n return this.#postMessage(Port.EVENTS.MESSAGE, { sid: this.#sid, rid: null, payload });\n } catch (err) {\n return Promise.reject(err);\n }\n }\n\n // ---- internals ----\n #createRequest(EVENT_TYPE, payload) {\n return new Promise((resolve, reject) => {\n try {\n const rid = nanoid();\n const timeout = requestTimeout(() => {\n this.#pendingResponses.delete(rid);\n reject(new Error('Request timeout'));\n }, this.#defaultTimeoutMs);\n this.#pendingResponses.set(rid, { resolve, reject, timeout });\n this.#postMessage(EVENT_TYPE, { sid: this.#sid, rid, payload });\n } catch (err) {\n reject(err);\n }\n });\n }\n\n #onmessage(e) {\n // Guard bad shapes\n const msg = e?.data;\n if (!Array.isArray(msg) || msg.length < 2) return;\n const [ EVENT_TYPE, MSG ] = msg || [];\n\n if (MSG?.sid && MSG.sid !== this.#sid) return;\n\n switch (EVENT_TYPE) {\n case Port.EVENTS.RESPONSE:\n this.#handleResponse(MSG?.rid, MSG?.payload, 'resolve');\n return;\n case Port.EVENTS.ERROR: \n const errText = MSG?.payload instanceof Error ? MSG.payload.message : String(MSG?.payload);\n this.#handleResponse(MSG?.rid, new Error(errText), 'reject');\n return;\n case Port.EVENTS.MESSAGE:\n this.#handleMessage(MSG?.rid, MSG?.payload);\n return;\n case Port.EVENTS.ENABLE:\n this.#handleEnable(MSG?.rid, MSG?.payload);\n return;\n default:\n return;\n }\n }\n\n async #handleMessage(rid, payload) {\n try {\n const listener = this.#messageListeners.get(Port.EVENTS.MESSAGE);\n const result = listener ? await listener(payload) : null;\n if (rid) {\n // Always send a response to prevent request timeouts\n // Send null if no listener or listener returns undefined\n return this.#postMessage(Port.EVENTS.RESPONSE, { rid, payload: result ?? null });\n }\n return;\n } catch (error) {\n const errText = error instanceof Error ? error.message : String(error);\n this.#postMessage(Port.EVENTS.ERROR, { rid, payload: errText });\n }\n }\n\n #handleResponse(rid, payload, verb) {\n const entry = this.#pendingResponses.get(rid);\n if (!entry) return;\n if (entry.timeout) clearTimeout(entry.timeout);\n this.#pendingResponses.delete(rid);\n if (verb === 'resolve') entry.resolve(payload);\n else entry.reject(payload);\n }\n\n\n #handleEnable(rid, payload) {\n this.#enabled = payload;\n const listener = this.#messageListeners.get(Port.EVENTS.ENABLE);\n if (listener) listener(payload);\n return this.#postMessage(Port.EVENTS.RESPONSE, { rid, payload });\n }\n\n #postMessage(event, msg) {\n this.#port?.postMessage?.([event, msg]);\n return true;\n }\n\n #onerror(err) {\n console.error('onerror', err);\n }\n}\n", "// Platform detection and environment-specific utilities\n\nexport function isNodeEnvironment() {\n return typeof window === 'undefined' && typeof global !== 'undefined';\n}\n\nexport function isBrowserEnvironment() {\n return typeof window !== 'undefined';\n}\n\nexport function isWorkerEnvironment() {\n return typeof self !== 'undefined' && typeof importScripts === 'function';\n}\n\nexport function getEnvironment() {\n if (isWorkerEnvironment()) return 'worker';\n if (isNodeEnvironment()) return 'node';\n if (isBrowserEnvironment()) return 'browser';\n return 'unknown';\n}\n\n// Environment-specific MessageChannel creation\nexport function createMessageChannel() {\n if (isNodeEnvironment()) {\n // Node.js environment - use worker_threads\n try {\n // Check if we're in a Node.js environment with worker_threads\n if (typeof require !== 'undefined') {\n const { MessageChannel } = require('worker_threads');\n return new MessageChannel();\n } else {\n throw new Error('require not available');\n }\n } catch (error) {\n // Fallback if worker_threads is not available\n console.warn('worker_threads not available, falling back to global MessageChannel');\n return new MessageChannel();\n }\n } else {\n // Browser/Worker environment - use global MessageChannel\n return new MessageChannel();\n }\n}\n\n// Environment-specific port setup\nexport function setupPort(port) {\n if (isNodeEnvironment()) {\n // Node.js specific setup\n if (port.start) {\n port.start();\n }\n } else {\n // Browser/Worker specific setup\n if (port.start) {\n port.start();\n }\n }\n}\n\n// Environment-specific error handling\nexport function handleError(error, context = '') {\n const env = getEnvironment();\n \n switch (env) {\n case 'node':\n console.error(`[Node.js] ${context}:`, error);\n break;\n case 'browser':\n console.error(`[Browser] ${context}:`, error);\n break;\n case 'worker':\n console.error(`[Worker] ${context}:`, error);\n break;\n default:\n console.error(`[${env}] ${context}:`, error);\n }\n}\n", "export const EVENT_TYPES = {\n HANDSHAKE: 'HANDSHAKE',\n MESSAGE: 'MESSAGE',\n SUBSCRIBE: 'SUBSCRIBE',\n UNSUBSCRIBE: 'UNSUBSCRIBE',\n}\n\n", "import { ServiceProvider } from '@jucie.io/engine';\nimport { Port } from './Port.js';\nimport { createMessageChannel } from './utils/platform.js';\nimport { EVENT_TYPES } from './EVENTS.js';\n\nexport class MessageBus extends ServiceProvider {\n #subscriptions = new Map();\n #ports = new Map();\n #schemas = {};\n #mode = 'development';\n\n static manifest = {\n name: 'Message Bus',\n description: 'A message bus for the engine',\n namespace: 'messageBus',\n version: '1.0.0',\n defaults: {\n mode: 'development',\n schemas: [],\n },\n }\n\n initialize(_, config) {\n this.#mode = config.mode || 'development';\n this.#schemas = config.schemas.map((schema) => [schema._name, schema()]);\n }\n\n actions(_, config) {\n return {\n createChannel: (name, cb) => {\n try {\n if (!name) {\n throw new Error('Channel name is required');\n }\n\n const messageChannel = createMessageChannel();\n \n this.#setupPort(name, messageChannel.port1, cb);\n \n // Return port2 for the Channel to connect to\n return messageChannel.port2;\n } catch (error) {\n console.error('MessageBus error:', error);\n // Preserve original error message if it's about channel name\n if (error.message === 'Channel name is required') {\n throw error;\n }\n throw new Error('Failed to create port');\n }\n },\n useChannel: (name, port, cb) => {\n if (!name) {\n throw new Error('Channel name is required');\n }\n if (!port) {\n throw new Error('Channel port is required');\n }\n this.#setupPort(name, port, cb);\n },\n disableChannel: (name) => {\n if (name && this.#ports.has(name)) {\n const port = this.#ports.get(name);\n return port.disable();\n }\n },\n enableChannel: (name) => {\n if (name && this.#ports.has(name)) {\n const port = this.#ports.get(name);\n return port.enable();\n }\n },\n isChannelActive: (name) => {\n if (name && this.#ports.has(name)) {\n const port = this.#ports.get(name);\n return port.enabled;\n }\n }\n } \n }\n\n async #setupPort(name, port, cb = null) {\n // MessageBus acts as primary, sends context (event schemas) to Channel\n const portInstance = await Port.connect({ port, options: { primary: true } });\n if (cb) cb();\n this.#ports.set(name, portInstance);\n portInstance.onMessage(async (MSG) => await this.#messageHandler(MSG, portInstance));\n portInstance.onError((ERROR) => this.#errorHandler(ERROR, portInstance));\n return portInstance;\n }\n\n async #messageHandler(MSG, portInstance) {\n try {\n const [type, event, payload, to] = MSG;\n // Find the name of the port that sent this message\n let fromName = null;\n for (const [name, port] of this.#ports.entries()) {\n if (port === portInstance) {\n fromName = name;\n break;\n }\n }\n \n switch (type) {\n case EVENT_TYPES.MESSAGE:\n if (!to || (Array.isArray(to) && to.length === 0)) {\n // Broadcast to all subscribed channels - collect responses for requests\n const responses = [];\n for (const toPort of this.#ports.values()) {\n if (toPort === portInstance) continue;\n if (this.#subscriptions.get(toPort)?.has(event)) {\n const response = await toPort?.request([type, event, payload, null, fromName]);\n if (response !== undefined) {\n responses.push(response);\n }\n }\n }\n // Always return something to prevent request timeouts\n // Return null if no responses, first response if single, array if multiple\n if (responses.length === 0) return null;\n return responses.length === 1 ? responses[0] : responses;\n }\n // Targeted messaging - to is an array of channel names\n if (Array.isArray(to)) {\n const responses = [];\n for (const name of to) {\n const toPort = this.#ports.get(name);\n if (!toPort || toPort === portInstance) continue;\n \n if (this.#subscriptions.get(toPort)?.has(event)) {\n const response = await toPort?.request([type, event, payload, [name], fromName]);\n if (response !== undefined) {\n responses.push(response);\n }\n }\n }\n // Always return something to prevent request timeouts\n // Return null if no responses, first response if single, array if multiple\n if (responses.length === 0) return null;\n return responses.length === 1 ? responses[0] : responses;\n }\n break;\n case EVENT_TYPES.SUBSCRIBE:\n if (!this.#subscriptions.has(portInstance)) {\n this.#subscriptions.set(portInstance, new Set());\n }\n this.#subscriptions.get(portInstance)?.add(event);\n break;\n case EVENT_TYPES.UNSUBSCRIBE:\n this.#subscriptions.get(portInstance)?.delete(event);\n break;\n }\n } catch (error) {\n // Only log errors in development mode, skip timeout errors in test mode\n if (this.#mode === 'development' || (this.#mode !== 'test' && !error.message?.includes('Request timeout'))) {\n console.error('MessageBus message error:', error);\n }\n }\n }\n\n #errorHandler(event, port) {\n console.error('MessageBus error:', event);\n }\n}\n", "export function extractArgs(types, args) {\n const used = new Set(); // so one arg can\u2019t fill multiple slots\n\n return types.map(type => {\n for (let i = 0; i < args.length; i++) {\n if (used.has(i)) continue;\n if (matches(args[i], type)) {\n used.add(i);\n return args[i];\n }\n }\n return undefined;\n });\n}\n\nfunction matches(arg, type) {\n if (arg == null) return false;\n\n switch (type) {\n case String: return typeof arg === 'string' || arg instanceof String;\n case Number: return typeof arg === 'number' || arg instanceof Number;\n case Boolean: return typeof arg === 'boolean' || arg instanceof Boolean;\n case Array: return Array.isArray(arg);\n case Object: {\n const proto = Object.getPrototypeOf(arg);\n return proto === Object.prototype || proto === null;\n }\n case Function: return typeof arg === 'function';\n default:\n try {\n return arg instanceof type;\n } catch {\n return false;\n }\n }\n}", "import { ServiceProvider, createDefinition } from '@jucie.io/engine';\nimport { Port } from './Port.js';\nimport { extractArgs } from '@shared/utils';\nimport { EVENT_TYPES } from './EVENTS.js';\n\nexport const defineContracts = createDefinition('channelContracts', [Object]);\n\nexport class Channel extends ServiceProvider {\n #port = null;\n #messagePort = null;\n #subscriptions = new Map();\n #pendingSubscriptions = [];\n #ready = false;\n #lifecycleSubscribers = {\n enable: new Set(),\n disable: new Set(),\n connect: new Set(),\n }\n \n static manifest = {\n name: 'Channel',\n dependencies: [],\n version: '1.0.0',\n namespace: 'channel',\n description: 'Channel extension for message passing between systems',\n defaults: {\n port: null,\n subscriptions: [],\n }\n };\n\n initialize(_, config) {\n this.#messagePort = config.port;\n \n if (config.subscriptions && config.subscriptions.length) {\n for (const subscription of config.subscriptions) {\n this.#pendingSubscriptions.push(subscription);\n }\n }\n }\n\n actions() {\n const actions = {\n ready: () => this.#ready,\n connect: async (...args) => {\n try {\n const [port, cb] = extractArgs([MessagePort, Function], args);\n this.#messagePort = port || this.#messagePort;\n\n if (!this.#messagePort) {\n throw new Error('Message port is required');\n }\n\n // Only add callback if it's provided and is a function\n if (cb && typeof cb === 'function') {\n this.#lifecycleSubscribers.connect.add(cb);\n }\n \n this.#port = await Port.connect({ port: this.#messagePort });\n this.#lifecycleHandler('CONNECT', true, actions);\n \n this.#ready = true;\n\n if (this.#pendingSubscriptions.length > 0) {\n for (const subscription of this.#pendingSubscriptions) {\n this.#setupSubscriptions(subscription);\n }\n }\n\n this.#port.onMessage(async (event) => await this.#messageHandler(event));\n this.#port.onEnable((enabled) => this.#lifecycleHandler('ENABLE', enabled, actions));\n this.#port.onError(this.#errorHandler);\n return actions\n } catch (err) {\n console.error('Channel error:', err);\n return false;\n }\n },\n onEnable: (listener) => {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n this.#lifecycleSubscribers.enable.add(listener);\n return () => this.#lifecycleSubscribers.enable.delete(listener);\n },\n onDisable: (listener) => {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n this.#lifecycleSubscribers.disable.add(listener);\n return () => this.#lifecycleSubscribers.disable.delete(listener);\n },\n use: (...subscriptions) => {\n if (this.#ready) {\n for (const subscription of subscriptions) {\n this.#setupSubscriptions(subscription);\n }\n return actions;\n }\n for (const subscription of subscriptions) {\n this.#pendingSubscriptions.push(subscription);\n }\n return actions;\n },\n publish: (event, ...payload) => {\n this.#emit(EVENT_TYPES.MESSAGE, event, payload);\n return actions;\n },\n request: (event, ...payload) => {\n return this.#request(EVENT_TYPES.MESSAGE, event, payload);\n },\n subscribe: (event, subscriber) => {\n return this.#addSubscriber(event, undefined, subscriber, false);\n },\n subscribeOnce: (event, subscriber) => {\n return this.#addSubscriber(event, undefined, subscriber, true);\n },\n unsubscribe: (event, subscriber) => {\n return this.#removeSubscriber(event, subscriber);\n },\n to: (...to) => {\n return {\n publish: (event, ...payload) => {\n this.#emit(EVENT_TYPES.MESSAGE, event, payload, to);\n },\n }\n },\n namespace: (namespace) => {\n return {\n publish: (event, ...payload) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n this.#emit(EVENT_TYPES.MESSAGE, namespacedEvent, payload);\n return actions;\n },\n request: (event, ...payload) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n return this.#request(EVENT_TYPES.MESSAGE, namespacedEvent, payload);\n },\n subscribe: (event, subscriber) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n this.#addSubscriber(namespacedEvent, undefined, subscriber, false);\n return actions;\n },\n subscribeOnce: (event, subscriber) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n this.#addSubscriber(namespacedEvent, undefined, subscriber, true);\n return actions;\n },\n unsubscribe: (event, subscriber) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n this.#removeSubscriber(namespacedEvent, subscriber);\n return actions;\n }\n }\n }\n }\n\n return actions;\n }\n\n #setupSubscriptions(contractFactory) {\n if (contractFactory && typeof contractFactory === 'function') {\n const contractGroup = contractFactory._name;\n const contracts = contractFactory(this.useContext);\n\n const contractEntries = Object.entries(contracts);\n\n for (const [event, contract] of contractEntries) {\n const { handler, schema, namespace, once } = contract;\n const finalEvent = namespace ? `${namespace}/${contractGroup}:${event}` : `${contractGroup}:${event}`;\n const subscriber = (...args) => {\n try {\n return handler(...args);\n } catch (error) {\n console.error(`Errow with ${finalEvent}:`, error);\n }\n }\n \n this.#addSubscriber(finalEvent, schema, subscriber, once);\n }\n }\n }\n\n #addSubscriber(event, schema, subscriber, once = false) {\n if (!this.#subscriptions.has(event)) {\n this.#subscriptions.set(event, new Set());\n }\n\n const subscription = {\n event,\n schema,\n subscriber,\n once\n }\n\n this.#subscriptions.get(event).add(subscription);\n\n this.#port.emit([EVENT_TYPES.SUBSCRIBE, event]);\n\n return () => this.#subscriptions.get(event).delete(subscription);\n }\n\n #removeSubscriber(event, subscriber) {\n if (!this.#subscriptions.has(event)) {\n return;\n }\n\n const subscriptions = this.#subscriptions.get(event);\n\n for (const subscription of subscriptions.values()) {\n if (subscription.subscriber === subscriber) {\n subscriptions.delete(subscription);\n return subscriber\n }\n }\n }\n\n #emit(type, event, payload, to = null) {\n this.#port.emit([type, event, payload, to]);\n }\n\n #request(type, event, payload, to = null) {\n return this.#port.request([type, event, payload, to]);\n }\n\n #messageHandler = async ([type, event, payload, to, from]) => {\n const response = [];\n switch (type) {\n case EVENT_TYPES.MESSAGE:\n const subscriptions = this.#subscriptions.get(event);\n if (subscriptions) {\n for (const subscription of subscriptions) {\n if (!this.#validateEvent(event, payload, subscription.schema)) {\n continue;\n }\n const res = await subscription.subscriber(...payload);\n response.push(res);\n if (subscription.once) {\n this.#subscriptions.get(event).delete(subscription);\n }\n }\n }\n break;\n }\n // Return first response if single subscriber, or array if multiple\n // Always return something to prevent request timeouts\n return response.length === 1 ? response[0] : (response.length > 1 ? response : null);\n }\n\n #lifecycleHandler = (type, payload, actions) => {\n switch (type) {\n case 'ENABLE':\n if (payload === true) {\n this.#lifecycleSubscribers.enable.forEach((listener) => listener(actions));\n } else {\n this.#lifecycleSubscribers.disable.forEach((listener) => listener(actions));\n }\n break;\n case 'CONNECT':\n this.#lifecycleSubscribers.connect.forEach((listener) => listener(actions));\n break;\n }\n }\n\n #errorHandler = (error) => {\n console.error('Channel error:', error);\n }\n\n #validateEvent(event, payload, schema) {\n // If schema is undefined, allow it (direct subscriptions without contracts)\n if (schema === undefined) {\n return true;\n }\n \n // Fast exit for wildcard schema\n if (schema === '*') return true;\n \n // Fast exit for null schema (no validation)\n if (schema === null) return true;\n \n if (payload === undefined) {\n return true;\n }\n \n // Handle array schema (type validation)\n if (Array.isArray(schema)) {\n // Check for wildcard array\n if (schema.length === 1 && schema[0] === '*') return true;\n \n const schemaLength = schema.length;\n const payloadLength = payload.length;\n \n // Quick length check\n if (schemaLength !== payloadLength) {\n console.warn(\n '\\nEvent:', event,\n '\\nExpected:', schema,\n '\\nReceived:', payload.map(p => typeof p)\n );\n return false;\n }\n\n // Fast loop for type checking\n for (let i = 0; i < schemaLength; i++) {\n const expected = schema[i];\n const value = payload[i];\n \n let actual;\n \n if (Array.isArray(value)) {\n actual = 'Array';\n } else if (value === null) {\n actual = 'null';\n } else {\n actual = Object.prototype.toString.call(value).slice(8, -1); // e.g. \"[object Object]\" \u2192 \"Object\"\n }\n \n if (expected === 'Object' && actual === 'Array') {\n console.warn(\n '\\nEvent:', event,\n '\\nValue:', value\n );\n return false;\n } else if (expected !== actual) {\n console.warn(\n '\\nEvent:', event,\n '\\nValue:', value\n );\n return false;\n }\n } \n }\n \n return true;\n }\n} "],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["
|
|
3
|
+
"sources": ["../src/MessageBus.js", "../src/utils/requestTimeout.js", "../../../node_modules/nanoid/index.js", "../../../node_modules/nanoid/url-alphabet/index.js", "../src/Port.js", "../src/utils/platform.js", "../src/EVENTS.js", "../src/Channel.js", "../../../src/shared-utils/extractArgs.js"],
|
|
4
|
+
"sourcesContent": ["import { ServiceProvider } from '@jucie.io/engine';\nimport { Port } from './Port.js';\nimport { createMessageChannel } from './utils/platform.js';\nimport { EVENT_TYPES } from './EVENTS.js';\n\nexport class MessageBus extends ServiceProvider {\n #subscriptions = new Map();\n #ports = new Map();\n #schemas = {};\n #mode = 'development';\n\n static manifest = {\n name: 'Message Bus',\n description: 'A message bus for the engine',\n namespace: 'messageBus',\n version: '1.0.0',\n defaults: {\n mode: 'development',\n schemas: [],\n },\n }\n\n initialize(_, config) {\n this.#mode = config.mode || 'development';\n this.#schemas = config.schemas.map((schema) => [schema._name, schema()]);\n }\n\n actions(_, config) {\n return {\n createChannel: (name, cb) => {\n try {\n if (!name) {\n throw new Error('Channel name is required');\n }\n\n const messageChannel = createMessageChannel();\n \n this.#setupPort(name, messageChannel.port1, cb);\n \n // Return port2 for the Channel to connect to\n return messageChannel.port2;\n } catch (error) {\n console.error('MessageBus error:', error);\n // Preserve original error message if it's about channel name\n if (error.message === 'Channel name is required') {\n throw error;\n }\n throw new Error('Failed to create port');\n }\n },\n useChannel: (name, port, cb) => {\n if (!name) {\n throw new Error('Channel name is required');\n }\n if (!port) {\n throw new Error('Channel port is required');\n }\n this.#setupPort(name, port, cb);\n },\n disableChannel: (name) => {\n if (name && this.#ports.has(name)) {\n const port = this.#ports.get(name);\n return port.disable();\n }\n },\n enableChannel: (name) => {\n if (name && this.#ports.has(name)) {\n const port = this.#ports.get(name);\n return port.enable();\n }\n },\n isChannelActive: (name) => {\n if (name && this.#ports.has(name)) {\n const port = this.#ports.get(name);\n return port.enabled;\n }\n }\n } \n }\n\n async #setupPort(name, port, cb = null) {\n // MessageBus acts as primary, sends context (event schemas) to Channel\n const portInstance = await Port.connect({ port, options: { primary: true } });\n if (cb) cb();\n this.#ports.set(name, portInstance);\n portInstance.onMessage(async (MSG) => await this.#messageHandler(MSG, portInstance));\n portInstance.onError((ERROR) => this.#errorHandler(ERROR, portInstance));\n return portInstance;\n }\n\n async #messageHandler(MSG, portInstance) {\n try {\n const [type, event, payload, to] = MSG;\n // Find the name of the port that sent this message\n let fromName = null;\n for (const [name, port] of this.#ports.entries()) {\n if (port === portInstance) {\n fromName = name;\n break;\n }\n }\n \n switch (type) {\n case EVENT_TYPES.MESSAGE:\n if (!to || (Array.isArray(to) && to.length === 0)) {\n // Broadcast to all subscribed channels - collect responses for requests\n const responses = [];\n for (const toPort of this.#ports.values()) {\n if (toPort === portInstance) continue;\n if (this.#subscriptions.get(toPort)?.has(event)) {\n const response = await toPort?.request([type, event, payload, null, fromName]);\n if (response !== undefined) {\n responses.push(response);\n }\n }\n }\n // Always return something to prevent request timeouts\n // Return null if no responses, first response if single, array if multiple\n if (responses.length === 0) return null;\n return responses.length === 1 ? responses[0] : responses;\n }\n // Targeted messaging - to is an array of channel names\n if (Array.isArray(to)) {\n const responses = [];\n for (const name of to) {\n const toPort = this.#ports.get(name);\n if (!toPort || toPort === portInstance) continue;\n \n if (this.#subscriptions.get(toPort)?.has(event)) {\n const response = await toPort?.request([type, event, payload, [name], fromName]);\n if (response !== undefined) {\n responses.push(response);\n }\n }\n }\n // Always return something to prevent request timeouts\n // Return null if no responses, first response if single, array if multiple\n if (responses.length === 0) return null;\n return responses.length === 1 ? responses[0] : responses;\n }\n break;\n case EVENT_TYPES.SUBSCRIBE:\n if (!this.#subscriptions.has(portInstance)) {\n this.#subscriptions.set(portInstance, new Set());\n }\n this.#subscriptions.get(portInstance)?.add(event);\n break;\n case EVENT_TYPES.UNSUBSCRIBE:\n this.#subscriptions.get(portInstance)?.delete(event);\n break;\n }\n } catch (error) {\n // Only log errors in development mode, skip timeout errors in test mode\n if (this.#mode === 'development' || (this.#mode !== 'test' && !error.message?.includes('Request timeout'))) {\n console.error('MessageBus message error:', error);\n }\n }\n }\n\n #errorHandler(event, port) {\n console.error('MessageBus error:', event);\n }\n}\n", "export const requestTimeout = (reject, defaultTimeoutMs) => setTimeout(() => {\n reject(new Error('Timeout waiting for connect'));\n}, defaultTimeoutMs);", "import crypto from 'crypto'\nimport { urlAlphabet } from './url-alphabet/index.js'\nconst POOL_SIZE_MULTIPLIER = 128\nlet pool, poolOffset\nlet fillPool = bytes => {\n if (!pool || pool.length < bytes) {\n pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)\n crypto.randomFillSync(pool)\n poolOffset = 0\n } else if (poolOffset + bytes > pool.length) {\n crypto.randomFillSync(pool)\n poolOffset = 0\n }\n poolOffset += bytes\n}\nlet random = bytes => {\n fillPool((bytes |= 0))\n return pool.subarray(poolOffset - bytes, poolOffset)\n}\nlet customRandom = (alphabet, defaultSize, getRandom) => {\n let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1\n let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)\n return (size = defaultSize) => {\n let id = ''\n while (true) {\n let bytes = getRandom(step)\n let i = step\n while (i--) {\n id += alphabet[bytes[i] & mask] || ''\n if (id.length === size) return id\n }\n }\n }\n}\nlet customAlphabet = (alphabet, size = 21) =>\n customRandom(alphabet, size, random)\nlet nanoid = (size = 21) => {\n fillPool((size |= 0))\n let id = ''\n for (let i = poolOffset - size; i < poolOffset; i++) {\n id += urlAlphabet[pool[i] & 63]\n }\n return id\n}\nexport { nanoid, customAlphabet, customRandom, urlAlphabet, random }\n", "let urlAlphabet =\n 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\nexport { urlAlphabet }\n", "import { requestTimeout } from './utils/requestTimeout.js';\nimport { nanoid } from 'nanoid';\n\nexport class Port {\n static get EVENTS() {\n return {\n CONNECT: 'CONNECT',\n CONFIRM_CONNECT: 'CONFIRM_CONNECT',\n RESPONSE: 'RESPONSE',\n ENABLE: 'ENABLE',\n ERROR: 'ERROR',\n MESSAGE: 'MESSAGE',\n WARNING: 'WARNING',\n INFO: 'INFO',\n DEBUG: 'DEBUG',\n TRACE: 'TRACE',\n }\n }\n\n static defaultOptions = {\n primary: false,\n maxRetries: 10,\n baseDelay: 200,\n maxDelay: 2000,\n jitter: 0.2\n }\n\n #port = null;\n #enabled = false;\n #sid = null;\n // rid -> { resolve, reject, timeout }\n #pendingResponses = new Map();\n\n // Single listener by event name\n #messageListeners = new Map();\n #defaultTimeoutMs = 1000;\n\n get enabled() { return this.#enabled; }\n\n static connect({ port, options = {}}) {\n options = { ...Port.defaultOptions, ...options };\n \n let sid = nanoid();\n \n return new Promise((resolve, reject) => {\n let attempt = 0;\n let timer = null;\n let resolved = false;\n \n const cleanup = () => {\n if (timer) clearTimeout(timer);\n try { port.onmessage = null; } catch {}\n try { port.onerror = null; } catch {}\n };\n\n if (options.primary) {\n // PRIMARY MODE: Listen for connections\n port.onmessage = (e) => {\n const msg = e?.data;\n \n if (!Array.isArray(msg) || msg.length < 2) return;\n\n const [EVENT_TYPE, MSG] = msg;\n if (EVENT_TYPE === Port.EVENTS.CONNECT) {\n // Secondary is trying to connect\n try {\n port.postMessage([\n Port.EVENTS.CONFIRM_CONNECT,\n { rid: MSG?.rid, sid: MSG?.sid }\n ]);\n \n resolved = true;\n resolve(new Port(port, MSG?.sid));\n } catch (err) {\n cleanup();\n reject(err);\n }\n }\n };\n\n port.onerror = (err) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(err);\n };\n\n if (typeof port.start === 'function') {\n try { port.start(); } catch {}\n }\n\n } else {\n // SECONDARY MODE: Initiate connection with retries\n const scheduleNext = () => {\n if (attempt >= options.maxRetries) {\n if (!resolved) {\n cleanup();\n reject(new Error('Max retries reached'));\n }\n return;\n }\n const delay = Math.min(options.baseDelay * (2 ** attempt), options.maxDelay);\n const fuzz = Math.floor(delay * options.jitter * Math.random());\n timer = setTimeout(sendConnect, delay + fuzz);\n };\n\n const sendConnect = () => {\n attempt += 1;\n try {\n port.postMessage([\n Port.EVENTS.CONNECT,\n { rid: nanoid(), sid }\n ]);\n } catch (err) {\n cleanup();\n reject(err);\n return;\n }\n scheduleNext();\n };\n\n port.onmessage = (e) => {\n const msg = e?.data;\n if (!Array.isArray(msg) || msg.length < 2) return;\n const [EVENT_TYPE, MSG] = msg;\n \n if (!MSG?.sid || !MSG?.rid) return;\n\n switch (EVENT_TYPE) {\n case Port.EVENTS.CONFIRM_CONNECT: {\n if (resolved) return;\n resolved = true;\n cleanup();\n \n resolve(new Port(port, MSG?.sid));\n break;\n }\n case Port.EVENTS.ERROR: {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(new Error('Handshake error'));\n break;\n }\n default:\n break;\n }\n };\n\n port.onerror = (err) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n reject(err);\n };\n\n if (typeof port.start === 'function') {\n try { port.start(); } catch {}\n }\n\n // Start connection attempts\n sendConnect();\n }\n });\n }\n\n constructor(port, sid = nanoid()) {\n if (port) {\n if (typeof port.postMessage !== 'function') {\n throw new Error('Port must be an object with postMessage');\n }\n this.#port = port;\n this.#sid = sid;\n this.#port.onmessage = (e) => this.#onmessage(e);\n this.#port.onerror = (err) => this.#onerror(err);\n this.#enabled = true;\n if (typeof this.#port.start === 'function') this.#port.start();\n }\n }\n\n /**\n * Handshake: resolves when the peer responds to CONNECT.\n */\n\n close() {\n if (this.#port) {\n this.#port.onmessage = null;\n this.#port.onerror = null;\n if (typeof this.#port.stop === 'function') this.#port.stop();\n if (typeof this.#port.close === 'function') this.#port.close();\n }\n\n // Reject any in-flight requests and clear timers\n for (const [, entry] of this.#pendingResponses) {\n if (entry.timeout) clearTimeout(entry.timeout);\n entry.reject?.(new Error('Port closed'));\n }\n\n this.#pendingResponses.clear();\n this.#port = null;\n this.#enabled = false;\n this.#messageListeners.clear();\n }\n\n emit(payload) {\n if (!this.#port) return Promise.reject(new Error('No port available'));\n if (!this.#enabled) return Promise.resolve(null);\n return this.#createEmit(payload);\n }\n\n request(payload) {\n if (!this.#port) return Promise.reject(new Error('No port available'));\n if (!this.#enabled) return Promise.resolve(null);\n return this.#createRequest(Port.EVENTS.MESSAGE, payload);\n }\n \n async enable() {\n if (!this.#port) return Promise.reject(new Error('No port available'));\n this.#enabled = await this.#createRequest(Port.EVENTS.ENABLE, true);\n return this.#enabled;\n }\n\n async disable() {\n if (!this.#port) return Promise.reject(new Error('No port available'));\n this.#enabled = await this.#createRequest(Port.EVENTS.ENABLE, false);\n return this.#enabled;\n }\n\n onMessage(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n if (this.#messageListeners.has(Port.EVENTS.MESSAGE)) {\n throw new Error('A listener is already registered. Remove the existing listener before adding a new one.');\n }\n this.#messageListeners.set(Port.EVENTS.MESSAGE, listener);\n return () => {\n // only remove if still same ref\n if (this.#messageListeners.get(Port.EVENTS.MESSAGE) === listener) {\n this.#messageListeners.delete(Port.EVENTS.MESSAGE);\n }\n };\n }\n\n onEnable(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n this.#messageListeners.set(Port.EVENTS.ENABLE, listener);\n return () => this.#messageListeners.delete(Port.EVENTS.ENABLE);\n }\n\n onError(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n if (this.#messageListeners.has(Port.EVENTS.ERROR)) {\n throw new Error('A listener is already registered. Remove the existing listener before adding a new one.');\n }\n this.#messageListeners.set(Port.EVENTS.ERROR, listener);\n return () => this.#messageListeners.delete(Port.EVENTS.ERROR);\n }\n\n #createEmit(payload) {\n try {\n return this.#postMessage(Port.EVENTS.MESSAGE, { sid: this.#sid, rid: null, payload });\n } catch (err) {\n return Promise.reject(err);\n }\n }\n\n // ---- internals ----\n #createRequest(EVENT_TYPE, payload) {\n return new Promise((resolve, reject) => {\n try {\n const rid = nanoid();\n const timeout = requestTimeout(() => {\n this.#pendingResponses.delete(rid);\n reject(new Error('Request timeout'));\n }, this.#defaultTimeoutMs);\n this.#pendingResponses.set(rid, { resolve, reject, timeout });\n this.#postMessage(EVENT_TYPE, { sid: this.#sid, rid, payload });\n } catch (err) {\n reject(err);\n }\n });\n }\n\n #onmessage(e) {\n // Guard bad shapes\n const msg = e?.data;\n if (!Array.isArray(msg) || msg.length < 2) return;\n const [ EVENT_TYPE, MSG ] = msg || [];\n\n if (MSG?.sid && MSG.sid !== this.#sid) return;\n\n switch (EVENT_TYPE) {\n case Port.EVENTS.RESPONSE:\n this.#handleResponse(MSG?.rid, MSG?.payload, 'resolve');\n return;\n case Port.EVENTS.ERROR: \n const errText = MSG?.payload instanceof Error ? MSG.payload.message : String(MSG?.payload);\n this.#handleResponse(MSG?.rid, new Error(errText), 'reject');\n return;\n case Port.EVENTS.MESSAGE:\n this.#handleMessage(MSG?.rid, MSG?.payload);\n return;\n case Port.EVENTS.ENABLE:\n this.#handleEnable(MSG?.rid, MSG?.payload);\n return;\n default:\n return;\n }\n }\n\n async #handleMessage(rid, payload) {\n try {\n const listener = this.#messageListeners.get(Port.EVENTS.MESSAGE);\n const result = listener ? await listener(payload) : null;\n if (rid) {\n // Always send a response to prevent request timeouts\n // Send null if no listener or listener returns undefined\n return this.#postMessage(Port.EVENTS.RESPONSE, { rid, payload: result ?? null });\n }\n return;\n } catch (error) {\n const errText = error instanceof Error ? error.message : String(error);\n this.#postMessage(Port.EVENTS.ERROR, { rid, payload: errText });\n }\n }\n\n #handleResponse(rid, payload, verb) {\n const entry = this.#pendingResponses.get(rid);\n if (!entry) return;\n if (entry.timeout) clearTimeout(entry.timeout);\n this.#pendingResponses.delete(rid);\n if (verb === 'resolve') entry.resolve(payload);\n else entry.reject(payload);\n }\n\n\n #handleEnable(rid, payload) {\n this.#enabled = payload;\n const listener = this.#messageListeners.get(Port.EVENTS.ENABLE);\n if (listener) listener(payload);\n return this.#postMessage(Port.EVENTS.RESPONSE, { rid, payload });\n }\n\n #postMessage(event, msg) {\n this.#port?.postMessage?.([event, msg]);\n return true;\n }\n\n #onerror(err) {\n console.error('onerror', err);\n }\n}\n", "// Platform detection and environment-specific utilities\n\nexport function isNodeEnvironment() {\n return typeof window === 'undefined' && typeof global !== 'undefined';\n}\n\nexport function isBrowserEnvironment() {\n return typeof window !== 'undefined';\n}\n\nexport function isWorkerEnvironment() {\n return typeof self !== 'undefined' && typeof importScripts === 'function';\n}\n\nexport function getEnvironment() {\n if (isWorkerEnvironment()) return 'worker';\n if (isNodeEnvironment()) return 'node';\n if (isBrowserEnvironment()) return 'browser';\n return 'unknown';\n}\n\n// Environment-specific MessageChannel creation\nexport function createMessageChannel() {\n if (isNodeEnvironment()) {\n // Node.js environment - use worker_threads\n try {\n // Check if we're in a Node.js environment with worker_threads\n if (typeof require !== 'undefined') {\n const { MessageChannel } = require('worker_threads');\n return new MessageChannel();\n } else {\n throw new Error('require not available');\n }\n } catch (error) {\n // Fallback if worker_threads is not available\n console.warn('worker_threads not available, falling back to global MessageChannel');\n return new MessageChannel();\n }\n } else {\n // Browser/Worker environment - use global MessageChannel\n return new MessageChannel();\n }\n}\n\n// Environment-specific port setup\nexport function setupPort(port) {\n if (isNodeEnvironment()) {\n // Node.js specific setup\n if (port.start) {\n port.start();\n }\n } else {\n // Browser/Worker specific setup\n if (port.start) {\n port.start();\n }\n }\n}\n\n// Environment-specific error handling\nexport function handleError(error, context = '') {\n const env = getEnvironment();\n \n switch (env) {\n case 'node':\n console.error(`[Node.js] ${context}:`, error);\n break;\n case 'browser':\n console.error(`[Browser] ${context}:`, error);\n break;\n case 'worker':\n console.error(`[Worker] ${context}:`, error);\n break;\n default:\n console.error(`[${env}] ${context}:`, error);\n }\n}\n", "export const EVENT_TYPES = {\n HANDSHAKE: 'HANDSHAKE',\n MESSAGE: 'MESSAGE',\n SUBSCRIBE: 'SUBSCRIBE',\n UNSUBSCRIBE: 'UNSUBSCRIBE',\n}\n\n", "import { ServiceProvider, createDefinition } from '@jucie.io/engine';\nimport { Port } from './Port.js';\nimport { extractArgs } from '@shared/utils';\nimport { EVENT_TYPES } from './EVENTS.js';\n\nexport const defineContracts = createDefinition('channelContracts', [Object]);\n\nexport class Channel extends ServiceProvider {\n #port = null;\n #messagePort = null;\n #subscriptions = new Map();\n #pendingSubscriptions = [];\n #ready = false;\n #lifecycleSubscribers = {\n enable: new Set(),\n disable: new Set(),\n connect: new Set(),\n }\n \n static manifest = {\n name: 'Channel',\n dependencies: [],\n version: '1.0.0',\n namespace: 'channel',\n description: 'Channel extension for message passing between systems',\n defaults: {\n port: null,\n subscriptions: [],\n }\n };\n\n initialize(_, config) {\n this.#messagePort = config.port;\n \n if (config.subscriptions && config.subscriptions.length) {\n for (const subscription of config.subscriptions) {\n this.#pendingSubscriptions.push(subscription);\n }\n }\n }\n\n actions() {\n const actions = {\n ready: () => this.#ready,\n connect: async (...args) => {\n try {\n const [port, cb] = extractArgs([MessagePort, Function], args);\n this.#messagePort = port || this.#messagePort;\n\n if (!this.#messagePort) {\n throw new Error('Message port is required');\n }\n\n // Only add callback if it's provided and is a function\n if (cb && typeof cb === 'function') {\n this.#lifecycleSubscribers.connect.add(cb);\n }\n \n this.#port = await Port.connect({ port: this.#messagePort });\n this.#lifecycleHandler('CONNECT', true, actions);\n \n this.#ready = true;\n\n if (this.#pendingSubscriptions.length > 0) {\n for (const subscription of this.#pendingSubscriptions) {\n this.#setupSubscriptions(subscription);\n }\n }\n\n this.#port.onMessage(async (event) => await this.#messageHandler(event));\n this.#port.onEnable((enabled) => this.#lifecycleHandler('ENABLE', enabled, actions));\n this.#port.onError(this.#errorHandler);\n return actions\n } catch (err) {\n console.error('Channel error:', err);\n return false;\n }\n },\n onEnable: (listener) => {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n this.#lifecycleSubscribers.enable.add(listener);\n return () => this.#lifecycleSubscribers.enable.delete(listener);\n },\n onDisable: (listener) => {\n if (typeof listener !== 'function') {\n throw new Error('Listener must be a function');\n }\n this.#lifecycleSubscribers.disable.add(listener);\n return () => this.#lifecycleSubscribers.disable.delete(listener);\n },\n use: (...subscriptions) => {\n if (this.#ready) {\n for (const subscription of subscriptions) {\n this.#setupSubscriptions(subscription);\n }\n return actions;\n }\n for (const subscription of subscriptions) {\n this.#pendingSubscriptions.push(subscription);\n }\n return actions;\n },\n publish: (event, ...payload) => {\n this.#emit(EVENT_TYPES.MESSAGE, event, payload);\n return actions;\n },\n request: (event, ...payload) => {\n return this.#request(EVENT_TYPES.MESSAGE, event, payload);\n },\n subscribe: (event, subscriber) => {\n return this.#addSubscriber(event, undefined, subscriber, false);\n },\n subscribeOnce: (event, subscriber) => {\n return this.#addSubscriber(event, undefined, subscriber, true);\n },\n unsubscribe: (event, subscriber) => {\n return this.#removeSubscriber(event, subscriber);\n },\n to: (...to) => {\n return {\n publish: (event, ...payload) => {\n this.#emit(EVENT_TYPES.MESSAGE, event, payload, to);\n },\n }\n },\n namespace: (namespace) => {\n return {\n publish: (event, ...payload) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n this.#emit(EVENT_TYPES.MESSAGE, namespacedEvent, payload);\n return actions;\n },\n request: (event, ...payload) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n return this.#request(EVENT_TYPES.MESSAGE, namespacedEvent, payload);\n },\n subscribe: (event, subscriber) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n this.#addSubscriber(namespacedEvent, undefined, subscriber, false);\n return actions;\n },\n subscribeOnce: (event, subscriber) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n this.#addSubscriber(namespacedEvent, undefined, subscriber, true);\n return actions;\n },\n unsubscribe: (event, subscriber) => {\n const namespacedEvent = namespace ? `${namespace}/${event}` : event;\n this.#removeSubscriber(namespacedEvent, subscriber);\n return actions;\n }\n }\n }\n }\n\n return actions;\n }\n\n #setupSubscriptions(contractFactory) {\n if (contractFactory && typeof contractFactory === 'function') {\n const contractGroup = contractFactory._name;\n const contracts = contractFactory(this.useContext);\n\n const contractEntries = Object.entries(contracts);\n\n for (const [event, contract] of contractEntries) {\n const { handler, schema, namespace, once } = contract;\n const finalEvent = namespace ? `${namespace}/${contractGroup}:${event}` : `${contractGroup}:${event}`;\n const subscriber = (...args) => {\n try {\n return handler(...args);\n } catch (error) {\n console.error(`Errow with ${finalEvent}:`, error);\n }\n }\n \n this.#addSubscriber(finalEvent, schema, subscriber, once);\n }\n }\n }\n\n #addSubscriber(event, schema, subscriber, once = false) {\n if (!this.#subscriptions.has(event)) {\n this.#subscriptions.set(event, new Set());\n }\n\n const subscription = {\n event,\n schema,\n subscriber,\n once\n }\n\n this.#subscriptions.get(event).add(subscription);\n\n this.#port.emit([EVENT_TYPES.SUBSCRIBE, event]);\n\n return () => this.#subscriptions.get(event).delete(subscription);\n }\n\n #removeSubscriber(event, subscriber) {\n if (!this.#subscriptions.has(event)) {\n return;\n }\n\n const subscriptions = this.#subscriptions.get(event);\n\n for (const subscription of subscriptions.values()) {\n if (subscription.subscriber === subscriber) {\n subscriptions.delete(subscription);\n return subscriber\n }\n }\n }\n\n #emit(type, event, payload, to = null) {\n this.#port.emit([type, event, payload, to]);\n }\n\n #request(type, event, payload, to = null) {\n return this.#port.request([type, event, payload, to]);\n }\n\n #messageHandler = async ([type, event, payload, to, from]) => {\n const response = [];\n switch (type) {\n case EVENT_TYPES.MESSAGE:\n const subscriptions = this.#subscriptions.get(event);\n if (subscriptions) {\n for (const subscription of subscriptions) {\n if (!this.#validateEvent(event, payload, subscription.schema)) {\n continue;\n }\n const res = await subscription.subscriber(...payload);\n response.push(res);\n if (subscription.once) {\n this.#subscriptions.get(event).delete(subscription);\n }\n }\n }\n break;\n }\n // Return first response if single subscriber, or array if multiple\n // Always return something to prevent request timeouts\n return response.length === 1 ? response[0] : (response.length > 1 ? response : null);\n }\n\n #lifecycleHandler = (type, payload, actions) => {\n switch (type) {\n case 'ENABLE':\n if (payload === true) {\n this.#lifecycleSubscribers.enable.forEach((listener) => listener(actions));\n } else {\n this.#lifecycleSubscribers.disable.forEach((listener) => listener(actions));\n }\n break;\n case 'CONNECT':\n this.#lifecycleSubscribers.connect.forEach((listener) => listener(actions));\n break;\n }\n }\n\n #errorHandler = (error) => {\n console.error('Channel error:', error);\n }\n\n #validateEvent(event, payload, schema) {\n // If schema is undefined, allow it (direct subscriptions without contracts)\n if (schema === undefined) {\n return true;\n }\n \n // Fast exit for wildcard schema\n if (schema === '*') return true;\n \n // Fast exit for null schema (no validation)\n if (schema === null) return true;\n \n if (payload === undefined) {\n return true;\n }\n \n // Handle array schema (type validation)\n if (Array.isArray(schema)) {\n // Check for wildcard array\n if (schema.length === 1 && schema[0] === '*') return true;\n \n const schemaLength = schema.length;\n const payloadLength = payload.length;\n \n // Quick length check\n if (schemaLength !== payloadLength) {\n console.warn(\n '\\nEvent:', event,\n '\\nExpected:', schema,\n '\\nReceived:', payload.map(p => typeof p)\n );\n return false;\n }\n\n // Fast loop for type checking\n for (let i = 0; i < schemaLength; i++) {\n const expected = schema[i];\n const value = payload[i];\n \n let actual;\n \n if (Array.isArray(value)) {\n actual = 'Array';\n } else if (value === null) {\n actual = 'null';\n } else {\n actual = Object.prototype.toString.call(value).slice(8, -1); // e.g. \"[object Object]\" \u2192 \"Object\"\n }\n \n if (expected === 'Object' && actual === 'Array') {\n console.warn(\n '\\nEvent:', event,\n '\\nValue:', value\n );\n return false;\n } else if (expected !== actual) {\n console.warn(\n '\\nEvent:', event,\n '\\nValue:', value\n );\n return false;\n }\n } \n }\n \n return true;\n }\n} ", "export function extractArgs(types, args) {\n const used = new Set(); // so one arg can\u2019t fill multiple slots\n\n return types.map(type => {\n for (let i = 0; i < args.length; i++) {\n if (used.has(i)) continue;\n if (matches(args[i], type)) {\n used.add(i);\n return args[i];\n }\n }\n return undefined;\n });\n}\n\nfunction matches(arg, type) {\n if (arg == null) return false;\n\n switch (type) {\n case String: return typeof arg === 'string' || arg instanceof String;\n case Number: return typeof arg === 'number' || arg instanceof Number;\n case Boolean: return typeof arg === 'boolean' || arg instanceof Boolean;\n case Array: return Array.isArray(arg);\n case Object: {\n const proto = Object.getPrototypeOf(arg);\n return proto === Object.prototype || proto === null;\n }\n case Function: return typeof arg === 'function';\n default:\n try {\n return arg instanceof type;\n } catch {\n return false;\n }\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["ServiceProvider", "requestTimeout", "reject", "defaultTimeoutMs", "crypto", "urlAlphabet", "POOL_SIZE_MULTIPLIER", "pool", "poolOffset", "fillPool", "bytes", "crypto", "nanoid", "size", "fillPool", "id", "i", "poolOffset", "urlAlphabet", "pool", "Port", "_Port", "#port", "#enabled", "#sid", "#pendingResponses", "#messageListeners", "#defaultTimeoutMs", "port", "options", "sid", "nanoid", "resolve", "reject", "attempt", "timer", "resolved", "cleanup", "e", "msg", "EVENT_TYPE", "MSG", "err", "scheduleNext", "delay", "fuzz", "sendConnect", "#onmessage", "#onerror", "entry", "payload", "#createEmit", "#createRequest", "listener", "#postMessage", "rid", "timeout", "requestTimeout", "#handleResponse", "errText", "#handleMessage", "#handleEnable", "result", "error", "verb", "event", "isNodeEnvironment", "createMessageChannel", "isNodeEnvironment", "__require", "MessageChannel", "EVENT_TYPES", "MessageBus", "ServiceProvider", "#subscriptions", "#ports", "#schemas", "#mode", "_", "config", "schema", "name", "cb", "messageChannel", "createMessageChannel", "#setupPort", "error", "port", "portInstance", "Port", "MSG", "#messageHandler", "ERROR", "#errorHandler", "type", "event", "payload", "to", "fromName", "EVENT_TYPES", "responses", "toPort", "response", "ServiceProvider", "createDefinition", "extractArgs", "types", "args", "used", "type", "i", "matches", "arg", "proto", "defineContracts", "createDefinition", "Channel", "ServiceProvider", "#port", "#messagePort", "#subscriptions", "#pendingSubscriptions", "#ready", "#lifecycleSubscribers", "_", "config", "subscription", "actions", "args", "port", "cb", "extractArgs", "Port", "#lifecycleHandler", "#setupSubscriptions", "event", "#messageHandler", "enabled", "#errorHandler", "err", "listener", "subscriptions", "payload", "#emit", "EVENT_TYPES", "#request", "subscriber", "#addSubscriber", "#removeSubscriber", "to", "namespace", "namespacedEvent", "contractFactory", "contractGroup", "contracts", "contractEntries", "contract", "handler", "schema", "once", "finalEvent", "error", "type", "from", "response", "#validateEvent", "res", "schemaLength", "payloadLength", "p", "i", "expected", "value", "actual"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jucie.io/engine-message",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"description": "Message bus system with event registry, channels, and subscriptions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/main.js",
|
|
7
7
|
"exports": {
|
|
8
|
-
".": "./dist/
|
|
8
|
+
".": "./dist/main.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/",
|
|
12
12
|
"README.md"
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
|
+
"build": "node build.js",
|
|
15
16
|
"test": "vitest"
|
|
16
17
|
},
|
|
17
18
|
"author": "Adrian Miller",
|