@jackens/jc v22.7.10-9.23.16
A collection of useful JavaScript helpers.
Demos
- Jackens’ Homepage (source)
- Jackens’ Bookmarks (source)
- “GYBR” Puzzle Game (source)
- Best strategy provider for “Nogi stonogi” board game (source)
- Simple chess application showing attack/defense counters (source)
- Jackens’ Components Demo (source)
- Login Page Demo (source)
- Gantt Chart Demo (source)
Usage
Installation:
npm i '@jackens/jc'
ES Modules:
import { «something» } from '@jackens/jc/esm/«file_name.js»'
CommonJS:
const { «something» } = require('@jackens/jc/cjs/«file_name.js»')
Sources
- File: src/deepEqual.js
- File: src/download.js
- File: src/elvis.js
- File: src/fixTypography.js
- File: src/fts.js
- File: src/hasOwnProperty.js
- File: src/j.js
- File: src/jCmp.js
- File: src/jsOnParse.js
- File: src/jss.js
- File: src/mdoc.js
- File: src/minifly.js
- File: src/numToKey.js
- File: src/plUral.js
- File: src/preloader.js
- File: src/priorityQueue.js
- File: src/scanDirs.js
- File: src/sql.js
- File: src/streamToBuffer.js
- File: src/translate.js
- File: src/typeOf.js
- Type: AsyncFunction
- Function: isArray
- Function: isAsyncFunction
- Function: isBoolean
- Function: isDate
- Function: isElement
- Function: isFunction
- Function: isGeneratorFunction
- Function: isHTMLButtonElement
- Function: isHTMLInputElement
- Function: isHTMLTextAreaElement
- Function: isNumber
- Function: isObject
- Function: isPromise
- Function: isRegExp
- Function: isString
- Function: isText
- Function: typeOf
- File: src/uuid1.js
- File: src/wsc.js
- File: src/wss.js
- File: src/wssFS.js
- File: src/wssMariaDB.js
📄 File: src/deepEqual.js
Helper that verifies deeply equality of two arguments of any type.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { deepEqual } from '../src/deepEqual.js'
test('deepEqual', () => {
assert.deepStrictEqual(deepEqual(true, true), true)
assert.deepStrictEqual(deepEqual(true, false), false)
assert.deepStrictEqual(deepEqual(false, true), false)
assert.deepStrictEqual(deepEqual(false, false), true)
assert.deepStrictEqual(deepEqual(null, null), true)
assert.deepStrictEqual(deepEqual(null, undefined), false)
assert.deepStrictEqual(deepEqual(undefined, null), false)
assert.deepStrictEqual(deepEqual(undefined, undefined), true)
assert.deepStrictEqual(deepEqual(42, 42), true)
assert.deepStrictEqual(deepEqual(42, '42'), false)
assert.deepStrictEqual(deepEqual('42', 42), false)
assert.deepStrictEqual(deepEqual('42', '42'), true)
assert.deepStrictEqual(deepEqual([1, { a: 2, b: 3 }, 4], [1, { b: 3, a: 2 }, 4]), true)
assert.deepStrictEqual(deepEqual([1, { a: 2, b: 3 }, 4], [1, { b: 3, a: '2' }, 4]), false)
assert.deepStrictEqual(deepEqual([1, { a: 2, b: 3 }, 4], [1, { b: 3, a: 2 }, '4']), false)
assert.deepStrictEqual(deepEqual(Object.create(null), {}), true)
assert.deepStrictEqual(deepEqual(() => { }, () => { }), false)
const keys = 'abcdefghilklmnopqrstuvwxyz0123456789_$'.split('')
const a = [{}, {}, {}]
const t = [a[0], a[1], a[2]]
for (let i = 0; i < t.length; ++i) {
for (let k = 0; k < 10000; ++k) {
t[i] = t[i][keys[k % keys.length]] = {}
}
t[i].deepest = !i
// console.log(JSON.stringify(a[i])) // Maximum call stack size exceeded
}
assert.deepStrictEqual(deepEqual(a[0], a[1]), false)
assert.deepStrictEqual(deepEqual(a[0], a[2]), false)
assert.deepStrictEqual(deepEqual(a[1], a[2]), true)
})
🟨 Function: deepEqual
function deepEqual(actual: any, expected: any): boolean;
Helper that verifies deeply equality of two arguments of any type. An iterative implementation that does not cause a stack overflow exception.
🔴 Parameter: actual
any
🔴 Parameter: expected
any
🟢 Returns
boolean
📄 File: src/download.js
Helper for handling client-side (web browser) generated downloads.
🟨 Function: download
function download(blobPart?: BlobPart[] | undefined, download?: string | undefined, type?: string | undefined): void;
Helper for handling client-side (web browser) generated downloads.
🔴 Parameter: blobPart
BlobPart[]=
🔴 Parameter: download
string=
🔴 Parameter: type
string=
📄 File: src/elvis.js
A set of helpers to deal with nested objects.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { get, set } from '../src/elvis.js'
test('should get existing non-nested property', () => {
const actual = { a: 42 }
assert.deepStrictEqual(get(actual, 'a'), 42)
})
test('should get existing nested property and get undefined for non existing nested property', () => {
const actual = {
The: {
answer: {
to: {
life: {
the: {
universe: {
and: {
everything: 42
}
}
}
}
}
}
}
}
assert.deepStrictEqual(get(actual, 'The', 'answer', 'to', 'life', 'the', 'universe', 'and', 'everything'), 42)
assert.deepStrictEqual(get(actual, 'The', 'answer', 'to', 'life', 'the', 'Universe', 'and', 'everything'), undefined)
})
test('should set not existing non-nested property', () => {
const actual = {}
set(actual).a = 42
assert.deepStrictEqual(actual, { a: 42 })
})
test('shoud set not existing nested property', () => {
const actual = {}
set(actual, 'E', 'l', 'v', 'i').s = 42
assert.deepStrictEqual(actual, { E: { l: { v: { i: { s: 42 } } } } })
})
🟨 Function: get
function get(ref: object, ...keys: string[]): any | undefined;
Helper similar to ?
operator (Elvis operator) for easy accessing nested object values.
🔴 Parameter: ref
object
🔴 Parameter: keys
string[]
🟢 Returns
any=
🟨 Function: set
function set(ref: object, ...keys: string[]): any | undefined;
Helper similar to ?
operator (Elvis operator) for easy assigning values to nested objects.
🔴 Parameter: ref
object
🔴 Parameter: keys
string[]
🟢 Returns
any=
📄 File: src/fixTypography.js
Helper implementing typographic corrections appropriate for Polish typography.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import './setup.js'
import { fixTypography } from '../src/fixTypography.js'
import { j } from '../src/j.js'
test('fixTypography', () => {
const p = j({
t: 'p',
k: {
innerHTML: 'a b c d e f g h i j k l m n o p q r s t u v w x y z ' +
'https://example.com ' +
'<a href="https://example.com">https://example.com</a>'
}
}).e
fixTypography(p)
assert.deepStrictEqual(p.outerHTML.replace(/\u200B/g, '​'),
'<p>a b c d e f g h ' +
'<span class="nbsp">i </span>j k l m n ' +
'<span class="nbsp">o </span>p q r s t ' +
'<span class="nbsp">u </span>v ' +
'<span class="nbsp">w </span>x y ' +
'<span class="nbsp">z </span>' +
'https:/​/​example.​com ' +
'<a href="https://example.com">' +
'https:/​/​example.​com' +
'</a></p>'
)
})
🟨 Function: fixTypography
function fixTypography(htmlElement: HTMLElement): void;
Helper implementing typographic corrections appropriate for Polish typography. An iterative implementation that does not cause a stack overflow exception.
🔴 Parameter: htmlElement
HTMLElement
📄 File: src/fts.js
A set of helpers for Full-Text Search.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { ftsIndex, ftsRank, levenshteinDistance, substitutionCostsDefault, substitutionCostsPL } from '../src/fts.js'
test('should work', () => {
const countWordId = {}
const countWord = {}
const countId = {}
const index = ftsIndex.bind(0, countWordId, countWord, countId)
const rank = ftsRank.bind(0, countWordId, countWord, countId)
index('one', 1)
index('one', 2)
index('two', 2)
index('two', 3)
assert.deepStrictEqual(rank('one'), { 1: 0.5, 2: 0.25 })
assert.deepStrictEqual(rank('two'), { 2: 0.25, 3: 0.5 })
})
test('should correctly calculate the Levenshtein distance', () => {
const levenshtein = levenshteinDistance.bind(null, 1, 1, substitutionCostsDefault)
assert.deepStrictEqual(levenshtein('kot', 'kat'), 1)
assert.deepStrictEqual(levenshtein('koty', 'kat'), 2)
assert.deepStrictEqual(levenshtein('levenshtein', 'lewensztejn'), 3)
assert.deepStrictEqual(levenshtein('kitten', 'sitting'), 3)
assert.deepStrictEqual(levenshtein('kat', 'kąt'), 1)
const levenshteinPL = levenshteinDistance.bind(null, 1, 1, substitutionCostsPL)
assert.deepStrictEqual(levenshteinPL('kat', 'kąt'), 0.3)
})
🟩 Type: SubstitutionCost
type SubstitutionCost = (letter1: string, letter2: string) => number;
The substitution cost function used by levenshteinDistance
.
🔴 Parameter: letter1
string
🔴 Parameter: letter2
string
🟢 Returns
number
🟨 Function: ftsIndex
function ftsIndex(countWordId: Record<string, Record<string, number>>, countWord: Record<string, number>, countId: Record<string, number>, word: string, id: string, rank?: number | undefined): void;
Helper that indexes the specified word
within the specified id
.
🔴 Parameter: countWordId
Record<string, Record<string, number>>
🔴 Parameter: countWord
Record<string, number>
🔴 Parameter: countId
Record<string, number>
🔴 Parameter: word
string
🔴 Parameter: id
string
🔴 Parameter: rank
number=
🟨 Function: ftsInitCounters
function ftsInitCounters(countWordId: Record<string, Record<string, number>>): [Record<string, number>, Record<string, number>];
Helper that creates countWord
and countId
maps based on the countWordId
map.
🔴 Parameter: countWordId
Record<string, Record<string, number>>
🟢 Returns
[Record<string, number>, Record<string, number>]
🟨 Function: ftsRank
function ftsRank(countWordId: Record<string, Record<string, number>>, countWord: Record<string, number>, countId: Record<string, number>, word: string, result?: Record<string, number> | undefined): Record<string, number>;
Helper that searches for the given word
among indexed words.
Returns a map of non-zero relevance coefficients for registered identifiers.
🔴 Parameter: countWordId
Record<string, Record<string, number>>
🔴 Parameter: countWord
Record<string, number>
🔴 Parameter: countId
Record<string, number>
🔴 Parameter: word
string
🔴 Parameter: result
Record<string, number>=
🟢 Returns
Record<string, number>
🟨 Function: levenshteinDistance
function levenshteinDistance(deletionCost: number, insertionCost: number, substitutionCost: SubstitutionCost, word1: string, word2: string): number;
Helper for calculating Levenshtein distances.
🔴 Parameter: deletionCost
number
🔴 Parameter: insertionCost
number
🔴 Parameter: substitutionCost
SubstitutionCost
🔴 Parameter: word1
string
🔴 Parameter: word2
string
🟢 Returns
number
🟥 Constant: substitutionCostsDefault
const substitutionCostsDefault: SubstitutionCost;
Default substitution costs function to use with levenshteinDistance
.
🟠 Type
SubstitutionCost
🟥 Constant: substitutionCostsPL
const substitutionCostsPL: SubstitutionCost;
Substitution costs function for the Polish language (to use with levenshteinDistance
).
🟠 Type
SubstitutionCost
📄 File: src/hasOwnProperty.js
Replacement for the in
operator (not to be confused with the for-in
loop) that works properly.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { hasOwnProperty } from '../src/hasOwnProperty.js'
test('hasOwnProperty', () => {
const ob = { key: 'K', null: 'N' }
assert.deepStrictEqual('key' in ob, true)
assert.deepStrictEqual(hasOwnProperty(ob, 'key'), true)
assert.deepStrictEqual('null' in ob, true)
assert.deepStrictEqual(hasOwnProperty(ob, 'null'), true)
assert.deepStrictEqual(null in ob, true)
assert.deepStrictEqual(hasOwnProperty(ob, null), false)
assert.deepStrictEqual('toString' in ob, true)
assert.deepStrictEqual(hasOwnProperty(ob, 'toString'), false)
assert.deepStrictEqual(hasOwnProperty(null, 'key'), false)
})
🟨 Function: hasOwnProperty
function hasOwnProperty(map: any, key: any): boolean;
Replacement for the in
operator (not to be confused with the for-in
loop) that works properly.
🔴 Parameter: map
any
🔴 Parameter: key
any
🟢 Returns
boolean
📄 File: src/j.js
Lightweight helper for creating and modifying DOM elements.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import './setup.js'
import { j, jStyle, jSvg, jSvgUse, jSymbol } from '../src/j.js'
test('j', () => {
assert.deepStrictEqual(j({
t: 'b',
i: [{
t: 'i', k: { className: 'some class', textContent: 'text' }
}]
}).e.outerHTML, '<b><i class="some class">text</i></b>')
const b = j({ t: 'b' })
assert.deepStrictEqual(b.e.outerHTML, '<b></b>')
const i = j({
t: 'i', i: [{ e: 'text' }], p: b.e
})
assert.deepStrictEqual(i.e.outerHTML, '<i>text</i>')
assert.deepStrictEqual(b.e.outerHTML, '<b><i>text</i></b>')
j({
e: i.e, k: { className: 'some class' }
})
assert.deepStrictEqual(i.e.outerHTML, '<i class="some class">text</i>')
assert.deepStrictEqual(b.e.outerHTML, '<b><i class="some class">text</i></b>')
assert.deepStrictEqual(j({
t: 'span', k: { className: 'some class' }, i: [{ e: 0 }]
}).e.outerHTML, '<span class="some class">0</span>')
assert.deepStrictEqual(j({
t: 'span', k: { className: 'some class', textContent: 'one' }
}).e.outerHTML, '<span class="some class">one</span>')
assert.deepStrictEqual(j({
t: 'div',
k: {
style: { margin: 0 }
}
}).e.outerHTML, '<div style="margin: 0px;"></div>')
assert.deepStrictEqual(j({
t: 'div',
k: { className: 'some class' },
i: [{
t: 'b', i: [{ e: 'bold 1' }]
}, {
t: 'b', i: [{ e: 'bold 2' }]
}, {
t: 'i', i: [{ e: 'italic' }]
}]
}).e.outerHTML,
'<div class="some class">' +
'<b>bold 1</b><b>bold 2</b><i>italic</i>' +
'</div>')
const input1 = j({
t: 'input', k: { value: 42 }
})
const input2 = j({
t: 'input', a: { value: 42 }
})
assert.deepStrictEqual(input1.e.value, '42')
assert.deepStrictEqual(input2.e.value, '42')
assert.deepStrictEqual(input1.e.outerHTML, '<input>')
assert.deepStrictEqual(input2.e.outerHTML, '<input value="42">')
assert.deepStrictEqual(j({
t: 'input', a: { type: 'checkbox', checked: true }
}).e.outerHTML, '<input type="checkbox" checked="">')
assert.deepStrictEqual(j({
t: 'input', a: { type: 'checkbox', checked: false }
}).e.outerHTML, '<input type="checkbox">')
assert.deepStrictEqual(j({
t: 'input', a: { type: 'checkbox', 'xhtml:checked': true }
}).e.outerHTML, '<input type="checkbox" checked="">')
assert.deepStrictEqual(j({
t: 'input', a: { type: 'checkbox', 'xhtml:checked': false }
}).e.outerHTML, '<input type="checkbox">')
assert.deepStrictEqual(j({
t: 'div', k: { key: { key_2: 42 } }
}).e.key, { key_2: 42 })
assert.deepStrictEqual(jSymbol({}).e.outerHTML, '<symbol></symbol>')
assert.deepStrictEqual(jSymbol({ t: 'non-symbol' }).e.outerHTML, '<symbol></symbol>')
assert.deepStrictEqual(jSymbol({ a: { id: 'id' } }).e.outerHTML, '<symbol id="id"></symbol>')
assert.deepStrictEqual(jSvg([{
a: { viewBox: '0 1 2 3', id: 'id' },
i: [{ t: 'some-tag' }]
}]).e.outerHTML,
'<svg style="display: none;">' +
'<symbol viewBox="0 1 2 3" id="id"><some-tag></some-tag></symbol>' +
'</svg>')
assert.deepStrictEqual(j(jSvgUse('id')).e.outerHTML.replace('xlink:', ''),
'<svg><use href="#id"></use></svg>')
assert.deepStrictEqual(j({
...jSvgUse('id'),
a: { fill: '#000', stroke: '#000', width: 42, height: 42 }
}).e.outerHTML.replace('xlink:', ''),
'<svg fill="#000" stroke="#000" width="42" height="42">' +
'<use href="#id"></use>' +
'</svg>')
const jsStyle = {
a: { b$$1: 1, b$$2: 2 }
}
assert.deepStrictEqual(jStyle(jsStyle).e.outerHTML,
'<style>a{b:1;b:2}</style>')
assert.deepStrictEqual(jStyle(jsStyle, '$$$').e.outerHTML,
'<style>a{b$$1:1;b$$2:2}</style>')
})
🟩 Type: JConfig
type JConfig = {
a?: Record<string, any>;
e?: Element | Text | string | number;
i?: JConfig[];
k?: Record<string, any>;
n?: string;
p?: Element;
t?: string;
};
The j
helper configuration.
a
: attributes of the created or modified element set bysetAttribute
orsetAttributeNS
e
: modified elementi
: an array of subelements (items) of the created or modified elementk
: properties (keys) to set in the created or modified elementn
: namespace forcreateElementNS
,setAttributeNS
andremoveAttributeNS
methodsp
: reference to the parent element for the created or modified elementt
: tag of the created element
🟥 Constant: NAMESPACE_SVG
const NAMESPACE_SVG: "http://www.w3.org/2000/svg";
🟨 Function: j
function j({ a, e, i, k, n, p, t }: JConfig): {
e: Element | Text;
};
Lightweight helper for creating and modifying DOM elements.
🔴 Parameter: config
JConfig
🟢 Returns
{
e: Element | Text;
}
🟨 Function: jStyle
function jStyle(jsStyle: import('./jss.js').JSS, splitter?: string | undefined): {
e: HTMLStyleElement;
};
Helper for creating <style>
elements.
🔴 Parameter: jsStyle
import('./jss.js').JSS
🔴 Parameter: splitter
string=
🟢 Returns
{
e: HTMLStyleElement;
}
🟨 Function: jSvg
function jSvg(configs: JConfig[]): {
e: SVGSVGElement;
};
Helper for creating <svg>
container elements.
🔴 Parameter: configs
JConfig[]
🟢 Returns
{
e: SVGSVGElement;
}
🟨 Function: jSvgUse
function jSvgUse(id: string): JConfig;
Helper for creating <svg><use>
elements.
🔴 Parameter: id
string
🟢 Returns
JConfig
🟨 Function: jSymbol
function jSymbol(config: JConfig): {
e: SVGSymbolElement;
};
Helper for creating <symbol>
elements.
🔴 Parameter: config
JConfig
🟢 Returns
{
e: SVGSymbolElement;
}
📄 File: src/jCmp.js
Jackens’ Components.
The sample file selection button component shown below
has the following HTML representation:
<body>
<div class="jCmp" label="Label">
<input type="file" id="jCmp1" />
<div>
<label for="jCmp1">Text</label>
</div>
</div>
<script type="module">
import { j, jStyle } from '../../src/j.js'
import { jCmpJss } from '../../src/jCmp.js'
window.onload = () => j({
e: document.body, i: [jStyle(jCmpJss())]
})
</script>
</body>
The file selection button component shown above can be generated with the following code:
<script type="module">
import { j, jStyle } from '../../src/j.js'
import { jCmp, jCmpJss } from '../../src/jCmp.js'
window.onload = () => j({
e: document.body,
i: [
jStyle(jCmpJss()),
jCmp({ type: 'file', label: 'Label', text: 'Text' })
]
})
</script>
Jackens’ Components layout system
Jackens’ Components layout system contains only two types of classes:
.w-«w»-«sw»
: width of«w»
slots when the screen is wide enough for«sw»
slots..h-«h»-«sw»
: height of«h»
slots when the screen is wide enough for«sw»
slots.
The minimum slot width is 200 pixels.
Example. Components defined as follows:
<script type="module">
import { j, jStyle } from '../../src/j.js'
import { jCmp, jCmpJss } from '../../src/jCmp.js'
window.onload = () => j({
e: document.body,
i: [
jStyle(jCmpJss()),
jCmp({
label: 'Component #1',
class: 'jCmp w-1-3 w-1-2',
text: 'jCmp w-1-3 w-1-2'
}), jCmp({
label: 'Component #2',
class: 'jCmp w-1-3 w-1-2',
text: 'jCmp w-1-3 w-1-2'
}), jCmp({
label: 'Component #3',
class: 'jCmp w-1-3',
text: 'jCmp w-1-3'
})
]
})
</script>
on a screen at least 600 pixels wide, will be arranged on a single line:
on a screen less than 600 pixels wide, but not less than 400 pixels wide, will be arranged in two lines:
while on a screen less than 400 pixels wide, they will be arranged in three rows:
🟩 Type: JCmpConfig
type JCmpConfig = ({
w?: import('./j.js').JConfig;
c?: import('./j.js').JConfig;
l?: import('./j.js').JConfig;
class?: string;
icon?: string;
label?: string;
p?: HTMLElement;
style?: Record<string, any>;
t?: keyof HTMLElementTagNameMap | keyof SVGElementTagNameMap;
text?: string;
} & Partial<{
onabort: (e: UIEvent) => any;
onanimationcancel: (e: AnimationEvent) => any;
onanimationend: (e: AnimationEvent) => any;
onanimationiteration: (e: AnimationEvent) => any;
onanimationstart: (e: AnimationEvent) => any;
onauxclick: (e: MouseEvent) => any;
onbeforeinput: (e: InputEvent) => any;
onblur: (e: FocusEvent) => any;
oncanplay: (e: Event) => any;
oncanplaythrough: (e: Event) => any;
onchange: (e: Event) => any;
onclick: (e: MouseEvent) => any;
onclose: (e: Event) => any;
oncompositionend: (e: CompositionEvent) => any;
oncompositionstart: (e: CompositionEvent) => any;
oncompositionupdate: (e: CompositionEvent) => any;
oncontextmenu: (e: MouseEvent) => any;
oncuechange: (e: Event) => any;
ondblclick: (e: MouseEvent) => any;
ondrag: (e: DragEvent) => any;
ondragend: (e: DragEvent) => any;
ondragenter: (e: DragEvent) => any;
ondragleave: (e: DragEvent) => any;
ondragover: (e: DragEvent) => any;
ondragstart: (e: DragEvent) => any;
ondrop: (e: DragEvent) => any;
ondurationchange: (e: Event) => any;
onemptied: (e: Event) => any;
onended: (e: Event) => any;
onerror: (e: ErrorEvent) => any;
onfocus: (e: FocusEvent) => any;
onfocusin: (e: FocusEvent) => any;
onfocusout: (e: FocusEvent) => any;
onformdata: (e: FormDataEvent) => any;
ongotpointercapture: (e: PointerEvent) => any;
oninput: (e: Event) => any;
oninvalid: (e: Event) => any;
onkeydown: (e: KeyboardEvent) => any;
onkeypress: (e: KeyboardEvent) => any;
onkeyup: (e: KeyboardEvent) => any;
onload: (e: Event) => any;
onloadeddata: (e: Event) => any;
onloadedmetadata: (e: Event) => any;
onloadstart: (e: Event) => any;
onlostpointercapture: (e: PointerEvent) => any;
onmousedown: (e: MouseEvent) => any;
onmouseenter: (e: MouseEvent) => any;
onmouseleave: (e: MouseEvent) => any;
onmousemove: (e: MouseEvent) => any;
onmouseout: (e: MouseEvent) => any;
onmouseover: (e: MouseEvent) => any;
onmouseup: (e: MouseEvent) => any;
onpause: (e: Event) => any;
onplay: (e: Event) => any;
onplaying: (e: Event) => any;
onpointercancel: (e: PointerEvent) => any;
onpointerdown: (e: PointerEvent) => any;
onpointerenter: (e: PointerEvent) => any;
onpointerleave: (e: PointerEvent) => any;
onpointermove: (e: PointerEvent) => any;
onpointerout: (e: PointerEvent) => any;
onpointerover: (e: PointerEvent) => any;
onpointerup: (e: PointerEvent) => any;
onprogress: (e: ProgressEvent<EventTarget>) => any;
onratechange: (e: Event) => any;
onreset: (e: Event) => any;
onresize: (e: UIEvent) => any;
onscroll: (e: Event) => any;
onsecuritypolicyviolation: (e: SecurityPolicyViolationEvent) => any;
onseeked: (e: Event) => any;
onseeking: (e: Event) => any;
onselect: (e: Event) => any;
onselectionchange: (e: Event) => any;
onselectstart: (e: Event) => any;
onslotchange: (e: Event) => any;
onstalled: (e: Event) => any;
onsubmit: (e: SubmitEvent) => any;
onsuspend: (e: Event) => any;
ontimeupdate: (e: Event) => any;
ontoggle: (e: Event) => any;
ontouchcancel: (e: TouchEvent) => any;
ontouchend: (e: TouchEvent) => any;
ontouchmove: (e: TouchEvent) => any;
ontouchstart: (e: TouchEvent) => any;
ontransitioncancel: (e: TransitionEvent) => any;
ontransitionend: (e: TransitionEvent) => any;
ontransitionrun: (e: TransitionEvent) => any;
ontransitionstart: (e: TransitionEvent) => any;
onvolumechange: (e: Event) => any;
onwaiting: (e: Event) => any;
onwebkitanimationend: (e: Event) => any;
onwebkitanimationiteration: (e: Event) => any;
onwebkitanimationstart: (e: Event) => any;
onwebkittransitionend: (e: Event) => any;
onwheel: (e: WheelEvent) => any;
}>) | Record<string, string | number | boolean>;
Jackens’ Components configuration.
Jackens’ Components configuration format (JCmpConfig
) is based on three main keys:
w
(wrapper):JConfig
format configuration of the component wrapper (HTMLDivElement
element)c
(control):JConfig
format configuration of the component controll
(label):JConfig
format configuration of the component label (HTMLLabelElement
element; applies to input controls of typecheckbox
,radio
andfile
)
All other keys are just an alternative, more convenient form for configuration using the main keys:
class
:w.a.class
configurationicon
: icon configurationlabel
:w.a.label
configurationp
:w.p
configurationstyle
:c.k.style
configurationt
:c.t
configurationtest
: text configuration- other:
c.a
configuration (string, number or boolean) orc.k
configuration (function)
The icon
and text
keys are handled in a special way: they allow you to conveniently specify the icon and text of the component you are defining.
The JCmpConfig
format has the following default values:
{ […], t: 'input', class: 'jCmp', […] }
🟨 Function: jCmp
function jCmp(config: JCmpConfig): import('./j.js').JConfig;
Convenient converter from JCmpConfig
format to JConfig
format.
import assert from 'node:assert/strict'
import { test } from 'node:test'
import './setup.js'
import { jSvgUse } from '../src/j.js'
import { jCmp, jCmpJss } from '../src/jCmp.js'
import { isObject } from '../src/typeOf.js'
test('jCmp', () => {
const svgUseConfig = {
a: { fill: '#fff', stroke: '#fff', width: 17, height: 17 }
}
const button1 = jCmp({
t: 'button',
w: {
a: { class: 'jCmp' }
},
c: {
a: { 'aria-label': 'button' },
i: [{
...jSvgUse('icon-id'), ...svgUseConfig
}, {
t: 'div'
}, {
e: 'Button'
}],
k: {
style: { marginLeft: 42, marginRight: 17 },
onclick: console.log // eslint-disable-line no-console
}
}
})
const button2 = jCmp({
t: 'button',
style: { marginLeft: 42, marginRight: 17 },
onclick: console.log, // eslint-disable-line no-console
text: 'Button',
icon: 'icon-id',
'aria-label': 'button'
})
assert.deepStrictEqual(button2, button1)
const file1 = jCmp({
t: 'input',
type: 'file',
w: {
a: { class: 'jCmp' }
},
l: {
i: [{ e: 'Choose file…' }]
}
})
const file2 = jCmp({
t: 'input', type: 'file', text: 'Choose file…'
})
file2.i[0].a.id = file2.i[1].i[0].a.for = 'jCmp1'
assert.deepStrictEqual(file2, file1)
const css = jCmpJss()
assert.deepStrictEqual(isObject(css), true)
})
🔴 Parameter: config
JCmpConfig
🟢 Returns
import('./j.js').JConfig
🟨 Function: jCmpJss
function jCmpJss({ fontFamily, focusColor, mainColor }?: {
fontFamily?: string;
focusColor?: string;
mainColor?: string;
}): import('./jss.js').JSS;
Jackens’ Components CSS rules in JSS
format.
🔴 Parameter: config
{
fontFamily?: string;
focusColor?: string;
mainColor?: string;
}
🟢 Returns
import('./jss.js').JSS
📄 File: src/jsOnParse.js
JSON.parse
with “JavaScript turned on”.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { jsOnParse } from '../src/jsOnParse.js'
const handlers = {
join: (...params) => params.join(' '),
outer: text => `Hello ${text}!`,
inner: text => text.charAt(0).toUpperCase() + text.slice(1).toLowerCase(),
question: text => ({ d: 'Yes!', t: 42 }[text[0]])
}
test('should use ‘join’ handler', () => {
assert.deepStrictEqual(jsOnParse(`{
"join": ["Hello", "World!"]
}`, handlers), 'Hello World!')
})
test('should ‘join’ and ‘to_much’ handlers', () => {
assert.deepStrictEqual(jsOnParse(`{
"join": ["Hello", "World!"], "to_much": "whatever"
}`, handlers), {
join: ['Hello', 'World!'], to_much: 'whatever'
})
})
test('should use ‘inner’ and ‘outer’ handlers', () => {
assert.deepStrictEqual(jsOnParse(`{
"outer":{ "inner": "wORld" }
}`, handlers), 'Hello World!')
})
test('should use ‘question’ handler', () => {
assert.deepStrictEqual(jsOnParse(`[{
"question": "does it really works?!?"
}, {
"question": "the answer to life the universe and everything"
}, {
"Question": null
}]`, handlers), ['Yes!', 42, { Question: null }])
})
test('should process nested objects', () => {
assert.deepStrictEqual(jsOnParse('{"H":{"e":{"l":{"l":{"o":["World!"]}}}}}', handlers)
, { H: { e: { l: { l: { o: ['World!'] } } } } })
})
Objects having exactly one «handlerName»
property present in the handlers
map, i.e. objects of form:
{ "«handlerName»": «param» }
and
{ "«handlerName»": [«params»] }
are replaced by the result of call
handlers['«handlerName»'](«param»)
and
handlers['«handlerName»'](...«params»)
Remark
To pass to handlers['«handlerName»']
a single argument that is an array, use the following form:
{ "«handlerName»": [[«elements»]] }
which will force a call
handlers['«handlerName»']([«elements»])
🟨 Function: jsOnParse
function jsOnParse(text: string, handlers: Record<string, Function>): any;
JSON.parse
with “JavaScript turned on”.
🔴 Parameter: text
string
🔴 Parameter: handlers
Record<string, Function>
🟢 Returns
any
📄 File: src/jss.js
CSS-in-JS helper based on the JSS
format.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { jss } from '../src/jss.js'
test('should handle nested definitions (level 1)', () => {
const actual = {
a: {
color: 'red',
margin: 1,
'.c': {
margin: 2,
padding: 2
},
padding: 1
}
}
const expected =
'a{color:red;margin:1}' +
'a.c{margin:2;padding:2}' +
'a{padding:1}'
assert.deepStrictEqual(jss(actual), expected)
})
test('should handle nested definitions (level 2)', () => {
const actual = {
a: {
'.b': {
color: 'red',
margin: 1,
'.c': {
margin: 2,
padding: 2
},
padding: 1
}
}
}
const expected =
'a.b{color:red;margin:1}' +
'a.b.c{margin:2;padding:2}' +
'a.b{padding:1}'
assert.deepStrictEqual(jss(actual), expected)
})
test('should handle ‘@’ prefixes and ‘$$suffix’ suffixes', () => {
const actual = {
'@font-face$$1': {
fontFamily: 'Jackens',
src$$1: 'url(fonts/jackens.otf)',
src$$2: "url(fonts/jackens.otf) format('opentype')," +
"url(fonts/jackens.svg) format('svg')",
fontWeight: 'normal',
fontStyle: 'normal'
},
'@font-face$$2': {
fontFamily: 'C64',
src: 'url(fonts/C64_Pro_Mono-STYLE.woff)'
},
'@keyframes spin': {
'0%': { transform: 'rotate(0deg)' },
'100%': { transform: 'rotate(360deg)' }
},
div: {
border: 'solid red 1px',
'.c1': { 'background-color': '#000' },
' .c1': { backgroundColor: 'black' },
'.c2': { backgroundColor: 'rgb(0,0,0)' }
},
'@media(min-width:200px)': {
div: { margin: 0, padding: 0 },
span: { color: '#000' }
}
}
const expected = '@font-face{font-family:Jackens;src:url(fonts/jackens.otf);' +
"src:url(fonts/jackens.otf) format('opentype')," +
"url(fonts/jackens.svg) format('svg');" +
'font-weight:normal;font-style:normal}' +
'@font-face{font-family:C64;src:url(fonts/C64_Pro_Mono-STYLE.woff)}' +
'@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}' +
'div{border:solid red 1px}' +
'div.c1{background-color:#000}' +
'div .c1{background-color:black}' +
'div.c2{background-color:rgb(0,0,0)}' +
'@media(min-width:200px){div{margin:0;padding:0}span{color:#000}}'
assert.deepStrictEqual(jss(actual), expected)
})
test('should handle comma separation (level 2)', () => {
const actual = {
a: {
'.b,.c': {
margin: 1,
'.d': {
margin: 2
}
}
}
}
const expected = 'a.b,a.c{margin:1}a.b.d,a.c.d{margin:2}'
assert.deepStrictEqual(jss(actual), expected)
})
test('should handle comma separation (level 1)', () => {
const actual = {
'.b,.c': {
margin: 1,
'.d': {
margin: 2
}
}
}
const expected = '.b,.c{margin:1}.b.d,.c.d{margin:2}'
assert.deepStrictEqual(jss(actual), expected)
})
test('should handle multiple comma separations', () => {
const actual = {
'.a,.b': {
margin: 1,
'.c,.d': {
margin: 2
}
}
}
const expected = '.a,.b{margin:1}' +
'.a.c,.a.d,.b.c,.b.d{margin:2}'
assert.deepStrictEqual(jss(actual), expected)
})
🟩 Type: JSS
type JSS = {
[ruleOrAttribute: string]: string | number | JSS;
};
The JSS
format provides a hierarchical description of CSS rules.
- Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of those CSS attributes; the concatenation of keys of all parent objects is a CSS rule.
- All keys ignore the part starting with a splitter (default: '$$') sign until the end of the key (e.g.
src$$1
→src
,@font-face$$1
→@font-face
). - In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional
-
character preceding them (e.g.fontFamily
→font-family
). - Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g.
{div:{margin:1,'.a,.b,.c':{margin:2}}}
→div{margin:1}div.a,div.b,div.c{margin:2}
). - Top-level keys that begin with
@
are not concatenated with sub-object keys.
🟨 Function: jss
function jss(style: JSS, splitter?: string | undefined): string;
CSS-in-JS helper based on the JSS
format.
An iterative implementation that does not cause a stack overflow exception.
🔴 Parameter: style
JSS
🔴 Parameter: splitter
string=
🟢 Returns
string
📄 File: src/mdoc.js
MDoc
MDoc is a converter from JSDoc to Markdown. It is exposed as “binary”:
#!/usr/bin/env node
import { jsOnParse } from '../src/jsOnParse.js'
import { mdoc, readFile, writeFile } from '../src/mdoc.js'
jsOnParse(readFile({ path: process.argv[2] ?? '.mdoc.json' }), { mdoc, readFile, writeFile })
As you can see it reads the configuration from the specified file or from the .mdoc.json
file.
Also, it uses the jsOnParse
helper, so the configuration can be placed anywhere in the parsed file!
For example, you can use the configuration from the mdoc
key in the package.json
file.
MDoc configuration file used to generate this documentation:
{
"writeFile": {
"lines": [
{
"readFile": {
"path": "readme.md",
"toMarker": "\n# Sources\n"
}
},
{
"mdoc": {}
},
{
"readFile": {
"fromMarker": "\n# License\n",
"path": "readme.md"
}
}
],
"path": "readme.md"
}
}
The readFile
, writeFile
and mdoc
keys/methods in the MDoc configuration are responsible for building Your documentation.
The readFile
and writeFile
methods are fairly self-explanatory, while the mdoc
method supports the following parameters:
debugJson
: optional path to save the debug JSON fileinsertExtraIds
: optional flag to insert extra ids (<a id="…" name="…"></a>
) — useful in case of some Markdown renderers (i.e. BitBucket)src
: array of directories with the JavaScript sources to scantocMaxDepth
: optional TOC max depth, can be one of0
1
or2
(2
is the default;0
means no TOC)topLevelHeader
: optional top-level HTML header level, can be one of1
,2
,3
or4
(1
is the default)
Remark
MDoc parses the .d.ts
files generated by the TypeScript compiler.
Your documentation may be even better if you call tsc
before calling mdoc
!
The tsconfig.json
file used in this repo:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"declaration": true,
"emitDeclarationOnly": true,
"module": "esnext",
"moduleResolution": "node",
"removeComments": true,
"skipLibCheck": true,
"target": "esnext"
},
"include": [
"app/**/*.js",
"src/**/*.js"
],
"exclude": [
"app/bookmarks/countWordId.js"
]
}
Remark
MDoc supports an extra non-standard JSDoc tag @include
that allows You to include files as Markdown code blocks into Your documentation.
Remark
For JavaScript source files in CommonJS format, MDoc needs @name
tags in the document blocks.
🟨 Function: mdoc
function mdoc({ debugJson, insertExtraIds, src, tocMaxDepth, topLevelHeader }?: {
debugJson?: string;
insertExtraIds?: boolean;
src?: string[];
tocMaxDepth?: 0 | 1 | 2;
topLevelHeader?: 1 | 2 | 3 | 4;
}): string;
Converter from JSDoc to Markdown.
🔴 Parameter: config
{
debugJson?: string;
insertExtraIds?: boolean;
src?: string[];
tocMaxDepth?: 0 | 1 | 2;
topLevelHeader?: 1 | 2 | 3 | 4;
}
🟢 Returns
string
🟨 Function: readFile
function readFile({ path, fromMarker, toMarker }: {
path: string;
fromMarker?: string;
toMarker?: string;
}): string;
Handler that reads the contents of the specified file.
🔴 Parameter: config
{
path: string;
fromMarker?: string;
toMarker?: string;
}
🟢 Returns
string
🟨 Function: writeFile
function writeFile({ lines, path }: {
lines: string[];
path: string;
}): string;
Helper that writes an array of lines to the specified file.
🔴 Parameter: config
{
lines: string[];
path: string;
}
🟢 Returns
string
📄 File: src/minifly.js
Helper that converts multiple occurrences of literals into constants in JavaScript code.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { minifly } from '../src/minifly.js'
test('minifly', () => {
const code = "'42' ? '42' : { '42' : /42/ }; 42 ? 42 : { 42 : /42/ }"
const expected = "const __minifly__1 = 42,__minifly__2 = '42',__minifly__3 = /42/;" +
"__minifly__2 ? __minifly__2 : { '42' : __minifly__3 }; __minifly__1 ? __minifly__1 : { 42 : __minifly__3 }"
assert.deepStrictEqual(minifly(code), expected)
})
🟨 Function: minifly
function minifly(code: string, acornOptions?: import('acorn').Options | null): string;
Helper that converts multiple occurrences of literals into constants in JavaScript code.
🔴 Parameter: code
string
🔴 Parameter: acornOptions
import('acorn').Options?
🟢 Returns
string
📄 File: src/numToKey.js
Helper for converting integers to map-friendly string identifiers.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { numToKey } from '../src/numToKey.js'
const ALPHA = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$'
const _1_TO_9 = '123456789'
const _0_TO_9 = `0${_1_TO_9}`
const ALPHA_NUM = `${_0_TO_9}${ALPHA}`
const KEYS = []
for (let a = 0; a < ALPHA_NUM.length; ++a) {
KEYS.push(ALPHA_NUM[a])
}
for (let a = 0; a < _1_TO_9.length; ++a) {
for (let b = 0; b < _0_TO_9.length; ++b) {
KEYS.push(`${_1_TO_9[a]}${_0_TO_9[b]}`)
}
}
for (let a = 0; a < ALPHA.length; ++a) {
for (let b = 0; b < ALPHA_NUM.length; ++b) {
KEYS.push(`${ALPHA[a]}${ALPHA_NUM[b]}`)
}
}
for (let a = 0; a < _1_TO_9.length; ++a) {
for (let b = 0; b < _0_TO_9.length; ++b) {
for (let c = 0; c < _0_TO_9.length; ++c) {
KEYS.push(`${_1_TO_9[a]}${_0_TO_9[b]}${_0_TO_9[c]}`)
}
}
}
for (let a = 0; a < ALPHA.length; ++a) {
for (let b = 0; b < ALPHA_NUM.length; ++b) {
for (let c = 0; c < ALPHA_NUM.length; ++c) {
KEYS.push(`${ALPHA[a]}${ALPHA_NUM[b]}${ALPHA_NUM[c]}`)
}
}
}
test('numToKey', () => {
for (let num = 0; num < KEYS.length; ++num) {
assert.deepStrictEqual(numToKey(num), KEYS[num])
}
})
🟨 Function: numToKey
function numToKey(num: number): string;
Helper for converting integers to map-friendly string identifiers.
🔴 Parameter: num
number
🟢 Returns
string
📄 File: src/plUral.js
Helper for choosing the correct singular and plural.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { plUral } from '../src/plUral.js'
test('should handle 0', () => {
assert.deepStrictEqual(plUral(0, 'car', 'cars', 'cars'), '0 cars')
assert.deepStrictEqual(plUral(0, 'auto', 'auta', 'aut'), '0 aut')
})
test('should handle 1', () => {
assert.deepStrictEqual(plUral(1, 'car', 'cars', 'cars'), '1 car')
assert.deepStrictEqual(plUral(1, 'auto', 'auta', 'aut'), '1 auto')
})
test('should handle 5', () => {
assert.deepStrictEqual(plUral(5, 'car', 'cars', 'cars'), '5 cars')
assert.deepStrictEqual(plUral(5, 'auto', 'auta', 'aut'), '5 aut')
})
test('should handle 2', () => {
assert.deepStrictEqual(plUral(42, 'car', 'cars', 'cars'), '42 cars')
assert.deepStrictEqual(plUral(42, 'auto', 'auta', 'aut'), '42 auta')
})
🟨 Function: plUral
function plUral(value: number, singular: string, plural2: string, plural5: string, noValue1?: string | undefined, noValue?: string | undefined): string;
Helper for choosing the correct singular and plural.
🔴 Parameter: value
number
🔴 Parameter: singular
string
🔴 Parameter: plural2
string
🔴 Parameter: plural5
string
🔴 Parameter: noValue1
string=
🔴 Parameter: noValue
string=
🟢 Returns
string
📄 File: src/preloader.js
Animated gear preloader.
🟥 Constant: preloader
const preloader: {
e: SVGSVGElement;
};
Animated gear preloader.
🟠 Type
{
e: SVGSVGElement;
}
🟥 Constant: preloaderJss
const preloaderJss: import('./jss.js').JSS;
Animated gear preloader CSS rules in JSS
format.
🟠 Type
import('./jss.js').JSS
📄 File: src/priorityQueue.js
🟩 Type: PriorityQueue
type PriorityQueue<T> = {
isEmpty: () => boolean;
push: (item: T, priority: string | number) => void;
shift: () => {
item: T;
priority: string | number;
};
};
🔵 Template parameter: T
🟨 Function: priorityQueue
function priorityQueue<T>(comparePriorities?: (priority_1: string | number, priority_2: string | number) => number): PriorityQueue<T>;
A simple implementation of a priority queue.
🔵 Template parameter: T
🔴 Parameter: comparePriorities
(priority_1: string | number, priority_2: string | number) => number=
Optional priorities comparison function.
🟢 Returns
PriorityQueue<T>
📄 File: src/scanDirs.js
Helper to scan files in the specified directories.
Unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { scanDirs } from '../src/scanDirs.js'
test('scanDirs', async () => {
const dirSrc = scanDirs('src')
const dirTest = scanDirs('test')
const dirsSrcAndTest = scanDirs('src', 'test')
assert.ok(dirSrc.length > 20)
assert.ok(dirTest.length > 20)
assert.deepStrictEqual(dirsSrcAndTest.length, dirSrc.length + dirTest.length)
})
🟨 Function: scanDirs
function scanDirs(...dirs: string[]): string[];
Helper to scan files in the specified directories.
🔴 Parameter: dirs
...string
🟢 Returns
string[]
📄 File: src/sql.js
A set of helpers for creating safe SQL queries.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { escapeMySQL, escapeSQL, sql } from '../src/sql.js'
test('sql', () => {
const actual = sql`
SELECT *
FROM ${escapeMySQL('table`name')}
WHERE
${escapeSQL('column"name')} = ${42} OR
column_name = ${true} OR
column_name = ${false} OR
column_name = ${new Date('1980-03-31T04:30:00.000Z')} OR
column_name IN (${[42, "'", true, false, new Date('1980-03-31T04:30:00.000Z')]})`
const expected = `
SELECT *
FROM \`table\`\`name\`
WHERE
"column""name" = 42 OR
column_name = b'1' OR
column_name = b'0' OR
column_name = '1980-03-31 04:30:00' OR
column_name IN (42,'''',b'1',b'0','1980-03-31 04:30:00')`
assert.deepStrictEqual(actual, expected)
})
🟩 Type: EscapeSQL
type EscapeSQL = {
[Symbol.toStringTag]: "EscapeSQL";
toString: () => string;
};
A special type for functions escaping SQL column, table and schema names.
🟨 Function: escapeMySQL
function escapeMySQL(name: string): EscapeSQL;
Helper for escaping MySQL/MariaDB column, table and schema names.
🔴 Parameter: name
string
🟢 Returns
EscapeSQL
🟨 Function: escapeSQL
function escapeSQL(name: string): EscapeSQL;
Helper for escaping SQL column, table and schema names.
🔴 Parameter: name
string
🟢 Returns
EscapeSQL
🟨 Function: sql
function sql(template: TemplateStringsArray, ...substitutions: any[]): string;
Tagged Template Literal helper for creating secure SQL queries.
🔴 Parameter: template
TemplateStringsArray
🔴 Parameter: substitutions
any[]
🟢 Returns
string
🟥 Constant: sqlEscapeType
const sqlEscapeType: Record<string, (value: any) => string>;
Methods that implement value escape for particular types.
🟠 Type
Record<string, (value: any) => string>
📄 File: src/streamToBuffer.js
Helper for converting streams to buffers.
Usage example from unit tests:
import { createReadStream } from 'fs'
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { streamToBuffer } from '../src/streamToBuffer.js'
test('streamToBuffer', async () => {
const stream = createReadStream('src/streamToBuffer.js')
const buffer = await streamToBuffer(stream)
assert.ok(buffer.toString('utf8').includes('export const streamToBuffer ='))
})
🟨 Function: streamToBuffer
function streamToBuffer(stream: import('stream').Stream): Promise<Buffer>;
Helper for converting streams to buffers.
🔴 Parameter: stream
import('stream').Stream
🟢 Returns
Promise<Buffer>
📄 File: src/translate.js
Language translations helper.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { translate } from '../src/translate.js'
const locales = {
pl: {
Password: 'Hasło',
button: { Login: 'Zaloguj' }
}
}
const _ = translate.bind(0, locales, 'pl')
test('should handle defined texts', () => {
assert.deepStrictEqual(_('Login'), 'Login')
assert.deepStrictEqual(_('Password'), 'Hasło')
})
test('should handle undefined text', () => {
assert.deepStrictEqual(_('Undefined text'), 'Undefined text')
})
test('should handle defined version', () => {
assert.deepStrictEqual(_('Login', 'button'), 'Zaloguj')
})
test('should handle undefined version', () => {
assert.deepStrictEqual(_('Password', 'undefined_version'), 'Hasło')
assert.deepStrictEqual(_('Undefined text', 'undefined_version'), 'Undefined text')
})
test('should have empty prototype', () => {
assert.deepStrictEqual(_('toString'), 'toString')
assert.deepStrictEqual(_('toString', 'undefined_version'), 'toString')
})
🟨 Function: getNavigatorLanguage
function getNavigatorLanguage(locales: Record<string, Record<string, string | Record<string, string>>>, defaultLanguage: string): string;
🔴 Parameter: locales
Record<string, Record<string, string | Record<string, string>>>
🔴 Parameter: defaultLanguage
string
🟨 Function: translate
function translate(locales: Record<string, Record<string, string | Record<string, string>>>, language: string, text: string, version?: string | undefined): string;
Language translations helper.
🔴 Parameter: locales
Record<string, Record<string, string | Record<string, string>>>
🔴 Parameter: language
string
🔴 Parameter: text
string
🔴 Parameter: version
string=
🟢 Returns
string
📄 File: src/typeOf.js
A collection of type testing helpers.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import './setup.js'
import {
isArray,
isAsyncFunction,
isBoolean,
isDate,
isElement,
isFunction,
isGeneratorFunction,
isHTMLButtonElement,
isHTMLInputElement,
isHTMLTextAreaElement,
isNumber,
isObject,
isPromise,
isRegExp,
isString,
isText,
typeOf
} from '../src/typeOf.js'
test('typeOf', () => {
assert.deepStrictEqual(typeof [], 'object')
assert.deepStrictEqual(typeOf([]), 'Array')
assert.deepStrictEqual(isArray([]), true)
assert.deepStrictEqual(typeof (async () => { }), 'function')
assert.deepStrictEqual(typeOf(async () => { }), 'AsyncFunction')
assert.deepStrictEqual(isAsyncFunction(async () => { }), true)
assert.deepStrictEqual(typeof true, 'boolean')
assert.deepStrictEqual(typeOf(true), 'Boolean')
assert.deepStrictEqual(isBoolean(true), true)
assert.deepStrictEqual(typeof new Date(), 'object')
assert.deepStrictEqual(typeOf(new Date()), 'Date')
assert.deepStrictEqual(isDate(new Date()), true)
assert.deepStrictEqual(typeof document.createElement('DIV'), 'object')
assert.deepStrictEqual(typeOf(document.createElement('DIV')), 'HTMLDivElement')
assert.deepStrictEqual(isElement(document.createElement('DIV')), true)
assert.deepStrictEqual(typeof function * () {}, 'function')
assert.deepStrictEqual(typeOf(function * () {}), 'GeneratorFunction')
assert.deepStrictEqual(isGeneratorFunction(function * () {}), true)
assert.deepStrictEqual(typeof typeOf, 'function')
assert.deepStrictEqual(typeOf(typeOf), 'Function')
assert.deepStrictEqual(isFunction(typeOf), true)
assert.deepStrictEqual(isHTMLButtonElement(document.createElement('BUTTON')), true)
assert.deepStrictEqual(isHTMLInputElement(document.createElement('INPUT')), true)
assert.deepStrictEqual(isHTMLTextAreaElement(document.createElement('TEXTAREA')), true)
assert.deepStrictEqual(typeof 42, 'number')
assert.deepStrictEqual(typeOf(42), 'Number')
assert.deepStrictEqual(isNumber(42), true)
assert.deepStrictEqual(typeof NaN, 'number')
assert.deepStrictEqual(typeOf(NaN), 'Number')
assert.deepStrictEqual(isNumber(NaN), true)
assert.deepStrictEqual(typeof Infinity, 'number')
assert.deepStrictEqual(typeOf(Infinity), 'Number')
assert.deepStrictEqual(isNumber(Infinity), true)
assert.deepStrictEqual(typeof {}, 'object')
assert.deepStrictEqual(typeOf({}), 'Object')
assert.deepStrictEqual(isObject({}), true)
assert.deepStrictEqual(typeof Promise.resolve(), 'object')
assert.deepStrictEqual(typeOf(Promise.resolve()), 'Promise')
assert.deepStrictEqual(isPromise(Promise.resolve()), true)
assert.deepStrictEqual(typeof /^(Reg)(Exp)$/, 'object')
assert.deepStrictEqual(typeOf(/^(Reg)(Exp)$/), 'RegExp')
assert.deepStrictEqual(isRegExp(/^(Reg)(Exp)$/), true)
assert.deepStrictEqual(typeof 'Jackens', 'string')
assert.deepStrictEqual(typeOf('Jackens'), 'String')
assert.deepStrictEqual(isString('Jackens'), true)
assert.deepStrictEqual(typeof String('Jackens'), 'string')
assert.deepStrictEqual(typeOf(String('Jackens')), 'String')
assert.deepStrictEqual(isString(String('Jackens')), true)
assert.deepStrictEqual(typeof new String('Jackens'), 'object') // eslint-disable-line no-new-wrappers
assert.deepStrictEqual(typeOf(new String('Jackens')), 'String') // eslint-disable-line no-new-wrappers
assert.deepStrictEqual(isString(new String('Jackens')), true) // eslint-disable-line no-new-wrappers
assert.deepStrictEqual(isText(document.createTextNode('')), true)
})
🟩 Type: AsyncFunction
type AsyncFunction = (...args: any[]) => Promise<any>;
🟨 Function: isArray
function isArray(arg: any): arg is any[];
Helper that checks if the arg
is of type Array
.
🔴 Parameter: arg
any
🟢 Returns
arg is Array
🟨 Function: isAsyncFunction
function isAsyncFunction(arg: any): arg is AsyncFunction;
Helper that checks if the arg
is of type AsyncFunction
.
🔴 Parameter: arg
any
🟢 Returns
arg is AsyncFunction
🟨 Function: isBoolean
function isBoolean(arg: any): arg is boolean;
Helper that checks if the arg
is of type Boolean
.
🔴 Parameter: arg
any
🟢 Returns
arg is Boolean
🟨 Function: isDate
function isDate(arg: any): arg is Date;
Helper that checks if the arg
is of type Date
.
🔴 Parameter: arg
any
🟢 Returns
arg is Date
🟨 Function: isElement
function isElement(arg: any): arg is Element;
Helper that checks if the arg
is of type Element
.
🔴 Parameter: arg
any
🟢 Returns
arg is Element
🟨 Function: isFunction
function isFunction(arg: any): arg is Function;
Helper that checks if the arg
is of type Function
.
🔴 Parameter: arg
any
🟢 Returns
arg is Function
🟨 Function: isGeneratorFunction
function isGeneratorFunction(arg: any): arg is GeneratorFunction;
Helper that checks if the arg
is of type GeneratorFunction
.
🔴 Parameter: arg
any
🟢 Returns
arg is GeneratorFunction
🟨 Function: isHTMLButtonElement
function isHTMLButtonElement(arg: any): arg is HTMLButtonElement;
Helper that checks if the arg
is of type HTMLButtonElement
.
🔴 Parameter: arg
any
🟢 Returns
arg is HTMLButtonElement
🟨 Function: isHTMLInputElement
function isHTMLInputElement(arg: any): arg is HTMLInputElement;
Helper that checks if the arg
is of type HTMLInputElement
.
🔴 Parameter: arg
any
🟢 Returns
arg is HTMLInputElement
🟨 Function: isHTMLTextAreaElement
function isHTMLTextAreaElement(arg: any): arg is HTMLTextAreaElement;
Helper that checks if the arg
is of type HTMLTextAreaElement
.
🔴 Parameter: arg
any
🟢 Returns
arg is HTMLTextAreaElement
🟨 Function: isNumber
function isNumber(arg: any): arg is number;
Helper that checks if the arg
is of type Number
.
🔴 Parameter: arg
any
🟢 Returns
arg is Number
🟨 Function: isObject
function isObject(arg: any): arg is any;
Helper that checks if the arg
is of type Object
.
🔴 Parameter: arg
any
🟢 Returns
arg is Object
🟨 Function: isPromise
function isPromise(arg: any): arg is Promise<any>;
Helper that checks if the arg
is of type Promise
.
🔴 Parameter: arg
any
🟢 Returns
arg is Promise
🟨 Function: isRegExp
function isRegExp(arg: any): arg is RegExp;
Helper that checks if the arg
is of type RegExp
.
🔴 Parameter: arg
any
🟢 Returns
arg is RegExp
🟨 Function: isString
function isString(arg: any): arg is string;
Helper that checks if the arg
is of type String
.
🔴 Parameter: arg
any
🟢 Returns
arg is String
🟨 Function: isText
function isText(arg: any): arg is Text;
Helper that checks if the arg
is of type Text
.
🔴 Parameter: arg
any
🟢 Returns
arg is Text
🟨 Function: typeOf
function typeOf(arg: any): string;
Replacement for the typeof
ope
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago