sleepless
Sleepless Inc.'s handy Javascript stuff.
Install
npm install sleepless
Usage
Browser
<script src="sleepless.js"></script>
<script>
sleepless.globalize() // optional
</script>
Node
sleepless = require( "sleepless" )
sleepless.globalize() // optional
Documentation
The sleepless.js file contains a bunch of code built over the course of years to help me speed up development on both the front and backend.
There is some code that is common to both environments, and there are also things that are only present for one or the other. There are also some things which are common in terms of the function calls, but which have different underlying code depending on the environment.
globalize()
sleepless.globalize() // typeof globalThis.log === "function"
log()
log( "foo", 7 )
throwIf( c, s )
throwIf( something === null, "ERROR: something is null" )
o2j(o)
o2j( { foo: 7 } ) // "{\"foo\":7}"
j2o(j)
j2o( "{\"foo\":7}" ) // { foo: 7 }
toFlt(v)
toFlt( "123.4" ) // 123.4
toFlt( 123.9 ) // 123.9
toInt(v)
toInt( "123.4" ) // 123
toInt( 123.9 ) // 124
centsToBucks(cents)
centsToBucks( 1234 ) // 12.34
centsToBucks( "1234" ) // 12.34
bucksToCents(bucks)
bucksToCents( "1234.56" ) // 123456
bucksToCents( 1234.56 ) // 123456
numFmt(n, plcs, dot, sep)
numFmt( 1234.56 ) // "1,235"
numFmt( 1234.56, 1 ) // "1,234.6"
numFmt( 1234.56, 1, "," ) // "1,234,6"
numFmt( 1234.56, 1, "_" ) // "1,234_6"
numFmt( 1234.56, 1, ",", "." ) // "1.234,6"
numFmt( 1234.56, 1, ".", "" ) // "1234.6"
toPct(n, plcs, dot, sep)
toPct( 0.4 ) + "%" // "40%"
toPct( 123.4,",", "." ) // "12,340"
toMoney(n, dot, sep)
toMoney( 1234.56 ) // "1,234.56"
toMoney( 1234.56, 1, ".", "" ) // "1.234,56"
byteSize(sz)
byteSize( 1024 ) // "1 KB"
time( dt )
time() // 1716740316
my2ts(m)
my2ts( "2024-05-26 17:18:36" ) // 1716740316
ts2my(ts)
ts2my( 1716740316 ) // "2024-05-26 17:18:36"
ts2dt(ts)
ts2dt( 1716740316 ) instanceof Date // true
dt2ts(dt)
dt2ts( ts2dt( 1716740316 ) ) // 1716740316
us2dt(us, utc)
us2ts(us, utc)
ts2us(ts)
ts2us_md(ts)
ts2us_mdy(ts)
ts2us_mdy2(ts)
ts2us_hm(ts)
ts2us_mdyhm(ts)
ts2us_mdy2hm(ts)
ts2us_dMy(ts)
Array.prototype.distinct( cb )
[ 1,2,2 ].distinct() // [1,2]
String.prototype.lcase()
"Foo".lcase() // "foo"
String.prototype.ucase()
"Foo".ucase() // "FOO"
String.prototype.ucfirst()
"foo bar".ucfirst() // "Foo bar"
String.prototype.ucwords( sep )
"foo bar".ucwords() // "Foo Bar"
String.prototype.startsWith(prefix)
"Foobar".startsWith( "Foo" ) // true
"foobar".startsWith( "Foo" ) // false
String.prototype.endsWith(suffix)
"Foobar".endsWith( "bar" ) // true
"foobar".endsWith( "Bar" ) // false
String.prototype.abbr(l)
"Foo bar baz".abbr(6) // "Fo ..."
String.prototype.toLabel()
"foo_bAr".toLabel() // "Foo BAr"
String.prototype.toId()
"Foo BAr".toId() // "foo_bar"
"#Foo.,BAr!!".toId() // "foo_bar"
String.prototype.looks_like()
"I,\nhave a lovely bunch of coconuts".looksLike("i have", "coconuts") == true
String.prototype.substitute( data )
"Welcome, __name__".substitute( { name: "Bart" } ) // "Welcome, Bart"
String.prototype.is_email()
"joe@sleepless.com".is_email() // true
"a@b.cd".is_email() // true
"joe@sleepless".is_email() // false
"joe.sleepless.com".is_email() // false
ago_str(ts, no_suffix)
agoStr( time() - 60 ) // "60 seconds ago"
agoStr( time() - 63 ) // "1 minute ago"
runp( a_this, ...args )
runq( a_this, ...args )
text2html( t )
log5( ...)
logger = log5.mkLog( "Me: " )
logger( 3 )
logger.V( "verbosity" )
logger.W( "warning" ) // 2024-05-26_17:41:12 Me: - - - - warning
Non-Browser Context Stuff
get_file(path, enc, cb)
let s = get_file( "./foo.json" ) // "{\"foo\":7}"
file_info( path, cb )
is_file( path, cb )
is_file( "./README.md" ) // true
is_file( "./missing.txt" ) // false
is_dir( path, cb )
is_dir( "/" ) // true
sha1(s)
sha1( "Bond. James Bond." ) // '045a3cfa9e2ec907262d47174ff9b980d72f7040'
sha256(s)
sha256( "Bond. James Bond." ) // '15f0045e4ba244ef613aeccfc0e3f1399fe0aaa79771add66ea02770cf3a1a74'
rand_hash()
rand_hash() // '8a3301c8b2e71f5a60617bc9215323e1ac7f1d24'
rand_hash() // 'c02bf00ed381c381bfa0c741224a4c0f715d2434'
rpc( url, opts, data, okay, fail )
Browser-Only Stuff
LS
LS.set( "foo", [ "foo", 2, true ] )
LS.get( "foo" ).length // 3
LS.clear()
get_file(url, cb)
get_file( "/data.json", function( text ) {
log( text ) // "{\"foo\":7}"
} )
rpc( url, opts, data, okay, fail )
query_data( key )
"https://example.com/?arg1=foo&arg2=bar"
query_data() // { arg1: "foo", arg2: "bar" }
query_data( "arg1" ) // "foo"
HTMLCollection.prototype.toArray()
NodeList.prototype.toArray();
HTMLElement.prototype.addClass(c)
HTMLElement.prototype.hasClass(c)
<div class="foo bar">...</div>
let elem = document.body.find( "div" )
elem.hasClass( "foo" ) // true
elem.hasClass( "bar" ) // true
elem.hasClass( "qux" ) // false
HTMLElement.prototype.remClass(c)
<div class="foo bar">
</div>
let elem = document.body.find( "div" )
elem.remClass( "foo" );
HTMLElement.prototype.findAll( qs )
<div name=a>
<div name=b>Yelp</div>
</div>
let arr = document.body.findAll( "div" ) // [ ... ]
arr.length // 2
arr[ 1 ].html() // "Yelp"
HTMLElement.prototype.find( qs )
<foo-element>
<bar data=yada>qux</bar>
</foo-element>
let foo = document.body.find( "foo-element" )
foo.find( "wobble" ) // null
let bar = foo.find( "bar" );
bar.html() // "qux"
HTMLElement.prototype.named( name )
<input name="blort">
document.body.named( "blort" ) // HTMLElement { name: "blort" }
document.body.named( "bloop" ) // null
HTMLElement.prototype.attr(a, v)
<input data="foo">
let elem = document.body.find( "input" )
elem.attr( "data" ) // "foo"
elem.attr( "data", "bar" )
HTMLElement.prototype.val(v, chg = false)
<form name=login>
<input name=name value="Bobby">
</form>
let elem = document.forms.login.name
elem.val() // "Bobby"
elem.val( "Sally" )
HTMLElement.prototype.html(h)
let elem = document.body.find( "div.foo" )
let h = elem.html() // "<p>Hi there!</p>"
elem.html( h.replace( /there/, "Bob" )
HTMLElement.prototype.change()
document.forms.login.username.change()
HTMLElement.prototype.inject( data )
<form>
<input name="username" value="__default_user__">
</form>
document.forms.login.inject( { default_user: "elmer" } )
HTMLFormElement.prototype.getData()
let f = document.body.find( "form" )
f.setData( { name: "Bob", email: "bob@example.com } )
f.onsubmit = function() {
let data = f.getData() // { name: "Robert", email: "rob@example.com" }
}
HTMLFormElement.prototype.setData( d, change_cb )
rplc8( elem, data, cb )
r8 = rplc8( document.body.find( "div.a_song" )
objs = [
{ band: "Abba", title: "Waterloo" },
{ band: "AC/DC", title: "T.N.T" },
]
r8.update( objs )
r8.update( objs, function( element, object, index ) {
...
} )
navigate( data, new_show )
Use history.push/popstate to navigate through pseudo-pages.
navigate( { page: "dashboard" } )
FDrop
Drag/Drop support
let elem = document.body.find( "#droptarget" )
FDrop.attach( elem, function( files, event ) {
let f = files[ 0 ]
FDrop.mk_data_url( f, function( url ) {
elem.find( "img" ).src = url
elem.find( "label" ).src = f.name
} )
} )
scale_data_image( image_data_url, new_width, new_height, cb )
Load an image asyncrhonously, scale it to a specific width/height, convert the image to a "data:" url, and return it via callback.