filer.js icon indicating copy to clipboard operation
filer.js copied to clipboard

synchronous functions

Open wehowski opened this issue 9 years ago • 6 comments

Hello, I know maybe it is without of you scope: I am interested to make some filer functions synchronous. Before I start to reinvent the wheel, I would like to ask if you can get me a hint where to start?

regards, Till

wehowski avatar Nov 11 '16 17:11 wehowski

If you're interested in this for workers, there's the Sync Filesystem API for workers: https://www.html5rocks.com/en/tutorials/file/filesystem-sync/

Other than that, I would think making promised-based APIs and using ES7 async and await would help you design a more synchronous API.

ebidel avatar Nov 11 '16 17:11 ebidel

Thank you! I am about reading the links right now and will give feedback if I have any questions, thanks!

wehowski avatar Nov 11 '16 18:11 wehowski

https://www.html5rocks.com/en/tutorials/file/filesystem-sync/ "The synchronous API can only be used within a Web Worker context, whereas the asynchronous API can be used in and out of a Worker." Ok, well. I read about workers ans Promises, but only use the last one right now in production projects (where in my case they resolve "to late"). As for workers I have to rely on addEventListener('message') in my main thread which is always asynchronous. So can I summer up: I can use filesystem API sync in workers but not in main thread?

I would further fallback to localStorage, but the quota is limited there?

I am now reading about https://www.google.de/?gws_rd=ssl#q=indexedDB+sync

I also provide a method frdl.wait https://github.com/frdl/-Flow/blob/master/api-d/4/js-api/library.js/core/plugin.core.js#L3810 but I think this one is "blocking itself?" ( https://github.com/frdl/-Flow/blob/master/api-d/4/js-api/library.js/core/plugin.core.js#L12381 ???)

Edit: I also use your indexedDB shim!

wehowski avatar Nov 11 '16 19:11 wehowski

Yes I don't think this API is a good fit for you if you want to to have something sync. Tbh, sync storage APIs are slow and jank the main thread, so you should try to use IDB or the filesystem API if possible. What's the reason for needing synchronous?

On Fri, Nov 11, 2016, 11:38 AM Till Wehowski [email protected] wrote:

https://www.html5rocks.com/en/tutorials/file/filesystem-sync/ "The synchronous API can only be used within a Web Worker context, whereas the asynchronous API can be used in and out of a Worker." Ok, well. I read about workers ans Promises, but only use the last one right now in production projects (where in my case they resolve "to late"). As for workers I have to rely on addEventListener('message') in my main thread which is always asynchronous. So can I summer up: I can use filesystem API sync in workers but not in main thread?

I would further fallback to localStorage, but the quota is limited there?

I am now reading about https://www.google.de/?gws_rd=ssl#q=indexedDB+sync

I also provide a method frdl.wait https://github.com/frdl/-Flow/blob/master/api-d/4/js-api/library.js/core/plugin.core.js#L3810 but I think this one is "blocking itself?" ( https://github.com/frdl/-Flow/blob/master/api-d/4/js-api/library.js/core/plugin.core.js#L12381 ???)

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/ebidel/filer.js/issues/64#issuecomment-260038079, or mute the thread https://github.com/notifications/unsubscribe-auth/AAOigBcMykhau5oWv50xNBuQZyPVJIoYks5q9MQhgaJpZM4Kv-sc .

ebidel avatar Nov 11 '16 19:11 ebidel

"What's the reason for needing synchronous? Your right, most time I'm satisfied with async. I just can give you one example where I would like to have an synchronous access to cached data: The framework, I already linked above, is using "widgets". If a widget refers to a css file, it is loaded and filtered by my require functions css compiler https://github.com/frdl/-Flow/blob/master/cdn/frdl/flow/ui/frdlui.js#L2082

        var _cssCompiler = function(content, module){

            var c = content;



            var urlMatchingRegex = /[:,\s]\s*url\s*\(\s*(?:'(\S*?)'|"(\S*?)"?|((?:\\\s|\\\)|\\\"|\\\'|\S)*?))\s*\)/gi;

             c = c.replace(urlMatchingRegex, function(fullMatch, url) { 
                   var n = str_replace('"', "'", fullMatch);
                   /*/c = str_replace(fullMatch, n, c); */
                   return n;
             });

             c = c.replace(urlMatchingRegex, function(fullMatch, url) { 
               var __U =  frdl.require('url');
               if('undefined' === typeof url){
                 var _u = frdl.explode('(', fullMatch, 2)[1];
                 var url = _u.substr(0, _u.length -1);
               }

              if('data:'===url.substr(0, 'data:'.length)) {
                return fullMatch;
              }


              try{
                var nu = __U.parse((module.directory || module.parent.directory) || '').resolve(url);
              }catch(err){
                 var nu = ((module.directory || module.parent.directory) || '') + url; 
                 if(1<frdl.debug.mode()) console.warn(err); 
              }

                var nt = str_replace(url, nu, fullMatch);
                return nt;
             });


             var i = 0, n = new Date().getTime();
             c = c.replace(urlMatchingRegex, function(fullMatch, url) { 
               if('undefined' === typeof url){
                 var _u = frdl.explode('(', fullMatch, 2)[1];
                 var url = _u.substr(0, _u.length -1);
               }

              if('data:'===url.substr(0, 'data:'.length)) {
                return fullMatch;
              }


              var ext = frdl.fs5.polyfill.getFiler().Util.getFileExtension(url);
                  if('.'===ext.substr(0,1)){
                       ext = ext.substr(1, ext.length);
                  }

               var imageExt = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'ico'];
               if(-1 === imageExt.indexOf(ext)){
                  return fullMatch;
               }

               i++;

               _full = fullMatch;
               var p = frdl.getImageDataUri(url);
               p.then(function(r){
                 _full = str_replace(url, r.uri, fullMatch);
                 c = frdl.str_replace(fullMatch, _full, c);   
                  i--;                      
               }, function(err){
                  i--;   
                  console.error(err);
                  console.trace(err);
               }); 


                 return _full;
             });


            var exports = {};


          var defProp = (Object.defineProperty) ? true : false;

           try{
             if(!!defProp){
               Object.defineProperty(exports, 'content', {
                 get : function(){ return c; }
               });  
            }

          }catch(err){
               defProp = false;
          }

          if(true !== defProp){
           if(Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) {
                exports.__defineGetter__('content', function(){
                   return c; 
                } );
           }else{
              exports.content = c;
            }            
          }  

             return exports;
        };

As you can see, the css compiler trys to convert all url(...) image referals into data:uris, what happens asynchronous (promise=frdl.getImageDataUri). I just would olike to use filer/filesystemAPI to cache this compile css files and load it if needed.

The one solution I imagine spontaneous would be to wrap the requireCSS/its callback into another wrapper. But this way I fear to run into a "callback hell"...?

P.S.: Yes, workers are on my next plan by the way, but they don't turn anything into synchronous?

wehowski avatar Nov 11 '16 20:11 wehowski

Hi Ebidel, although indexedDB maybe better, I think I got it now for readFileSync by just sending a XMLHttpRequest to the filesystemUrl. regards, Till

Edit: Sorry, I have to correct: This only works in filesystemAPI enabled browser, not with the indexedDB/filer shim!?!

wehowski avatar Nov 12 '16 03:11 wehowski