Package Exports
- @e280/stz
- @e280/stz/x/index.js
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 (@e280/stz) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@e280/stz
standard library of environment-agnostic typescript functions we use basically everywhere
- zero dependencies
MapG
extended js map
map.require
import {MapG} from "@e280/stz" const map = new MapG<number, string>([ [1, "hello"], [2, "world"], ]) // throws error if the value is undefined const value = map.require(1)
map.guarantee
// if the value is undefined, the new value "rofl" is set and returned const value = map.guarantee(3, () => "rofl")
pub and sub
ergonomic event emitters
- make a publisher fn
import {pub} from "@e280/stz" // create a pub fn const sendMessage = pub<[string]>() // subscribe to it sendMessage.sub(m => console.log(m)) // publish to it sendMessage("hello")
- make a subscriber fn (see how it's just the reverse of pub?)
import {sub} from "@e280/stz" // create a sub fn const onMessage = sub<[string]>() // subscribe to it onMessage(m => console.log(m)) // publish to it onMessage.pub("hello")
- the pub and sub are the same, but have differing invoke signatures
- i seem to use
sub
more often - both have some extra functionality
// pub fns return a promise, to wait for all async subscribers await sendMessage("hello") await onMessage.pub("hello") // sub fns return an unsub fn const unsub1 = onMessage(m => console.log(m)) unsub1() // unsubscribe that listener const unsub2 = sendMessage.sub(m => console.log(m)) unsub2() // unsubscribe that listener // you can clear all subscribers from a pub or a sub sendMessage.clear() onMessage.clear() // you can subscribe to only one next call onMessage.once(m => console.log(m)) sendMessage.once(m => console.log(m))
Data utilities
codecs for representing data in different ways
BaseX
- make a BaseX instance
import {BaseX} from "@e280/stz" const hex = new BaseX(BaseX.lexicons.hex)
- convert between strings and binary
hex.toBytes("9960cd633a46acfe8307d8a400e842da0d930a75fb8188e0f5da264e4b6b4e5b") // Uint8Array hex.fromBytes(bytes) // string
- you can also convert between strings and integers
hex.fromInteger(Date.now()) // "197140ac804" hex.toInteger(hex) // 1748387940356
- available lexicons include
- base2
- hex
- base36
- base58
- base62
- base64 (with standard padding)
- base64url
- you can make insanely compact timestamps like this:
import {BaseX} from "@e280/stz" const base62 = new BaseX(BaseX.lexicons.base62) base62.fromInteger(Date.now() / 1000) // "1uK3au"
1748388028
base10 epoch seconds (10 chars)1uK3au
base62 epoch seconds (6 chars)- nice
Bytename
friendly string encoding for binary data
a bytename looks like "midsen.picmyn.widrep.baclut dotreg.filtyp.nosnus.siptev"
. that's 16 bytes. each byte maps to a three-letter triplet
the bytename parser (Bytename.toBytes
) ignores all non-alphabetic characters. thus midsen.picmyn
, midsenpicmyn
, and mid@sen$pic@myn
are all equal.
import {Bytename} from "@e280/stz"
Bytename.fromBytes(new Uint8Array([0xDE, 0xAD, 0xBE, 0xEF])) // "ribmug.hilmun"
Bytename.toBytes("ribmug.hilmun") // Uint8Array, 4 bytes
const bytes = new Uint8Array([ 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, ]) Bytename.fromBytes(bytes, { groupSize: 2, // default is 4 groupSeparator: " ", wordSeparator: ".", }) // "ribmug.hilmun ribmug.hilmun"
💖 stz is made with open source love
reward us with github stars
build with us at https://e280.org/ but only if you're cool