@e280/stz 0.0.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/license +23 -0
- package/package.json +40 -0
- package/readme.md +85 -0
- package/s/clone/clone.test.ts +124 -0
- package/s/clone/clone.ts +41 -0
- package/s/concurrent.ts +12 -0
- package/s/data/anka.ts +66 -0
- package/s/data/barname/badge.ts +78 -0
- package/s/data/barname/barname.ts +62 -0
- package/s/data/barname/demo.ts +49 -0
- package/s/data/barname/index.ts +4 -0
- package/s/data/barname/utils/prefixes.ts +20 -0
- package/s/data/barname/utils/suffixes.ts +20 -0
- package/s/data/base58.ts +65 -0
- package/s/data/base64.ts +22 -0
- package/s/data/base64url.ts +27 -0
- package/s/data/bytes.ts +7 -0
- package/s/data/hex.ts +35 -0
- package/s/data/nomen/demo.ts +8 -0
- package/s/data/nomen/grammar.ts +41 -0
- package/s/data/nomen/index.ts +5 -0
- package/s/data/nomen/nomen.ts +34 -0
- package/s/data/nomen/presets/falrysk.ts +112 -0
- package/s/data/nomen/types.ts +9 -0
- package/s/data/txt.ts +11 -0
- package/s/deadline.ts +24 -0
- package/s/debounce/debounce.test.ts +73 -0
- package/s/debounce/debounce.ts +54 -0
- package/s/debounce/types.ts +8 -0
- package/s/dedupe.ts +5 -0
- package/s/deep/deep.test.ts +8 -0
- package/s/deep/deep.ts +11 -0
- package/s/deep/parts/equal.test.ts +124 -0
- package/s/deep/parts/equal.ts +49 -0
- package/s/deep/parts/freeze.ts +34 -0
- package/s/defer-promise.ts +29 -0
- package/s/escape-regex.ts +5 -0
- package/s/hat.ts +17 -0
- package/s/index.ts +23 -0
- package/s/is.ts +27 -0
- package/s/map-g.ts +52 -0
- package/s/nap.ts +5 -0
- package/s/ob.ts +66 -0
- package/s/pipe.ts +24 -0
- package/s/pubsub.ts +68 -0
- package/s/trash.ts +30 -0
- package/x/clone/clone.d.ts +1 -0
- package/x/clone/clone.js +26 -0
- package/x/clone/clone.js.map +1 -0
- package/x/clone/clone.test.d.ts +1 -0
- package/x/clone/clone.test.js +125 -0
- package/x/clone/clone.test.js.map +1 -0
- package/x/concurrent.d.ts +1 -0
- package/x/concurrent.js +7 -0
- package/x/concurrent.js.map +1 -0
- package/x/data/anka.d.ts +5 -0
- package/x/data/anka.js +53 -0
- package/x/data/anka.js.map +1 -0
- package/x/data/barname/badge.d.ts +25 -0
- package/x/data/barname/badge.js +64 -0
- package/x/data/barname/badge.js.map +1 -0
- package/x/data/barname/barname.d.ts +7 -0
- package/x/data/barname/barname.js +49 -0
- package/x/data/barname/barname.js.map +1 -0
- package/x/data/barname/demo.d.ts +1 -0
- package/x/data/barname/demo.js +45 -0
- package/x/data/barname/demo.js.map +1 -0
- package/x/data/barname/index.d.ts +2 -0
- package/x/data/barname/index.js +3 -0
- package/x/data/barname/index.js.map +1 -0
- package/x/data/barname/utils/prefixes.d.ts +1 -0
- package/x/data/barname/utils/prefixes.js +19 -0
- package/x/data/barname/utils/prefixes.js.map +1 -0
- package/x/data/barname/utils/suffixes.d.ts +1 -0
- package/x/data/barname/utils/suffixes.js +19 -0
- package/x/data/barname/utils/suffixes.js.map +1 -0
- package/x/data/base58.d.ts +5 -0
- package/x/data/base58.js +58 -0
- package/x/data/base58.js.map +1 -0
- package/x/data/base64.d.ts +5 -0
- package/x/data/base64.js +17 -0
- package/x/data/base64.js.map +1 -0
- package/x/data/base64url.d.ts +5 -0
- package/x/data/base64url.js +22 -0
- package/x/data/base64url.js.map +1 -0
- package/x/data/bytes.d.ts +3 -0
- package/x/data/bytes.js +6 -0
- package/x/data/bytes.js.map +1 -0
- package/x/data/hex.d.ts +6 -0
- package/x/data/hex.js +30 -0
- package/x/data/hex.js.map +1 -0
- package/x/data/nomen/demo.d.ts +1 -0
- package/x/data/nomen/demo.js +5 -0
- package/x/data/nomen/demo.js.map +1 -0
- package/x/data/nomen/grammar.d.ts +11 -0
- package/x/data/nomen/grammar.js +32 -0
- package/x/data/nomen/grammar.js.map +1 -0
- package/x/data/nomen/index.d.ts +3 -0
- package/x/data/nomen/index.js +4 -0
- package/x/data/nomen/index.js.map +1 -0
- package/x/data/nomen/nomen.d.ts +11 -0
- package/x/data/nomen/nomen.js +29 -0
- package/x/data/nomen/nomen.js.map +1 -0
- package/x/data/nomen/presets/falrysk.d.ts +5 -0
- package/x/data/nomen/presets/falrysk.js +99 -0
- package/x/data/nomen/presets/falrysk.js.map +1 -0
- package/x/data/nomen/types.d.ts +6 -0
- package/x/data/nomen/types.js +2 -0
- package/x/data/nomen/types.js.map +1 -0
- package/x/data/txt.d.ts +4 -0
- package/x/data/txt.js +9 -0
- package/x/data/txt.js.map +1 -0
- package/x/deadline.d.ts +6 -0
- package/x/deadline.js +17 -0
- package/x/deadline.js.map +1 -0
- package/x/debounce/debounce.d.ts +2 -0
- package/x/debounce/debounce.js +37 -0
- package/x/debounce/debounce.js.map +1 -0
- package/x/debounce/debounce.test.d.ts +1 -0
- package/x/debounce/debounce.test.js +75 -0
- package/x/debounce/debounce.test.js.map +1 -0
- package/x/debounce/types.d.ts +2 -0
- package/x/debounce/types.js +2 -0
- package/x/debounce/types.js.map +1 -0
- package/x/dedupe.d.ts +1 -0
- package/x/dedupe.js +4 -0
- package/x/dedupe.js.map +1 -0
- package/x/deep/deep.d.ts +7 -0
- package/x/deep/deep.js +9 -0
- package/x/deep/deep.js.map +1 -0
- package/x/deep/deep.test.d.ts +1 -0
- package/x/deep/deep.test.js +10 -0
- package/x/deep/deep.test.js.map +1 -0
- package/x/deep/parts/equal.d.ts +1 -0
- package/x/deep/parts/equal.js +39 -0
- package/x/deep/parts/equal.js.map +1 -0
- package/x/deep/parts/equal.test.d.ts +1 -0
- package/x/deep/parts/equal.test.js +126 -0
- package/x/deep/parts/equal.test.js.map +1 -0
- package/x/deep/parts/freeze.d.ts +1 -0
- package/x/deep/parts/freeze.js +24 -0
- package/x/deep/parts/freeze.js.map +1 -0
- package/x/defer-promise.d.ts +10 -0
- package/x/defer-promise.js +15 -0
- package/x/defer-promise.js.map +1 -0
- package/x/escape-regex.d.ts +1 -0
- package/x/escape-regex.js +4 -0
- package/x/escape-regex.js.map +1 -0
- package/x/hat.d.ts +6 -0
- package/x/hat.js +16 -0
- package/x/hat.js.map +1 -0
- package/x/index.d.ts +20 -0
- package/x/index.js +21 -0
- package/x/index.js.map +1 -0
- package/x/is.d.ts +10 -0
- package/x/is.js +11 -0
- package/x/is.js.map +1 -0
- package/x/map-g.d.ts +17 -0
- package/x/map-g.js +40 -0
- package/x/map-g.js.map +1 -0
- package/x/nap.d.ts +1 -0
- package/x/nap.js +2 -0
- package/x/nap.js.map +1 -0
- package/x/ob.d.ts +14 -0
- package/x/ob.js +21 -0
- package/x/ob.js.map +1 -0
- package/x/pipe.d.ts +8 -0
- package/x/pipe.js +16 -0
- package/x/pipe.js.map +1 -0
- package/x/pubsub.d.ts +18 -0
- package/x/pubsub.js +40 -0
- package/x/pubsub.js.map +1 -0
- package/x/trash.d.ts +14 -0
- package/x/trash.js +25 -0
- package/x/trash.js.map +1 -0
package/s/data/base58.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
|
|
2
|
+
/*
|
|
3
|
+
|
|
4
|
+
256-bit base58 ids look like this:
|
|
5
|
+
|
|
6
|
+
9X1D9rdkDgRdykzmogNcxfopRc7TnbS869ow1E2ehCFS
|
|
7
|
+
AmRKyNfq6jhhsd9qda1Y6rAVS2NLUqyTUvfcB2wUiiAC
|
|
8
|
+
8skYcqBAXsejDcJzsZMo19PErt43DHP3bykaXBtMvdu
|
|
9
|
+
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {Hex} from "./hex.js"
|
|
13
|
+
import {Bytes} from "./bytes.js"
|
|
14
|
+
|
|
15
|
+
const base = 58
|
|
16
|
+
const characters = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
|
17
|
+
|
|
18
|
+
export const Base58 = Object.freeze({
|
|
19
|
+
string(bytes: Uint8Array) {
|
|
20
|
+
let intVal = BigInt("0x" + Hex.string(bytes))
|
|
21
|
+
let encoded = ""
|
|
22
|
+
|
|
23
|
+
while (intVal > 0) {
|
|
24
|
+
const remainder = intVal % BigInt(base)
|
|
25
|
+
intVal = intVal / BigInt(base)
|
|
26
|
+
encoded = characters[Number(remainder)] + encoded
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
for (const byte of bytes) {
|
|
30
|
+
if (byte === 0) encoded = characters[0] + encoded
|
|
31
|
+
else break
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return encoded
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
bytes(string: string) {
|
|
38
|
+
let intVal = BigInt(0)
|
|
39
|
+
|
|
40
|
+
for (const char of string) {
|
|
41
|
+
const index = characters.indexOf(char)
|
|
42
|
+
if (index === -1) throw new Error(`Invalid character '${char}' in base58 string`)
|
|
43
|
+
intVal = intVal * BigInt(base) + BigInt(index)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let hex = intVal.toString(16)
|
|
47
|
+
if (hex.length % 2 !== 0) hex = "0" + hex
|
|
48
|
+
const bytes = Hex.bytes(hex)
|
|
49
|
+
|
|
50
|
+
let leadingZeroes = 0
|
|
51
|
+
for (const char of string) {
|
|
52
|
+
if (char === characters[0]) leadingZeroes++
|
|
53
|
+
else break
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const decoded = new Uint8Array(leadingZeroes + bytes.length)
|
|
57
|
+
decoded.set(bytes, leadingZeroes)
|
|
58
|
+
return decoded
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
random(count = 32) {
|
|
62
|
+
return this.string(Bytes.random(count))
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
|
package/s/data/base64.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
import {Bytes} from "./bytes.js"
|
|
3
|
+
|
|
4
|
+
export const Base64 = {
|
|
5
|
+
|
|
6
|
+
string(bytes: Uint8Array) {
|
|
7
|
+
return (typeof btoa === "function")
|
|
8
|
+
? btoa(String.fromCharCode(...bytes))
|
|
9
|
+
: Buffer.from(bytes).toString("base64")
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
bytes(string: string) {
|
|
13
|
+
return (typeof atob === "function")
|
|
14
|
+
? Uint8Array.from(atob(string), char => char.charCodeAt(0))
|
|
15
|
+
: Uint8Array.from(Buffer.from(string, "base64"))
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
random(count = 32) {
|
|
19
|
+
return this.string(Bytes.random(count))
|
|
20
|
+
},
|
|
21
|
+
}
|
|
22
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
import {Bytes} from "./bytes.js"
|
|
3
|
+
import {Base64} from "./base64.js"
|
|
4
|
+
|
|
5
|
+
export const Base64url = {
|
|
6
|
+
|
|
7
|
+
string(bytes: Uint8Array) {
|
|
8
|
+
return Base64.string(bytes)
|
|
9
|
+
.replace(/\+/g, "-")
|
|
10
|
+
.replace(/\//g, "_")
|
|
11
|
+
.replace(/=+$/g, "")
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
bytes(string: string) {
|
|
15
|
+
let b64 = string
|
|
16
|
+
.replace(/-/g, "+")
|
|
17
|
+
.replace(/_/g, "/")
|
|
18
|
+
if (b64.length % 4 !== 0)
|
|
19
|
+
b64 = b64.padEnd(b64.length + (4 - b64.length % 4) % 4, "=")
|
|
20
|
+
return Base64.bytes(b64)
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
random(count = 32) {
|
|
24
|
+
return this.string(Bytes.random(count))
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
|
package/s/data/bytes.ts
ADDED
package/s/data/hex.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
/*
|
|
3
|
+
|
|
4
|
+
256-bit hex ids look like this:
|
|
5
|
+
|
|
6
|
+
8ff8dfbc7c994c5439d2dd327b9898aa6796f97fb396e262985f03f868707e32
|
|
7
|
+
6b99284a2c4a1c5f101502bd009f9fb592ca4427e4375155e411ddd07ed9da6b
|
|
8
|
+
2eb73fb00a2b9e38c855b5aa353b530d820a3a2dcea5013b7e4e277ddfe9d0ad
|
|
9
|
+
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {Bytes} from "./bytes.js"
|
|
13
|
+
|
|
14
|
+
export const Hex = {
|
|
15
|
+
string(bytes: Uint8Array) {
|
|
16
|
+
return [...bytes]
|
|
17
|
+
.map(byte => byte.toString(16).padStart(2, "0"))
|
|
18
|
+
.join("")
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
bytes(string: string) {
|
|
22
|
+
if (string.length % 2 !== 0)
|
|
23
|
+
throw new Error("must have even number of hex characters")
|
|
24
|
+
const bytes = new Uint8Array(string.length / 2)
|
|
25
|
+
for (let i = 0; i < string.length; i += 2)
|
|
26
|
+
bytes[i / 2] = parseInt(string.slice(i, i + 2), 16)
|
|
27
|
+
return bytes
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
/** generate a random hex string. byteCount defaults to 32. */
|
|
31
|
+
random(byteCount = 32) {
|
|
32
|
+
return this.string(Bytes.random(byteCount))
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
import {ob} from "../../ob.js"
|
|
3
|
+
import {Bytes} from "../bytes.js"
|
|
4
|
+
import {GrammarTemplate, PhraseFns} from "./types.js"
|
|
5
|
+
|
|
6
|
+
export class Grammar<P extends PhraseFns> {
|
|
7
|
+
constructor(
|
|
8
|
+
public phraseFns: P,
|
|
9
|
+
public templates: GrammarTemplate<P>[],
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
static phrases = <P extends PhraseFns>(phrases: P) => ({
|
|
13
|
+
templates: (templates: GrammarTemplate<P>[]) => (
|
|
14
|
+
new this<P>(phrases, templates)
|
|
15
|
+
),
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
generate([firstByte, ...bytes]: Uint8Array) {
|
|
19
|
+
const template = this.templates[firstByte % this.templates.length]
|
|
20
|
+
const phraseCount = Object.keys(this.phraseFns).length
|
|
21
|
+
const bytesPerPhrase = Math.floor(bytes.length / phraseCount)
|
|
22
|
+
|
|
23
|
+
let indexCounter = 0
|
|
24
|
+
|
|
25
|
+
const phrases = ob(this.phraseFns).map(fn => {
|
|
26
|
+
const index = indexCounter++
|
|
27
|
+
const start = index * bytesPerPhrase
|
|
28
|
+
const end = Math.min(start + bytesPerPhrase, bytes.length - 1)
|
|
29
|
+
const buffer = new Uint8Array(bytes.slice(start, end))
|
|
30
|
+
return fn(buffer)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
return template(phrases)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
random() {
|
|
37
|
+
const buffer = Bytes.random(32)
|
|
38
|
+
return this.generate(buffer)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
import {Bytes} from "../bytes.js"
|
|
3
|
+
import {Dictionary, Pattern} from "./types.js"
|
|
4
|
+
|
|
5
|
+
export class Nomen<D extends Dictionary> {
|
|
6
|
+
constructor(public dictionary: D, public patterns: Pattern<D>[]) {}
|
|
7
|
+
|
|
8
|
+
static dictionary = <D extends Dictionary>(dictionary: D) => ({
|
|
9
|
+
patterns: (patterns: Pattern<D>[]) => (
|
|
10
|
+
new this<D>(dictionary, patterns)
|
|
11
|
+
),
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
generate([firstByte, ...bytes]: Uint8Array) {
|
|
15
|
+
const pattern = this.patterns[firstByte % this.patterns.length]
|
|
16
|
+
let index = 0
|
|
17
|
+
|
|
18
|
+
const obtainWordChunk = (key: keyof D) => {
|
|
19
|
+
const dictionary = this.dictionary[key]
|
|
20
|
+
const byte = bytes[(index++) % bytes.length]
|
|
21
|
+
return dictionary[byte % dictionary.length]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return pattern
|
|
25
|
+
.map(wordpattern => wordpattern.map(obtainWordChunk).join(""))
|
|
26
|
+
.join(" ")
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
random() {
|
|
30
|
+
const buffer = Bytes.random(32)
|
|
31
|
+
return this.generate(buffer)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
|
|
2
|
+
import {Nomen} from "../nomen.js"
|
|
3
|
+
import {Grammar} from "../grammar.js"
|
|
4
|
+
|
|
5
|
+
export function falryskNameGrammar() {
|
|
6
|
+
const person = Nomen
|
|
7
|
+
.dictionary({
|
|
8
|
+
prefix: [
|
|
9
|
+
"Aed", "Ael", "Aer", "Aeg",
|
|
10
|
+
"Aes", "Aet", "Aeon", "Aek",
|
|
11
|
+
"Årg", "Ard", "Arn", "Ayn",
|
|
12
|
+
"Ar", "Ad", "Atl", "An",
|
|
13
|
+
"And", "Anr", "Ain", "Ayn",
|
|
14
|
+
"End", "Esk", "Eld", "Ŏln",
|
|
15
|
+
"Elg", "Erd", "Eyn", "Esn",
|
|
16
|
+
"Olf", "Of", "Oy", "Oc",
|
|
17
|
+
"War", "Wer", "Wot", "Wal",
|
|
18
|
+
"Gäl", "Gar", "Gaer", "Gir",
|
|
19
|
+
"Gor", "Gil", "Ger", "Gan",
|
|
20
|
+
"Thós", "Thès", "Tír", "Tal",
|
|
21
|
+
"Fâl", "Fen", "Fel", "Fol",
|
|
22
|
+
"Fír", "For", "Feyt", "Fern",
|
|
23
|
+
"Feyn", "Fayn", "Feln", "Faln",
|
|
24
|
+
"Ven", "Van", "Vèl", "Val",
|
|
25
|
+
"Veyn", "Vayn", "Veyl", "Vayl",
|
|
26
|
+
"Nýz", "Nor", "Nal", "Nyn",
|
|
27
|
+
"Mór", "Mar", "Myor", "Mor",
|
|
28
|
+
"Lom", "Lem", "Lorn", "Leyn",
|
|
29
|
+
"Kal", "Kel", "Kyel", "Kol",
|
|
30
|
+
"Shel", "Shen", "Shal", "Shey",
|
|
31
|
+
"Pip", "Par", "Pyot", "Poy",
|
|
32
|
+
"Thar", "Ther", "Thor", "Thel",
|
|
33
|
+
"Uyn", "Uer", "Usn", "Uin",
|
|
34
|
+
"Yön", "Yès", "Yol", "Yel",
|
|
35
|
+
"Xen", "Zael", "Zaer", "Zod",
|
|
36
|
+
"Aʼ", "Oʼ",
|
|
37
|
+
],
|
|
38
|
+
|
|
39
|
+
suffix: [
|
|
40
|
+
"th", "st", "yt", "ft",
|
|
41
|
+
"sk", "rk", "rd", "nd",
|
|
42
|
+
"by", "cy", "ry", "ny",
|
|
43
|
+
"yn", "vn", "vy", "ly",
|
|
44
|
+
"rik", "rek", "nok", "rôk",
|
|
45
|
+
"bie", "rie", "lie",
|
|
46
|
+
"nar", "råg", "lg", "rn",
|
|
47
|
+
],
|
|
48
|
+
|
|
49
|
+
o: [..."aaeeiou"],
|
|
50
|
+
x: [..."bcdfghklmnprstvwxyz"],
|
|
51
|
+
|
|
52
|
+
oo: [
|
|
53
|
+
"au", "ea", "ía", "oa",
|
|
54
|
+
"áe", "ës", "ie", "oé",
|
|
55
|
+
"aí", "ei", "iû", "uî",
|
|
56
|
+
"al", "eo", "io", "us",
|
|
57
|
+
],
|
|
58
|
+
|
|
59
|
+
ox: [
|
|
60
|
+
"ës", "us", "is", "os",
|
|
61
|
+
"as", "ar", "er", "or",
|
|
62
|
+
"ad", "ed", "id", "od",
|
|
63
|
+
"aw", "ew", "iw", "ow",
|
|
64
|
+
],
|
|
65
|
+
|
|
66
|
+
xox: [
|
|
67
|
+
"nak", "nëk", "nud", "nok",
|
|
68
|
+
"rár", "råth", "ýeg", "rin",
|
|
69
|
+
"wég", "wug", "wøg",
|
|
70
|
+
],
|
|
71
|
+
|
|
72
|
+
oxo: [
|
|
73
|
+
"ana", "ëna", "anu", "irá",
|
|
74
|
+
"arna", "erna", "arnû", "irna",
|
|
75
|
+
"ánla", "ënla", "arlu", "irla",
|
|
76
|
+
"ára", "atho", "oýo", "ina",
|
|
77
|
+
"éwe", "uwa", "øga",
|
|
78
|
+
],
|
|
79
|
+
})
|
|
80
|
+
.patterns([
|
|
81
|
+
[["prefix", "o"]],
|
|
82
|
+
[["prefix", "oo"]],
|
|
83
|
+
[["prefix", "ox"]],
|
|
84
|
+
[["prefix", "oxo"]],
|
|
85
|
+
|
|
86
|
+
[["prefix", "o", "suffix"]],
|
|
87
|
+
[["prefix", "o", "suffix"]],
|
|
88
|
+
[["prefix", "o", "suffix"]],
|
|
89
|
+
[["prefix", "o", "suffix"]],
|
|
90
|
+
|
|
91
|
+
[["prefix", "oo", "suffix"]],
|
|
92
|
+
[["prefix", "oxo", "suffix"]],
|
|
93
|
+
|
|
94
|
+
// // long names
|
|
95
|
+
// [["prefix", "oo", "x", "oo", "suffix"]],
|
|
96
|
+
// [["prefix", "o", "x", "oo", "suffix"]],
|
|
97
|
+
])
|
|
98
|
+
|
|
99
|
+
return Grammar
|
|
100
|
+
.phrases({
|
|
101
|
+
first: b => person.generate(b),
|
|
102
|
+
last: b => person.generate(b),
|
|
103
|
+
})
|
|
104
|
+
.templates([
|
|
105
|
+
o => `${o.first} ${o.last}`,
|
|
106
|
+
|
|
107
|
+
// // long names
|
|
108
|
+
// o => `${o.first} of ${o.last}`,
|
|
109
|
+
// o => `${o.first} from ${o.last}`,
|
|
110
|
+
])
|
|
111
|
+
}
|
|
112
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
export type Dictionary = Record<string, string[]>
|
|
3
|
+
export type Pattern<D extends Dictionary> = (keyof D)[][]
|
|
4
|
+
|
|
5
|
+
export type PhraseFn = (bytes: Uint8Array) => string
|
|
6
|
+
export type PhraseFns = Record<string, PhraseFn>
|
|
7
|
+
export type Phrases<P extends PhraseFns> = Record<keyof P, string>
|
|
8
|
+
export type GrammarTemplate<P extends PhraseFns> = (phrases: Phrases<P>) => string
|
|
9
|
+
|
package/s/data/txt.ts
ADDED
package/s/deadline.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
export class DeadlineError extends Error {
|
|
3
|
+
name = this.constructor.name
|
|
4
|
+
constructor(milliseconds: number) {
|
|
5
|
+
super(`deadline exceeded (${milliseconds.toLocaleString()} ms)`)
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** set a deadline for a fn to do something, will reject with a `DeadlineError` if it takes too long */
|
|
10
|
+
export function deadline<R>(milliseconds: number, fn: () => Promise<R>) {
|
|
11
|
+
return new Promise<R>((resolve, reject) => {
|
|
12
|
+
|
|
13
|
+
const id = setTimeout(
|
|
14
|
+
() => reject(new DeadlineError(milliseconds)),
|
|
15
|
+
milliseconds,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
fn()
|
|
19
|
+
.then(resolve)
|
|
20
|
+
.catch(reject)
|
|
21
|
+
.finally(() => clearTimeout(id))
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
//
|
|
2
|
+
// import {nap} from "../nap.js"
|
|
3
|
+
// import {Suite, expect} from "cynic"
|
|
4
|
+
// import {debounce as debounce} from "./debounce.js"
|
|
5
|
+
//
|
|
6
|
+
// export default <Suite>{
|
|
7
|
+
// async "reduces many calls into one"() {
|
|
8
|
+
// let count = 0
|
|
9
|
+
// const increment = debounce(100, () => {
|
|
10
|
+
// count += 1
|
|
11
|
+
// })
|
|
12
|
+
// increment()
|
|
13
|
+
// increment()
|
|
14
|
+
// increment()
|
|
15
|
+
// await nap(200)
|
|
16
|
+
// expect(count).equals(1)
|
|
17
|
+
// },
|
|
18
|
+
// async "timer gets reset on each call"() {
|
|
19
|
+
// let count = 0
|
|
20
|
+
// const increment = debounce(100, () => {
|
|
21
|
+
// count += 1
|
|
22
|
+
// })
|
|
23
|
+
// increment()
|
|
24
|
+
// await nap(50)
|
|
25
|
+
// increment()
|
|
26
|
+
// await nap(50)
|
|
27
|
+
// increment()
|
|
28
|
+
// await nap(50)
|
|
29
|
+
// increment()
|
|
30
|
+
// await nap(50)
|
|
31
|
+
// increment()
|
|
32
|
+
// expect(count).equals(0)
|
|
33
|
+
// await nap(101)
|
|
34
|
+
// expect(count).equals(1)
|
|
35
|
+
// },
|
|
36
|
+
// async "provides a promise that resolves when done"() {
|
|
37
|
+
// let count = 0
|
|
38
|
+
// const increment = debounce(100, () => {
|
|
39
|
+
// count += 1
|
|
40
|
+
// })
|
|
41
|
+
// let done = false
|
|
42
|
+
// increment()
|
|
43
|
+
// .then(() => done = true)
|
|
44
|
+
// await nap(50)
|
|
45
|
+
// increment()
|
|
46
|
+
// await nap(50)
|
|
47
|
+
// increment()
|
|
48
|
+
// await nap(50)
|
|
49
|
+
// increment()
|
|
50
|
+
// await nap(50)
|
|
51
|
+
// increment()
|
|
52
|
+
// expect(done).equals(false)
|
|
53
|
+
// await nap(201)
|
|
54
|
+
// expect(done).equals(true)
|
|
55
|
+
// },
|
|
56
|
+
// async "can wait multiple rounds"() {
|
|
57
|
+
// let count = 0
|
|
58
|
+
// const increment = debounce(100, () => {
|
|
59
|
+
// count += 1
|
|
60
|
+
// })
|
|
61
|
+
// await increment()
|
|
62
|
+
// expect(count).equals(1)
|
|
63
|
+
// await increment()
|
|
64
|
+
// expect(count).equals(2)
|
|
65
|
+
// },
|
|
66
|
+
// async "errors are passed into promise chain"() {
|
|
67
|
+
// const err = debounce(1, () => {
|
|
68
|
+
// throw new Error()
|
|
69
|
+
// })
|
|
70
|
+
// await expect(async() => err()).throws()
|
|
71
|
+
// },
|
|
72
|
+
// }
|
|
73
|
+
//
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
|
|
2
|
+
import {AnyFunction, DebounceReturn} from "./types.js"
|
|
3
|
+
|
|
4
|
+
export function debounce<xAction extends AnyFunction>(
|
|
5
|
+
delay: number,
|
|
6
|
+
action: xAction,
|
|
7
|
+
): DebounceReturn<xAction> {
|
|
8
|
+
|
|
9
|
+
let latestArgs: any[]
|
|
10
|
+
let timeout: any
|
|
11
|
+
|
|
12
|
+
let waitingQueue: {
|
|
13
|
+
resolve: (r: ReturnType<xAction>) => void
|
|
14
|
+
reject: (reason: any) => void
|
|
15
|
+
}[] = []
|
|
16
|
+
|
|
17
|
+
function reset() {
|
|
18
|
+
latestArgs = []
|
|
19
|
+
if (timeout)
|
|
20
|
+
clearTimeout(timeout)
|
|
21
|
+
timeout = undefined
|
|
22
|
+
waitingQueue = []
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
reset()
|
|
26
|
+
|
|
27
|
+
return <DebounceReturn<xAction>>((...args) => {
|
|
28
|
+
latestArgs = args
|
|
29
|
+
|
|
30
|
+
if (timeout)
|
|
31
|
+
clearTimeout(timeout)
|
|
32
|
+
|
|
33
|
+
const promise = new Promise((resolve, reject) => {
|
|
34
|
+
waitingQueue.push({resolve, reject})
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
timeout = setTimeout(() => {
|
|
38
|
+
Promise.resolve()
|
|
39
|
+
.then(() => action(...latestArgs))
|
|
40
|
+
.then(r => {
|
|
41
|
+
for (const {resolve} of waitingQueue)
|
|
42
|
+
resolve(r)
|
|
43
|
+
reset()
|
|
44
|
+
})
|
|
45
|
+
.catch(err => {
|
|
46
|
+
for (const {reject} of waitingQueue)
|
|
47
|
+
reject(err)
|
|
48
|
+
reset()
|
|
49
|
+
})
|
|
50
|
+
}, delay)
|
|
51
|
+
|
|
52
|
+
return promise
|
|
53
|
+
})
|
|
54
|
+
}
|
package/s/dedupe.ts
ADDED