<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_quote"><div dir="ltr">Hi Mattias, sorry for the late answer.<br></div><div dir="ltr"><br></div><div>I have bad and good news. Also I have an idea about a possible 'full-offline cross-browser virtual-fs' logic. :-)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
... and speed vs compatibility.<br>
<br>
How do you propose to replace the methods ReadBuffer and WriteBuffer?<br></blockquote><div><br></div><div>The bad news:</div><div><br></div><div>Unfortunately, the local filesystem specs were discontinued around 2014 by W3C: "<a href="https://www.w3.org/TR/file-system-api/" target="_blank">Work on this document has been discontinued and it should not be referenced or used as a basis for implementation</a>". Another message (from Eric U): <a href="http://lists.w3.org/Archives/Public/public-webapps/2014AprJun/0010.html" target="_blank">http://lists.w3.org/Archives/Public/public-webapps/2014AprJun/0010.html</a> .</div><div><br></div><div>However, the File()/Blob() objects were kept. A File object can be accessed via an '<input type=file>' or as item of a FileList from an '<input ... multiple>'. I've done some tests and both works properly, but for security reasons (which I totally agree) "you can only access a file with the user's consent". Thus, I can't imagine how we could easily handle it via <streamed-pascal-classes>.SaveTo/LoadFromFile(), due to user need to 'click' in a HTML control. :-(</div><div><br></div><div>The good news:</div><div><br></div><div>Both File/Blob objects allows to create a URL object, that can assigned to a control (even hidden) and finally downloaded to the user downloads without his consent. It could be useful for our SaveToFile() methods. Please take a look at this project (implementing the W3C's saveAs() FileSaver interface): <a href="https://eligrey.com/demos/FileSaver.js/" target="_blank">https://eligrey.com/demos/FileSaver.js</a> . It allows you to specify the name of the file to be saved (the example uses an image, text and a rich text) .</div><div><br></div><div>At the end of this email I'm going to show how it could be useful + local buffering...</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Does that mean streams require at least ECMAScript6?<br></blockquote><div><br></div><div>After checking how pas2js already handles the TBytes (array of byte) type, we don't need ArrayBuffer anymore. :-) The growing buffer logic and the error handling can be easily done in purely Pascal code, as you suggested. Advantages by using TBytes: it will be compatible in any ES (1st edition or higher). :-)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
What about the nodejs platform? As you stated below it provides an API,<br>
that gives more complete and more direct access.<br></blockquote><div><br></div><div>The nodejs' fs is awesome. We should use it for that platform. And ...</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
What transpiler parameter?<br></blockquote><div><br></div><div>... switched using something like this:</div><div><br></div><div>{$IFDEF BROWSER} // when the -Tbrowser parameter is passed</div><div>... browser logic ...</div><div>{$ENDIF}</div><div>...</div><div><div>{$IFDEF NODEJS} // when the -Tnodejs parameter is passed</div><div>... nodejs logic ...</div><div>{$ENDIF}</div></div><div><br></div><div>I'm not sure if these macros are available when passing the '-T<script-style>' parameter, but we could easily add it.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
A big challenge is the asynchronous file system access in the<br>
browser. How do you want to handle this?</blockquote></div><div><br></div><div>Indeed. But I have an idea which I would like to check if you agree:</div><div><br></div><div>The following native technique would be great, but it is Chrome-specific and it's unlikely to be implemented by other browsers and is no longer being standardized with the W3C: <a href="https://www.html5rocks.com/en/tutorials/file/filesystem" target="_blank">https://www.html5rocks.com/en/tutorials/file/filesystem</a> . (It have the latest Chromium in my Linux and the 'FileSystem API' availability is 'No' in the <a href="http://html5test.com" target="_blank">http://html5test.com</a> checker). However, we could use only this logic idea. Supposing we would use a browser storage to implement the TFileStream:</div><div><br></div><div>- since its last parameter is a Word type, we could add  two new types pas2js-specific without breaking the original TFileStream ABI: fmUseSessionStorage/fmUseLocalStorage (that can be flagged as 'fmCreate or fmUseSessionStorage', 'fmOpenReadWrite or fmUseLocalStorage' and so on);</div><div>- the write(), read(), seek() logics would be handled in the session/localstorage (according the fmUse* above);</div><div>- the flush() logic would read the buffer from session/localstorage and downloaded to the user downloads (using the FileSaver.js idea);</div><div>- if any fmUseSessionStorage/fmUseLocalStorage is passed, it assumes fmUseSessionStorage be default to make the browser storage clear.</div><div><br></div><div>The session/localstorage are good because they don't need a user agreement to be used, and both are already consolidated in several browsers (even mobile ones). Perhaps they are even more useful than <a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers" target="_blank">Service Workers</a> (SW) to handle big files, because SW is a very recent technology and I'm not sure if it provides anything to be used in our seek() logic. IMHO, the session/localstorage has good limits for our buffering. This link shows a table + info about them and 'offline' data limits: <a href="https://www.html5rocks.com/en/tutorials/offline/quota-research" target="_blank">https://www.html5rocks.com/en/tutorials/offline/quota-research</a> .</div><div><br></div><div><div>Use Cases of the idea:</div><div><br></div><div>- when a file or directory is selected for upload, it copies the files into a local browser data and uploads a chunk at a time, rather than sending a file at a time in a XHR;</div><div>- uploads/downloads can be restarted after browser crashes, network interruptions, etc. using an efficient streaming + seek;</div><div><div>- the ability to organize and configure projects by creating directories, files etc.;</div><div>- edited files could be accessed by client-side applications;</div></div></div><div><br></div><div>Some topics above were cut from this <a href="https://www.html5rocks.com/en/tutorials/file/filesystem/" target="_blank">article</a> and its <a href="http://www.htmlfivewow.com/demos/terminal/terminal.html" target="_blank">HTML5 Terminal project</a> example. It uses the unstandardized fs, but it can be implemented using session/localstorage with some work.</div><div><br></div><div>What do you think? Maybe I'm dreaming out loud. 😅</div><div><br></div>--<br><div dir="ltr" class="m_4699985615965478838m_3745922336745329520gmail-m_-8815894642464923859gmail-m_4475679815334892161gmail_signature"><div dir="ltr"><div>Silvio Clécio</div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>