
Security News
Package Maintainers Call for Improvements to GitHub’s New npm Security Plan
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
@jackens/jc
Advanced tools
A collection of useful JavaScript helpers.
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»')
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(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.
any
any
boolean
Helper for handling client-side (web browser) generated downloads.
function download(blobPart?: BlobPart[] | undefined, download?: string | undefined, type?: string | undefined): void;
Helper for handling client-side (web browser) generated downloads.
BlobPart[]=
string=
string=
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(ref: object, ...keys: string[]): any | undefined;
Helper similar to ?
operator (Elvis operator) for easy accessing nested object values.
object
string[]
any=
function set(ref: object, ...keys: string[]): any | undefined;
Helper similar to ?
operator (Elvis operator) for easy assigning values to nested objects.
object
string[]
any=
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(htmlElement: HTMLElement): void;
Helper implementing typographic corrections appropriate for Polish typography. An iterative implementation that does not cause a stack overflow exception.
HTMLElement
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 = (letter1: string, letter2: string) => number;
The substitution cost function used by levenshteinDistance
.
string
string
number
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
.
Record<string, Record<string, number>>
Record<string, number>
Record<string, number>
string
string
number=
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.
Record<string, Record<string, number>>
[Record<string, number>, Record<string, number>]
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.
Record<string, Record<string, number>>
Record<string, number>
Record<string, number>
string
Record<string, number>=
Record<string, number>
function levenshteinDistance(deletionCost: number, insertionCost: number, substitutionCost: SubstitutionCost, word1: string, word2: string): number;
Helper for calculating Levenshtein distances.
number
number
SubstitutionCost
string
string
number
const substitutionCostsDefault: SubstitutionCost;
Default substitution costs function to use with levenshteinDistance
.
SubstitutionCost
const substitutionCostsPL: SubstitutionCost;
Substitution costs function for the Polish language (to use with levenshteinDistance
).
SubstitutionCost
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(map: any, key: any): boolean;
Replacement for the in
operator (not to be confused with the for-in
loop) that works properly.
any
any
boolean
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 = {
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 by setAttribute
or setAttributeNS
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 for createElementNS
, setAttributeNS
and removeAttributeNS
methodsp
: reference to the parent element for the created or modified elementt
: tag of the created elementconst NAMESPACE_SVG: "http://www.w3.org/2000/svg";
function j({ a, e, i, k, n, p, t }: JConfig): {
e: Element | Text;
};
Lightweight helper for creating and modifying DOM elements.
JConfig
{
e: Element | Text;
}
function jStyle(jsStyle: import('./jss.js').JSS, splitter?: string | undefined): {
e: HTMLStyleElement;
};
Helper for creating <style>
elements.
import('./jss.js').JSS
string=
{
e: HTMLStyleElement;
}
function jSvg(configs: JConfig[]): {
e: SVGSVGElement;
};
Helper for creating <svg>
container elements.
JConfig[]
{
e: SVGSVGElement;
}
function jSvgUse(id: string): JConfig;
Helper for creating <svg><use>
elements.
string
JConfig
function jSymbol(config: JConfig): {
e: SVGSymbolElement;
};
Helper for creating <symbol>
elements.
JConfig
{
e: SVGSymbolElement;
}
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 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 = ({
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 type checkbox
, radio
and file
)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 configurationc.a
configuration (string, number or boolean) or c.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(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)
})
JCmpConfig
import('./j.js').JConfig
function jCmpJss({ fontFamily, focusColor, mainColor }?: {
fontFamily?: string;
focusColor?: string;
mainColor?: string;
}): import('./jss.js').JSS;
Jackens’ Components CSS rules in JSS
format.
{
fontFamily?: string;
focusColor?: string;
mainColor?: string;
}
import('./jss.js').JSS
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»)
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(text: string, handlers: Record<string, Function>): any;
JSON.parse
with “JavaScript turned on”.
string
Record<string, Function>
any
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 = {
[ruleOrAttribute: string]: string | number | JSS;
};
The JSS
format provides a hierarchical description of CSS rules.
src$$1
→ src
, @font-face$$1
→ @font-face
).-
character preceding them (e.g. fontFamily
→ font-family
).{div:{margin:1,'.a,.b,.c':{margin:2}}}
→ div{margin:1}div.a,div.b,div.c{margin:2}
).@
are not concatenated with sub-object keys.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.
JSS
string=
string
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 of 0
1
or 2
(2
is the default; 0
means no TOC)topLevelHeader
: optional top-level HTML header level, can be one of 1
, 2
, 3
or 4
(1
is the default)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"
]
}
MDoc supports an extra non-standard JSDoc tag @include
that allows You to include files as Markdown code blocks into Your documentation.
For JavaScript source files in CommonJS format, MDoc needs @name
tags in the document blocks.
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.
{
debugJson?: string;
insertExtraIds?: boolean;
src?: string[];
tocMaxDepth?: 0 | 1 | 2;
topLevelHeader?: 1 | 2 | 3 | 4;
}
string
function readFile({ path, fromMarker, toMarker }: {
path: string;
fromMarker?: string;
toMarker?: string;
}): string;
Handler that reads the contents of the specified file.
{
path: string;
fromMarker?: string;
toMarker?: string;
}
string
function writeFile({ lines, path }: {
lines: string[];
path: string;
}): string;
Helper that writes an array of lines to the specified file.
{
lines: string[];
path: string;
}
string
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(code: string, acornOptions?: import('acorn').Options | null): string;
Helper that converts multiple occurrences of literals into constants in JavaScript code.
string
import('acorn').Options?
string
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(num: number): string;
Helper for converting integers to map-friendly string identifiers.
number
string
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(value: number, singular: string, plural2: string, plural5: string, noValue1?: string | undefined, noValue?: string | undefined): string;
Helper for choosing the correct singular and plural.
number
string
string
string
string=
string=
string
Animated gear preloader.
const preloader: {
e: SVGSVGElement;
};
Animated gear preloader.
{
e: SVGSVGElement;
}
const preloaderJss: import('./jss.js').JSS;
Animated gear preloader CSS rules in JSS
format.
import('./jss.js').JSS
type PriorityQueue<T> = {
isEmpty: () => boolean;
push: (item: T, priority: string | number) => void;
shift: () => {
item: T;
priority: string | number;
};
};
function priorityQueue<T>(comparePriorities?: (priority_1: string | number, priority_2: string | number) => number): PriorityQueue<T>;
A simple implementation of a priority queue.
(priority_1: string | number, priority_2: string | number) => number=
Optional priorities comparison function.
PriorityQueue<T>
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(...dirs: string[]): string[];
Helper to scan files in the specified directories.
...string
string[]
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 = {
[Symbol.toStringTag]: "EscapeSQL";
toString: () => string;
};
A special type for functions escaping SQL column, table and schema names.
function escapeMySQL(name: string): EscapeSQL;
Helper for escaping MySQL/MariaDB column, table and schema names.
string
EscapeSQL
function escapeSQL(name: string): EscapeSQL;
Helper for escaping SQL column, table and schema names.
string
EscapeSQL
function sql(template: TemplateStringsArray, ...substitutions: any[]): string;
Tagged Template Literal helper for creating secure SQL queries.
TemplateStringsArray
any[]
string
const sqlEscapeType: Record<string, (value: any) => string>;
Methods that implement value escape for particular types.
Record<string, (value: any) => string>
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(stream: import('stream').Stream): Promise<Buffer>;
Helper for converting streams to buffers.
import('stream').Stream
Promise<Buffer>
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(locales: Record<string, Record<string, string | Record<string, string>>>, defaultLanguage: string): string;
Record<string, Record<string, string | Record<string, string>>>
string
function translate(locales: Record<string, Record<string, string | Record<string, string>>>, language: string, text: string, version?: string | undefined): string;
Language translations helper.
Record<string, Record<string, string | Record<string, string>>>
string
string
string=
string
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 = (...args: any[]) => Promise<any>;
function isArray(arg: any): arg is any[];
Helper that checks if the arg
is of type Array
.
any
arg is Array
function isAsyncFunction(arg: any): arg is AsyncFunction;
Helper that checks if the arg
is of type AsyncFunction
.
any
arg is AsyncFunction
function isBoolean(arg: any): arg is boolean;
Helper that checks if the arg
is of type Boolean
.
any
arg is Boolean
function isDate(arg: any): arg is Date;
Helper that checks if the arg
is of type Date
.
any
arg is Date
function isElement(arg: any): arg is Element;
Helper that checks if the arg
is of type Element
.
any
arg is Element
function isFunction(arg: any): arg is Function;
Helper that checks if the arg
is of type Function
.
any
arg is Function
function isGeneratorFunction(arg: any): arg is GeneratorFunction;
Helper that checks if the arg
is of type GeneratorFunction
.
any
arg is GeneratorFunction
function isHTMLButtonElement(arg: any): arg is HTMLButtonElement;
Helper that checks if the arg
is of type HTMLButtonElement
.
any
arg is HTMLButtonElement
function isHTMLInputElement(arg: any): arg is HTMLInputElement;
Helper that checks if the arg
is of type HTMLInputElement
.
any
arg is HTMLInputElement
function isHTMLTextAreaElement(arg: any): arg is HTMLTextAreaElement;
Helper that checks if the arg
is of type HTMLTextAreaElement
.
any
arg is HTMLTextAreaElement
function isNumber(arg: any): arg is number;
Helper that checks if the arg
is of type Number
.
any
arg is Number
function isObject(arg: any): arg is any;
Helper that checks if the arg
is of type Object
.
any
arg is Object
function isPromise(arg: any): arg is Promise<any>;
Helper that checks if the arg
is of type Promise
.
any
arg is Promise
function isRegExp(arg: any): arg is RegExp;
Helper that checks if the arg
is of type RegExp
.
any
arg is RegExp
function isString(arg: any): arg is string;
Helper that checks if the arg
is of type String
.
any
arg is String
function isText(arg: any): arg is Text;
Helper that checks if the arg
is of type Text
.
any
arg is Text
function typeOf(arg: any): string;
Replacement for the typeof
operator that works properly.
any
string
A collection of UUID v1 helpers.
Usage example from unit tests:
import assert from 'node:assert/strict'
import { test } from 'node:test'
import { uuid1, uuid1Decode } from '../src/uuid1.js'
test('uuid1', () => {
for (let i = 0; i < 4200; ++i) {
const counter = uuid1().split('-')[3]
if (i === 0) {
assert.deepStrictEqual(counter, '8001')
} else if (i === 4094) {
assert.deepStrictEqual(counter, '8fff')
} else if (i === 4095) {
assert.deepStrictEqual(counter, '8000')
} else if (i === 4096) {
assert.deepStrictEqual(counter, '8001')
}
}
assert.ok(uuid1().match(/^[\da-f]{8}-[\da-f]{4}-1[\da-f]{3}-8[\da-f]{3}-[\da-f]{12}$/))
const u1 = uuid1(new Date(323325e6), 205163983024656)
assert.deepStrictEqual(u1.startsWith('c1399400-9a71-11bd'), true)
assert.deepStrictEqual(u1.endsWith('-ba9876543210'), true)
const u2 = uuid1(new Date(323325e6), 486638959735312)
assert.deepStrictEqual(u2.startsWith('c1399400-9a71-11bd'), true)
assert.deepStrictEqual(u2.endsWith('-ba9876543210'), true)
const date1 = new Date()
const uuid = uuid1(date1)
const date2 = uuid1Decode(uuid)
assert.deepStrictEqual(+date2, +date1)
})
function uuid1(date?: Date | undefined, value?: string | undefined): string;
UUID v1 identifier (containing creation timestamp) generator.
Date=
string=
string
function uuid1Decode(uuid: string): Date;
Date extractor from UUID v1 identifier.
string
Date
Generic JSON RPC 2.0 WebSocket Client.
Usage examples:
<script type="module">
import { wsc } from '../../src/wsc.js'
window.onload = async () => {
const fs = await wsc('ws://localhost:12345/')
const list = await fs('list', { path: 'src' })
const file = await fs('read', { path: 'src/wsc.js' })
console.log(list)
console.log(file)
}
</script>
<script type="module">
import { wsc } from '../../src/wsc.js'
window.onload = async () => {
const mariadb = await wsc('ws://localhost:13306/')
const status = await mariadb('connect', {
config: { host: 'localhost', user: 'root', password: 'qwerty' }
})
const rows = await mariadb('query', { query: 'SELECT CURRENT_TIMESTAMP' })
console.log(status)
console.log(rows)
}
</script>
type WSCSend = (method: string, params: Record<string, any>) => Promise<any>;
string
Record<string, any>
Promise<any>
function wsc(url: string, handlers?: Record<string, [Function, Function]> | undefined): Promise<WSCSend>;
Generic JSON RPC 2.0 WebSocket Client.
string
Record<string, [Function, Function]>=
Promise<WSCSend>
Generic JSON RPC 2.0 WebSocket Server.
type WSSMethod = (param0: {
clients: WebSocket[];
client: WebSocket;
params: Record<string, any>;
}) => Promise<any>;
{
clients: WebSocket[];
client: WebSocket;
params: Record<string, any>;
}
Promise<any>
function wss(methods: Record<string, WSSMethod>, port: number): void;
Generic JSON RPC 2.0 WebSocket Server.
Record<string, WSSMethod>
number
File System JSON RPC 2.0 WebSocket Server.
Usage example:
import { wssFS } from '../../src/wssFS.js'
wssFS(12345)
const wssFS: (port: number) => void;
File System JSON RPC 2.0 WebSocket Server.
(port: number) => void
MariaDB JSON RPC 2.0 WebSocket Server.
Usage example:
import { wssMariaDB } from '../../src/wssMariaDB.js'
wssMariaDB(13306)
const wssMariaDB: (port: number) => void;
MariaDB JSON RPC 2.0 WebSocket Server.
(port: number) => void
MIT License
Copyright (c) 2016+ Jackens
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Generated with MDoc.
FAQs
Jackens’ Collection of useful JavaScript helpers.
The npm package @jackens/jc receives a total of 0 weekly downloads. As such, @jackens/jc popularity was classified as not popular.
We found that @jackens/jc demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
Product
Socket Firewall is a free tool that blocks malicious packages at install time, giving developers proactive protection against rising supply chain attacks.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.