VulpesOS/assets/webapps/music.gaiamobile.org/components/bridge/bridge.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

27 lines
No EOL
19 KiB
JavaScript

;;;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){var bridge={'service':require('../src/service'),'client':require('../src/client'),_m:require('../src/message')};if((typeof define)[0]!='u')define([],()=>bridge);else self['bridge']=bridge;},{"../src/client":2,"../src/message":4,"../src/service":6}],2:[function(require,module,exports){'use strict';var createPort=require('./message/port-adaptors');var Emitter=require('./emitter');var message=require('./message');var uuid=require('./utils').uuid;module.exports=Client;var debug={0:()=>{},1:arg=>performance.mark(`[${self.constructor.name}][Client] - ${arg}`),2:(arg1,...args)=>{var type=`[${self.constructor.name}][${location.pathname}]`;console.log(`[Client]${type} - "${arg1}"`,...args);}}[0];var env=constructor.name
function Client(service,endpoint,timeout){if(!(this instanceof Client))return new Client(service,endpoint,timeout);if(typeof service=='object'){endpoint=service.endpoint;timeout=service.timeout;service=service.service;}
this.id=uuid();this.service=service;this.timeout=timeout;this.endpoint=endpoint||this.endpoint;if(!this.endpoint)throw error(1);this.setPort(this.endpoint);this.pending=new Set();this.receiver=message.receiver(this.id).on('_push',this.onPush.bind(this));debug('initialized',service);}
Client.prototype={connect(){debug('connect');if(this.connected)return this.connected;debug('connecting...',this.service);var mc=new MessageChannel();this.channel=mc.port1;this.channel.start();var data={clientId:this.id,service:this.service,originEnv:env};return this.connected=this.message('_connect').set('transfer',[mc.port2]).set('data',data).listen(mc.port1).send().then(response=>{debug('connected',response);var usingChannel=response.event.target===this.channel;if(usingChannel)this.setPort(this.channel);else{this.channel.close();delete this.channel;}
this.receiver.listen(this.port);}).catch(err=>{var msg=err&&err.message;if(msg=='timeout'){err=error(2,this.service);console.error(err.message);}
throw err;});},disconnect(options){if(!this.connected)return Promise.resolve();debug('disconnecting ...');var config={noRespond:options&&options.noRespond,data:this.id};this.cancelPending();return this.message('_disconnect').set(config).send().then(()=>this.onDisconnected());},method(name,...args){return this.connect().then(()=>{debug('method',name);return this.message('_method').set({recipient:this.service,data:{name:name,args:args}}).send();}).then(response=>response.value).catch(err=>{var msg=err&&err.message;if(msg=='timeout'){err=error(3,name);console.error(err.message);}
throw err;});},plugin(fn){fn(this,{'Emitter':Emitter,'uuid':uuid});return this;},message(type){debug('create message',type);var msg=message(type).set('port',this.port).set('timeout',this.timeout).on('response',()=>this.pending.delete(msg)).on('cancel',()=>this.pending.delete(msg));this.pending.add(msg);return msg;},cancelPending(){debug('cancel pending');this.pending.forEach(msg=>{msg.cancel();});this.pending.clear();},pendingResponded(){var responded=[];this.pending.forEach(msg=>responded.push(msg.responded));return Promise.all(responded);},onPush(message){debug('on push',message.data);this._emit(message.data.type,message.data.data);},onDisconnected(){delete this.connected;this.pendingResponded().then(()=>{debug('disconnected');if(this.channel)this.channel.close();this._emit('disconnected');});},setPort(endpoint){debug('set port');this.port=createPort(endpoint);},destroy:function(){return this.disconnect().then(()=>{if(this.destroyed)return;debug('destroy');this.destroyed=true;this.receiver.destroy();this._off();this.port=this.endpoint=this.receiver=null;});},_on:Emitter.prototype.on,_off:Emitter.prototype.off,_emit:Emitter.prototype.emit};Client.prototype.on=function(name,fn){this.connect().then(()=>{debug('bind on',name);Emitter.prototype.on.call(this,name,fn);this.message('_on').set('noRespond',true).set('data',{name:name,clientId:this.id}).send(this.port);});return this;};Client.prototype.off=function(name,fn){this.connect().then(()=>{Emitter.prototype.off.call(this,name,fn);this.message('_off').set('noRespond',true).set('data',{name:name,clientId:this.id}).send(this.port);});return this;};function error(id,...args){var help='Either the target endpoint is not alive or the Service is not `.listen()`ing.';return new Error({1:'an endpoint must be defined',2:`Unable to establish a connection with "${args[0]}". ${help}`,3:`Method "${args[0]}" didn't get a response. ${help}`}[id]);}},{"./emitter":3,"./message":4,"./message/port-adaptors":5,"./utils":7}],3:[function(require,module,exports){'use strict';module.exports=Emitter;var debug=0?console.log.bind(console,'[Emitter]'):()=>{};function Emitter(host){if(host)return Object.assign(host,Emitter.prototype);}
Emitter.prototype={on:function(type,callback){debug('on',type,callback);if(!this._callbacks)this._callbacks={};if(!this._callbacks[type])this._callbacks[type]=[];this._callbacks[type].push(callback);return this;},off:function(type,callback){debug('off',type,callback);if(this._callbacks){switch(arguments.length){case 0:this._callbacks={};break;case 1:delete this._callbacks[type];break;default:var typeListeners=this._callbacks[type];if(!typeListeners)return;var i=typeListeners.indexOf(callback);if(~i)typeListeners.splice(i,1);}}
return this;},emit:function(type,data){debug('emit',type,data);if(this._callbacks){var fns=this._callbacks[type]||[];fns=fns.concat(this._callbacks['*']||[]);for(var i=0;i<fns.length;i++)fns[i].call(this,data,type);}
return this;}};var p=Emitter.prototype;p['off']=p.off;p['on']=p.on;},{}],4:[function(require,module,exports){'use strict';var createPort=require('./port-adaptors');var Emitter=require('../emitter');var utils=require('../utils');var defer=utils.deferred;var uuid=utils.uuid;exports=module.exports=type=>new Message(type);exports.receiver=(id,n)=>new Receiver(id,n);exports.Receiver=Receiver;exports.Message=Message;var debug={0:()=>{},1:arg=>performance.mark(`[${self.constructor.name}][Message] - ${arg}`),2:(arg1,...args)=>{var type=`[${self.constructor.name}][${location.pathname}]`;console.log(`[Message]${type} - "${arg1}"`,...args);}}[0];var TIMEOUT=1000;function Message(type){this.cancelled=false;this.listeners=[];this.deferred=defer();this.onMessage=this.onMessage.bind(this);this.onTimeout=this.onTimeout.bind(this);if(typeof type==='object')this.setupInbound(type);else this.setupOutbound(type);debug('initialized',type);}
Message.prototype={setupOutbound(type){this.id=uuid();this.type=type;this.sent=false;this.recipient='*';},setupInbound(e){debug('inbound');this.hasResponded=false;this.setSourcePort(e.source||e.target);this.event=e;Object.assign(this,e.data);},setSourcePort(endpoint){debug('set source',endpoint.constructor.name);this.sourcePort=createPort(endpoint,{ready:true});return this;},set(key,value){debug('set',key,value);if(typeof key=='object')Object.assign(this,key);else this[key]=value;return this;},serialize(){return{id:this.id,type:this.type,data:this.data,recipient:this.recipient,noRespond:this.noRespond};},preventDefault(){debug('prevent default');this.defaultPrevented=true;},send(endpoint){debug('send',this.type);if(this.sent)throw error(1);var serialized=this.serialize();var expectsResponse=!this.noRespond;this.port=endpoint?createPort(endpoint):this.port;if(!this.port)throw error(3);if(expectsResponse){this.listen(this.port);this.setResponseTimeout();}else this.deferred.resolve();this.port.postMessage(serialized,this.getTransfer());debug('sent',serialized);return this.deferred.promise;},setResponseTimeout(){if(this.timeout===false)return;var ms=this.timeout||TIMEOUT;this._timer=setTimeout(this.onTimeout,ms);},clearResponseTimeout(){clearTimeout(this._timer);},getTransfer(){return this.transfer||this.event&&this.event.ports;},onMessage(e){var valid=!!e.data.response&&e.data.id===this.id&&!this.cancelled;if(valid)this.onResponse(e);},onTimeout(){debug('response timeout',this.type);if(!this.silentTimeout)this.deferred.reject(error(4));this.teardown();},listen(thing){debug('add response listener',thing);var port=createPort(thing);port.addListener(this.onMessage);this.listeners.push(port);return this;},unlisten(){debug('remove response listeners');this.listeners.forEach(port=>port.removeListener(this.onMessage));this.listeners=[];},cancel(){this.teardown();this.cancelled=true;this.emit('cancel');},teardown(){this.clearResponseTimeout();this.unlisten();},respond(result){debug('respond',result);if(this.hasResponded)throw error(2);if(!this.sourcePort)return;if(this.noRespond)return;var self=this;this.hasResponded=true;if(result instanceof Error)reject(result);Promise.resolve(result).then(resolve,reject).catch(reject);function resolve(value){debug('resolve',value);respond({type:'resolve',value:value});}
function reject(err){var msg=err&&err.message||err;debug('reject',msg);respond({type:'reject',value:msg});}
function respond(response){self.response=response;self.sourcePort.postMessage({id:self.id,response:response},self.transfer);debug('responded with:',response);}},forward(endpoint){debug('forward');return this.set('silentTimeout',true).send(endpoint).then(result=>this.respond(result.value));},onResponse(e){debug('on response',e.data);var response=e.data.response;var type=response.type;var value=type=='reject'?response.value:response;response.event=e;this.response=response;this.teardown();this.deferred[this.response.type](value);this.emit('response',response);}};Emitter(Message.prototype);function Receiver(name){this.name=name;this.ports=new Set();this.onMessage=this.onMessage.bind(this);this['listen']=this['listen'].bind(this);this['unlisten']=this['unlisten'].bind(this);debug('receiver initialized',name);}
Receiver.prototype={listen(thing){debug('listen');var _port=createPort(thing||self,{receiver:true});if(this.ports.has(_port))return;_port.addListener(this.onMessage,this.listen);this.ports.add(_port);return this;},unlisten(){debug('unlisten');this.ports.forEach(port=>{port.removeListener(this.onMessage,this.unlisten);});},onMessage(e){if(!e.data.id)return;if(!e.data.type)return;if(!this.isRecipient(e.data.recipient))return;debug('receiver on message',e.data);var message=new Message(e);this.emit('message',message);if(message.defaultPrevented)return;try{this.emit(message.type,message);}
catch(e){message.respond(e);throw e;}},isRecipient(recipient){return recipient==this.name||recipient=='*'||this.name=='*';},destroy:function(){this.unlisten();delete this.name;return this;}};Emitter(Receiver.prototype);function error(id,...args){return new Error({1:'.send() can only be called once',2:'response already sent for this message',3:'a port must be defined',4:'timeout'}[id]);}},{"../emitter":3,"../utils":7,"./port-adaptors":5}],5:[function(require,module,exports){'use strict';var deferred=require('../utils').deferred;const MSG='message';var debug=0?function(arg1,...args){var type=`[${self.constructor.name}][${location.pathname}]`;console.log(`[PortAdaptor]${type} - "${arg1}"`,...args);}:()=>{};module.exports=function create(target,options){if(!target)throw error(1);if(isEndpoint(target))return target;var type=target.constructor.name;var CustomAdaptor=adaptors[type];debug('creating port adaptor for',type);if(CustomAdaptor)return CustomAdaptor(target,options);return new PortAdaptor(target,options);};function PortAdaptor(target){debug('PortAdaptor');this.target=target;}
var PortAdaptorProto=PortAdaptor.prototype={constructor:PortAdaptor,addListener(callback){on(this.target,MSG,callback);},removeListener(callback){off(this.target,MSG,callback);},postMessage(data,transfer){this.target.postMessage(data,transfer);}};var adaptors={'HTMLIFrameElement':function(iframe){debug('HTMLIFrameElement');var ready=windowReady(iframe);return{addListener(callback,listen){on(window,MSG,callback);},removeListener(callback,listen){off(window,MSG,callback);},postMessage(data,transfer){ready.then(()=>postMessageSync(iframe.contentWindow,data,transfer));}};},'BroadcastChannel':function(channel,options){debug('BroadcastChannel',channel.name);var receiver=options&&options.receiver;var ready=options&&options.ready;var sendReady=()=>{channel.postMessage('ready');debug('sent ready');};ready=ready||receiver?Promise.resolve():setupSender();if(receiver){sendReady();on(channel,MSG,e=>{if(e.data!='ready?')return;sendReady();});}
function setupSender(){debug('setup sender');var promise=deferred();channel.postMessage('ready?');on(channel,MSG,function fn(e){if(e.data!='ready')return;off(channel,MSG,fn);debug('BroadcastChannel: ready');promise.resolve();});return promise.promise;}
return{target:channel,addListener:PortAdaptorProto.addListener,removeListener:PortAdaptorProto.removeListener,postMessage(data,transfer){ready.then(()=>channel.postMessage(data,transfer));}};},'Window':function(win,options){debug('Window');var ready=options&&options.ready||win===parent||win===self;ready=ready?Promise.resolve():windowReady(win);return{addListener(callback,listen){on(window,MSG,callback);},removeListener(callback,listen){off(window,MSG,callback);},postMessage(data,transfer){ready.then(()=>postMessageSync(win,data,transfer));}};},'SharedWorker':function(worker){worker.port.start();return new PortAdaptor(worker.port);},'SharedWorkerGlobalScope':function(){var ports=[];return{postMessage(){},addListener(callback,listen){this.onconnect=e=>{var port=e.ports[0];ports.push(port);port.start();listen(port);};on(self,'connect',this.onconnect);},removeListener(callback,unlisten){off(self,'connect',this.onconnect);ports.forEach(port=>{port.close();unlisten(port);});}};}};var windowReady=(function(){if(typeof window=='undefined')return;var parent=window.opener||window.parent;var domReady='DOMContentLoaded';var windows=new WeakSet();if(parent!=self){on(window,domReady,function fn(){off(window,domReady,fn);postMessageSync(parent,'load');});}
on(self,'message',e=>e.data=='load'&&windows.add(e.source));return target=>{var win=target.contentWindow||target;if(windows.has(win))return Promise.resolve();if(win==window.parent)return Promise.resolve();var def=deferred();debug('waiting for Window to be ready ...');on(window,'message',function fn(e){if(e.data=='load'&&e.source==win){debug('Window ready');off(window,'message',fn);def.resolve();}});return def.promise;};})();function isEndpoint(thing){return!!(thing&&thing.addListener);}
function on(target,name,fn){target.addEventListener(name,fn);}
function off(target,name,fn){target.removeEventListener(name,fn);}
function postMessageSync(win,data,transfer){try{void win.document;}catch(_){win.postMessage(data,location.origin,transfer||[]);return;}var event={data:data,source:self};if(transfer)event.ports=transfer;win.dispatchEvent(new MessageEvent('message',event));}
function error(id){return new Error({1:'target is undefined'}[id]);}},{"../utils":7}],6:[function(require,module,exports){'use strict';var uuid=require('./utils').uuid;var message=require('./message');var Receiver=message.Receiver;module.exports=Service;var debug={0:()=>{},1:arg=>performance.mark(`[${self.constructor.name}][Service] - ${arg}`),2:(arg1,...args)=>{var type=`[${self.constructor.name}][${location.pathname}]`;console.log(`[Service]${type} - "${arg1}"`,...args);}}[0];Service.prototype=Object.create(Receiver.prototype);function Service(name){if(!(this instanceof Service))return new Service(name);message.Receiver.call(this,name);this.clients={};this.methods={};this.on('_disconnect',this.onDisconnect.bind(this)).on('_connect',this.onConnect.bind(this)).on('_method',this.onMethod.bind(this)).on('_off',this.onOff.bind(this)).on('_on',this.onOn.bind(this));this.destroy=this.destroy.bind(this);debug('initialized',name);}
Service.prototype.inWindow=constructor.name==='Window';Service.prototype.method=function(name,fn){this.methods[name]=fn;return this;};Service.prototype.broadcast=function(type,data,only){debug('broadcast',type,data,only);this.eachClient(client=>{if(only&&!~only.indexOf(client.id))return;debug('broadcasting to',client.id);this.push(type,data,client.id,{noRespond:true});});return this;};Service.prototype.push=function(type,data,clientId,options){var noRespond=options&&options.noRespond;var client=this.getClient(clientId);return message('_push').set({recipient:clientId,noRespond:noRespond,data:{type:type,data:data}}).send(client.port);};Service.prototype.eachClient=function(fn){for(var id in this.clients)fn(this.clients[id]);};Service.prototype.getClient=function(id){return this.clients[id];};Service.prototype.onConnect=function(message){debug('connection attempt',message.data,this.name);var data=message.data;var clientId=data.clientId;if(!clientId)return;if(data.service!==this.name)return;if(this.clients[clientId])return;this.emit('before-connect',message);if(message.defaultPrevented)return;this.upgradeChannel(message);this.addClient(clientId,message.sourcePort);message.respond();this.emit('connected',clientId);debug('connected',clientId);};Service.prototype.upgradeChannel=function(message){if(this.inWindow&&message.data.originEnv==='Window')return;var ports=message.event.ports;var channel=ports&&ports[0];if(channel){message.setSourcePort(channel);this.listen(channel);channel.start();}
debug('channel upgraded');};Service.prototype.onDisconnect=function(message){var client=this.clients[message.data];if(!client)return;this.emit('before-disconnect',message);if(message.defaultPrevented)return;this.removeClient(client.id);message.respond();this.emit('disconnected',client.id);debug('disconnected',client.id);};Service.prototype.onMethod=function(message){debug('on method',message.data);this.emit('before-method',message);if(message.defaultPrevented)return;var method=message.data;var name=method.name;var result;var fn=this.methods[name];if(!fn)throw error(4,name);try{result=fn.apply(this,method.args);}
catch(err){result=err;}
message.respond(result);};Service.prototype.onOn=function(message){debug('on on',message.data);this.emit('on',message.data);};Service.prototype.onOff=function(message){debug('on off');this.emit('off',message.data);};Service.prototype.addClient=function(id,port){this.clients[id]={id:id,port:port};};Service.prototype.removeClient=function(id){delete this.clients[id];};Service.prototype.plugin=function(fn){fn(this,{'uuid':uuid});return this;};Service.prototype.disconnect=function(client){this.removeClient(client.id);message('disconnect').set({recipient:client.id,noRespond:true}).send(client.port);};Service.prototype.destroy=function(){delete this.clients;this.unlisten();this.off();};var sp=Service.prototype;sp['broadcast']=sp.broadcast;sp['destroy']=sp.destroy;sp['method']=sp.method;sp['plugin']=sp.plugin;function error(id){var args=[].slice.call(arguments,1);return new Error({4:'method "'+args[0]+'" doesn\'t exist'}[id]);}},{"./message":4,"./utils":7}],7:[function(require,module,exports){'use strict';exports.uuid=function(){return'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(c){var r=Math.random()*16|0,v=c=='x'?r:(r&0x3|0x8);return v.toString(16);});};exports.deferred=function(){var promise={};promise.promise=new Promise((resolve,reject)=>{promise.resolve=resolve;promise.reject=reject;});return promise;};},{}]},{},[1]);