@vbarbarosh/node-helpers 3.76.1 → 3.76.2
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/README.md +1 -1
- package/dist/browser.js +1 -1
- package/package.json +1 -1
- package/src/assert_positive_integer.js +10 -0
- package/src/assert_positive_integer.md +8 -0
- package/src/fastdl.js +45 -4
- package/src/fastdl.md +8 -0
- package/src/http_get_file.js +15 -7
- package/src/http_get_file.md +7 -3
- package/src/http_get_stream_range.js +25 -7
- package/src/http_get_stream_range.md +10 -8
- package/src/http_stream_range.js +5 -0
- package/src/http_stream_range.md +4 -1
- package/src/mongo_stream_upsert.js +2 -0
- package/src/mongo_stream_upsert.md +1 -0
- package/src/mongo_stream_write.js +2 -0
- package/src/mongo_stream_write.md +1 -0
- package/src/parallel.js +2 -0
- package/src/parallel.md +1 -0
- package/src/redis_poll_zshift_callback_rpush.js +3 -3
- package/src/stream_map_parallel.js +2 -0
- package/src/stream_map_parallel.md +2 -0
- package/src/stream_multiplex.js +5 -3
- package/src/stream_multiplex.md +2 -0
- package/src/stream_progress.js +10 -3
- package/src/stream_progress.md +1 -0
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ npm install @vbarbarosh/node-helpers
|
|
|
20
20
|
A subset of `@vbarbarosh/node-helpers` is available for browser:
|
|
21
21
|
|
|
22
22
|
```html
|
|
23
|
-
<script src="https://unpkg.com/@vbarbarosh/node-helpers@3.76.
|
|
23
|
+
<script src="https://unpkg.com/@vbarbarosh/node-helpers@3.76.2/dist/browser.js"></script>
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
⚠️ All browser functions are exposed globally.
|
package/dist/browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var t={932(t){t.exports=function(t){return"number"==typeof t&&isFinite(t)}},5392(t,e,n){const r=n(932);t.exports=function(t,e){return r(t)&&t>e}},4106(t,e){function n(t,e){var n=[],r=[];return null==e&&(e=function(t,e){return n[0]===e?"[Circular ~]":"[Circular ~."+r.slice(0,n.indexOf(e)).join(".")+"]"}),function(o,s){if(n.length>0){var u=n.indexOf(this);~u?n.splice(u+1):n.push(this),~u?r.splice(u,1/0,o):r.push(o),~n.indexOf(s)&&(s=e.call(this,o,s))}else n.push(s);return null==t?s:t.call(this,o,s)}}(t.exports=function(t,e,r,o){return JSON.stringify(t,n(e,o),r)}).getSerialize=n},6083(t){t.exports=function(t=[],e=1){if(e<1)throw new Error("Limit value should be at least 1");const n=[];for(let r=0,o=t.length;r<o;r+=e)n.push(t.slice(r,r+e));return n}},2458(t,e,n){const r=n(7727);t.exports=function(t=[],e=1,n=1){const o=r(1,e,Math.floor(t.length/n)),s=Math.floor(t.length/o);let u=t.length%o;const c=[];for(let e=0;e<t.length;){const n=s+(u?1:0);c.push(t.slice(e,e+n)),e+=n,u&&u--}return c}},353(t,e,n){const r=n(4476),o=1e-5;t.exports=function(t,e){const n=Math.floor(t*e);if(n<=1)return[0];const s=[];for(let e=0;e<n;++e)s.push(r(e/(n-1)*(t-o),o));return s}},6372(t,e,n){const r=n(6785);t.exports=function(t,e=Number){return t.map(t=>e(t)).reduce((t,e)=>r(t,e),0)}},3537(t){t.exports=function(t,e){const n=new Map;return t.forEach(function(t){const r=e(t);n.has(r)||n.set(r,{key:r,items:[]}),n.get(r).items.push(t)}),n.values().toArray()}},2976(t){t.exports=function(t,e){const n={};return t.forEach(function(t){const r=e(t);n[r]=n[r]||{key:r,items:[]},n[r].items.push(t)}),n}},2166(t,e,n){const r=n(956);t.exports=function(t,e=r){const n={};return t.forEach(t=>n[e(t)]=t),n}},7866(t,e,n){const r=n(7347);t.exports=function(t,e=Number){return t.map(t=>e(t)).reduce((t,e)=>r(t,e),1)}},6772(t,e,n){const r=n(956);t.exports=function(t,e=r){let n=null,o=null,s=!1;return t.forEach(function(t){const r=e(t);Number.isNaN(r)||(!s||o<r)&&(s=!0,o=r,n=t)}),n}},42(t,e,n){const r=n(956);t.exports=function(t,e=r){let n=null,o=null,s=!1;return t.forEach(function(t){const r=e(t);Number.isNaN(r)||(!s||o>r)&&(s=!0,o=r,n=t)}),n}},3685(t){t.exports=function t(e,n=e.length){if(n!==e.length)return function(e,n){if(0===n)return[[]];if(e.length<n)return[];const r=[];for(let o=0;o<e.length;o++){const s=e.slice(0,o).concat(e.slice(o+1));for(const u of t(s,n-1))r.push([e[o],...u])}return r}(e,n);let r,o,s=(e=e.slice()).length,u=[e.slice()],c=new Array(s).fill(0),a=1;for(;a<s;)c[a]<a?(r=a%2&&c[a],o=e[a],e[a]=e[r],e[r]=o,++c[a],a=1,u.push(e.slice())):(c[a]=0,++a);return u}},4943(t){t.exports=function(t){for(let e=t.length;--e>0;){const n=Math.floor(Math.random()*(e+1)),r=t[e];t[e]=t[n],t[n]=r}return t}},2356(t,e,n){const r=n(8310),o=n(4332);t.exports=function(t,e,n=r){const s=new Map;return t.sort(function(t,r){if(!s.has(t)){const n=e(t);s.set(t,Array.isArray(n)?n:[n])}if(!s.has(r)){const t=e(r);s.set(r,Array.isArray(t)?t:[t])}return o(s.get(t),s.get(r),n)})}},5181(t,e,n){const r=n(8310);t.exports=function(t,e,n,o=r){const s=Object.create(null);return n.forEach((t,e)=>s[t]=e+1),t.sort(function(t,n){const r=s[e(t)],u=s[e(n)];return r&&u?r-u:r?-1:u?1:o(t,n)})}},453(t){t.exports=function(t,e=Number){let n=0;return t.forEach(function(t){n+=e(t)}),n}},3523(t,e,n){const r=n(956);t.exports=function(t,e=r){const n=new Set;return t.filter(function(t){const r=e(t);return!n.has(r)&&(n.add(r),!0)})}},6382(t,e,n){const r=n(956);t.exports=function(t,e=r){const n=[],o=new Set;for(let r=t.length;--r>=0;){const s=t[r],u=e(s);o.has(u)||(o.add(u),n.push(s))}return n.reverse()}},7727(t){t.exports=function(t,e,n){return Math.max(t,Math.min(e,n))}},9870(t){t.exports=function(t,e){return t.setHours(t.getHours()+e),t}},5799(t){t.exports=function(t,e){return t.setMilliseconds(t.getMilliseconds()+e),t}},3160(t){t.exports=function(t,e){return t.setMinutes(t.getMinutes()+e),t}},1570(t){t.exports=function(t,e){if(!e)return t;const n=t.getDate();return t.setMonth(t.getMonth()+e),t.getDate()!==n&&t.setDate(0),t}},9296(t){t.exports=function(t,e){return t.setSeconds(t.getSeconds()+e),t}},5488(t){t.exports=function(t,e){return Math.floor((t.getTime()-e.getTime())/1e3)}},3752(t){t.exports=function(t){const e=t.getFullYear();return e%4==0&&e%100!=0||e%400==0}},3150(t){t.exports=function(t){return t=Math.trunc(Math.abs(t)),[Math.floor(t/36e5),Math.floor(t%36e5/6e4),Math.floor(t%6e4/1e3),t%1e3]}},2806(t){t.exports=function(t,e){return t.getTime()-e.getTime()}},8310(t,e,n){const r=n(7668);t.exports=function(t,e){return"string"==typeof t&&"string"==typeof e?r(t,e):t<e?-1:t>e?1:0}},2092(t,e,n){const r=n(8310);t.exports=function(t,e){return r(e,t)}},3553(t){function e(t){return"-"===t[0]?(t=t.slice(1),function(e,r){return n(r[t],e[t])}):function(e,r){return n(e[t],r[t])}}function n(t,e){return"string"==typeof t&&"string"==typeof e?t.localeCompare(e):t-e}t.exports=function(t){const n=t.map(e);switch(n.length){case 0:return()=>0;case 1:return n[0];case 2:return function(t,e){return n[0](t,e)||n[1](t,e)};case 3:return function(t,e){return n[0](t,e)||n[1](t,e)||n[2](t,e)};default:return function(t,e){for(let r=0;r<n.length;++r){const o=n[r](t,e);if(o)return o}return 0}}}},3129(t){t.exports=function(t,e){return t-e}},4332(t,e,n){const r=n(8310);t.exports=function(t,e,n=r){const o=Math.min(t.length,e.length);for(let r=0;r<o;++r){const o=n(t[r],e[r]);if(o)return o}return 0}},3106(t){t.exports=function(t,e){return t<e?-1:t>e?1:0}},2271(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{sensitivity:"base"})}},4457(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{sensitivity:"variant"})}},7668(t){function e(t,e){const r=t.replace(/^0+/,""),o=e.replace(/^0+/,"");return r.length-o.length||n(r,o)||t.length-e.length}function n(t,e){return t<e?-1:t>e?1:0}t.exports=function(t,r){const o=t.match(/\d+|\D+/g)||[],s=r.match(/\d+|\D+/g)||[],u=Math.min(o.length,s.length);for(let t=0;t<u;++t){const r=o[t][0]<="9"&&s[t][0]<="9"&&o[t][0]>="0"&&s[t][0]>="0"?e(o[t],s[t]):n(o[t],s[t]);if(r)return r}return o.length-s.length}},4385(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{numeric:!0,sensitivity:"base"})}},8951(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{numeric:!0,sensitivity:"variant"})}},4734(t,e,n){const r=n(8310),o=n(2092),s=n(956),u=Symbol("fcmpx.missing");function c(t){const{read:e,fcmp:n}=a(t);return function(t,r){return n(e(t),e(r))}}function a(t){if("function"==typeof t)return{read:i(t),fcmp:f(r)};if("string"==typeof t){const e=t.startsWith("-");return{read:i(e?t.slice(1):t),fcmp:f(e?o:r)}}const e=t.fcmp,n=i(t.read),s=f(t.desc?e?(t,n)=>e(n,t):o:e??r);if(Array.isArray(t.top)){const e=new Map(t.top.map((t,e)=>[t,e]));return{read:t=>e.get(n(t))??e.size,fcmp:s}}if(Array.isArray(t.bottom)){const e=new Map(t.bottom.map((t,e)=>[t,e]));return{read:t=>e.get(n(t))??-1,fcmp:s}}return{read:n,fcmp:s}}function i(t){if(void 0===t||""===t||"."===t)return s;if("function"==typeof t)return function(e){return t(e)??u};if("string"==typeof t){const e=t.split("."),[n,r,o,s,c]=e;switch(e.length){case 1:return t=>t?.[n]??u;case 2:return t=>t?.[n]?.[r]??u;case 3:return t=>t?.[n]?.[r]?.[o]??u;case 4:return t=>t?.[n]?.[r]?.[o]?.[s]??u;case 5:return t=>t?.[n]?.[r]?.[o]?.[s]?.[c]??u;default:return t=>e.reduce((t,e)=>t?.[e],t)??u}}return e=>e?.[t]??u}function f(t){return function(e,n){return e===u?n===u?0:1:n===u?-1:t(e,n)}}t.exports=function t(e){if("string"==typeof e)return e.includes(",")?t(e.split(",")):c(e);if(!Array.isArray(e))return c(e);const n=e.map(a);return function(t,e){const r=n.map(e=>e.read(t)),o=n.map(t=>t.read(e));for(let t=0;t<n.length;++t){const e=n[t].fcmp(r[t],o[t]);if(e)return e}return 0}}},7960(t){function e(t){let e,n,r;return e=t.replaceAll("^",""),n=e.length!==t.length,e=(t=e).replaceAll("$",""),r=e.length!==t.length,e=(t=e).replaceAll("!",""),(t.length-e.length)%2?n&&r?t=>!(t.startsWith(e)&&t.endsWith(e)):n?t=>!t.startsWith(e):r?t=>!t.endsWith(e):t=>!t.includes(e):n&&r?t=>t.startsWith(e)&&t.endsWith(e):n?t=>t.startsWith(e):r?t=>t.endsWith(e):t=>t.includes(e)}t.exports=function(t){let n,r,o,s;const u=function(t){return t.split("/").filter(t=>t).map(e)}(t);switch(u.length){case 0:return()=>!0;case 1:return u[0];case 2:return[n,r]=u,t=>n(t)&&r(t);case 3:return[n,r,o]=u,t=>n(t)&&r(t)&&o(t);case 4:return[n,r,o,s]=u,t=>n(t)&&r(t)&&o(t)&&s(t);default:return t=>u.every(e=>e(t))}}},6017(t){t.exports=function(t){if("number"!=typeof t||Number.isNaN(t))return"n/a";if(!t)return"0KB";if(t<1024)return"1KB";const e=Math.floor(Math.log(t)/Math.log(1024));return`${(t/1024**e).toFixed(t>1048576?2:0)}${["B","KB","MB","GB","TB","PB"][e]}`.replace(/\.00/,".0")}},1284(t){t.exports=function(t){return t.getFullYear()+`/0${t.getMonth()+1}/0${t.getDate()} 0${t.getHours()}:0${t.getMinutes()}:0${t.getSeconds()}`.replace(/0(\d\d)/g,"$1")}},5224(t){function e(t){return t>9?`${t}`:`0${t}`}t.exports=function(t){return t.getFullYear()+e(t.getMonth()+1)+e(t.getDate())+"_"+(e(t.getHours())+e(t.getMinutes())+e(t.getSeconds()))}},1690(t){function e(t){return t>9?`${t}`:`0${t}`}t.exports=function(t){return t.getFullYear()+"/"+e(t.getMonth()+1)+"/"+e(t.getDate())+" "+e(t.getHours())+":"+e(t.getMinutes())+":"+e(t.getSeconds())}},6997(t){t.exports=function(t){return t.getFullYear()+`/0${t.getMonth()+1}/0${t.getDate()}`.replace(/0(\d\d)/g,"$1")}},9009(t,e,n){const r=n(3332);t.exports=function(t){return t?t.response?.status&&t.response?.statusText&&t.response?.config?function(t){return`\n${t.message??"n/a"}\n\n--- REQUEST ---\n\n${(t.response.config.method||"").toUpperCase()} ${t.response.config.url}\n\n${JSON.stringify(t.response.config.headers||{},null,4).slice(1,-1).replace(/^\s+|,$/gm,"").trim()}\n\n--- RESPONSE ---\n\n${t.response.status} ${t.response.statusText}\n\n${String(t.response.data??"").slice(0,10240)||"n/a"}\n\n--- STACK ---\n\n${t.stack??"n/a"}\n`.trimStart()}(t):t.config?function(t){return`\n${t.message??"n/a"}\n\n--- REQUEST ---\n\n${(t.config.method||"").toUpperCase()} ${t.config.url}\n\n${JSON.stringify(t.config.headers||{},null,4).slice(1,-1).replace(/^\s+|,$/gm,"").trim()}\n\n--- STACK ---\n\n${t.stack??"n/a"}\n`.trimStart()}(t):r({code:t.code,name:t.name,message:t.message??"n/a",stack:t.stack&&t.stack.split(/\n\s*/)},null,4):r({error:void 0===t?"---undefined---":t})}},6015(t){t.exports=function(t,e=6){const[n,r]=t;return(n+r/1e9).toFixed(e)+"s"}},4153(t){t.exports=function(t){if("number"!=typeof t||Number.isNaN(t))return"n/a";if(!t)return"0";if(t<1e3)return t.toFixed(0);const e=parseInt(Math.floor(Math.log(t)/Math.log(1e3)),10);return`${(t/1e3**e).toFixed(2)}${["","K","M","G","T","P"][e]}`}},1120(t,e,n){const r=n(3150);t.exports=function(t){t||(t=0);const e=t<0?"-":"",[n,o,s]=r(t);return n?e+`0${n}:0${o}:0${s}`.replace(/0+(?=\d\d)/g,""):e+`0${o}:0${s}`.replace(/0+(?=\d\d)/g,"")}},7336(t,e,n){const r=n(3150);t.exports=function(t){t||(t=0);const e=t<0?"-":"",[n,o,s,u]=r(10*Math.round(Math.abs(t)/10));return n?e+`0${n}:0${o}:0${s}.0${u/10}`.replace(/0+(?=\d\d)/g,""):e+`0${o}:0${s}.0${u/10}`.replace(/0+(?=\d\d)/g,"")}},495(t,e,n){const r=n(3150);t.exports=function(t,e=!1){t||(t=0);const n=t<0?"-":"",[o,s,u,c]=r(t);return o||e?n+`0${o}:0${s}:0${u}.00${c}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g,""):n+`0${s}:0${u}.00${c}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g,"")}},7882(t){t.exports=function(t){return(100*t).toFixed(2).replace(/^(0|100).00$/,"$1")+"%"}},7111(t,e,n){const r=n(6017),o=n(7882),s=n(3527),u=n(5392);t.exports=function({percents:t,total:e,done:n,rate:c,eta:a,duration:i}){const f=u(c,0)?`${r(c)}/s`:"~";if(n>e)return`${r(n)} at ${f} duration=${s(i)}`;if(u(e,0)){const c=u(a,0)?s(a):"~";return`${o(t)} | ${r(n)} of ${r(e)} at ${f} ETA ${c} duration=${s(i)}`}return u(n,0)?`${r(n)} of ~ at ${f} duration=${s(i)}`:u(i,0)?`~ duration=${s(i)}`:"~"}},5051(t,e,n){const r=n(4153),o=n(7882),s=n(3527),u=n(5392);t.exports=function({percents:t,total:e,done:n,rate:c,eta:a,duration:i}){const f=u(c,0)?`${r(c)}/s`:"~";if(n>e)return`${r(n)} at ${f} duration=${s(i)}`;if(u(e,0)){const c=u(a,0)?s(a):"~";return`${o(t)} | ${r(n)} of ${r(e)} at ${f} ETA ${c} duration=${s(i)}`}return u(n,0)?`${r(n)} of ~ at ${f} duration=${s(i)}`:u(i,0)?`~ duration=${s(i)}`:"~"}},3527(t){t.exports=function(t){const e=Math.abs(Math.trunc(t)),n=`0${Math.floor(e/60/60)}:0${Math.floor(e/60)%60}:0${e%60}`.replace(/0(\d\d)/g,"$1");return t<=-1?"-"+n:n}},2677(t){t.exports=function(t){return t.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g,",")}},4206(t,e,n){const r=n(3719);t.exports=function(t,e){return r.delete(t,{responseType:"json",...e}).then(t=>t.data)}},4131(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"blob",...e}).then(t=>t.data)}},706(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"arraybuffer",...e}).then(t=>t.data)}},3066(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"json",...e}).then(t=>t.data)}},3019(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"text",responseEncoding:"utf8",...e}).then(t=>t.data)}},7379(t,e,n){const r=n(3719);t.exports=function(t,e){return r.head(t,e).then(t=>t.request.res.headers)}},2552(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.patch(t,e,n).then(t=>t.data)}},7484(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.post(t,e,n).then(t=>t.data)}},5420(t,e,n){const r=n(8241),o=n(3719);t.exports=function(t,e,n){const s=new r;for(let t=0,n=e.length;t<n;++t){const n=e[t];n.options?s.append(n.name,n.body,n.options):s.append(n.name,n.body)}if(s.getHeaders){const e={...n};return e.headers={...e.headers,...s.getHeaders()},Promise.resolve(o.post(t,s,e)).then(t=>t.data)}return Promise.resolve(o.post(t,s,n)).then(t=>t.data)}},4605(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},6357(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},2380(t,e,n){const r=n(3719);t.exports=async function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},956(t){t.exports=function(t){return t}},1828(t){t.exports=function(){}},3332(t,e,n){const r=n(4106);t.exports=r},6785(t){t.exports=function t(e,n){return n?t(n,e%n):Math.abs(e)}},7347(t,e,n){const r=n(6785);t.exports=function(t,e){return Math.abs(t*e)/r(t,e)}},792(t){t.exports=function(t,e,n,r){return 0===t&&"string"==typeof r?r:t%10==1&&t%100!=11?e.split("#").join(t):n.split("#").join(t)}},131(t){t.exports=function(t,e){return Math.floor(Math.random()*(e-t+1)+t)}},4476(t){t.exports=function(t,e=1){if(0===e)return t;const n=1/e,r=Math.sign(t),o=function(t){if(Math.floor(t)===t)return 0;const[e,n]=t.toExponential().split("e"),r=(e.split(".")[1]||"").length;return Math.max(0,r-parseInt(n,10))}(e),s=1e-12*r,u=Math.round(t*n+s)/n;return Number(u.toFixed(o))}},7233(t){t.exports=function(t,e){const n=String(t||""),r=Object.entries(e||{});if(!r.length)return n;const o=n.indexOf("#"),s=-1===o?"":n.slice(o),u=-1===o?n:n.slice(0,o),c=u.indexOf("?"),a=-1===c?u:u.slice(0,c),i=-1===c?"":u.slice(c+1),f=new URLSearchParams(i);r.forEach(function([t,e]){switch(e){case null:case void 0:f.delete(t);break;case!0:f.set(t,"1");break;case!1:f.set(t,"0");break;default:f.set(t,String(e))}});const p=f.toString();return a+(p?`?${p}`:"")+s}},6966(t,e,n){const r=n(2468);t.exports=function(t){return new r(function(e,n){t(function(t,r){t?n(t):e(r)})})}},7072(t,e,n){const r={"./array_chunk.js":6083,"./array_chunk_balanced.js":2458,"./array_fps.js":353,"./array_gcd.js":6372,"./array_group.js":3537,"./array_group_map.js":2976,"./array_index.js":2166,"./array_lcm.js":7866,"./array_max.js":6772,"./array_min.js":42,"./array_permutations.js":3685,"./array_shuffle.js":4943,"./array_sort.js":2356,"./array_sort_other.js":5181,"./array_sum.js":453,"./array_unique.js":3523,"./array_unique_last.js":6382,"./date_add_hours.js":9870,"./date_add_milliseconds.js":5799,"./date_add_minutes.js":3160,"./date_add_months.js":1570,"./date_add_seconds.js":9296,"./date_diff_seconds.js":5488,"./date_is_leap_year.js":3752,"./fcmp_dates.js":2806,"./fcmp_default.js":8310,"./fcmp_default_desc.js":2092,"./fcmp_from_spec.js":3553,"./fcmp_numbers.js":3129,"./fcmp_tuples.js":4332,"./fcmp_utf8_bin.js":3106,"./fcmp_utf8_ci.js":2271,"./fcmp_utf8_cs.js":4457,"./fcmp_utf8_natural_bin.js":7668,"./fcmp_utf8_natural_ci.js":4385,"./fcmp_utf8_natural_cs.js":8951,"./fcmpx.js":4734,"./filter1_from_spec.js":7960,"./format_bytes.js":6017,"./format_date.js":1284,"./format_date_fs.js":5224,"./format_date_human.js":1690,"./format_date_ymd.js":6997,"./format_error_report.js":9009,"./format_hrtime.js":6015,"./format_kilo.js":4153,"./format_ms.js":1120,"./format_ms2.js":7336,"./format_ms3.js":495,"./format_percents.js":7882,"./format_progress_bytes.js":7111,"./format_progress_kilo.js":5051,"./format_seconds.js":3527,"./format_thousands.js":2677,"./http_delete.js":4206,"./http_get_blob.js":4131,"./http_get_buffer.js":706,"./http_get_json.js":3066,"./http_get_utf8.js":3019,"./http_head.js":7379,"./http_patch_json.js":2552,"./http_post_json.js":7484,"./http_post_multipart.js":5420,"./http_put_buffer.js":4605,"./http_put_json.js":6357,"./http_put_utf8.js":2380,"./identity.js":956,"./ignore.js":1828,"./plural.js":792,"./random_int.js":131,"./urlmod.js":7233,"./waitcb.js":6966};function o(t){const e=s(t);return n(e)}function s(t){if(!n.o(r,t)){const e=new Error("Cannot find module '"+t+"'");throw e.code="MODULE_NOT_FOUND",e}return r[t]}o.keys=function(){return Object.keys(r)},o.resolve=s,t.exports=o,o.id=7072},8241(t){"use strict";t.exports=FormData},2468(t){"use strict";t.exports=Promise},3719(t){"use strict";t.exports=axios}};const e={};function n(r){const o=e[r];if(void 0!==o)return o.exports;const s=e[r]={exports:{}};return t[r](s,s.exports,n),s.exports}n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);const r=new URL(document.currentScript.src).searchParams.get("var")??"h";if(void 0!==window[r])console.log(`❌ @vbarbarosh/node-helpers@3.76.1 was not injected — window.${r} is already in use`);else{console.log(`🎉 @vbarbarosh/node-helpers@3.76.1 successfully exposed as window.${r}`),window[r]={};const t=n(7072);t.keys().forEach(function(e){const[,n]=e.match(/([^/]+)\.js$/);window[r][n]=t(e)})}})();
|
|
1
|
+
(()=>{var t={932(t){t.exports=function(t){return"number"==typeof t&&isFinite(t)}},5392(t,e,n){const r=n(932);t.exports=function(t,e){return r(t)&&t>e}},4106(t,e){function n(t,e){var n=[],r=[];return null==e&&(e=function(t,e){return n[0]===e?"[Circular ~]":"[Circular ~."+r.slice(0,n.indexOf(e)).join(".")+"]"}),function(o,s){if(n.length>0){var u=n.indexOf(this);~u?n.splice(u+1):n.push(this),~u?r.splice(u,1/0,o):r.push(o),~n.indexOf(s)&&(s=e.call(this,o,s))}else n.push(s);return null==t?s:t.call(this,o,s)}}(t.exports=function(t,e,r,o){return JSON.stringify(t,n(e,o),r)}).getSerialize=n},6083(t){t.exports=function(t=[],e=1){if(e<1)throw new Error("Limit value should be at least 1");const n=[];for(let r=0,o=t.length;r<o;r+=e)n.push(t.slice(r,r+e));return n}},2458(t,e,n){const r=n(7727);t.exports=function(t=[],e=1,n=1){const o=r(1,e,Math.floor(t.length/n)),s=Math.floor(t.length/o);let u=t.length%o;const c=[];for(let e=0;e<t.length;){const n=s+(u?1:0);c.push(t.slice(e,e+n)),e+=n,u&&u--}return c}},353(t,e,n){const r=n(4476),o=1e-5;t.exports=function(t,e){const n=Math.floor(t*e);if(n<=1)return[0];const s=[];for(let e=0;e<n;++e)s.push(r(e/(n-1)*(t-o),o));return s}},6372(t,e,n){const r=n(6785);t.exports=function(t,e=Number){return t.map(t=>e(t)).reduce((t,e)=>r(t,e),0)}},3537(t){t.exports=function(t,e){const n=new Map;return t.forEach(function(t){const r=e(t);n.has(r)||n.set(r,{key:r,items:[]}),n.get(r).items.push(t)}),n.values().toArray()}},2976(t){t.exports=function(t,e){const n={};return t.forEach(function(t){const r=e(t);n[r]=n[r]||{key:r,items:[]},n[r].items.push(t)}),n}},2166(t,e,n){const r=n(956);t.exports=function(t,e=r){const n={};return t.forEach(t=>n[e(t)]=t),n}},7866(t,e,n){const r=n(7347);t.exports=function(t,e=Number){return t.map(t=>e(t)).reduce((t,e)=>r(t,e),1)}},6772(t,e,n){const r=n(956);t.exports=function(t,e=r){let n=null,o=null,s=!1;return t.forEach(function(t){const r=e(t);Number.isNaN(r)||(!s||o<r)&&(s=!0,o=r,n=t)}),n}},42(t,e,n){const r=n(956);t.exports=function(t,e=r){let n=null,o=null,s=!1;return t.forEach(function(t){const r=e(t);Number.isNaN(r)||(!s||o>r)&&(s=!0,o=r,n=t)}),n}},3685(t){t.exports=function t(e,n=e.length){if(n!==e.length)return function(e,n){if(0===n)return[[]];if(e.length<n)return[];const r=[];for(let o=0;o<e.length;o++){const s=e.slice(0,o).concat(e.slice(o+1));for(const u of t(s,n-1))r.push([e[o],...u])}return r}(e,n);let r,o,s=(e=e.slice()).length,u=[e.slice()],c=new Array(s).fill(0),a=1;for(;a<s;)c[a]<a?(r=a%2&&c[a],o=e[a],e[a]=e[r],e[r]=o,++c[a],a=1,u.push(e.slice())):(c[a]=0,++a);return u}},4943(t){t.exports=function(t){for(let e=t.length;--e>0;){const n=Math.floor(Math.random()*(e+1)),r=t[e];t[e]=t[n],t[n]=r}return t}},2356(t,e,n){const r=n(8310),o=n(4332);t.exports=function(t,e,n=r){const s=new Map;return t.sort(function(t,r){if(!s.has(t)){const n=e(t);s.set(t,Array.isArray(n)?n:[n])}if(!s.has(r)){const t=e(r);s.set(r,Array.isArray(t)?t:[t])}return o(s.get(t),s.get(r),n)})}},5181(t,e,n){const r=n(8310);t.exports=function(t,e,n,o=r){const s=Object.create(null);return n.forEach((t,e)=>s[t]=e+1),t.sort(function(t,n){const r=s[e(t)],u=s[e(n)];return r&&u?r-u:r?-1:u?1:o(t,n)})}},453(t){t.exports=function(t,e=Number){let n=0;return t.forEach(function(t){n+=e(t)}),n}},3523(t,e,n){const r=n(956);t.exports=function(t,e=r){const n=new Set;return t.filter(function(t){const r=e(t);return!n.has(r)&&(n.add(r),!0)})}},6382(t,e,n){const r=n(956);t.exports=function(t,e=r){const n=[],o=new Set;for(let r=t.length;--r>=0;){const s=t[r],u=e(s);o.has(u)||(o.add(u),n.push(s))}return n.reverse()}},7727(t){t.exports=function(t,e,n){return Math.max(t,Math.min(e,n))}},9870(t){t.exports=function(t,e){return t.setHours(t.getHours()+e),t}},5799(t){t.exports=function(t,e){return t.setMilliseconds(t.getMilliseconds()+e),t}},3160(t){t.exports=function(t,e){return t.setMinutes(t.getMinutes()+e),t}},1570(t){t.exports=function(t,e){if(!e)return t;const n=t.getDate();return t.setMonth(t.getMonth()+e),t.getDate()!==n&&t.setDate(0),t}},9296(t){t.exports=function(t,e){return t.setSeconds(t.getSeconds()+e),t}},5488(t){t.exports=function(t,e){return Math.floor((t.getTime()-e.getTime())/1e3)}},3752(t){t.exports=function(t){const e=t.getFullYear();return e%4==0&&e%100!=0||e%400==0}},3150(t){t.exports=function(t){return t=Math.trunc(Math.abs(t)),[Math.floor(t/36e5),Math.floor(t%36e5/6e4),Math.floor(t%6e4/1e3),t%1e3]}},2806(t){t.exports=function(t,e){return t.getTime()-e.getTime()}},8310(t,e,n){const r=n(7668);t.exports=function(t,e){return"string"==typeof t&&"string"==typeof e?r(t,e):t<e?-1:t>e?1:0}},2092(t,e,n){const r=n(8310);t.exports=function(t,e){return r(e,t)}},3553(t){function e(t){return"-"===t[0]?(t=t.slice(1),function(e,r){return n(r[t],e[t])}):function(e,r){return n(e[t],r[t])}}function n(t,e){return"string"==typeof t&&"string"==typeof e?t.localeCompare(e):t-e}t.exports=function(t){const n=t.map(e);switch(n.length){case 0:return()=>0;case 1:return n[0];case 2:return function(t,e){return n[0](t,e)||n[1](t,e)};case 3:return function(t,e){return n[0](t,e)||n[1](t,e)||n[2](t,e)};default:return function(t,e){for(let r=0;r<n.length;++r){const o=n[r](t,e);if(o)return o}return 0}}}},3129(t){t.exports=function(t,e){return t-e}},4332(t,e,n){const r=n(8310);t.exports=function(t,e,n=r){const o=Math.min(t.length,e.length);for(let r=0;r<o;++r){const o=n(t[r],e[r]);if(o)return o}return 0}},3106(t){t.exports=function(t,e){return t<e?-1:t>e?1:0}},2271(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{sensitivity:"base"})}},4457(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{sensitivity:"variant"})}},7668(t){function e(t,e){const r=t.replace(/^0+/,""),o=e.replace(/^0+/,"");return r.length-o.length||n(r,o)||t.length-e.length}function n(t,e){return t<e?-1:t>e?1:0}t.exports=function(t,r){const o=t.match(/\d+|\D+/g)||[],s=r.match(/\d+|\D+/g)||[],u=Math.min(o.length,s.length);for(let t=0;t<u;++t){const r=o[t][0]<="9"&&s[t][0]<="9"&&o[t][0]>="0"&&s[t][0]>="0"?e(o[t],s[t]):n(o[t],s[t]);if(r)return r}return o.length-s.length}},4385(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{numeric:!0,sensitivity:"base"})}},8951(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{numeric:!0,sensitivity:"variant"})}},4734(t,e,n){const r=n(8310),o=n(2092),s=n(956),u=Symbol("fcmpx.missing");function c(t){const{read:e,fcmp:n}=a(t);return function(t,r){return n(e(t),e(r))}}function a(t){if("function"==typeof t)return{read:i(t),fcmp:f(r)};if("string"==typeof t){const e=t.startsWith("-");return{read:i(e?t.slice(1):t),fcmp:f(e?o:r)}}const e=t.fcmp,n=i(t.read),s=f(t.desc?e?(t,n)=>e(n,t):o:e??r);if(Array.isArray(t.top)){const e=new Map(t.top.map((t,e)=>[t,e]));return{read:t=>e.get(n(t))??e.size,fcmp:s}}if(Array.isArray(t.bottom)){const e=new Map(t.bottom.map((t,e)=>[t,e]));return{read:t=>e.get(n(t))??-1,fcmp:s}}return{read:n,fcmp:s}}function i(t){if(void 0===t||""===t||"."===t)return s;if("function"==typeof t)return function(e){return t(e)??u};if("string"==typeof t){const e=t.split("."),[n,r,o,s,c]=e;switch(e.length){case 1:return t=>t?.[n]??u;case 2:return t=>t?.[n]?.[r]??u;case 3:return t=>t?.[n]?.[r]?.[o]??u;case 4:return t=>t?.[n]?.[r]?.[o]?.[s]??u;case 5:return t=>t?.[n]?.[r]?.[o]?.[s]?.[c]??u;default:return t=>e.reduce((t,e)=>t?.[e],t)??u}}return e=>e?.[t]??u}function f(t){return function(e,n){return e===u?n===u?0:1:n===u?-1:t(e,n)}}t.exports=function t(e){if("string"==typeof e)return e.includes(",")?t(e.split(",")):c(e);if(!Array.isArray(e))return c(e);const n=e.map(a);return function(t,e){const r=n.map(e=>e.read(t)),o=n.map(t=>t.read(e));for(let t=0;t<n.length;++t){const e=n[t].fcmp(r[t],o[t]);if(e)return e}return 0}}},7960(t){function e(t){let e,n,r;return e=t.replaceAll("^",""),n=e.length!==t.length,e=(t=e).replaceAll("$",""),r=e.length!==t.length,e=(t=e).replaceAll("!",""),(t.length-e.length)%2?n&&r?t=>!(t.startsWith(e)&&t.endsWith(e)):n?t=>!t.startsWith(e):r?t=>!t.endsWith(e):t=>!t.includes(e):n&&r?t=>t.startsWith(e)&&t.endsWith(e):n?t=>t.startsWith(e):r?t=>t.endsWith(e):t=>t.includes(e)}t.exports=function(t){let n,r,o,s;const u=function(t){return t.split("/").filter(t=>t).map(e)}(t);switch(u.length){case 0:return()=>!0;case 1:return u[0];case 2:return[n,r]=u,t=>n(t)&&r(t);case 3:return[n,r,o]=u,t=>n(t)&&r(t)&&o(t);case 4:return[n,r,o,s]=u,t=>n(t)&&r(t)&&o(t)&&s(t);default:return t=>u.every(e=>e(t))}}},6017(t){t.exports=function(t){if("number"!=typeof t||Number.isNaN(t))return"n/a";if(!t)return"0KB";if(t<1024)return"1KB";const e=Math.floor(Math.log(t)/Math.log(1024));return`${(t/1024**e).toFixed(t>1048576?2:0)}${["B","KB","MB","GB","TB","PB"][e]}`.replace(/\.00/,".0")}},1284(t){t.exports=function(t){return t.getFullYear()+`/0${t.getMonth()+1}/0${t.getDate()} 0${t.getHours()}:0${t.getMinutes()}:0${t.getSeconds()}`.replace(/0(\d\d)/g,"$1")}},5224(t){function e(t){return t>9?`${t}`:`0${t}`}t.exports=function(t){return t.getFullYear()+e(t.getMonth()+1)+e(t.getDate())+"_"+(e(t.getHours())+e(t.getMinutes())+e(t.getSeconds()))}},1690(t){function e(t){return t>9?`${t}`:`0${t}`}t.exports=function(t){return t.getFullYear()+"/"+e(t.getMonth()+1)+"/"+e(t.getDate())+" "+e(t.getHours())+":"+e(t.getMinutes())+":"+e(t.getSeconds())}},6997(t){t.exports=function(t){return t.getFullYear()+`/0${t.getMonth()+1}/0${t.getDate()}`.replace(/0(\d\d)/g,"$1")}},9009(t,e,n){const r=n(3332);t.exports=function(t){return t?t.response?.status&&t.response?.statusText&&t.response?.config?function(t){return`\n${t.message??"n/a"}\n\n--- REQUEST ---\n\n${(t.response.config.method||"").toUpperCase()} ${t.response.config.url}\n\n${JSON.stringify(t.response.config.headers||{},null,4).slice(1,-1).replace(/^\s+|,$/gm,"").trim()}\n\n--- RESPONSE ---\n\n${t.response.status} ${t.response.statusText}\n\n${String(t.response.data??"").slice(0,10240)||"n/a"}\n\n--- STACK ---\n\n${t.stack??"n/a"}\n`.trimStart()}(t):t.config?function(t){return`\n${t.message??"n/a"}\n\n--- REQUEST ---\n\n${(t.config.method||"").toUpperCase()} ${t.config.url}\n\n${JSON.stringify(t.config.headers||{},null,4).slice(1,-1).replace(/^\s+|,$/gm,"").trim()}\n\n--- STACK ---\n\n${t.stack??"n/a"}\n`.trimStart()}(t):r({code:t.code,name:t.name,message:t.message??"n/a",stack:t.stack&&t.stack.split(/\n\s*/)},null,4):r({error:void 0===t?"---undefined---":t})}},6015(t){t.exports=function(t,e=6){const[n,r]=t;return(n+r/1e9).toFixed(e)+"s"}},4153(t){t.exports=function(t){if("number"!=typeof t||Number.isNaN(t))return"n/a";if(!t)return"0";if(t<1e3)return t.toFixed(0);const e=parseInt(Math.floor(Math.log(t)/Math.log(1e3)),10);return`${(t/1e3**e).toFixed(2)}${["","K","M","G","T","P"][e]}`}},1120(t,e,n){const r=n(3150);t.exports=function(t){t||(t=0);const e=t<0?"-":"",[n,o,s]=r(t);return n?e+`0${n}:0${o}:0${s}`.replace(/0+(?=\d\d)/g,""):e+`0${o}:0${s}`.replace(/0+(?=\d\d)/g,"")}},7336(t,e,n){const r=n(3150);t.exports=function(t){t||(t=0);const e=t<0?"-":"",[n,o,s,u]=r(10*Math.round(Math.abs(t)/10));return n?e+`0${n}:0${o}:0${s}.0${u/10}`.replace(/0+(?=\d\d)/g,""):e+`0${o}:0${s}.0${u/10}`.replace(/0+(?=\d\d)/g,"")}},495(t,e,n){const r=n(3150);t.exports=function(t,e=!1){t||(t=0);const n=t<0?"-":"",[o,s,u,c]=r(t);return o||e?n+`0${o}:0${s}:0${u}.00${c}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g,""):n+`0${s}:0${u}.00${c}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g,"")}},7882(t){t.exports=function(t){return(100*t).toFixed(2).replace(/^(0|100).00$/,"$1")+"%"}},7111(t,e,n){const r=n(6017),o=n(7882),s=n(3527),u=n(5392);t.exports=function({percents:t,total:e,done:n,rate:c,eta:a,duration:i}){const f=u(c,0)?`${r(c)}/s`:"~";if(n>e)return`${r(n)} at ${f} duration=${s(i)}`;if(u(e,0)){const c=u(a,0)?s(a):"~";return`${o(t)} | ${r(n)} of ${r(e)} at ${f} ETA ${c} duration=${s(i)}`}return u(n,0)?`${r(n)} of ~ at ${f} duration=${s(i)}`:u(i,0)?`~ duration=${s(i)}`:"~"}},5051(t,e,n){const r=n(4153),o=n(7882),s=n(3527),u=n(5392);t.exports=function({percents:t,total:e,done:n,rate:c,eta:a,duration:i}){const f=u(c,0)?`${r(c)}/s`:"~";if(n>e)return`${r(n)} at ${f} duration=${s(i)}`;if(u(e,0)){const c=u(a,0)?s(a):"~";return`${o(t)} | ${r(n)} of ${r(e)} at ${f} ETA ${c} duration=${s(i)}`}return u(n,0)?`${r(n)} of ~ at ${f} duration=${s(i)}`:u(i,0)?`~ duration=${s(i)}`:"~"}},3527(t){t.exports=function(t){const e=Math.abs(Math.trunc(t)),n=`0${Math.floor(e/60/60)}:0${Math.floor(e/60)%60}:0${e%60}`.replace(/0(\d\d)/g,"$1");return t<=-1?"-"+n:n}},2677(t){t.exports=function(t){return t.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g,",")}},4206(t,e,n){const r=n(3719);t.exports=function(t,e){return r.delete(t,{responseType:"json",...e}).then(t=>t.data)}},4131(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"blob",...e}).then(t=>t.data)}},706(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"arraybuffer",...e}).then(t=>t.data)}},3066(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"json",...e}).then(t=>t.data)}},3019(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"text",responseEncoding:"utf8",...e}).then(t=>t.data)}},7379(t,e,n){const r=n(3719);t.exports=function(t,e){return r.head(t,e).then(t=>t.request.res.headers)}},2552(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.patch(t,e,n).then(t=>t.data)}},7484(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.post(t,e,n).then(t=>t.data)}},5420(t,e,n){const r=n(8241),o=n(3719);t.exports=function(t,e,n){const s=new r;for(let t=0,n=e.length;t<n;++t){const n=e[t];n.options?s.append(n.name,n.body,n.options):s.append(n.name,n.body)}if(s.getHeaders){const e={...n};return e.headers={...e.headers,...s.getHeaders()},Promise.resolve(o.post(t,s,e)).then(t=>t.data)}return Promise.resolve(o.post(t,s,n)).then(t=>t.data)}},4605(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},6357(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},2380(t,e,n){const r=n(3719);t.exports=async function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},956(t){t.exports=function(t){return t}},1828(t){t.exports=function(){}},3332(t,e,n){const r=n(4106);t.exports=r},6785(t){t.exports=function t(e,n){return n?t(n,e%n):Math.abs(e)}},7347(t,e,n){const r=n(6785);t.exports=function(t,e){return Math.abs(t*e)/r(t,e)}},792(t){t.exports=function(t,e,n,r){return 0===t&&"string"==typeof r?r:t%10==1&&t%100!=11?e.split("#").join(t):n.split("#").join(t)}},131(t){t.exports=function(t,e){return Math.floor(Math.random()*(e-t+1)+t)}},4476(t){t.exports=function(t,e=1){if(0===e)return t;const n=1/e,r=Math.sign(t),o=function(t){if(Math.floor(t)===t)return 0;const[e,n]=t.toExponential().split("e"),r=(e.split(".")[1]||"").length;return Math.max(0,r-parseInt(n,10))}(e),s=1e-12*r,u=Math.round(t*n+s)/n;return Number(u.toFixed(o))}},7233(t){t.exports=function(t,e){const n=String(t||""),r=Object.entries(e||{});if(!r.length)return n;const o=n.indexOf("#"),s=-1===o?"":n.slice(o),u=-1===o?n:n.slice(0,o),c=u.indexOf("?"),a=-1===c?u:u.slice(0,c),i=-1===c?"":u.slice(c+1),f=new URLSearchParams(i);r.forEach(function([t,e]){switch(e){case null:case void 0:f.delete(t);break;case!0:f.set(t,"1");break;case!1:f.set(t,"0");break;default:f.set(t,String(e))}});const p=f.toString();return a+(p?`?${p}`:"")+s}},6966(t,e,n){const r=n(2468);t.exports=function(t){return new r(function(e,n){t(function(t,r){t?n(t):e(r)})})}},7072(t,e,n){const r={"./array_chunk.js":6083,"./array_chunk_balanced.js":2458,"./array_fps.js":353,"./array_gcd.js":6372,"./array_group.js":3537,"./array_group_map.js":2976,"./array_index.js":2166,"./array_lcm.js":7866,"./array_max.js":6772,"./array_min.js":42,"./array_permutations.js":3685,"./array_shuffle.js":4943,"./array_sort.js":2356,"./array_sort_other.js":5181,"./array_sum.js":453,"./array_unique.js":3523,"./array_unique_last.js":6382,"./date_add_hours.js":9870,"./date_add_milliseconds.js":5799,"./date_add_minutes.js":3160,"./date_add_months.js":1570,"./date_add_seconds.js":9296,"./date_diff_seconds.js":5488,"./date_is_leap_year.js":3752,"./fcmp_dates.js":2806,"./fcmp_default.js":8310,"./fcmp_default_desc.js":2092,"./fcmp_from_spec.js":3553,"./fcmp_numbers.js":3129,"./fcmp_tuples.js":4332,"./fcmp_utf8_bin.js":3106,"./fcmp_utf8_ci.js":2271,"./fcmp_utf8_cs.js":4457,"./fcmp_utf8_natural_bin.js":7668,"./fcmp_utf8_natural_ci.js":4385,"./fcmp_utf8_natural_cs.js":8951,"./fcmpx.js":4734,"./filter1_from_spec.js":7960,"./format_bytes.js":6017,"./format_date.js":1284,"./format_date_fs.js":5224,"./format_date_human.js":1690,"./format_date_ymd.js":6997,"./format_error_report.js":9009,"./format_hrtime.js":6015,"./format_kilo.js":4153,"./format_ms.js":1120,"./format_ms2.js":7336,"./format_ms3.js":495,"./format_percents.js":7882,"./format_progress_bytes.js":7111,"./format_progress_kilo.js":5051,"./format_seconds.js":3527,"./format_thousands.js":2677,"./http_delete.js":4206,"./http_get_blob.js":4131,"./http_get_buffer.js":706,"./http_get_json.js":3066,"./http_get_utf8.js":3019,"./http_head.js":7379,"./http_patch_json.js":2552,"./http_post_json.js":7484,"./http_post_multipart.js":5420,"./http_put_buffer.js":4605,"./http_put_json.js":6357,"./http_put_utf8.js":2380,"./identity.js":956,"./ignore.js":1828,"./plural.js":792,"./random_int.js":131,"./urlmod.js":7233,"./waitcb.js":6966};function o(t){const e=s(t);return n(e)}function s(t){if(!n.o(r,t)){const e=new Error("Cannot find module '"+t+"'");throw e.code="MODULE_NOT_FOUND",e}return r[t]}o.keys=function(){return Object.keys(r)},o.resolve=s,t.exports=o,o.id=7072},8241(t){"use strict";t.exports=FormData},2468(t){"use strict";t.exports=Promise},3719(t){"use strict";t.exports=axios}};const e={};function n(r){const o=e[r];if(void 0!==o)return o.exports;const s=e[r]={exports:{}};return t[r](s,s.exports,n),s.exports}n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);const r=new URL(document.currentScript.src).searchParams.get("var")??"h";if(void 0!==window[r])console.log(`❌ @vbarbarosh/node-helpers@3.76.2 was not injected — window.${r} is already in use`);else{console.log(`🎉 @vbarbarosh/node-helpers@3.76.2 successfully exposed as window.${r}`),window[r]={};const t=n(7072);t.keys().forEach(function(e){const[,n]=e.match(/([^/]+)\.js$/);window[r][n]=t(e)})}})();
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "Vladimir Barbarosh <vladimir.barbarosh@gmail.com>",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"name": "@vbarbarosh/node-helpers",
|
|
5
|
-
"version": "3.76.
|
|
5
|
+
"version": "3.76.2",
|
|
6
6
|
"description": "A set of helpers for JavaScript/Node.js",
|
|
7
7
|
"unpkg": "dist/browser.js",
|
|
8
8
|
"jsdelivr": "dist/browser.js",
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const is_num_gt = require('@vbarbarosh/type-helpers/src/is_num_gt');
|
|
2
|
+
|
|
3
|
+
function assert_positive_integer(value, name = 'value')
|
|
4
|
+
{
|
|
5
|
+
if (!is_num_gt(value, 0) || !Number.isInteger(value)) {
|
|
6
|
+
throw new Error(`[${name}] should be a positive integer.`);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
module.exports = assert_positive_integer;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Asserts that `value` is a finite integer greater than or equal to `1`.
|
|
2
|
+
The optional `name` is included in the error message.
|
|
3
|
+
|
|
4
|
+
```js
|
|
5
|
+
assert_positive_integer(3, 'concurrency') // returns undefined
|
|
6
|
+
assert_positive_integer(0, 'concurrency') // throws Error
|
|
7
|
+
assert_positive_integer(1.5, 'concurrency') // throws Error
|
|
8
|
+
```
|
package/src/fastdl.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
const UserFriendlyError = require('./errors/UserFriendlyError');
|
|
2
|
+
const assert_positive_integer = require('./assert_positive_integer');
|
|
2
3
|
const format_bytes = require('./format_bytes');
|
|
3
4
|
const format_progress_bytes = require('./format_progress_bytes');
|
|
4
5
|
const format_thousands = require('./format_thousands');
|
|
5
6
|
const fs = require('fs');
|
|
6
7
|
const fs_path_basename = require('./fs_path_basename');
|
|
8
|
+
const fs_rename = require('./fs_rename');
|
|
9
|
+
const fs_rmf = require('./fs_rmf');
|
|
10
|
+
const fs_write = require('./fs_write');
|
|
7
11
|
const ignore = require('./ignore');
|
|
8
12
|
const make_progress = require('./make_progress');
|
|
9
13
|
const parallel = require('./parallel');
|
|
14
|
+
const random_hex = require('./random_hex');
|
|
10
15
|
const stream = require('stream');
|
|
11
16
|
|
|
12
17
|
/**
|
|
@@ -18,13 +23,32 @@ const stream = require('stream');
|
|
|
18
23
|
* });
|
|
19
24
|
*/
|
|
20
25
|
async function fastdl({file, read_stream_with_range, concurrency = 60, user_friendly_status = v => console.log(v)})
|
|
26
|
+
{
|
|
27
|
+
assert_positive_integer(concurrency, 'concurrency');
|
|
28
|
+
const tmp_file = `${file}.${process.pid}.${random_hex(8)}.tmp`;
|
|
29
|
+
try {
|
|
30
|
+
user_friendly_status(`Preparing destination file [${fs_path_basename(file)}]...`);
|
|
31
|
+
await fs_write(tmp_file, '', {flag: 'wx'});
|
|
32
|
+
await download({
|
|
33
|
+
concurrency,
|
|
34
|
+
file: tmp_file,
|
|
35
|
+
read_stream_with_range,
|
|
36
|
+
user_friendly_status,
|
|
37
|
+
});
|
|
38
|
+
await fs_rename(tmp_file, file);
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
await fs_rmf(tmp_file);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function download({file, read_stream_with_range, concurrency, user_friendly_status})
|
|
21
46
|
{
|
|
22
47
|
const M = 1024*1024;
|
|
23
48
|
const chunk_min_bytes = M;
|
|
24
49
|
const chunk_max_bytes = 50*M;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
await fs.promises.writeFile(file, '');
|
|
50
|
+
const active_streams = new Set();
|
|
51
|
+
const writers = new Set();
|
|
28
52
|
|
|
29
53
|
user_friendly_status('Requesting first chunk to determine total size...');
|
|
30
54
|
const rs0 = await read_stream_with_range(0, chunk_min_bytes);
|
|
@@ -49,6 +73,11 @@ async function fastdl({file, read_stream_with_range, concurrency = 60, user_frie
|
|
|
49
73
|
try {
|
|
50
74
|
await parallel({concurrency, spawn});
|
|
51
75
|
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
active_streams.forEach(v => v.destroy(error));
|
|
78
|
+
await Promise.all([...writers].map(v => v.catch(ignore)));
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
52
81
|
finally {
|
|
53
82
|
tick();
|
|
54
83
|
clearInterval(timer);
|
|
@@ -66,7 +95,12 @@ async function fastdl({file, read_stream_with_range, concurrency = 60, user_frie
|
|
|
66
95
|
const last = Math.min(total - 1, first + (first === 0 ? rs0.content_range.last : chunk_size));
|
|
67
96
|
next_first = last + 1;
|
|
68
97
|
connections++;
|
|
69
|
-
|
|
98
|
+
const writer = Promise.resolve(run()).catch(run).catch(run).finally(function () {
|
|
99
|
+
connections--;
|
|
100
|
+
writers.delete(writer);
|
|
101
|
+
});
|
|
102
|
+
writers.add(writer);
|
|
103
|
+
return writer;
|
|
70
104
|
async function run() {
|
|
71
105
|
if (first > last) {
|
|
72
106
|
return;
|
|
@@ -89,8 +123,11 @@ async function fastdl({file, read_stream_with_range, concurrency = 60, user_frie
|
|
|
89
123
|
});
|
|
90
124
|
const ws = fs.createWriteStream(file, {
|
|
91
125
|
flags: fs.constants.O_WRONLY, // |fs.constants.O_CREAT,
|
|
126
|
+
flush: true,
|
|
92
127
|
start: first,
|
|
93
128
|
});
|
|
129
|
+
active_streams.add(rs);
|
|
130
|
+
active_streams.add(ws);
|
|
94
131
|
try {
|
|
95
132
|
await stream.promises.pipeline(rs, acc, ws);
|
|
96
133
|
}
|
|
@@ -100,6 +137,10 @@ async function fastdl({file, read_stream_with_range, concurrency = 60, user_frie
|
|
|
100
137
|
progress.add(-counted);
|
|
101
138
|
throw error;
|
|
102
139
|
}
|
|
140
|
+
finally {
|
|
141
|
+
active_streams.delete(rs);
|
|
142
|
+
active_streams.delete(ws);
|
|
143
|
+
}
|
|
103
144
|
}
|
|
104
145
|
}
|
|
105
146
|
}
|
package/src/fastdl.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
Download a file in several connections in parallel.
|
|
2
2
|
|
|
3
|
+
`concurrency` defaults to `60` and must be a positive integer.
|
|
4
|
+
|
|
5
|
+
All ranges are written to a unique temporary file beside `file`. After every
|
|
6
|
+
range completes and the final byte count is validated, the temporary file is
|
|
7
|
+
flushed, closed, and atomically renamed over `file`. A failed request, exhausted
|
|
8
|
+
retry, size mismatch, or write error removes the temporary file and preserves
|
|
9
|
+
an existing destination.
|
|
10
|
+
|
|
3
11
|
```js
|
|
4
12
|
await fastdl({
|
|
5
13
|
file: fs_path_basename(new URL(url).pathname),
|
package/src/http_get_file.js
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
const axios = require('axios');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
+
const fs_rename = require('./fs_rename');
|
|
4
|
+
const fs_rmf = require('./fs_rmf');
|
|
5
|
+
const random_hex = require('./random_hex');
|
|
3
6
|
const stream = require('stream');
|
|
4
7
|
|
|
5
8
|
// https://stackoverflow.com/a/61269447
|
|
6
9
|
async function http_get_file(url, out_file, options)
|
|
7
10
|
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const tmp_file = `${out_file}.${process.pid}.${random_hex(8)}.tmp`;
|
|
12
|
+
try {
|
|
13
|
+
const response = await axios.get(url, {responseType: 'stream', ...options});
|
|
14
|
+
await stream.promises.pipeline(response.data, fs.createWriteStream(tmp_file, {
|
|
15
|
+
flags: 'wx',
|
|
16
|
+
flush: true,
|
|
17
|
+
}));
|
|
18
|
+
await fs_rename(tmp_file, out_file);
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
await fs_rmf(tmp_file);
|
|
22
|
+
}
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
module.exports = http_get_file;
|
package/src/http_get_file.md
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
Downloads `url` into `out_file`.
|
|
2
2
|
|
|
3
|
-
-
|
|
4
|
-
|
|
3
|
+
- The response is written to a unique temporary file in the destination
|
|
4
|
+
directory, flushed, closed, and atomically renamed to `out_file` only after
|
|
5
|
+
the complete download succeeds.
|
|
6
|
+
- An HTTP error status (e.g. 404) rejects without creating `out_file`.
|
|
5
7
|
- Rejects when the server aborts the download mid-stream (no hanging) and
|
|
6
|
-
when `out_file` is not writable; both streams are destroyed
|
|
8
|
+
when `out_file` is not writable; both streams are destroyed and the
|
|
9
|
+
temporary file is removed on failure. An existing `out_file` remains
|
|
10
|
+
unchanged.
|
|
7
11
|
- `options` are passed through to `axios.get` (after
|
|
8
12
|
`responseType: 'stream'`).
|
|
9
13
|
|
|
@@ -2,12 +2,15 @@ const axios = require('axios');
|
|
|
2
2
|
const format_thousands = require('./format_thousands');
|
|
3
3
|
const parse_http_content_range = require('./parse_http_content_range');
|
|
4
4
|
|
|
5
|
-
async function http_get_stream_range(url, first, last)
|
|
5
|
+
async function http_get_stream_range(url, first, last, options)
|
|
6
6
|
{
|
|
7
7
|
const a = Number.isInteger(first) ? first : '';
|
|
8
8
|
const b = Number.isInteger(last) ? last : '';
|
|
9
|
-
const headers = {
|
|
10
|
-
|
|
9
|
+
const headers = {...options?.headers};
|
|
10
|
+
if (a !== '' || b !== '') {
|
|
11
|
+
headers.Range = `bytes=${a}-${b}`;
|
|
12
|
+
}
|
|
13
|
+
const res = await axios.get(url, {responseType: 'stream', ...options, headers});
|
|
11
14
|
const out = res.data;
|
|
12
15
|
out.headers = res.headers;
|
|
13
16
|
try {
|
|
@@ -27,15 +30,30 @@ async function http_get_stream_range(url, first, last)
|
|
|
27
30
|
out.destroy(); // release the socket; nobody will ever read this stream
|
|
28
31
|
throw error;
|
|
29
32
|
}
|
|
30
|
-
// A server reaching the end of the resource returns a shorter range than
|
|
31
|
-
// requested: `bytes=0-999999` of a 500-byte file is `bytes 0-499/500` (RFC 7233)
|
|
32
|
-
const expected_last = (b === '' || out.content_range.total === null) ? b : Math.min(b, out.content_range.total - 1);
|
|
33
33
|
if (a !== '' && out.content_range.first !== a) {
|
|
34
34
|
out.destroy(new Error(`First byte of a returned range (${fmt(out.content_range.first)}) is not as expected: [${fmt(a)}]`));
|
|
35
35
|
}
|
|
36
|
-
else if (
|
|
36
|
+
else if (a !== '' && b !== '') {
|
|
37
|
+
const expected_last = out.content_range.total === null ? b : Math.min(b, out.content_range.total - 1);
|
|
38
|
+
if (out.content_range.last !== expected_last) {
|
|
39
|
+
out.destroy(new Error(`Last byte of a returned range (${fmt(out.content_range.last)}) is not as expected: [${fmt(expected_last)}]`));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (a !== '' && out.content_range.total !== null && out.content_range.last !== out.content_range.total - 1) {
|
|
43
|
+
const expected_last = out.content_range.total - 1;
|
|
37
44
|
out.destroy(new Error(`Last byte of a returned range (${fmt(out.content_range.last)}) is not as expected: [${fmt(expected_last)}]`));
|
|
38
45
|
}
|
|
46
|
+
else if (b !== '') {
|
|
47
|
+
const actual_length = out.content_range.last - out.content_range.first + 1;
|
|
48
|
+
const expected_length = out.content_range.total === null ? Math.min(actual_length, b) : Math.min(out.content_range.total, b);
|
|
49
|
+
if (actual_length !== expected_length) {
|
|
50
|
+
out.destroy(new Error(`Length of a returned range (${fmt(actual_length)}) is not as expected: [${fmt(expected_length)}]`));
|
|
51
|
+
}
|
|
52
|
+
else if (out.content_range.total !== null && out.content_range.last !== out.content_range.total - 1) {
|
|
53
|
+
const expected_last = out.content_range.total - 1;
|
|
54
|
+
out.destroy(new Error(`Last byte of a returned range (${fmt(out.content_range.last)}) is not as expected: [${fmt(expected_last)}]`));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
39
57
|
out.total = out.content_range.total;
|
|
40
58
|
return out;
|
|
41
59
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
GETs `url` with a `Range: bytes=first-last` header and returns the response
|
|
2
|
-
body as a readable stream.
|
|
3
|
-
|
|
4
|
-
a regular GET.
|
|
2
|
+
body as a readable stream. Omitting `last` requests `bytes=first-`; omitting
|
|
3
|
+
`first` requests the final `last` bytes with `bytes=-last`. When both are
|
|
4
|
+
omitted, the `Range` header is omitted and a regular GET is sent. Extra Axios
|
|
5
|
+
options are accepted as the fourth argument; caller headers are merged with
|
|
6
|
+
the computed `Range` header.
|
|
5
7
|
|
|
6
8
|
The stream gets extra properties attached: `headers` (raw response headers),
|
|
7
9
|
`content_range` (parsed `{type, first, last, total}`), and `total`. When the
|
|
@@ -9,11 +11,11 @@ server sends no `Content-Range`, it is synthesized from `Content-Length`; a
|
|
|
9
11
|
chunked 200 response (neither header) is accepted as
|
|
10
12
|
`{first: 0, last: null, total: null}` — body starts at byte 0, size unknown.
|
|
11
13
|
|
|
12
|
-
The returned range is validated
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
The returned range is validated according to the requested form. Closed ranges
|
|
15
|
+
accept a `last` clamped to the end of the resource; open-ended ranges must end
|
|
16
|
+
at the resource end when its size is known; suffix ranges validate their
|
|
17
|
+
length and resource end. A server that ignores a range and replies 200 is
|
|
18
|
+
rejected.
|
|
17
19
|
|
|
18
20
|
```js
|
|
19
21
|
const rs = await http_get_stream_range(url, 100, 199);
|
package/src/http_stream_range.js
CHANGED
|
@@ -86,6 +86,11 @@ async function http_stream_range(req, res, file)
|
|
|
86
86
|
|
|
87
87
|
for (let offset = first; offset <= last && !req_close; ) {
|
|
88
88
|
const chunk = await fs_fread(fp, buf, offset, Math.min(buf.length, last - offset + 1));
|
|
89
|
+
if (chunk.length === 0) {
|
|
90
|
+
const error = new Error(`File ended at byte ${offset} before the requested range ended at byte ${last}`);
|
|
91
|
+
error.code = 'ERR_HTTP_STREAM_RANGE_SHORT_READ';
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
89
94
|
offset += chunk.length;
|
|
90
95
|
if (res.write(chunk)) {
|
|
91
96
|
// req.log(`[http_stream_range_write] ${chunk.length}`);
|
package/src/http_stream_range.md
CHANGED
|
@@ -22,7 +22,10 @@ http_stream_range(req, res, file) → Promise
|
|
|
22
22
|
`GET` and `HEAD` responses advertise `Accept-Ranges: bytes`.
|
|
23
23
|
|
|
24
24
|
Reads in 2 MiB chunks with an `fs_fread` loop, respecting backpressure
|
|
25
|
-
(`res.write` + `drain`) and stopping early when the client disconnects.
|
|
25
|
+
(`res.write` + `drain`) and stopping early when the client disconnects. If the
|
|
26
|
+
file becomes shorter than the size captured at the beginning of the request,
|
|
27
|
+
the handler rejects with code `ERR_HTTP_STREAM_RANGE_SHORT_READ` instead of
|
|
28
|
+
waiting indefinitely.
|
|
26
29
|
|
|
27
30
|
```js
|
|
28
31
|
app.get('/file', (req, res) => http_stream_range(req, res, '/data/movie.mp4'));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
|
+
const assert_positive_integer = require('./assert_positive_integer');
|
|
2
3
|
const stream = require('stream');
|
|
3
4
|
const wait_while = require('./wait_while');
|
|
4
5
|
|
|
@@ -7,6 +8,7 @@ const wait_while = require('./wait_while');
|
|
|
7
8
|
*/
|
|
8
9
|
function mongo_stream_upsert({collection, concurrency = 1})
|
|
9
10
|
{
|
|
11
|
+
assert_positive_integer(concurrency, 'concurrency');
|
|
10
12
|
const errors = [];
|
|
11
13
|
return new stream.Writable({
|
|
12
14
|
objectMode: true,
|
|
@@ -5,6 +5,7 @@ a `replaceOne` upsert keyed by its `_id`, and the batch goes to
|
|
|
5
5
|
|
|
6
6
|
- Up to `concurrency` (default `1`) `bulkWrite` calls run in flight; further
|
|
7
7
|
writes wait until a slot frees up.
|
|
8
|
+
- `concurrency` must be a positive integer.
|
|
8
9
|
- A `bulkWrite` error is reported on the next write or when the stream
|
|
9
10
|
finishes. `final` and `destroy` wait for all in-flight batches first, so an
|
|
10
11
|
error from the last batch is never silently dropped.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
|
+
const assert_positive_integer = require('./assert_positive_integer');
|
|
2
3
|
const stream = require('stream');
|
|
3
4
|
const wait_while = require('./wait_while');
|
|
4
5
|
|
|
@@ -7,6 +8,7 @@ const wait_while = require('./wait_while');
|
|
|
7
8
|
*/
|
|
8
9
|
function mongo_stream_write({collection, concurrency = 1})
|
|
9
10
|
{
|
|
11
|
+
assert_positive_integer(concurrency, 'concurrency');
|
|
10
12
|
const errors = [];
|
|
11
13
|
return new stream.Writable({
|
|
12
14
|
objectMode: true,
|
|
@@ -4,6 +4,7 @@ passed to `collection.bulkWrite(operations)` as is.
|
|
|
4
4
|
|
|
5
5
|
- Up to `concurrency` (default `1`) `bulkWrite` calls run in flight; further
|
|
6
6
|
writes wait until a slot frees up.
|
|
7
|
+
- `concurrency` must be a positive integer.
|
|
7
8
|
- A `bulkWrite` error is reported on the next write or when the stream
|
|
8
9
|
finishes. `final` and `destroy` wait for all in-flight batches first, so an
|
|
9
10
|
error from the last batch is never silently dropped.
|
package/src/parallel.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const NotImplemented = require('./errors/NotImplemented');
|
|
2
2
|
const Promise = require('bluebird');
|
|
3
|
+
const assert_positive_integer = require('./assert_positive_integer');
|
|
3
4
|
const is_fn_async = require('@vbarbarosh/type-helpers/src/is_fn_async');
|
|
4
5
|
const is_fn_gen_async = require('@vbarbarosh/type-helpers/src/is_fn_gen_async');
|
|
5
6
|
|
|
@@ -12,6 +13,7 @@ const is_fn_gen_async = require('@vbarbarosh/type-helpers/src/is_fn_gen_async');
|
|
|
12
13
|
*/
|
|
13
14
|
async function parallel({concurrency, spawn, progress})
|
|
14
15
|
{
|
|
16
|
+
assert_positive_integer(concurrency, 'concurrency');
|
|
15
17
|
if (is_fn_async(spawn) || is_fn_gen_async(spawn)) {
|
|
16
18
|
throw new Error('[spawn] should not be async function. Instead, it should be a simple function returning either [null] or a [promise].');
|
|
17
19
|
}
|
package/src/parallel.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
- Run until `spawn` return `null`.
|
|
2
2
|
- Keep no more than `concurrency` number of workers at a time.
|
|
3
|
+
- `concurrency` must be a positive integer.
|
|
3
4
|
|
|
4
5
|
⚠️ Warning: `spawn` should not be async function (async functions are always return `promise`).
|
|
5
6
|
Instead, it should be a simple function returning either `null` or a `promise`.
|
|
@@ -82,13 +82,13 @@ async function redis_poll_zshift_callback_rpush(options)
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
const value = await worker(log.spawn(), message, options);
|
|
85
|
-
const response = JSON.stringify({uid: message.uid, version, type: 'resolve', value});
|
|
85
|
+
const response = JSON.stringify({uid: message.uid, version, type: 'resolve', time: new Date().toJSON(), value});
|
|
86
86
|
await redis.rpush_p(redis_output_queue, response);
|
|
87
87
|
|
|
88
88
|
log(`[${log_waiter_rpush}]`);
|
|
89
89
|
}
|
|
90
90
|
catch (error) {
|
|
91
|
-
const response = JSON.stringify({uid: message.uid, version, type: 'reject', value: `${(error && (error.stack || error.message)) || 'Error N/A'}`});
|
|
91
|
+
const response = JSON.stringify({uid: message.uid, version, type: 'reject', time: new Date().toJSON(), value: `${(error && (error.stack || error.message)) || 'Error N/A'}`});
|
|
92
92
|
log(`[${log_waiter_error}] ${response}`);
|
|
93
93
|
await redis.rpush_p(redis_output_queue, response);
|
|
94
94
|
}
|
|
@@ -133,7 +133,7 @@ async function worker(log, message, options)
|
|
|
133
133
|
|
|
134
134
|
async function user_friendly_status(value) {
|
|
135
135
|
log(`[${log_worker_user_friendly_status}] ${value}`);
|
|
136
|
-
await redis.rpush_p(redis_output_queue, JSON.stringify({uid, version, type: 'user_friendly_status', value}));
|
|
136
|
+
await redis.rpush_p(redis_output_queue, JSON.stringify({uid, version, type: 'user_friendly_status', time: new Date().toJSON(), value}));
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const Promise = require('bluebird');
|
|
2
|
+
const assert_positive_integer = require('./assert_positive_integer');
|
|
2
3
|
const stream = require('stream');
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -10,6 +11,7 @@ const stream = require('stream');
|
|
|
10
11
|
*/
|
|
11
12
|
function stream_map_parallel({handler, concurrency})
|
|
12
13
|
{
|
|
14
|
+
assert_positive_integer(concurrency, 'concurrency');
|
|
13
15
|
let running = 0;
|
|
14
16
|
let callback_next = null;
|
|
15
17
|
let callback_flush = null;
|
package/src/stream_multiplex.js
CHANGED
|
@@ -25,12 +25,14 @@ function stream_multiplex(...streams)
|
|
|
25
25
|
streams.forEach(s => s.once('error', e => this.destroy(e)));
|
|
26
26
|
callback();
|
|
27
27
|
},
|
|
28
|
-
destroy:
|
|
28
|
+
destroy: function (error, callback) {
|
|
29
29
|
let done = 0;
|
|
30
|
+
let final_error = error;
|
|
30
31
|
streams.forEach(function (stream) {
|
|
31
|
-
stream.destroy(error, function () {
|
|
32
|
+
stream.destroy(error, function (error2) {
|
|
33
|
+
final_error = final_error || error2;
|
|
32
34
|
if (++done === streams.length) {
|
|
33
|
-
callback();
|
|
35
|
+
callback(final_error);
|
|
34
36
|
}
|
|
35
37
|
});
|
|
36
38
|
});
|
package/src/stream_multiplex.md
CHANGED
|
@@ -7,6 +7,8 @@ completes only after every target accepted the chunk.
|
|
|
7
7
|
- Ending the multiplex ends all targets; destroying it destroys all targets.
|
|
8
8
|
- An error in any target destroys the multiplex (and, through it, the other
|
|
9
9
|
targets) with that error — the first error wins.
|
|
10
|
+
- Destroying the multiplex with an error preserves that error after all targets
|
|
11
|
+
finish cleanup.
|
|
10
12
|
|
|
11
13
|
```js
|
|
12
14
|
await stream.promises.pipeline(
|
package/src/stream_progress.js
CHANGED
|
@@ -16,15 +16,22 @@ function stream_progress({objectMode = false, interval = 1000, total, user_frien
|
|
|
16
16
|
{
|
|
17
17
|
let done = 0;
|
|
18
18
|
const timer = setInterval(tick, interval);
|
|
19
|
+
const timeout = setTimeout(tick, 0);
|
|
19
20
|
const progress = make_progress(total);
|
|
20
21
|
const format_progress = objectMode ? format_progress_kilo : format_progress_bytes;
|
|
21
|
-
setTimeout(tick, 0);
|
|
22
22
|
return new stream.Transform({
|
|
23
23
|
objectMode,
|
|
24
24
|
destroy: function (error, callback) {
|
|
25
|
-
tick();
|
|
26
25
|
clearInterval(timer);
|
|
27
|
-
|
|
26
|
+
clearTimeout(timeout);
|
|
27
|
+
try {
|
|
28
|
+
tick();
|
|
29
|
+
}
|
|
30
|
+
catch (error2) {
|
|
31
|
+
callback(error || error2);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
callback(error);
|
|
28
35
|
},
|
|
29
36
|
transform: function (buffer, encoding, callback) {
|
|
30
37
|
if (objectMode) {
|