-
Notifications
You must be signed in to change notification settings - Fork 1.1k
add shareWorker/Worker #583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
nenge123
commented
Apr 22, 2024
```javascript function getWorker(port,data,tables){return new Promise(back=>{port.addEventListener('message',async function(e){console.log(this);if(e.data=='complete'||e.data&&e.data.result=='complete'){let sql=new(class{constructor(port){console.log(port);this.port=port;this.port.addEventListener('message',x=>{let xx=x.data;if(xx&&xx.constructor===Object){let id=xx.id;if(this.feedback[id]instanceof Function){return this.feedback[id](xx)}console.log(xx)}})}feedback={};getRandom(){return crypto?crypto.randomUUID():btoa(performance.now()+Math.random())}async getMessage(result,method){return await this.getResult({result,method})}async getResult(result,transf){return new Promise((back,error)=>{const id=this.getRandom();this.feedback[id]=function(data){const id=data.id;if(id&&this[id]instanceof Function){delete this[id]}if(data.error)return error(data.error);back(data.result)};result.id=id;this.postMessage(result,transf)})}postMessage(result,transf){this.port.postMessage(result,transf)}})(this);let method=await sql.getResult({result:[data,tables],method:'install'},data instanceof Uint8Array?[data.buffer]:[]);method.forEach(v=>{if(v=='constructor')return;sql[v]=new Function('...result','return this.getResult({result,method:"'+v+'"})')});back(sql)}},{once:true})})} let share = new SharedWorker('worker2.js','SQLite'); //let share = new SharedWorker('worker2.js?idb','SQLite'); //idb will use indexedb save/load sql-wasm.js/sql-wasm.wasm //let worker = new Worker('worker2.js'); //let worker = new Worker('worker2.js?idb'); //let sqlite = await getWorker(worker); share.port.start(); let sqlite = await getWorker(share.port,uint8,{...tables});//tables: {data:{id:'int int primary key',value:'char'}}; await sqlite.insert('data',{id:1,value:'are you ok?'}); await sqlite.all('select * from `data`'); await sqlite.all('select * from `data` where `id` = ?',[1]); await sqlite.once('select * from `data` where `id` = ?',[1]); await sqlite.result('select `value` from `data` where `id` = ?',[1]); //are you ok? ```
//old code method
await sqlite.postMessage({
id:1,
action:"exec",
sql: "SELECT * FROM test",
config: {useBigInt: true}, /*Optional param*/
}); |
lovasoa
requested changes
Apr 22, 2024
@@ -0,0 +1 @@ | |||
new class{ports=[];constructor(name,table){const S=this;self.S=S;const isLocal=/(127\.0\.0\.1|localhost|local\.nenge\.net)/.test(location.host)||/(cdn|npm)/.test(location.host);const mode=self.location.search.indexOf('idb')!==-1;const root=self.location.href.split('/').slice(0,-1).join('/')+'/';this.name=name||'sql-lite';this.table=table||'files';this.datafile='data.sqlite3';this.jsfile=isLocal?root+'sql-wasm.js':'https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/sql-wasm.js';this.wasmfile=isLocal?root+'sql-wasm.wasm':'https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.10.3/sql-wasm.wasm';this.ready=new Promise(async(ok,error)=>{try{await(mode?this.loadDB():this.loadImport())}catch(e){error(e);throw e;}if(self.postMessage){self.addEventListener('message',this.baseMessage);self.postMessage({result:'complete',database:self.database instanceof self.SQLite})}ok(true)});self.addEventListener("rejectionhandled",(event)=>{console.log(`Promise rejected;reason:${event.reason}`)});self.addEventListener("unhandledrejection",(event)=>{console.log(`Promise unhandled rejected;reason:${event.reason}`)});if(self.SharedWorkerGlobalScope&&self instanceof self.SharedWorkerGlobalScope){self.onconnect=async function(e){const source=e.source;await self.S.ready;source.onmessage=self.S.baseMessage;source.postMessage({result:'complete',database:self.database instanceof self.SQLite})}}}async loadImport(){importScripts(this.jsfile);this.onRuntimeInitialized(await initSqlJs());return true}postError(e){postMessage({method:'error',error:e});throw e;}async loadDB(){let script=await this.getItem('sql-wasm.js');if(!script){let response=await fetch(this.jsfile).catch(e=>this.postError(e));if(response&&response.status==200){script=await response.blob();this.setItem('sql-wasm.js',script)}else{throw'file error';}}let initSqlJs=(new Function(await script.text()+';return initSqlJs;'))();let wasmBinary=await this.getItem('sql-wasm.wasm');if(!wasmBinary){let response=await fetch(this.wasmfile).catch(e=>this.postError(e));if(response&&response.status==200){wasmBinary=new Uint8Array(await response.arrayBuffer());this.setItem('sql-wasm.wasm',wasmBinary)}else{throw'file error';}}this.onRuntimeInitialized(await initSqlJs({wasmBinary}));return true}methods={async install(data){if(data.result[0]===true){self.database=new self.SQLite(await self.S.getData(),data.result[1])}else{self.database=new self.SQLite(...data.result)}return this.getMethod()},async reload(data){if(self.database)self.database.close();if(!(data.result instanceof Array))data.result=[data.result];this.install(data);return true},getMethod(){return['run','exec','close','each'].concat(Reflect.ownKeys(self.SQLite.prototype))},closeworker(data,port){port.postMessage({id:data.id,result:true});self.close();throw'close';},async save2exit(data,port){port.postMessage({id:data.id,result:true});await self.database.savedata();self.close();throw'close';},old_create(){if(!self.database)self.database=new self.SQLite()},old_nosql(data,port){if(!data.sql){port.postMessage({id:data.id,error:"exec: Missing query string"});return true}return false},old_open(data,port){if(self.database)self.database.close();self.database=new self.SQLite(Uint8Array(data['buffer']));port.postMessage({id:data.id,ready:true})},old_exec(data,port){this.old_create();if(this.old_nosql(data,port))return;port.postMessage({id:data.id,results:db.exec(data.sql,data["params"],data.config)})},old_each(data,port){this.old_create();if(this.old_nosql(data,port))return;self.database.each(data.sql,data.param,row=>{port.postMessage({id:data.id,row:row,finished:false})},()=>port.postMessage({id:data.id,finished:true}),data.config)},old_export(data,port){this.old_create();const result={id:data.id,buffer:self.database.export()};port.postMessage(result,[result.buffer.buffer])},old_close(){if(self.database)self.database.close();port.postMessage({id:data.id})}};onRuntimeInitialized(SQL){const S=this;delete SQL.wasmBinary;self.SQLite=class extends SQL.Database{constructor(data,tablelist){super(data instanceof Uint8Array?data:undefined);if(tablelist&&!(data instanceof Uint8Array)){this.createtable(tablelist)}}all(sql,params,limit){let result=this.exec(sql,params);if(result[0]){let data=[];for(let value of result[0].values){data.push(Object.fromEntries(value.map((v,k)=>[result[0].columns[k],v])));if(limit)break}return data}}one(sql,params){let result=this.all(sql,params,1);if(result&&result[0]){return result[0]}}columns(index,sql,params){let result=Object.values(this.one(sql,params)||[]);if(result.length){return result[index||0]}}result(sql,params){return this.columns(0,sql,params)}delete(table,where){let whereStr=Array.from(Object.keys(where),e=>'`'+e+'` = ? ').join(' AND ');this.run('DELETE FROM `'+table+'` WHERE '+whereStr+';',Object.values(where))}insert(table,data,where){if(where){this.delete(table,where)}return this.result('INSERT INTO `'+table+'` ('+Array.from(Object.keys(data),e=>'`'+e+'`').join(',')+') VALUES ('+Object.keys(data).fill('?').join(',')+');',Object.values(data))}update(table,data,where){let setStr=Array.from(Object.keys(data),e=>'`'+e+'` = ?').join(',');let whereStr=Array.from(Object.keys(where),e=>'`'+e+'` = ? ').join(' AND ');let param=Object.values(data);param.push(...Object.values(where));return this.run('UPDATE `'+table+'` SET '+setStr+' WHERE '+whereStr+' ;',param)}createtable(tablelist){Array.from(Object.entries(tablelist)||[],entry=>{let keys=Array.from(Object.entries(entry[1]),sub=>{return'`'+sub[0]+'` '+sub[1]}).join(',');this.run(`CREATE TABLE\`${entry[0]}\`(${keys});`)})}async savedata(){return await S.setItem(self.S.datafile,this.export())}}}async open(version){if(this.idb instanceof Promise)return await this.idb;if(!this.idb){this.idb=new Promise(resolve=>{let req=indexedDB.open(this.name,version);req.addEventListener("upgradeneeded",e=>{const db=req.result;if(!db.objectStoreNames.contains(this.table)){const store=db.createObjectStore(this.table);store.createIndex('timestamp','timestamp',{"unique":false})}},{once:true});req.addEventListener('success',async e=>{const db=req.result;if(!db.objectStoreNames.contains(this.table)){let version=db.version+=1;db.close();return resolve(await this.open(version))}return resolve(db)},{once:true})})}return this.idb}async ObjectStore(ReadMode){const db=await this.open();const transaction=db.transaction([this.table],ReadMode?undefined:"readwrite");return transaction.objectStore(this.table)}readOnly(){return this.ObjectStore(!0)}readWrite(){return this.ObjectStore()}async getItem(name){let request=(await this.readOnly()).get(name);return new Promise((resolve)=>request.addEventListener('success',(e)=>{resolve(e.target.result&&e.target.result.contents||e.target.result)}))}async setItem(name,contents){let request=(await this.readWrite()).put({contents,timestamp:new Date},name);return new Promise((resolve)=>request.addEventListener('success',(e)=>{resolve(e.target.result)}))}async getData(){return await this.getItem(this.datafile)}async baseMessage(e){const data=e.data;if(data&&data.constructor===Object){const id=data.id;if(data.action){data.config=data.config?data.config:{};if(self.S.methods['old_'+data.action]instanceof Function)return self.S.methods['old_'+data.action](data,this);return this.postMessage({id:data.id,error:"Invalid action : "+data["action"]})}const method=data.method;const transf=[];let newResult={id};if(self.database&&self.database[method]instanceof Function){if(!(data.result instanceof Array))data.result=data.result?[data.result]:[];try{newResult.result=self.database[method](...data.result)}catch(e){newResult.error=e}}else if(self.S.methods[method]instanceof Function){newResult.result=await self.S.methods[method](data,this);if(!newResult.result)return}else{newResult.error='undefined:method or database or not create'}if(newResult.error)delete newResult.result;if(newResult.result instanceof Uint8Array)transf.push(newResult.result.buffer);this.postMessage(newResult,transf)}}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, you can't add this kind of obfuscated undocumented code to the repo
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.