@statewalker/webrun-files 0.1.0
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/CHANGELOG.md +2 -0
- package/LICENSE +21 -0
- package/README.md +17 -0
- package/dist/index-umd.js +881 -0
- package/dist/index-umd.min.js +2 -0
- package/dist/index.js +862 -0
- package/dist/index.min.js +2 -0
- package/index.js +1 -0
- package/package.json +49 -0
- package/src/BrowserFilesApi.js +164 -0
- package/src/FilesApi.js +133 -0
- package/src/MemFilesApi.js +129 -0
- package/src/NodeFilesApi.js +222 -0
- package/src/addFilesApiLogger.js +25 -0
- package/src/getMimeType.js +19 -0
- package/src/index.js +10 -0
- package/src/mimeTypes.js +96 -0
- package/src/normalizePath.js +8 -0
- package/src/notImplemented.js +3 -0
- package/src/openBrowserFilesApi.js +67 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// @statewalker/webrun-files v0.1.0 https://github.com/statewalker/webrun-files Copyright 2023 Mikhail Kotelnikov
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).statewalker=e.statewalker||{},e.statewalker["webrun-files"]=e.statewalker["webrun-files"]||{}))}(this,(function(e){"use strict";function t(e){const t=e.split("/").filter((e=>!!e&&"."!==e));return 0===t.length&&t.push(""),t.unshift(""),t.join("/")}function i(){throw new Error("Not implemented.")}class n{constructor(e){this.options=e||{}}async*list(e,t={}){yield i()}async stats(e){return i()}async remove(e){return i()}async write(e,t){return i()}async*read(e,t){yield i()}async copy(e,t,i={}){const n=async(e,t,i)=>{t=`${t}${i.path.substring(e.length)}`;const n=this.read(i);return await this.write(t,n)},s=void 0===i.recursive||!!i.recursive,o=await this.stats(e);if("directory"===o.kind)for await(const o of this.list(e,{...i,recursive:s}))"directory"!==o.kind&&await n(e,t,o);else await n(e,t,o);return!0}async move(e,t,i={}){return!!await this.copy(e,t,i)&&(await this.remove(e),!0)}normalizePath(e){return t("object"==typeof e?e.path:e+"")}}const s=[{extensions:["aac"],mime:"audio/aac",description:"AAC audio"},{extensions:["abw"],mime:"application/x-abiword",description:"AbiWord document"},{extensions:["arc"],mime:"application/x-freearc",description:"Archive document (multiple files embedded)"},{extensions:["avi"],mime:"video/x-msvideo",description:"AVI: Audio Video Interleave"},{extensions:["azw"],mime:"application/vnd.amazon.ebook",description:"Amazon Kindle eBook format"},{extensions:["bin"],mime:"application/octet-stream",description:"Any kind of binary data"},{extensions:["bmp"],mime:"image/bmp",description:"Windows OS/2 Bitmap Graphics"},{extensions:["bz"],mime:"application/x-bzip",description:"BZip archive"},{extensions:["bz2"],mime:"application/x-bzip2",description:"BZip2 archive"},{extensions:["csh"],mime:"application/x-csh",description:"C-Shell script"},{extensions:["css"],mime:"text/css",description:"Cascading Style Sheets (CSS)"},{extensions:["csv"],mime:"text/csv",description:"Comma-separated values (CSV)"},{extensions:["doc"],mime:"application/msword",description:"Microsoft Word"},{extensions:["docx"],mime:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",description:"Microsoft Word (OpenXML)"},{extensions:["eot"],mime:"application/vnd.ms-fontobject",description:"MS Embedded OpenType fonts"},{extensions:["epub"],mime:"application/epub+zip",description:"Electronic publication (EPUB)"},{extensions:["gz"],mime:"application/gzip",description:"GZip Compressed Archive"},{extensions:["gif"],mime:"image/gif",description:"Graphics Interchange Format (GIF)"},{extensions:["htm","html"],mime:"text/html",description:"HyperText Markup Language (HTML)"},{extensions:["ico"],mime:"image/vnd.microsoft.icon",description:"Icon format"},{extensions:["ics"],mime:"text/calendar",description:"iCalendar format"},{extensions:["jar"],mime:"application/java-archive",description:"Java Archive (JAR)"},{extensions:["jpg","jpeg"],mime:"image/jpeg",description:"JPEG images"},{extensions:["js"],mime:"text/javascript",description:"JavaScript per the following specifications: https://html.spec.whatwg.org/multipage/#scriptingLanguages, https://html.spec.whatwg.org/multipage/#dependencies:willful-violation, https://datatracker.ietf.org/doc/draft-ietf-dispatch-javascript-mjs/"},{extensions:["json"],mime:"application/json",description:"JSON format"},{extensions:["jsonld"],mime:"application/ld+json",description:"JSON-LD format"},{extensions:["mid","midi"],mime:"application/ld+json",description:"Musical Instrument Digital Interface (MIDI)\taudio/midi audio/x-midi"},{extensions:["mjs"],mime:"text/javascript",description:"JavaScript module"},{extensions:["mp3"],mime:"audio/mpeg",description:"MP3 audio"},{extensions:["md"],mime:"text/markdown",description:"Markdown"},{extensions:["mpeg"],mime:"video/mpeg",description:"MPEG Video"},{extensions:["mpkg"],mime:"application/vnd.apple.installer+xml",description:"Apple Installer Package"},{extensions:["odp"],mime:"application/vnd.oasis.opendocument.presentation",description:"OpenDocument presentation document"},{extensions:["ods"],mime:"application/vnd.oasis.opendocument.spreadsheet",description:"OpenDocument spreadsheet document"},{extensions:["odt"],mime:"application/vnd.oasis.opendocument.text",description:"OpenDocument text document"},{extensions:["oga"],mime:"audio/ogg",description:"OGG audio"},{extensions:["ogv"],mime:"video/ogg",description:"OGG video"},{extensions:["ogx"],mime:"application/ogg",description:"OGG"},{extensions:["opus"],mime:"audio/opus",description:"Opus audio"},{extensions:["otf"],mime:"font/otf",description:"OpenType font"},{extensions:["png"],mime:"image/png",description:"Portable Network Graphics"},{extensions:["pdf"],mime:"application/pdf",description:"Adobe Portable Document Format (PDF)"},{extensions:["php"],mime:"application/x-httpd-php",description:"Hypertext Preprocessor (Personal Home Page)"},{extensions:["ppt"],mime:"application/vnd.ms-powerpoint",description:"Microsoft PowerPoint"},{extensions:["pptx"],mime:"application/vnd.openxmlformats-officedocument.presentationml.presentation",description:"Microsoft PowerPoint (OpenXML)"},{extensions:["rar"],mime:"application/vnd.rar",description:"RAR archive"},{extensions:["rtf"],mime:"application/rtf",description:"Rich Text Format (RTF)"},{extensions:["sh"],mime:"application/x-sh",description:"Bourne shell script"},{extensions:["svg"],mime:"image/svg+xml",description:"Scalable Vector Graphics (SVG)"},{extensions:["swf"],mime:"application/x-shockwave-flash",description:"Small web format (SWF) or Adobe Flash document"},{extensions:["tar"],mime:"application/x-tar",description:"Tape Archive (TAR)"},{extensions:["tif","tiff"],mime:"image/tiff",description:"Tagged Image File Format (TIFF)"},{extensions:["ttf"],mime:"font/ttf",description:"TrueType Font"},{extensions:["txt"],mime:"text/plain",description:"Text, (generally ASCII or ISO 8859-n)"},{extensions:["vsd"],mime:"application/vnd.visio",description:"Microsoft Visio"},{extensions:["wav"],mime:"audio/wav",description:"Waveform Audio Format"},{extensions:["weba"],mime:"audio/webm",description:"WEBM audio"},{extensions:["webm"],mime:"video/webm",description:"WEBM video"},{extensions:["webp"],mime:"image/webp",description:"WEBP image"},{extensions:["woff"],mime:"font/woff",description:"Web Open Font Format (WOFF)"},{extensions:["woff2"],mime:"font/woff2",description:"Web Open Font Format (WOFF)"},{extensions:["xhtml"],mime:"application/xhtml+xml",description:"XHTML"},{extensions:["xls"],mime:"application/vnd.ms-excel",description:"Microsoft Excel"},{extensions:["xlsx"],mime:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",description:"Microsoft Excel (OpenXML)"},{extensions:["xml"],mime:"application/xml",description:"XML; application/xml - if not readable from casual users (RFC 3023, section 3); text/xml - if readable from casual users (RFC 3023, section 3)"},{extensions:["xul"],mime:"application/vnd.mozilla.xul+xml",description:"XUL"},{extensions:["zip"],mime:"application/zip",description:"ZIP archive"},{extensions:["3gp"],mime:"video/3gpp",description:"3GPP audio/video container"},{extensions:["3g2"],mime:"video/3gpp2",description:"3GPP2 audio/video container; audio/3gpp if it doesn't contain video; audio/3gpp2 if it doesn't contain video"},{extensions:["7z"],mime:"application/x-7z-compressed",description:"7-zip archive"},{extensions:["jsx"],mime:"text/jsx",description:"JavaScript Syntax Extension / JavaScript XML format"},{extensions:["ts"],mime:"text/ts",description:"TypeScript format"},{extensions:["tsx"],mime:"text/tsx",description:"TypeScript Syntax Extension / TypeScript XML format"}],o=s.reduce(((e,t)=>(e[t.mime]=t.description,e)),{}),a=s.reduce(((e,t)=>{for(const i of t.extensions)e[i]=t.mime;return e}),{}),r=s.reduce(((e,t)=>(e[t.mime]=t.extensions,e)),{});function c(e){const t=e=e||"",i=(e=(e=e.split("?").shift()).split("/").pop()).split(".").pop();let n=a[i];return n||(n=t.match(/api\.observablehq\.com/)||t.match(/\.ojs$/)?"application/javascript-observable":"application/binary"),n}function p(e){const t=e.split("/");return t.pop(),t.join("/")}function d(...e){let t=e.map((e=>e.split("/"))).reduce(((e,t)=>(e.push(...t),e)),[]);const i=t.shift();return t=t.filter((e=>!!e&&"."!==e)),t.unshift(i),t.join("/")}async function m(e,t){try{const i=await e.stat(t);if(i&&i.isDirectory())return!0}catch(e){}const i=p(t);return t!==i&&(await m(e,i),await e.mkdir(t,{recursive:!0}),!0)}async function l(e,t){try{if((await e.stat(t)).isDirectory()){for await(let i of f(e,t,!1))await l(e,i.path);await e.rmdir(t)}else await e.unlink(t)}catch(e){if("ENOENT"!==e.code)throw e}}async function*f(e,t,i){try{if((await e.stat(t)).isDirectory()){const n=await e.readdir(t);for(const s of n.sort()){const n=d(t,s);let o=await e.stat(n);yield{path:n,stat:o},i&&o.isDirectory()&&(yield*f(e,n,!0))}}}catch(e){if("ENOENT"!==e.code)throw e}}class h extends n{constructor(e){if(super(e),!this.rootHandler)throw new Error("Root directory handler is not defined")}get rootHandler(){return this.options.rootHandler}async*list(e,{recursive:t=!1}={}){const i=this._getPathSegments(e),n=await this._getHandler(i,!1),s=this;"directory"===n.kind&&(yield*async function*e(t,i,n){for await(const o of i.values())yield await s._getFileInfo([...t,o.name],o),n&&"directory"==o.kind&&(yield*e([...t,o.name],o,n))}(i,n,t))}async stats(e){const t=this._getPathSegments(e),i=await this._getHandler(t,!1);return i?await this._getFileInfo(t,i):null}async remove(e){let t=this._getPathSegments(e);const i=t.pop(),n=await this._getHandler(t,!1),s=[];if(i)s.push(i);else for await(const e of n.values())s.push(e.name);for(const e of s)await n.removeEntry(e,{recursive:!0});return!0}async write(e,t){const i=this._getPathSegments(e),n=await this._getFileHandler(i),s=await n.createWritable();try{"function"==typeof t&&(t=t());for await(let e of t)await s.write(e.buffer?e.buffer:e)}finally{await s.close()}}async*read(e){const t=this._getPathSegments(e),i=await this._getFileHandler(t,!1);if(!i)return;const n=(await i.getFile()).stream().getReader();try{let e;for(;(e=await n.read())&&!e.done;)yield e.value}finally{n.cancel&&n.cancel()}}async _getHandler(e,t=!1){let i;try{i=await this._getFileHandler(e,t)}catch(n){try{i=await this._getDirectoryHandler(e,t)}catch(e){}}return i}async _getDirectoryHandler(e,t=!0){e=[...e];let i=this.rootHandler;for(let n of e)i=await i.getDirectoryHandle(n,{create:t});return i}async _getFileHandler(e,t=!0){const i=(e=[...e]).pop();let n=this.rootHandler;for(let t of e)n=await n.getDirectoryHandle(t,{create:!0});return await n.getFileHandle(i,{create:t})}async _getFileInfo(e,t){const i=(e=[...e])[e.length-1];e.unshift("");const n=e.join("/"),s={kind:"",path:n,name:i};if("directory"===t.kind)s.kind="directory";else{s.kind="file";const e=await t.getFile();s.size=e.size,s.type=c(n),s.lastModified=e.lastModified}return s}_getPathSegments(e){return("object"==typeof e?e.path:e+"").split("/").filter((e=>!!e))}}e.BrowserFilesApi=h,e.FilesApi=n,e.MemFilesApi=class extends n{constructor(e){super(e),this.index={"/":{kind:"directory",path:"/",name:""}}}async*list(e,{recursive:t=!1}={}){await this._init();const i=this.normalizePath(e),n=this._getPaths();for(const e of n){if(0!==e.indexOf(i)||e===i)continue;const n=e.substring(i.length+1).split("/");(t||1===n.length)&&(yield this._getFileInfo(e))}}async stats(e){await this._init();const t=this.normalizePath(e);return this._getFileInfo(t)}async remove(e){await this._init();const t=await this.stats(e);if(!t)return!1;for await(const{path:e}of this.list(t,{recursive:!0}))"/"!==e&&delete this.index[e];delete this.index[t.path]}async write(e,t){await this._init(),await this._doWrite(e,t)}async*read(e){await this._init();const t=this.normalizePath(e),i=this.index[t];if(!i||"file"!==i.kind)return;const n=i.content;yield*n}async _init(){return this._initPromise=this._initPromise||Promise.resolve().then((()=>this._addEntries(this.options.files)))}async _doWrite(e,t){const i=this.normalizePath(e).split("/").filter((e=>!!e)),n=[""];let s;for(let e=0;e<i.length;e++){const t=i[e];n.push(t);const o=n.join("/");s=this.index[o]=this.index[o]||{path:o,name:t,kind:"directory"}}s.kind="file",s.content=[],s.type=c(s.path),s.size=0,s.lastModified=Date.now(),"function"==typeof t&&(t=t());for await(let e of t)e=new Uint8Array(e),s.content.push(e),s.size+=e.length}async _addEntries(e={}){for(let[t,i]of Object.entries(e))"string"==typeof i?i=[(new TextEncoder).encode(i)]:i instanceof Uint8Array&&(i=[i]),await this._doWrite(t,i)}_getPaths(){return this._getIndexPaths(this.index)}_getIndexPaths(e){return Object.keys(e).sort((function(e,t){return e>t?1:e<t?-1:0}))}_getFileInfo(e){const t=this.index[e];if(!t)return null;const i={...t};return delete i.content,i}},e.NodeFilesApi=class extends n{constructor(e){if(super(e),!this.fs)throw new Error("File System is not defined.");if(!this.rootDir)throw new Error("Root directory is not defined.")}get rootDirSegments(){return this._rootDirSegments||(this._rootDirSegments=this._toPathSegments(this.options.rootDir||"./")),this._rootDirSegments}get rootDir(){return this._rootDir||(this._rootDir=this.rootDirSegments.join("/")),this._rootDir}get fs(){return this.options.fs}async _init(){return this._initialized=this._initialized||(async()=>{const e=this.rootDir;return await m(this.fs,e)})()}async*list(e,{recursive:t=!1}={}){await this._init();const i=this._expandPath(e),n=await this._stats(i);if(n&&"directory"===n.kind)for await(let e of f(this.fs,i,t))yield this._getFileInfo(e.path,e.stat)}async stats(e){await this._init();const t=this._expandPath(e);return this._stats(t)}async remove(e){await this._init();const t=this._expandPath(e);return await l(this.fs,t)}async write(e,t){await this._init();const i=this._expandPath(e),n=p(i);let s;await this.fs.mkdir(n,{recursive:!0});try{s=await this.fs.open(i,"w"),"function"==typeof t&&(t=t()),await s.writeFile(t)}finally{s&&await s.close()}}async*read(e,{start:t=0,bufferSize:i=8192}={}){await this._init();const n=this._expandPath(e);let s;try{s=await this.fs.open(n,"r");const e=0;for(let n=t,o=0;;n+=o){const t=new Uint8ClampedArray(i),a=await s.read(t,e,i,n);if(o=a.bytesRead,0===o)break;yield o<i?a.buffer.slice(0,o):a.buffer}}finally{s&&await s.close()}}async _stats(e){try{const t=await this.fs.stat(e);return this._getFileInfo(e,t)}catch(e){if("ENOENT"!==e.code)throw e;return null}}_getFileInfo(e,t){const i=this._toPathSegments(e).slice(this.rootDirSegments.length);i.unshift("");const n=i[i.length-1];let s={path:e=i.join("/"),name:n,kind:""};return t.isFile()?(s.size=t.size||0,s.type=c(e),s.kind="file",s.lastModified=new Date(t.mtime).getTime()):s.kind="directory",s}_toPathSegments(e){return(e=this.normalizePath(e)).split("/")}_expandPath(e){const t="object"==typeof e?e.path:e+"",i=this._toPathSegments(t).filter((e=>!!e));return i.unshift(...this.rootDirSegments),i.join("/")}},e.addFilesApiLogger=function({filesApi:e,log:t=console.log,wrapper:i={}}){return["list","stats","remove","write","read","copy","move"].reduce(((i,n)=>{const s=e[n].bind(e);return i[n]=(...i)=>{let o={method:n,stage:"enter",args:i};try{return t(o),o.result=s.call(e,...i)}catch(e){o.error=e}finally{o.stage="exit",t(o)}},i}),i)},e.extensionToMimeType=a,e.getMimeType=c,e.mimeTypeToExtensions=r,e.mimeTypes=s,e.mimeTypesDescriptions=o,e.normalizePath=t,e.openBrowserFilesApi=async function({handlerKey:e="root-dir",readwrite:t=!0,index:i={},get:n=(async e=>i[e]),set:s=(async(e,t)=>i[e]=t),del:o=(async e=>delete i[e])}={}){let a=await n(e);if(a||(a=await window.showDirectoryPicker(),await s(e,a)),!await async function(e,t){const i={};t&&(i.mode="readwrite");let n=!1;"granted"===await e.queryPermission(i)&&(n=!0);n||"granted"!==await e.requestPermission(i)||(n=!0);return n}(a,t))throw new Error("Access was not granted");if(!await async function(e){let t=!1;try{if("file"===e.kind)await e.getFile();else for await(let t of e.values())break;t=!0}catch(i){console.log(i,e),t=!1}return t}(a))throw await o(e),new Error("Can not access to the folder. Please try again.");return new h({rootHandler:a})}}));
|