@miso.ai/doggoganger 0.9.0-beta.13 → 0.9.0-beta.14

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/cli/index.js CHANGED
@@ -10,6 +10,11 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
10
10
  const SRC_DIR = join(__dirname, '../src');
11
11
 
12
12
  let { watch, ...argv } = yargs(hideBin(process.argv))
13
+ .option('verbose', {
14
+ alias: 'v',
15
+ describe: 'Be verbose',
16
+ type: 'boolean',
17
+ })
13
18
  .option('port', {
14
19
  alias: 'p',
15
20
  describe: 'Port of mock API endpoint',
@@ -21,10 +26,6 @@ let { watch, ...argv } = yargs(hideBin(process.argv))
21
26
  describe: 'Watch files for changes',
22
27
  type: 'boolean',
23
28
  })
24
- .option('answer-format', {
25
- describe: 'Answer field format in answers API response',
26
- type: 'string',
27
- })
28
29
  .option('serve', {
29
30
  alias: 's',
30
31
  describe: 'Serve static files as well',
@@ -32,8 +33,8 @@ let { watch, ...argv } = yargs(hideBin(process.argv))
32
33
  })
33
34
  .argv;
34
35
 
35
- const { port, serve, ['answer-format']: answerFormat } = argv;
36
- argv = { port, serve, answerFormat };
36
+ const { verbose, port, serve } = argv;
37
+ argv = { verbose, port, serve };
37
38
 
38
39
  if (watch) {
39
40
  const exec = `node ${resolve(__dirname, 'server.js')} ${JSON.stringify(JSON.stringify(argv))}`;
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).doggoganger=e()}(this,(function(){"use strict";function t(t,e){return null!=e&&e>t?t+Math.floor(Math.random()*(e-t)):t}function e(){return Math.random().toString(36).substring(2,10)}function n(t){return`https://picsum.photos/seed/${Math.floor(1e3*Math.random())}/${Array.isArray(t)?t.length>1?`${t[0]}/${t[1]}`:""+t[0]:""+t}`}function r(t,e){return void 0!==e?Math.ceil(t*e):t}var o=["lorem","ipsum","dolor","sit","amet","consectetur","adipiscing","elit","curabitur","vel","hendrerit","libero","eleifend","blandit","nunc","ornare","odio","ut","orci","gravida","imperdiet","nullam","purus","lacinia","a","pretium","quis","congue","praesent","sagittis","laoreet","auctor","mauris","non","velit","eros","dictum","proin","accumsan","sapien","nec","massa","volutpat","venenatis","sed","eu","molestie","lacus","quisque","porttitor","ligula","dui","mollis","tempus","at","magna","vestibulum","turpis","ac","diam","tincidunt","id","condimentum","enim","sodales","in","hac","habitasse","platea","dictumst","aenean","neque","fusce","augue","leo","eget","semper","mattis","tortor","scelerisque","nulla","interdum","tellus","malesuada","rhoncus","porta","sem","aliquet","et","nam","suspendisse","potenti","vivamus","luctus","fringilla","erat","donec","justo","vehicula","ultricies","varius","ante","primis","faucibus","ultrices","posuere","cubilia","curae","etiam","cursus","aliquam","quam","dapibus","nisl","feugiat","egestas","class","aptent","taciti","sociosqu","ad","litora","torquent","per","conubia","nostra","inceptos","himenaeos","phasellus","nibh","pulvinar","vitae","urna","iaculis","lobortis","nisi","viverra","arcu","morbi","pellentesque","metus","commodo","ut","facilisis","felis","tristique","ullamcorper","placerat","aenean","convallis","sollicitudin","integer","rutrum","duis","est","etiam","bibendum","donec","pharetra","vulputate","maecenas","mi","fermentum","consequat","suscipit","aliquam","habitant","senectus","netus","fames","quisque","euismod","curabitur","lectus","elementum","tempor","risus","cras"];function s({decorates:e=[],output:n="string",size:r,min:s,max:i,...u}={}){let c=function(e=[5,10]){const n="number"==typeof e?e:t(...e);return function*(t){let e=0;for(let r of t){if(e++>=n)break;yield r}}}(r||[s,i])(function*({words:t=o,fixedStarts:e=0}={}){const n=t.length;for(let r=0;;r++)yield t[e>r?r:Math.floor(Math.random()*n)]}(u));for(const t of e)c=a(t)(c);return a(n)(c)}const i={string:function({separator:t=" "}={}){return e=>[...e].join(t)},array:function(){return t=>[...t]},title:function({}={}){return function*(t){for(let e of t)yield u(e)}},description:function({wordsPerSentence:t={avg:24,std:5,min:1}}={}){return function*(e){let n,r=0;for(let o of e)n&&(yield n),n=o,0===r&&(n=u(n),r=c(t)),0==--r&&(n+=".");n&&(n.endsWith(".")||(n+="."),yield n)}},multiline:function({wordsPerLine:t={avg:10,std:3,min:1}}={}){return e=>{let n=c(t),r="";for(let o of e)r&&(0==n--?(r+="\n",n=c(t)):r+=" "),r+=o;return r}}};function a(t){return"string"==typeof t?i[t]():t}function u(t){return t[0].toUpperCase()+t.substring(1)}function c(t){if("number"==typeof t)return Math.round(e);let{avg:e,std:n,min:r,max:o}=t;void 0===n&&(n=e/4);let s=(l()+l()+l())*n+e;return void 0!==r&&(s=Math.max(r,s)),void 0!==o&&(s=Math.min(o,s)),Math.round(s)}function l(){return 2*Math.random()-1}const f="// module\nimport { a, b } from './module';\nimport * as module from './module';\nimport module from './module';\nexport default module;\nexport const a = 0;\nexport * from './module';\nexport * as module from './module';\n\n// variables\nlet a = 10;\nconst b = 20;\n\n// function declaration\nfunction sum(x, y) {\n return x + y;\n}\n\n// generator function\nfunction* iterator() {\n yield 0;\n yield 1;\n}\n\n// arrow function\nconst multiply = (x, y) => x * y;\n\n// class\nclass Person {\n constructor(name, age) {\n this.name = name;\n this.age = age;\n }\n\n greet() {\n console.log('Hello, my name is Miso.');\n }\n}\n\n// primitive\nconst str = 'Hello, world!';\nconst num = 10.99;\n\n// object\nconst person = new Person('John', 30);\nperson.greet();\n\n// object literal\nconst object = {\n name: 'John',\n [x]: 10,\n ...props,\n};\n\n// array literal\nconst arr = [1, 2, 3, 4, 5, ...props];\n\n// regexp literal\nconst regexp = /\\w+/g;\n\n// operators\nconst sum = a + b;\nconst product = a * b;\nconst negation = -a;\nconst max = a > b ? a : b;\n\n// flow control\nlet i = 9;\nfor (const n of arr) {\n if (n > i) {\n console.log(n);\n }\n i++;\n}\n\n// async/await\n(async () => {\n const result = await asyncFunction();\n})();\n\n// try/catch\ntry {\n} catch (e) {\n}\n\n// destructuring\nconst { name, age, ...rest } = person;\nconst [ x, y, ...rest ] = arr;\n\n// template literals\nconsole.log(`The sum of ${a} and ${b} is ${sum(a, b)}.`);";var d=Object.freeze({__proto__:null,javascript:function(){return f},js:function(){return f}});function m({features:e,blocks:r=[8,12],sampling:o=1}={}){let i=[];return[i,e]=function(t=[]){const e=new Set,n=[];for(const r of t)if(r.startsWith("lang-")){let t=r.slice(5);"javascript"===t&&(t="js"),e.add(t)}else n.push(r);return[[...e],n]}(e),function(t,e){const n=[];for(const r of t)1>e&&Math.random()>=e||n.push(r());return n}([()=>p({features:e}),()=>g({features:e}),...i.map((t=>()=>h({lang:t,features:e}))),...i.length?[]:[()=>h({features:e})],()=>g({features:e}),()=>function({columns:e=[2,4],rows:n=[2,8]}){e=t(...e),n=t(...n);const r=[...$({size:1},e-1),{size:[3,8]}],o=s({size:e,output:"array"}),i=r.map((()=>"---")),a=[o,i];for(let t=0;n-1>t;t++)a.push(r.map((({size:t})=>s({size:t}))));return a.map(x).join("\n")}({features:e}),()=>function({url:t,imageSize:e=[400,250],...r}={}){return t=t||n(e),`![${function({size:t=[1,3],content:e}={}){return e||s({size:t})}(r)}](${t})`}(),()=>g({features:e}),()=>"*-_".charAt(t(0,2)).repeat(t(3,6)),()=>p({features:e}),()=>g({features:e}),()=>w({features:e}),()=>g({features:e})],o).join("\n\n")}function p({level:e=[1,6],size:n=[1,8],content:r}){const o=r||s({size:n});return`${"#".repeat(t(...e))} ${o}`}function h({lang:e,content:n,size:r,fenceChar:o="`"}){return"random"===o&&(o="`~".charAt(t(0,1))),n=n||function({lang:t,size:e=[10,30]}){return t&&d[t]?d[t]():s({output:"multiline",size:e})}({lang:e,size:r}),`${o.repeat(3)}${e||""}\n${n}\n${o.repeat(3)}`}function g({size:t=[20,50]}){return s({size:t,decorates:["description",z()]})}const _=["ordered","bullet","task"];function w({features:e,type:n="random",count:r=[1,8],size:o=[5,15]}){r="number"==typeof r?r:t(...r);const s="random"===n?_[Math.floor(3*Math.random())]:n,i=[];for(;r>0;){const a=t(1,r);let u=g({features:e,size:o});a>1&&(u+="\n"+w({features:e,type:n,count:a-1,size:o})),i.push(M(s,u)),r-=a}return i.join("\n")}const y={"code-span":()=>["`","`"],"emphasis-1":()=>$(b(1),2),"emphasis-2":()=>$(b(2),2),"emphasis-3":()=>$(b(3),2),strikethrough:()=>["~","~"],link:({url:t="https://miso.ai"}={})=>["[",`](${t})`]};function b(e=[1,3]){return e="number"==typeof e?e:t(...e),"_*".charAt(t(0,1)).repeat(e)}const v=Object.keys(y),q=new Set(v);function z({features:e=v,size:n=[1,3],rest:r=[0,8]}={}){e=e.filter((t=>q.has(t)));const o=function(t){for(let e=t.length-1;e>0;e--){const n=Math.floor(Math.random()*(e+1));[t[e],t[n]]=[t[n],t[e]]}return t}([...e]);let s=o.length-1;const i=()=>"number"==typeof r?r:t(...r);return function*(r){let a,u,c=i();for(const l of r)if(u&&(yield u),0===c)if(a)u=`${l}${a}`,a=void 0,c=i();else{const[r,i]=y[0>s?e[t(0,e.length-1)]:o[s--]]();u=`${r}${l}`,a=i,c="number"==typeof n?n:t(...n)}else u=l,c--;u&&(yield void 0!==a?`${u}${a}`:u)}}function M(t,e){const[n,r]=e.split("\n",2),o=`${function(t,e="random"){switch(t){case"ordered":return"1.";case"bullet":return"-";case"task":return`- [${("random"===e?.5>Math.random():e)?"x":" "}]`;default:throw Error("unknown list item type: "+t)}}(t)} ${n}`;return r?o+"\n"+function(t,e){return e.split("\n").map((e=>" ".repeat(t)+e)).join("\n")}("ordered"===t?3:2,r):o}function x(t){return`| ${t.join(" | ")} |`}function $(t,e){const n=[];for(let r=0;e>r;r++)n.push("function"==typeof t?t():t);return n}function j({size:t=300}={}){return n(t)}function S({size:t=[1,3]}={}){return s({size:t,decorates:["title"],output:"array"})}function k({size:t=[1,4]}={}){return s({size:t,output:"array"})}function O({size:t=[2,6]}={}){return s({size:t,decorates:["title"]})}function A({size:t=[10,20]}={}){return s({size:t,decorates:["description"]})}function T(){return Math.floor(1e4*Math.random())/100}function*C({rows:t,...e}={}){for(let n=0;t>n;n++)yield F({...e,index:n})}function F({}={}){const n=e(),r=function(e,n){const r=t(...n),o=[];for(let t=0;r>t;t++)o.push(e());return o}(T,[1,2]);return r.sort(),{product_id:n,authors:S(),categories:[],tags:k(),title:O(),description:A(),cover_image:j(),url:"/products/"+n,sale_price:r[0],original_price:r[r.length-1],rating:Math.floor(500*Math.random())/100+1,availability:Math.random()>.3?"IN_STOCK":"OUT_OF_STOCK"}}function*D({rows:t,...e}={}){for(let n=0;t>n;n++)yield L({...e,index:n})}function L({}={}){const t=e();return{product_id:t,authors:S(),categories:[],tags:k(),title:O({size:[4,10]}),snippet:A({size:[20,40]}),cover_image:j(),url:"/products/"+t}}function P({question:t,parent_question_id:e,timestamp:n=Date.now()},{answerFormat:o="markdown",answerSampling:i,answerLanguages:a=[]}={}){const u="10000000-1000-4000-8000-100000000000".replace(/[018]/g,(t=>(t^16*Math.random()>>t/4).toString(16))),c=function(t){const e=new Date(t).toISOString();return e.endsWith("Z")?e.slice(0,-1):e}(n),l=void 0!==i?Math.max(0,Math.min(1,i)):void 0,f=function({format:t,sampling:e,features:n}){return"markdown"===t?m({sampling:e,features:n}):s({min:r(50,e),max:r(50,e),decorates:["description"]})}({format:o,sampling:l,features:a.length?a.map((t=>"lang-"+t)):void 0});return{question:t,question_id:u,...e&&{parent_question_id:e},datetime:c,answer:f,related_resources:[...D({rows:W(6,8,l)})],sources:[...D({rows:W(4,6,l)})]}}function W(e,n,o){return t(r(e,o),r(n,o))}const H=[{name:"fetch",duration:1.5,text:"Checking the question and fetching results... "},{name:"verify",duration:1.5,text:"Verifying results... "},{name:"generate",duration:1.5,text:"Generating answer... "}];class I{constructor(t={}){this._options=t,this._answers=new Map}questions(t,e={}){return new J(t,{...this._options,...e})}}class J{constructor({question:t,parent_question_id:e},{answerFormat:n,answerSampling:r,answerLanguages:o,...s}={}){this._options=Object.freeze(s);const i=this.timestamp=Date.now();this._data=P({question:t,parent_question_id:e,timestamp:i},{answerFormat:n,answerSampling:r,answerLanguages:o})}get question_id(){return this._data.question_id}get(){const t=(Date.now()-this.timestamp)*(this._options.speedRate||1)/1e3,[e,n,r]=this._answer(t),o=this._sources(t,r),s=this._related_resources(t,r),{question_id:i,question:a,datetime:u,parent_question_id:c}=this._data;return{answer:n,answer_stage:e,datetime:u,finished:r,parent_question_id:c,question:a,question_id:i,related_resources:s,sources:o}}_answer(t){for(const e of H)if(0>(t-=e.duration))return[e.name,e.text,!1];const{answer:e}=this._data,n=Math.floor(100*t),r=n>=e.length;return["result",r?e:e.slice(0,n),r]}_sources(t,e){const{sources:n}=this._data;if(e)return n;const{length:r}=n;return n.slice(0,Math.floor(r*t/3))}_related_resources(t,e){const{related_resources:n}=this._data;if(e)return n;const{length:r}=n;return n.slice(0,Math.floor(r*t/3))}}class K{constructor(t){this._options=t}search({rows:t=5}){return{products:[...C({rows:t})]}}}class U{constructor(t){this._options=t}user_to_products({rows:t=5}){return{products:[...C({rows:t})]}}product_to_products({rows:t=5}){return{products:[...C({rows:t})]}}}class E{constructor(t){this.ask=new I(t),this.search=new K(t),this.recommendation=new U(t)}}return{buildApi:(...t)=>new E(...t)}}));
1
+ !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t="undefined"!=typeof globalThis?globalThis:t||self).doggoganger=n()}(this,(function(){"use strict";function t(t,n){return null!=n&&n>t?t+Math.floor(Math.random()*(n-t)):t}function n(){return Math.random().toString(36).substring(2,10)}function e(t){return`https://picsum.photos/seed/${Math.floor(1e3*Math.random())}/${Array.isArray(t)?t.length>1?`${t[0]}/${t[1]}`:""+t[0]:""+t}`}function r(t,n){return void 0!==n?Math.ceil(t*n):t}var o=["lorem","ipsum","dolor","sit","amet","consectetur","adipiscing","elit","curabitur","vel","hendrerit","libero","eleifend","blandit","nunc","ornare","odio","ut","orci","gravida","imperdiet","nullam","purus","lacinia","a","pretium","quis","congue","praesent","sagittis","laoreet","auctor","mauris","non","velit","eros","dictum","proin","accumsan","sapien","nec","massa","volutpat","venenatis","sed","eu","molestie","lacus","quisque","porttitor","ligula","dui","mollis","tempus","at","magna","vestibulum","turpis","ac","diam","tincidunt","id","condimentum","enim","sodales","in","hac","habitasse","platea","dictumst","aenean","neque","fusce","augue","leo","eget","semper","mattis","tortor","scelerisque","nulla","interdum","tellus","malesuada","rhoncus","porta","sem","aliquet","et","nam","suspendisse","potenti","vivamus","luctus","fringilla","erat","donec","justo","vehicula","ultricies","varius","ante","primis","faucibus","ultrices","posuere","cubilia","curae","etiam","cursus","aliquam","quam","dapibus","nisl","feugiat","egestas","class","aptent","taciti","sociosqu","ad","litora","torquent","per","conubia","nostra","inceptos","himenaeos","phasellus","nibh","pulvinar","vitae","urna","iaculis","lobortis","nisi","viverra","arcu","morbi","pellentesque","metus","commodo","ut","facilisis","felis","tristique","ullamcorper","placerat","aenean","convallis","sollicitudin","integer","rutrum","duis","est","etiam","bibendum","donec","pharetra","vulputate","maecenas","mi","fermentum","consequat","suscipit","aliquam","habitant","senectus","netus","fames","quisque","euismod","curabitur","lectus","elementum","tempor","risus","cras"];function s({decorates:n=[],output:e="string",size:r,min:s,max:i,...u}={}){let c=function(n=[5,10]){const e="number"==typeof n?n:t(...n);return function*(t){let n=0;for(let r of t){if(n++>=e)break;yield r}}}(r||[s,i])(function*({words:t=o,fixedStarts:n=0}={}){const e=t.length;for(let r=0;;r++)yield t[n>r?r:Math.floor(Math.random()*e)]}(u));for(const t of n)c=a(t)(c);return a(e)(c)}const i={string:function({separator:t=" "}={}){return n=>[...n].join(t)},array:function(){return t=>[...t]},title:function({}={}){return function*(t){for(let n of t)yield u(n)}},description:function({wordsPerSentence:t={avg:24,std:5,min:1},punctuation:n="."}={}){return function*(e){let r,o=0;for(let s of e)r&&(yield r),r=s,0===o&&(r=u(r),o=c(t)),0==--o&&(r+=n);r&&(r.endsWith(n)||(r+=n),yield r)}},multiline:function({wordsPerLine:t={avg:10,std:3,min:1}}={}){return n=>{let e=c(t),r="";for(let o of n)r&&(0==e--?(r+="\n",e=c(t)):r+=" "),r+=o;return r}}};function a(t){switch(typeof t){case"string":return i[t]();case"function":return t;case"object":if(Array.isArray(t)){const[n,e={}]=t;return i[n](e)}}throw Error("Unrecognized decorator/output form: "+t)}function u(t){return t[0].toUpperCase()+t.substring(1)}function c(t){if("number"==typeof t)return Math.round(n);let{avg:n,std:e,min:r,max:o}=t;void 0===e&&(e=n/4);let s=(l()+l()+l())*e+n;return void 0!==r&&(s=Math.max(r,s)),void 0!==o&&(s=Math.min(o,s)),Math.round(s)}function l(){return 2*Math.random()-1}const f="// module\nimport { a, b } from './module';\nimport * as module from './module';\nimport module from './module';\nexport default module;\nexport const a = 0;\nexport * from './module';\nexport * as module from './module';\n\n// variables\nlet a = 10;\nconst b = 20;\n\n// function declaration\nfunction sum(x, y) {\n return x + y;\n}\n\n// generator function\nfunction* iterator() {\n yield 0;\n yield 1;\n}\n\n// arrow function\nconst multiply = (x, y) => x * y;\n\n// class\nclass Person {\n constructor(name, age) {\n this.name = name;\n this.age = age;\n }\n\n greet() {\n console.log('Hello, my name is Miso.');\n }\n}\n\n// primitive\nconst str = 'Hello, world!';\nconst num = 10.99;\n\n// object\nconst person = new Person('John', 30);\nperson.greet();\n\n// object literal\nconst object = {\n name: 'John',\n [x]: 10,\n ...props,\n};\n\n// array literal\nconst arr = [1, 2, 3, 4, 5, ...props];\n\n// regexp literal\nconst regexp = /\\w+/g;\n\n// operators\nconst sum = a + b;\nconst product = a * b;\nconst negation = -a;\nconst max = a > b ? a : b;\n\n// flow control\nlet i = 9;\nfor (const n of arr) {\n if (n > i) {\n console.log(n);\n }\n i++;\n}\n\n// async/await\n(async () => {\n const result = await asyncFunction();\n})();\n\n// try/catch\ntry {\n} catch (e) {\n}\n\n// destructuring\nconst { name, age, ...rest } = person;\nconst [ x, y, ...rest ] = arr;\n\n// template literals\nconsole.log(`The sum of ${a} and ${b} is ${sum(a, b)}.`);";var d=Object.freeze({__proto__:null,javascript:function(){return f},js:function(){return f}});function p({features:n,blocks:r=[8,12],sampling:o=1}={}){let i=[];return[i,n]=function(t=[]){const n=new Set,e=[];for(const r of t)if(r.startsWith("lang-")){let t=r.slice(5);"javascript"===t&&(t="js"),n.add(t)}else e.push(r);return[[...n],e]}(n),function(t,n){const e=[];for(const r of t)1>n&&Math.random()>=n||e.push(r());return e}([()=>m({features:n}),()=>g({features:n}),...i.map((t=>()=>h({lang:t,features:n}))),...i.length?[]:[()=>h({features:n})],()=>g({features:n}),()=>function({columns:n=[2,4],rows:e=[2,8]}){n=t(...n),e=t(...e);const r=[...$({size:1},n-1),{size:[3,8]}],o=s({size:n,output:"array"}),i=r.map((()=>"---")),a=[o,i];for(let t=0;e-1>t;t++)a.push(r.map((({size:t})=>s({size:t}))));return a.map(x).join("\n")}({features:n}),()=>function({url:t,imageSize:n=[400,250],...r}={}){return t=t||e(n),`![${function({size:t=[1,3],content:n}={}){return n||s({size:t})}(r)}](${t})`}(),()=>g({features:n}),()=>"*-_".charAt(t(0,2)).repeat(t(3,6)),()=>m({features:n}),()=>g({features:n}),()=>w({features:n}),()=>g({features:n})],o).join("\n\n")}function m({level:n=[1,6],size:e=[1,8],content:r}){const o=r||s({size:e});return`${"#".repeat(t(...n))} ${o}`}function h({lang:n,content:e,size:r,fenceChar:o="`"}){return"random"===o&&(o="`~".charAt(t(0,1))),e=e||function({lang:t,size:n=[10,30]}){return t&&d[t]?d[t]():s({output:"multiline",size:n})}({lang:n,size:r}),`${o.repeat(3)}${n||""}\n${e}\n${o.repeat(3)}`}function g({size:t=[20,50]}){return s({size:t,decorates:["description",z()]})}const _=["ordered","bullet","task"];function w({features:n,type:e="random",count:r=[1,8],size:o=[5,15]}){r="number"==typeof r?r:t(...r);const s="random"===e?_[Math.floor(3*Math.random())]:e,i=[];for(;r>0;){const a=t(1,r);let u=g({features:n,size:o});a>1&&(u+="\n"+w({features:n,type:e,count:a-1,size:o})),i.push(M(s,u)),r-=a}return i.join("\n")}const y={"code-span":()=>["`","`"],"emphasis-1":()=>$(b(1),2),"emphasis-2":()=>$(b(2),2),"emphasis-3":()=>$(b(3),2),strikethrough:()=>["~","~"],link:({url:t="https://miso.ai"}={})=>["[",`](${t})`]};function b(n=[1,3]){return n="number"==typeof n?n:t(...n),"_*".charAt(t(0,1)).repeat(n)}const q=Object.keys(y),v=new Set(q);function z({features:n=q,size:e=[1,3],rest:r=[0,8]}={}){n=n.filter((t=>v.has(t)));const o=function(t){for(let n=t.length-1;n>0;n--){const e=Math.floor(Math.random()*(n+1));[t[n],t[e]]=[t[e],t[n]]}return t}([...n]);let s=o.length-1;const i=()=>"number"==typeof r?r:t(...r);return function*(r){let a,u,c=i();for(const l of r)if(u&&(yield u),0===c)if(a)u=`${l}${a}`,a=void 0,c=i();else{const[r,i]=y[0>s?n[t(0,n.length-1)]:o[s--]]();u=`${r}${l}`,a=i,c="number"==typeof e?e:t(...e)}else u=l,c--;u&&(yield void 0!==a?`${u}${a}`:u)}}function M(t,n){const[e,r]=n.split("\n",2),o=`${function(t,n="random"){switch(t){case"ordered":return"1.";case"bullet":return"-";case"task":return`- [${("random"===n?.5>Math.random():n)?"x":" "}]`;default:throw Error("unknown list item type: "+t)}}(t)} ${e}`;return r?o+"\n"+function(t,n){return n.split("\n").map((n=>" ".repeat(t)+n)).join("\n")}("ordered"===t?3:2,r):o}function x(t){return`| ${t.join(" | ")} |`}function $(t,n){const e=[];for(let r=0;n>r;r++)e.push("function"==typeof t?t():t);return e}function j({size:t=300}={}){return e(t)}function S({size:t=[1,3]}={}){return s({size:t,decorates:["title"],output:"array"})}function k({size:t=[1,4]}={}){return s({size:t,output:"array"})}function O({size:t=[2,6]}={}){return s({size:t,decorates:["title"]})}function A({size:t=[10,20],...n}={}){return s({size:t,decorates:[Object.keys(n).length?["description",n]:"description"]})}function T(){return Math.floor(1e4*Math.random())/100}function*C({rows:t,...n}={}){for(let e=0;t>e;e++)yield F({...n,index:e})}function F({}={}){const e=n(),r=function(n,e){const r=t(...e),o=[];for(let t=0;r>t;t++)o.push(n());return o}(T,[1,2]);return r.sort(),{product_id:e,authors:S(),categories:[],tags:k(),title:O(),description:A(),cover_image:j(),url:"/products/"+e,sale_price:r[0],original_price:r[r.length-1],rating:Math.floor(500*Math.random())/100+1,availability:Math.random()>.3?"IN_STOCK":"OUT_OF_STOCK"}}function*D({rows:t,...n}={}){for(let e=0;t>e;e++)yield L({...n,index:e})}function L({}={}){const t=n();return{product_id:t,authors:S(),categories:[],tags:k(),title:O({size:[4,10]}),snippet:A({size:[20,40]}),cover_image:j(),url:"/products/"+t}}function*P({rows:t,...n}={}){for(let e=0;t>e;e++)yield U({...n,index:e})}function U({}={}){return A({size:[4,8],punctuation:"?"})}function W({question:t,parent_question_id:n,timestamp:e=Date.now()},{answerFormat:o="markdown",answerSampling:i,answerLanguages:a=[]}={}){const u="10000000-1000-4000-8000-100000000000".replace(/[018]/g,(t=>(t^16*Math.random()>>t/4).toString(16))),c=function(t){const n=new Date(t).toISOString();return n.endsWith("Z")?n.slice(0,-1):n}(e),l=void 0!==i?Math.max(0,Math.min(1,i)):void 0,f=function({format:t,sampling:n,features:e}){return"markdown"===t?p({sampling:n,features:e}):s({min:r(50,n),max:r(50,n),decorates:["description"]})}({format:o,sampling:l,features:a.length?a.map((t=>"lang-"+t)):void 0}),d=[...D({rows:E(6,8,l)})];return{question:t,question_id:u,...n&&{parent_question_id:n},datetime:c,answer:f,sources:[...D({rows:E(4,6,l)})],related_resources:d,followup_questions:[...P({rows:E(3,6)})]}}function E(n,e,o){return t(r(n,o),r(e,o))}const H=[{name:"fetch",duration:1.5,text:"Checking the question and fetching results... "},{name:"verify",duration:1.5,text:"Verifying results... "},{name:"generate",duration:1.5,text:"Generating answer... "}];class I{constructor(t={}){this._options=t,this._answers=new Map}questions(t,n={}){return new J(t,{...this._options,...n})}}class J{constructor({question:t,parent_question_id:n},{answerFormat:e,answerSampling:r,answerLanguages:o,...s}={}){this._options=Object.freeze(s);const i=this.timestamp=Date.now();this._data=W({question:t,parent_question_id:n,timestamp:i},{answerFormat:e,answerSampling:r,answerLanguages:o})}get question_id(){return this._data.question_id}get(){const t=(Date.now()-this.timestamp)*(this._options.speedRate||1)/1e3,[n,e,r]=this._answer(t),o=this._sources(t,r),s=this._related_resources(t,r),i=this._followup_questions(t,r),{question_id:a,question:u,datetime:c,parent_question_id:l}=this._data;return{answer:e,answer_stage:n,datetime:c,finished:r,parent_question_id:l,question:u,question_id:a,sources:o,related_resources:s,followup_questions:i}}_answer(t){for(const n of H)if(0>(t-=n.duration))return[n.name,n.text,!1];const{answer:n}=this._data,e=Math.floor(100*t),r=e>=n.length;return["result",r?n:n.slice(0,e),r]}_sources(t,n){const{sources:e}=this._data;if(n)return e;const{length:r}=e;return e.slice(0,Math.floor(r*t/3))}_related_resources(t,n){const{related_resources:e}=this._data;if(n)return e;const{length:r}=e;return e.slice(0,Math.floor(r*t/3))}_followup_questions(t,n){const{followup_questions:e}=this._data;if(n||!e)return e;const{length:r}=e;return e.slice(0,Math.floor(r*t/3))}}class K{constructor(t){this._options=t}search({rows:t=5}){return{products:[...C({rows:t})]}}}class G{constructor(t){this._options=t}user_to_products({rows:t=5}){return{products:[...C({rows:t})]}}product_to_products({rows:t=5}){return{products:[...C({rows:t})]}}}class N{constructor(t){this._options=t}upload(t){return[]}}class R{constructor(t){this._options=t}upload(t){return[]}ids(){const t=[];for(let n=0;5e3>n;n++)t.push(V(n));return{ids:t}}}function V(t){return`${10>t?"p_000":100>t?"p_00":1e3>t?"p_0":"p_"}${t}`}class Z{constructor(t){this.ask=new I(t),this.search=new K(t),this.recommendation=new G(t),this.interactions=new N(t),this.products=new R(t)}}return{buildApi:(...t)=>new Z(...t)}}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miso.ai/doggoganger",
3
- "version": "0.9.0-beta.13",
3
+ "version": "0.9.0-beta.14",
4
4
  "description": "A dummy miso endpoint for demo and testing",
5
5
  "type": "module",
6
6
  "bin": {
@@ -14,7 +14,8 @@
14
14
  "build:js": "rollup -c",
15
15
  "build": "npm run build:data && npm run build:js",
16
16
  "start:js": "rollup -w -c rollup.config.dev.mjs",
17
- "start": "nodemon src/index.js",
17
+ "start": "nodemon cli/index.js",
18
+ "dev": "npm run start -- -- -v",
18
19
  "version": "node ./bin/version.js"
19
20
  },
20
21
  "repository": {
@@ -36,7 +37,7 @@
36
37
  "koa": "^2.14.1",
37
38
  "koa-body": "^6.0.1",
38
39
  "koa-static": "^5.0.0",
39
- "nodemon": "^2.0.15",
40
+ "nodemon": "^2.0.22",
40
41
  "yargs": "^17.5.1"
41
42
  },
42
43
  "devDependencies": {
package/src/api/ask.js CHANGED
@@ -51,6 +51,7 @@ class Answer {
51
51
  const [answer_stage, answer, finished] = this._answer(elapsed);
52
52
  const sources = this._sources(elapsed, finished);
53
53
  const related_resources = this._related_resources(elapsed, finished);
54
+ const followup_questions = this._followup_questions(elapsed, finished);
54
55
  const { question_id, question, datetime, parent_question_id } = this._data;
55
56
 
56
57
  return {
@@ -61,8 +62,9 @@ class Answer {
61
62
  parent_question_id,
62
63
  question,
63
64
  question_id,
64
- related_resources,
65
65
  sources,
66
+ related_resources,
67
+ followup_questions,
66
68
  };
67
69
  }
68
70
 
@@ -100,4 +102,14 @@ class Answer {
100
102
  return related_resources.slice(0, loaded);
101
103
  }
102
104
 
105
+ _followup_questions(elapsed, finished) {
106
+ const { followup_questions } = this._data;
107
+ if (finished || !followup_questions) {
108
+ return followup_questions;
109
+ }
110
+ const { length } = followup_questions;
111
+ const loaded = Math.floor(length * elapsed / ITEMS_LOADING_TIME);
112
+ return followup_questions.slice(0, loaded);
113
+ }
114
+
103
115
  }
package/src/api/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import Ask from './ask.js';
2
2
  import Search from './search.js';
3
3
  import Recommendation from './recommendation.js';
4
+ import Interactions from './interactions.js';
5
+ import Products from './products.js';
4
6
 
5
7
  export default class Api {
6
8
 
@@ -8,6 +10,8 @@ export default class Api {
8
10
  this.ask = new Ask(options);
9
11
  this.search = new Search(options);
10
12
  this.recommendation = new Recommendation(options);
13
+ this.interactions = new Interactions(options);
14
+ this.products = new Products(options);
11
15
  }
12
16
 
13
17
  }
@@ -0,0 +1,13 @@
1
+ export default class Interactions {
2
+
3
+ constructor(options) {
4
+ this._options = options;
5
+ }
6
+
7
+ upload(records) {
8
+ return [];
9
+ }
10
+
11
+ // TODO: delete
12
+
13
+ }
@@ -0,0 +1,28 @@
1
+ export default class Products {
2
+
3
+ constructor(options) {
4
+ this._options = options;
5
+ }
6
+
7
+ upload(records) {
8
+ return [];
9
+ }
10
+
11
+ ids() {
12
+ const ids = [];
13
+ for (let i = 0; i < 5000; i++) {
14
+ ids.push(mockProductId(i));
15
+ }
16
+ return {
17
+ ids,
18
+ };
19
+ }
20
+
21
+ // TODO: delete (batch)
22
+
23
+ }
24
+
25
+ function mockProductId(i) {
26
+ const prefix = i < 10 ? 'p_000' : i < 100 ? 'p_00' : i < 1000 ? 'p_0' : 'p_';
27
+ return `${prefix}${i}`;
28
+ }
@@ -1,6 +1,7 @@
1
1
  import { randomInt, formatDatetime, sample, uuid } from './utils.js';
2
2
  import * as fields from './fields.js';
3
3
  import { articles } from './articles.js';
4
+ import { questions } from './questions.js';
4
5
 
5
6
  export function answer({ question, parent_question_id, timestamp = Date.now() }, { answerFormat = 'markdown', answerSampling, answerLanguages = [] } = {}) {
6
7
 
@@ -13,6 +14,7 @@ export function answer({ question, parent_question_id, timestamp = Date.now() },
13
14
  const answer = fields.answer({ format: answerFormat, sampling, features });
14
15
  const related_resources = [...articles({ rows: sampleRandomInt(6, 8, sampling) })];
15
16
  const sources = [...articles({ rows: sampleRandomInt(4, 6, sampling) })];
17
+ const followup_questions = [...questions({ rows: sampleRandomInt(3, 6) })];
16
18
 
17
19
  return {
18
20
  question,
@@ -20,8 +22,9 @@ export function answer({ question, parent_question_id, timestamp = Date.now() },
20
22
  ...(parent_question_id && { parent_question_id }),
21
23
  datetime,
22
24
  answer,
23
- related_resources,
24
25
  sources,
26
+ related_resources,
27
+ followup_questions,
25
28
  };
26
29
  }
27
30
 
@@ -30,10 +30,11 @@ export function title({ size = [2, 6] } = {}) {
30
30
  });
31
31
  }
32
32
 
33
- export function description({ size = [10, 20] } = {}) {
33
+ export function description({ size = [10, 20], ...options } = {}) {
34
+ const decorator = Object.keys(options).length ? ['description', options] : 'description';
34
35
  return lorem.lorem({
35
36
  size,
36
- decorates: ['description'],
37
+ decorates: [decorator],
37
38
  });
38
39
  }
39
40
 
package/src/data/index.js CHANGED
@@ -2,5 +2,6 @@ export * as md from './markdown/index.js';
2
2
  export * as lorem from './lorem.js';
3
3
  export * from './products.js';
4
4
  export * from './articles.js';
5
+ export * from './questions.js';
5
6
  export * from './answers.js';
6
7
  export * as utils from './utils.js';
package/src/data/lorem.js CHANGED
@@ -18,7 +18,18 @@ const FNS = {
18
18
  }
19
19
 
20
20
  function lookup(fn) {
21
- return typeof fn === 'string' ? FNS[fn]() : fn;
21
+ switch (typeof fn) {
22
+ case 'string':
23
+ return FNS[fn]();
24
+ case 'function':
25
+ return fn;
26
+ case 'object':
27
+ if (Array.isArray(fn)) {
28
+ const [name, options = {}] = fn;
29
+ return FNS[name](options);
30
+ }
31
+ }
32
+ throw new Error(`Unrecognized decorator/output form: ${fn}`);
22
33
  }
23
34
 
24
35
  // base //
@@ -91,6 +102,7 @@ export function description({
91
102
  std: 5,
92
103
  min: 1,
93
104
  },
105
+ punctuation = '.',
94
106
  } = {}) {
95
107
  return function *(iterator) {
96
108
  let word;
@@ -105,12 +117,12 @@ export function description({
105
117
  slen = gaussMS(wordsPerSentence);
106
118
  }
107
119
  if (--slen === 0) {
108
- word += '.';
120
+ word += punctuation;
109
121
  }
110
122
  }
111
123
  if (word) {
112
- if (!word.endsWith('.')) {
113
- word += '.';
124
+ if (!word.endsWith(punctuation)) {
125
+ word += punctuation;
114
126
  }
115
127
  yield word;
116
128
  }
@@ -0,0 +1,11 @@
1
+ import * as fields from './fields.js';
2
+
3
+ export function *questions({ rows, ...options } = {}) {
4
+ for (let i = 0; i < rows; i++) {
5
+ yield question({ ...options, index: i });
6
+ }
7
+ }
8
+
9
+ function question({} = {}) {
10
+ return fields.description({ size: [4, 8], punctuation: '?' });
11
+ }
package/src/index.js CHANGED
@@ -13,6 +13,7 @@ export default function doggoganger({ port = 9901, serve = false, ...options } =
13
13
  const api = _route(new Api(options));
14
14
 
15
15
  router.use('/api', api.routes(), api.allowedMethods());
16
+ router.use('/v1', api.routes(), api.allowedMethods());
16
17
 
17
18
  if (serve) {
18
19
  app
@@ -22,8 +23,32 @@ export default function doggoganger({ port = 9901, serve = false, ...options } =
22
23
 
23
24
  app
24
25
  .use(cors())
25
- .use(koaBody())
26
+ .use(koaBody({
27
+ formLimit: '100mb',
28
+ textLimit: '100mb',
29
+ jsonLimit: '100mb',
30
+ onerror: function (err, ctx) {
31
+ console.error(err);
32
+ ctx.throw('body parse error', 422);
33
+ },
34
+ }))
35
+ .use(handleAllPath(options))
26
36
  .use(router.routes())
27
37
  .use(router.allowedMethods())
38
+ .use(handleUnrecognizedPath(options))
28
39
  .listen(port);
29
40
  }
41
+
42
+ function handleAllPath({ verbose } = {}) {
43
+ return async (ctx, next) => {
44
+ verbose && console.log(`${ctx.method} ${ctx.url}`);
45
+ await next();
46
+ };
47
+ }
48
+
49
+ function handleUnrecognizedPath({ verbose } = {}) {
50
+ return async (ctx, next) => {
51
+ verbose && console.log(`Unrecognized path: ${ctx.method} ${ctx.url}`);
52
+ await next();
53
+ };
54
+ }
@@ -3,6 +3,7 @@ import ask from './ask.js';
3
3
  import recommendation from './recommendation.js';
4
4
  import search from './search.js';
5
5
  import interactions from './interactions.js';
6
+ import products from './products.js';
6
7
 
7
8
  function use(router, path, middleware) {
8
9
  router.use(path, middleware.routes(), middleware.allowedMethods());
@@ -14,7 +15,8 @@ export default function(api) {
14
15
  use(router, '/ask', ask(api));
15
16
  use(router, '/recommendation', recommendation(api));
16
17
  use(router, '/search', search(api));
17
- use(router, '/interactions', interactions);
18
+ use(router, '/interactions', interactions(api));
19
+ use(router, '/products', products(api));
18
20
 
19
21
  return router;
20
22
  };
@@ -1,9 +1,17 @@
1
1
  import Router from '@koa/router';
2
+ import { parseBodyIfNecessary } from './utils.js';
2
3
 
3
- const router = new Router();
4
+ export default function(api) {
5
+ const router = new Router();
4
6
 
5
- router.post('/', (ctx) => {
6
- ctx.body = { took: 1, errors: false, data: [] };
7
- });
7
+ router.post('/', (ctx) => {
8
+ const { data } = parseBodyIfNecessary(ctx.request.body);
9
+ ctx.body = {
10
+ took: 5,
11
+ errors: false,
12
+ data: api.interactions.upload(data),
13
+ };
14
+ });
8
15
 
9
- export default router;
16
+ return router;
17
+ }
@@ -0,0 +1,24 @@
1
+ import Router from '@koa/router';
2
+ import { parseBodyIfNecessary } from './utils.js';
3
+
4
+ export default function(api) {
5
+ const router = new Router();
6
+
7
+ router.post('/', (ctx) => {
8
+ const { data } = parseBodyIfNecessary(ctx.request.body);
9
+ ctx.body = {
10
+ took: 5,
11
+ errors: false,
12
+ data: api.products.upload(data),
13
+ };
14
+ });
15
+
16
+ router.get('/_ids', (ctx) => {
17
+ ctx.body = {
18
+ message: 'success',
19
+ data: api.products.ids(),
20
+ };
21
+ });
22
+
23
+ return router;
24
+ }