Tumgik
skitsanoscom · 4 years
Link
Orbit is an open-source design system created for specific needs of Kiwi.com and together with that – for needs of travel projects.
From Kiwi.com perspective, Orbit aims to bring order and consistency to Kiwi.com products and processes behind building them.
0 notes
skitsanoscom · 4 years
Link
0 notes
skitsanoscom · 4 years
Text
count(doc) is faster than count(doc._key)
One more hint on queries performance tuning. Although document keys (_key) are indexed, counting docs is faster by the entire doc, not by a key of the doc.
So the following query will be faster
let ds = (for doc in random_data return doc) return count(ds)
Compare to this one, that in my case went for entire 12ms slower on 100K records
let ds = (for doc in random_data return doc) return count(ds._key)
0 notes
skitsanoscom · 4 years
Text
AQL performance and indexes
A little experiment with 100,000 randomly generated docs queried in two ways produce the same result, but time takes on execution is like 80 times different.
The following query took like 1.6s to execute
for doc in random_data limit 1,100 return merge(doc, { client: ( for client in random_data_details filter client.source==doc.value return unset(client, "_id","_rev") ) })
While this one, took just 0.02s
for doc in random_data limit 1,100 sort doc._key DESC collect project = doc, found_client = ( for client in random_data_details filter client.source==doc.value return unset(client, "_id","_rev") )[0] || {} return merge(project, { client: found_client })
Worth mentioning here that those benchmarks are valid only for the case when you have indexes enabled on datasets you querying.
Without indexes enabled the first query took 17s and second one executed with 8.5s.
Indexes allow fast access to documents, provided the indexed attribute(s) are used in a query. While ArangoDB automatically indexes some system attributes, users are free to create extra indexes on non-system attributes of documents.
0 notes
skitsanoscom · 5 years
Text
JavaScript: check if date is next week or next month
moment.js has couple of nice functions that allows us to check if the given date is next week or next month:
const today = '2019-09-06'; const nextWeek = '2019-09-11'; const nextMonth = '2019-10-11'; console.log(moment(today).isSame(today, 'day')); console.log(moment(nextWeek).isAfter(today, 'week')); console.log(moment(nextMonth).isAfter(today, 'month'));
0 notes
skitsanoscom · 5 years
Text
Writing simple Webix component
Unfortunately Webix is rather poorly documented when you trying to do something more than app with basic functionality. Coming from Extjs, YUI, Flex, working with React, today Webix is still my number one choice when it comes to building enterprise apps.
Today's code snippet demonstrates you how to create your own basic component. In my particular case, I'm creating header component that can uses title and icon as its view properties. So if icon property is set, it renders FontAwesome icon and title, otherwise just a title.
webix.protoUI({ name: 'header', defaults: { height: 40, icon: undefined, title: 'Untitled' }, $init: function (cfg) { this.$ready.push(() => { if (this.config.icon === undefined) { this.$view.innerHTML = this.title; } else { this.$view.innerHTML = `<i class="fas fa-${this.config.icon}"></i> ${this.config.title}`; } }); this.$view.className += ' webix_header'; this.$view.innerHTML = ''; this.$view.style.paddingLeft = '0.5rem'; }, $getSize: function (x, y) { // own logic // ... // parent logic return webix.ui.view.prototype.$getSize.call(this, x, y); }, $setSize: function (x, y) { //if parent has changed its size if (webix.ui.view.prototype.$setSize.call(this, x, y)) { //custom logic } }, title_setter: function (value) { return value; }, icon_setter: function (value) { return value; } }, webix.ui.view);
Now you can use your new component within application you create:
const ui = { rows: [ { id: 'appheader', view: 'header', title: 'SKITSANOS', icon: 'dizzy' }, {}, { height: 40, template: 'Copyright ® Skitsanos' } ] }; webix.ui(ui)
Please make sure you added FontAwesome into your html header, like this:
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.10.2/css/all.css">
To change config properties, like title for example, you need redefine them this way, (assuming your header component id is 'appheader'):
$$('appheader').define('title', 'My app');
0 notes
skitsanoscom · 5 years
Link
0 notes
skitsanoscom · 5 years
Link
0 notes
skitsanoscom · 5 years
Text
Writing schemas with hapi/joi is quite different to Ajv, you might find its syntax is somewhat readable, just keep in mind it is not a JSON-Schema stard actually.
const Joi = require('@hapi/joi'); const SchemaBase = require('~framework/schemas/joi'); class User extends SchemaBase { constructor() { super(); this.schema = Joi.object().keys({ email: Joi.string().required().email({minDomainSegments: 2}), password: Joi.string().alphanum().min(3).max(30), access_token: [Joi.string(), Joi.number()], role: Joi.string().alphanum().min(3).max(128) }).or('password', 'access_token').without('password', 'role'); } } module.exports = User;
SchemaBase class defined like that:
const Joi = require('@hapi/joi'); class JoiSchema { constructor() { this.schema = {}; } validate(data) { return Joi.validate(data, this.schema); } describe() { return Joi.describe(this.schema); } } module.exports = JoiSchema;
0 notes
skitsanoscom · 5 years
Text
AJV sample schema
Example on how to write JSON Schema with AJV:
const SchemaBase = require('~framework/schemas/ajv'); class User extends SchemaBase { constructor() { super(); this.schema = { type: 'object', properties: { email: { type: 'string', minLength: 5, maxLength: 254, format: 'email' }, password: { type: 'string', minLength: 6, maxLength: 30 }, role: { type: 'string', enum: ['admin', 'user'], default: 'user' } }, required: ['email', 'password'] }; } } module.exports = User;
and AJV Schema Base class:
const Ajv = require('ajv'); const ajv = new Ajv({allErrors: true}); class AjvSchema { constructor() { this.schema = {}; } validate(data) { return ajv.validate(this.schema, data); } } module.exports = AjvSchema;
0 notes
skitsanoscom · 5 years
Link
Just add your desired image size (width & height) after our URL, and you'll get a random image.
0 notes
skitsanoscom · 5 years
Link
0 notes
skitsanoscom · 5 years
Link
0 notes
skitsanoscom · 5 years
Text
On npm install: Unhandled rejection Error: EACCES: permission denied
A simple way to resolve EACCES rejection error when trying to perform npm install:
sudo chown -R $USER:$GROUP ~/.npm sudo chown -R $USER:$GROUP ~/.config
0 notes
skitsanoscom · 5 years
Text
Fixing that ‘Brownout detector was triggered’ error
Although some suggest to switch pff entirely that brownout detector with this line:
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
Reality is, - it might be just your USB cable... Get a better cable and you might have your problem fixed. Worked for me.
0 notes
skitsanoscom · 5 years
Text
JavaScript Array unions, intersection and difference
Below are handy utilties to obtain union, intersection and difference on two arrays.
const app = { utils: { array: { union: (arr_a, arr_b) => { const set_a = new Set(arr_a); const set_b = new Set(arr_b); return new Set([...set_a, ...set_b]); }, intersection: (arr_a, arr_b) => { const set_a = new Set(arr_a); const set_b = new Set(arr_b); return new Set([...set_a].filter(x => set_b.has(x))); }, difference: (arr_a, arr_b) => { const set_a = new Set(arr_a); const set_b = new Set(arr_b); return new Set([...set_a].filter(x => !set_b.has(x))); } } } }; const arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; const arr2 = [1, 22, 3, 74, 5, 26, 7, 8, 9, 10]; const set_union = app.utils.array.union(arr1, arr2); const set_intersection = app.utils.array.intersection(arr1, arr2); const set_difference = app.utils.array.difference(arr1, arr2); console.log(set_union); console.log(set_intersection); console.log(set_difference); console.log(Array.from(set_intersection)); //converts set to array
0 notes
skitsanoscom · 5 years
Text
Reading MHZ-19 sensor data in Node.js
Below is an example on how to read CO2 level readings from MHZ-19 NDIR sensor via serial port in Node.js
/** * MHZ-19 UART Monitor * @author skitsanos */ const winston = require('winston'); const Transport = require('winston-transport'); const fs = require('fs'); const SerialPort = require('serialport'); const port = new SerialPort('/dev/tty.usbserial', {baudRate: 9600, autoOpen: false}); class FileTransport extends Transport { constructor(opts) { super(opts); } log(info, callback) { fs.appendFile(process.cwd() + '/app.log', `${info.level} ${info.message}\n`, (err) => { if (err) { console.log(err.message); } }); callback(); } } const loggingFormat = winston.format.combine( winston.format.colorize(), winston.format.splat(), winston.format.printf(info => { return ` ${(new Date()).getTime()} ${info.level}: ${info.message}`; })); const log = winston.createLogger({ exitOnError: false, //level: 'debug', transports: [ new FileTransport( { format: loggingFormat, timestamp: true } ), new winston.transports.Console({ format: loggingFormat }) ] }); let app = { meta: require('./package'), commands: { READ_VALUE: Buffer.from([0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79]) }, utils: { ord: (str) => { console.log(str); return str.charCodeAt(0); }, sleep: (ms) => new Promise(resolve => setTimeout(resolve, ms)) }, serial: { list: () => { SerialPort.list().then((arr_portInfo) => { arr_portInfo.map(el => { console.log(el); log.info('Found: ' + el.comName); }); }); }, open: () => { if (port !== undefined) { return new Promise((resolve, reject) => { port.open(err => { if (err) { return reject(err); } return resolve(); }); }); } else { log.error('Failed to open port. Not found?'); } }, close: () => { if (port !== undefined) { log.debug('Closing serial port'); port.close(); } else { log.error('Failed to open port. Not found?'); } }, write: (data) => { return new Promise((resolve, reject) => { if (port !== undefined) { log.debug('Writing to serial port...'); port.write(data, (err) => { if (err) { return reject(err); } return resolve(); }); } else { return reject({message: 'Failed to write. Not found?'}); } }); } } }; log.info(`${app.meta.name} ver. ${app.meta.version}`); app.serial.open().then(() => { log.debug('Port open'); port.on('readable', async () => { const buf = port.read(9); if (buf !== null && Buffer.byteLength(buf) === 9) { if (buf[0] === 0xff && buf[1] === 0x86) { const co2 = Number(buf[2].toString()) * 256 + Number(buf[3].toString()); log.info(`${co2}ppm`); } await app.utils.sleep(5000); app.serial.write(app.commands.READ_VALUE); } }); app.serial.write(app.commands.READ_VALUE).then(() => { }).catch(err => log.error(err.message)); }).catch(err => log.error(err.message));
0 notes