JSPM

@zouloux/ecma-core

0.2.3
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 33
  • Score
    100M100P100Q83298F
  • License MIT

Isomorphic 0-dependency typed core functions for Node and browser.

Package Exports

  • @zouloux/ecma-core
  • @zouloux/ecma-core/dist/index.es2019.cjs
  • @zouloux/ecma-core/dist/index.es2022.mjs

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@zouloux/ecma-core) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

ecma-core

Ecma-Core is an Isomorphic and 0-dependency typed core functions for Node and browser.

Library size is about .

No Browser or Node specific code in this lib ! Only isomorphic helpers.


Table of contents


Usage

Install

npm i @zouloux/ecma-core

Module import

import { toHex, limitRange } from "@zouloux/ecma-core"

CommonJS import

const { toHex, limitRange } = require( "@zouloux/ecma-core" )

Operations

No-op

No-op is a do nothing handler, typed like any handler (...rest) => any|void for compatibility

addEventListener("click", noop) // do nothing

Compare with operator

import { compareWithOperator } from "./operations";
compareWithOperator(2, 5, "<") // true

Available operators

export type TCompareOperators = '===' | '==' | '!==' | '!=' | '>=' | '>' | '<=' | '<';

Numbers

To Hex

toHex(16) // 0xF

UIDs

createUID( antiCollectionEntropy = 1, dateEntropy = 1, randomEntropy = 1 )
createUID() // '4c80-489f7937-14f7'
createUID( 0, 0, 1000 ) // only random based '5b3eb'

Maths

// Limit a value into a range of min and max
limitRange( min, value, max )
limitRange( 0, -10, 1 ) // 0
limitRange( 0, +10, 1 ) // 1

// Limite a value into a random of -max and +max
symmetricLimitRange( value, max )
symmetricLimitRange( 10, 2 ) // 2
symmetricLimitRange( -10, 2 ) // -2

// Compute modulo compatible with negative values
positiveModulo( base, modulo )
positiveModulo( 11, 2 ) // 1
positiveModulo( 11, -2 ) // -1

// Move value with offset until 0 or max is reached and loop
circularRange( value, max, offset )
circularRange( 0, 10, 1 ) // 1
circularRange( 0, 10, -1 ) // 9
circularRange( 3, 10, -5 ) // 8

Geometry

// Compute distance between 2 points
distance( x1, x2, y1, y2 )
distanceBetweenPoints( { x: number, y: number }, { x: number, y: number } )

// Compute angle between 3 points
angle3( [{x, y}, {x, y}, {x, y}] )

// From randians to degrees 
radToDeg( angle )
// From degrees to radians
degToRad( angle )

// Limit angle between -Math.PI and + Math.PI 
limitAngle( angle )
limitAngle( Math.PI * 3 ) == -Math.PI

Random

// Random positive number from 0 to max
randomPositive( max )

// Random number from min to max
randomRange( min, max )

// Random number between -max and + max
randomSymmetricRange( max )

// Random sign (-1 or +1)
randomSign()

// Random boolean
randBoolean( threshold = .5 ) // true or false
randBoolean( threshold = .9 ) // Higher change to have true
randBoolean( threshold = .1 ) // Higher change to have false

randomPick(["a", "b"]) // a or b
randomPick(["a", "b", "c", "d"]) // Any value randomly

// Pick a random value from an object
const familly = {
    a: { name: "Pauline" },
    b: { name: "John" },
    c: { name: "Brune" },
}
randomPickFromObject( familly ) // { name: "Brune" }

// Randomize an array
arrayShuffle(["a", "b", "c"]) // ["b", "c", "a"]

// Functional value map, see doc in src/numbers.ts
functionalValueMap( valueMap )

Paths

Isomorphic path utils without having to import browserified "path" in the browser.

getFileFromPath("./dir/dir/file.ext"); // file.ext

getBaseFromPath("./dir/dir/file.ext"); // ./dir/dir/

extractPathFromBase("/my/base/dir/file.html", "/my/base") // /dir/file.html

removeExtensions("file.config.js") // file.config
removeExtensions("file.config.js", 2) // file

extractExtensions("file.module.less") // ['less', 'module']
extractExtensions("a-folder/") // [] 

Strings

Check if string is a number

isNumber("12") // true
isNumber("") // false
isNumber("0.5") // true
isNumber("1e10") // true
isNumber("0xF1") // true
isNumber("#51") // false
isNumber("NaN") // false

Zero fill

Will prepend zeros to match a certain number a chars

function zeroFill ( totalChars:number, number:number, placeholder = '0' ) : string {}
zeroFill(2, 1) // "01"
zeroFill(10, 1) // "0000000001"
zeroFill(2, 20) // "20"
zeroFill(4, 14) // "014"

Trailing and leading

Add or remove leading or trailing char

function trailing ( source:string, add = true, char = '/' ) : string {}
function leading ( source:string, add = true, char = '/' ) : string {}
trailing("/lib/test") // /lib/test/
trailing("/lib/test/", false) // /lib/test
leading("lib/test") // /lib/test
leading("/lib/test", false) // lib/test
leading(trailing("lib/test")) // /lib/test/

nl2br

Same as PHP function, convert \n new lines to

nl2br(`
Hi !
`) // <br>Hi!<br>

// And if you need auto closing tag : 
nl2br( multiline, '<br/>') 

Repeat a char

repeat(10, 'a') // "aaaaaaaaaa"

Indent

function indent ( total:number, content = '', tabSize = 0 ) : string {}
indent(3, "Hello", 2) 	// "      Hello" ( 3x2 spaces before the Hello string )
indent(3, "Hello") 		// "			Hello" ( 3 tabs, because tabSize is 0 )

upperCaseFirst / lowerCaseFirst

upperCaseFirst("courgette? Oui!") // "Courgette, Oui!"
lowerCaseFirst("Fromage? Oui!") // "fromage? Oui!"

dashToCamelCase / camelToDashCase

dashToCamelCase("my-string") // "myString"

camelToDashCase("myString") // my-string
camelToDashCase("myString", "_") // my_string
camelToDashCase("myString", "_", true) // MY_STRING

Slugs

QuickSlug does not replace special chars

quickSlug("This is a test") // "this-is-a-test"
quickSlug("Le fromage rapé") // "le-fromage-rapé" <- still have special chars
quickSlug("With      spaces") // "with-spaces" <- no repeated dashes

Slugify is slower, but it converts special chars to their corresponding ASCII char

slugify("This is a test") // "this-is-a-test"
slugify("Le fromage rapé") // "le-fromage-rape" <- spcial chars are replaced !
slugify("With      spaces") // "with-spaces" <- no repeated dashes
slugify("Weird_- -test-héééé-haça@_ test") // "weird_-test-heeee-haca_-test" <- safe string

Parse query string safely

Number and boolean are parsed. No support for PHP like array notation. Last parameter will pollute first parameters

parseQueryString("?test=string&special=With%20spaces&boolean=false&flag")
// {
// 	test: "string",
// 	special: "With spaces",
// 	boolean: false,
// 	flag: true
// }

Parse booleans

function parseBoolean ( booleanAsString:string|number, strict = true, areTrue = ['true'], areFalse = ['false'] ):boolean|null {}

parseBoolean("true") // true
parseBoolean("false") // false
parseBoolean("bla") // null
parseBoolean("bla", false) // false
parseBoolean("y") // null
parseBoolean("n") // null

parseBooleanCLI("y") // true
parseBooleanCLI("yes") // true
parseBooleanCLI("N") // false
parseBooleanCLI("no") // false
parseBooleanCLI("bla") // null

countStartingChars

countStartingChars("	how many tabs ?") // 1
countStartingChars("  how many spaces ?", " ") // 2

untab

function testUntab () {
    return untab(`
        Remove tabs
        From this multi-line text into a function
    `)
}
const string = testUntab();
//'Remove tabs\nFrom this multi-line text into a function'

Structs

forceArray("ok") // ["ok"]
forceArray(["ok"]) // ["ok"]
arrayFrom(4).map( i => console.log(i) ) // 0, 1, 2, 3
arrayFrom(4, i => i * 2 ).map( i => console.log(i) ) // 0, 2, 4, 6

Time

Delay in seconds

await delay( 2 ) // wait 2 seconds

Create delta counter

Create a counter usable in tick-loops to have time based animations

const deltaCounter = createDeltaCounter( baseFrameRate = 1000 / 60 )
function tickBasedLoop () {
    const [ timeFactor, delta ] = deltaCounter()
    // timeFactor -> 1 		If exactly ticked 1 frame later
    // timeFactor -> .5 	If ticked too soon
    // timeFactor -> 2 		If ticked too late (skipped a frame)
    // timeFactor -> 1.222	Realistic values are like this
    // delta -> 16.333		How many ms since last tick ?
}

Some types

Types are exported from their respective module, but here are some examples :

type AnyHandler = (...rest) => any|void
type FunctionalFilter <GType> = ( r:GType ) => GType
type ScalarValue = ( string | number | boolean )
type ScalarRecord = Record<string, ScalarValue>

Unpkg

Helpers are available on UNPKG. Import it with a script tag to use it in the browser. Specify version for better performances (will not check last version at each request).

<script src="https://unpkg.com/@zouloux/ecma-core@0.2.0"></script>