@e280/stz 0.2.10 → 0.2.11
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/README.md +108 -83
- package/package.json +2 -2
- package/s/data/base-x-codecs.ts +11 -0
- package/s/data/base-x.ts +2 -2
- package/s/data/bytename/bytename.test.ts +16 -16
- package/s/data/bytename/bytename.ts +19 -16
- package/s/data/bytename/thumbprint.test.ts +25 -25
- package/s/data/bytename/thumbprint.ts +54 -37
- package/s/data/bytes.ts +4 -1
- package/s/data/data.test.ts +19 -17
- package/s/data/{base58.ts → legacy/base58.ts} +3 -2
- package/s/data/{base64.ts → legacy/base64.ts} +3 -2
- package/s/data/{base64url.ts → legacy/base64url.ts} +3 -2
- package/s/data/{hex.ts → legacy/hex.ts} +3 -2
- package/s/data/nomen/grammar.ts +2 -2
- package/s/data/nomen/nomen.ts +2 -2
- package/s/data/txt.ts +6 -3
- package/s/deep/{parts/equal.test.ts → equal.test.ts} +33 -33
- package/s/deep/{parts/equal.ts → equal.ts} +2 -2
- package/s/deep/{parts/freeze.ts → freeze.ts} +2 -3
- package/s/deep/index.barrel.ts +5 -0
- package/s/deep/index.test.ts +10 -0
- package/s/deep/index.ts +3 -0
- package/s/g/map.ts +36 -0
- package/s/g/pool.ts +24 -0
- package/s/{set-g.ts → g/set.ts} +4 -1
- package/s/g/weak-map.ts +32 -0
- package/s/index.ts +15 -8
- package/s/tests.test.ts +5 -9
- package/s/time.ts +15 -12
- package/s/toq/index.ts +3 -0
- package/s/toq/toq.test.ts +46 -0
- package/s/toq/toq.ts +62 -0
- package/x/data/base-x-codecs.d.ts +8 -0
- package/x/data/base-x-codecs.js +9 -0
- package/x/data/base-x-codecs.js.map +1 -0
- package/x/data/base-x.js +2 -2
- package/x/data/bytename/bytename.d.ts +13 -4
- package/x/data/bytename/bytename.js +16 -14
- package/x/data/bytename/bytename.js.map +1 -1
- package/x/data/bytename/bytename.test.js +16 -16
- package/x/data/bytename/bytename.test.js.map +1 -1
- package/x/data/bytename/thumbprint.d.ts +32 -11
- package/x/data/bytename/thumbprint.js +44 -35
- package/x/data/bytename/thumbprint.js.map +1 -1
- package/x/data/bytename/thumbprint.test.js +25 -25
- package/x/data/bytename/thumbprint.test.js.map +1 -1
- package/x/data/bytes.d.ts +5 -0
- package/x/data/bytes.js +3 -1
- package/x/data/bytes.js.map +1 -1
- package/x/data/data.test.d.ts +37 -0
- package/x/data/data.test.js +18 -17
- package/x/data/data.test.js.map +1 -1
- package/x/data/{base58.d.ts → legacy/base58.d.ts} +1 -0
- package/x/data/{base58.js → legacy/base58.js} +3 -2
- package/x/data/legacy/base58.js.map +1 -0
- package/x/data/{base64.d.ts → legacy/base64.d.ts} +1 -0
- package/x/data/{base64.js → legacy/base64.js} +3 -2
- package/x/data/legacy/base64.js.map +1 -0
- package/x/data/{base64url.d.ts → legacy/base64url.d.ts} +1 -0
- package/x/data/{base64url.js → legacy/base64url.js} +3 -2
- package/x/data/legacy/base64url.js.map +1 -0
- package/x/data/{hex.d.ts → legacy/hex.d.ts} +1 -0
- package/x/data/{hex.js → legacy/hex.js} +3 -2
- package/x/data/legacy/hex.js.map +1 -0
- package/x/data/nomen/grammar.js +2 -2
- package/x/data/nomen/nomen.js +2 -2
- package/x/data/txt.d.ts +9 -0
- package/x/data/txt.js +5 -3
- package/x/data/txt.js.map +1 -1
- package/x/deep/clone.js.map +1 -0
- package/x/deep/clone.test.js.map +1 -0
- package/x/deep/equal.d.ts +1 -0
- package/x/deep/{parts/equal.js → equal.js} +2 -2
- package/x/deep/equal.js.map +1 -0
- package/x/deep/{parts/equal.test.js → equal.test.js} +33 -33
- package/x/deep/equal.test.js.map +1 -0
- package/x/deep/freeze.d.ts +1 -0
- package/x/deep/{parts/freeze.js → freeze.js} +2 -2
- package/x/deep/freeze.js.map +1 -0
- package/x/deep/index.barrel.d.ts +3 -0
- package/x/deep/index.barrel.js +4 -0
- package/x/deep/index.barrel.js.map +1 -0
- package/x/deep/index.d.ts +1 -0
- package/x/deep/index.js +2 -0
- package/x/deep/index.js.map +1 -0
- package/x/deep/{deep.test.d.ts → index.test.d.ts} +15 -1
- package/x/deep/index.test.js +8 -0
- package/x/deep/index.test.js.map +1 -0
- package/x/g/map.d.ts +10 -0
- package/x/g/map.js +30 -0
- package/x/g/map.js.map +1 -0
- package/x/g/pool.d.ts +12 -0
- package/x/g/pool.js +17 -0
- package/x/g/pool.js.map +1 -0
- package/x/{set-g.d.ts → g/set.d.ts} +3 -1
- package/x/{set-g.js → g/set.js} +4 -2
- package/x/g/set.js.map +1 -0
- package/x/g/weak-map.d.ts +9 -0
- package/x/g/weak-map.js +27 -0
- package/x/g/weak-map.js.map +1 -0
- package/x/index.d.ts +13 -8
- package/x/index.js +13 -8
- package/x/index.js.map +1 -1
- package/x/tests.test.js +5 -9
- package/x/tests.test.js.map +1 -1
- package/x/time.d.ts +19 -0
- package/x/time.js +14 -12
- package/x/time.js.map +1 -1
- package/x/toq/index.d.ts +1 -0
- package/x/toq/index.js +2 -0
- package/x/toq/index.js.map +1 -0
- package/x/toq/toq.d.ts +4 -0
- package/x/toq/toq.js +48 -0
- package/x/toq/toq.js.map +1 -0
- package/x/toq/toq.test.d.ts +9 -0
- package/x/toq/toq.test.js +40 -0
- package/x/toq/toq.test.js.map +1 -0
- package/s/data/bytename/index.ts +0 -4
- package/s/deep/deep.test.ts +0 -8
- package/s/deep/deep.ts +0 -11
- package/s/map-g.ts +0 -79
- package/x/clone/clone.js.map +0 -1
- package/x/clone/clone.test.js.map +0 -1
- package/x/data/base58.js.map +0 -1
- package/x/data/base64.js.map +0 -1
- package/x/data/base64url.js.map +0 -1
- package/x/data/bytename/index.d.ts +0 -2
- package/x/data/bytename/index.js +0 -3
- package/x/data/bytename/index.js.map +0 -1
- package/x/data/hex.js.map +0 -1
- package/x/deep/deep.d.ts +0 -7
- package/x/deep/deep.js +0 -9
- package/x/deep/deep.js.map +0 -1
- package/x/deep/deep.test.js +0 -6
- package/x/deep/deep.test.js.map +0 -1
- package/x/deep/parts/equal.d.ts +0 -1
- package/x/deep/parts/equal.js.map +0 -1
- package/x/deep/parts/equal.test.js.map +0 -1
- package/x/deep/parts/freeze.d.ts +0 -1
- package/x/deep/parts/freeze.js.map +0 -1
- package/x/map-g.d.ts +0 -24
- package/x/map-g.js +0 -65
- package/x/map-g.js.map +0 -1
- package/x/set-g.js.map +0 -1
- /package/s/{clone → deep}/clone.test.ts +0 -0
- /package/s/{clone → deep}/clone.ts +0 -0
- /package/x/{clone → deep}/clone.d.ts +0 -0
- /package/x/{clone → deep}/clone.js +0 -0
- /package/x/{clone → deep}/clone.test.d.ts +0 -0
- /package/x/{clone → deep}/clone.test.js +0 -0
- /package/x/deep/{parts/equal.test.d.ts → equal.test.d.ts} +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {Bytename} from "./bytename.js"
|
|
2
|
+
import {bytename} from "./bytename.js"
|
|
3
|
+
import {base58, hex} from "../base-x-codecs.js"
|
|
5
4
|
|
|
6
5
|
export type ThumbprintOptions = {
|
|
7
6
|
delimiter: string
|
|
@@ -10,11 +9,17 @@ export type ThumbprintOptions = {
|
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
export type ThumbprintData = {
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
raw: Uint8Array
|
|
13
|
+
full: string
|
|
15
14
|
preview: string
|
|
16
15
|
bulk: string
|
|
17
16
|
sigil: string
|
|
17
|
+
|
|
18
|
+
/** @deprecated renamed to `raw` */
|
|
19
|
+
readonly bytes: Uint8Array
|
|
20
|
+
|
|
21
|
+
/** @deprecated renamed to `full` */
|
|
22
|
+
readonly thumbprint: string
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
/**
|
|
@@ -25,43 +30,43 @@ export type ThumbprintData = {
|
|
|
25
30
|
* - the sigil: "nodlyn.fasrep" (shorter part of the bytename)
|
|
26
31
|
* - originally designed to be a nice way to present 256-bit ids, but can actually represent any number of bytes
|
|
27
32
|
*/
|
|
28
|
-
export const
|
|
33
|
+
export const thumbprint = {
|
|
29
34
|
defaults: (<ThumbprintOptions>{
|
|
30
35
|
delimiter: ".",
|
|
31
36
|
sigilBytes: 4,
|
|
32
37
|
previewBytes: 8,
|
|
33
38
|
}),
|
|
34
39
|
|
|
35
|
-
toBytes(
|
|
36
|
-
|
|
37
|
-
const beans =
|
|
40
|
+
toBytes(tstring: string) {
|
|
41
|
+
tstring = tstring.trim()
|
|
42
|
+
const beans = tstring.split(/[^a-zA-Z0-9]+/m)
|
|
38
43
|
.filter(Boolean)
|
|
39
44
|
.map(s => s.trim())
|
|
40
45
|
|
|
41
46
|
if (beans.length < 2)
|
|
42
|
-
return
|
|
47
|
+
return bytename.toBytes(beans.join(""))
|
|
43
48
|
|
|
44
49
|
const bulk = beans.pop()!
|
|
45
50
|
const preview = beans.join("")
|
|
46
51
|
|
|
47
52
|
return new Uint8Array([
|
|
48
|
-
...
|
|
49
|
-
...
|
|
53
|
+
...bytename.toBytes(preview),
|
|
54
|
+
...base58.toBytes(bulk),
|
|
50
55
|
])
|
|
51
56
|
},
|
|
52
57
|
|
|
53
|
-
parse(
|
|
54
|
-
const bytes =
|
|
55
|
-
return
|
|
58
|
+
parse(tstring: string, options?: Partial<ThumbprintOptions>): ThumbprintData {
|
|
59
|
+
const bytes = thumbprint.toBytes(tstring)
|
|
60
|
+
return thumbprint.build.fromBytes(bytes, options)
|
|
56
61
|
},
|
|
57
62
|
|
|
58
63
|
build: {
|
|
59
|
-
fromBytes(
|
|
64
|
+
fromBytes(raw: Uint8Array, options: Partial<ThumbprintOptions> = {}): ThumbprintData {
|
|
60
65
|
const {delimiter, previewBytes, sigilBytes}
|
|
61
|
-
= {...
|
|
66
|
+
= {...thumbprint.defaults, ...options}
|
|
62
67
|
|
|
63
|
-
const yoink = (
|
|
64
|
-
?
|
|
68
|
+
const yoink = (len: number) => (raw.length > 0)
|
|
69
|
+
? bytename.fromBytes(raw.slice(0, len), {
|
|
65
70
|
wordSeparator: delimiter,
|
|
66
71
|
groupSeparator: delimiter,
|
|
67
72
|
})
|
|
@@ -70,43 +75,55 @@ export const Thumbprint = {
|
|
|
70
75
|
const sigil = yoink(sigilBytes)
|
|
71
76
|
const preview = yoink(previewBytes)
|
|
72
77
|
|
|
73
|
-
const bulk = (
|
|
74
|
-
?
|
|
78
|
+
const bulk = (raw.length > previewBytes)
|
|
79
|
+
? base58.fromBytes(raw.slice(previewBytes))
|
|
75
80
|
: ""
|
|
76
81
|
|
|
77
|
-
const
|
|
82
|
+
const full = [preview, bulk]
|
|
78
83
|
.filter(s => s.length > 0)
|
|
79
84
|
.join(delimiter)
|
|
80
85
|
|
|
81
|
-
return {
|
|
86
|
+
return {
|
|
87
|
+
raw,
|
|
88
|
+
full,
|
|
89
|
+
preview,
|
|
90
|
+
bulk,
|
|
91
|
+
sigil,
|
|
92
|
+
|
|
93
|
+
bytes: raw,
|
|
94
|
+
thumbprint: full,
|
|
95
|
+
}
|
|
82
96
|
},
|
|
83
97
|
|
|
84
|
-
fromHex(
|
|
85
|
-
const bytes =
|
|
86
|
-
return
|
|
98
|
+
fromHex(hstring: string, options?: Partial<ThumbprintOptions>) {
|
|
99
|
+
const bytes = hex.toBytes(hstring)
|
|
100
|
+
return thumbprint.build.fromBytes(bytes, options)
|
|
87
101
|
},
|
|
88
102
|
},
|
|
89
103
|
|
|
90
|
-
toHex(
|
|
91
|
-
const bytes =
|
|
92
|
-
return
|
|
104
|
+
toHex(tstring: string) {
|
|
105
|
+
const bytes = thumbprint.toBytes(tstring)
|
|
106
|
+
return hex.fromBytes(bytes)
|
|
93
107
|
},
|
|
94
108
|
|
|
95
|
-
fromBytes(
|
|
96
|
-
return
|
|
109
|
+
fromBytes(b: Uint8Array, options?: Partial<ThumbprintOptions>) {
|
|
110
|
+
return thumbprint.build.fromBytes(b, options).full
|
|
97
111
|
},
|
|
98
112
|
|
|
99
|
-
fromHex(
|
|
100
|
-
return
|
|
113
|
+
fromHex(h: string, options?: Partial<ThumbprintOptions>) {
|
|
114
|
+
return thumbprint.fromBytes(hex.toBytes(h), options)
|
|
101
115
|
},
|
|
102
116
|
|
|
103
117
|
sigil: {
|
|
104
|
-
fromHex(
|
|
105
|
-
return
|
|
118
|
+
fromHex(h: string, options?: Partial<ThumbprintOptions>) {
|
|
119
|
+
return thumbprint.build.fromHex(h, options).sigil
|
|
106
120
|
},
|
|
107
|
-
fromBytes(
|
|
108
|
-
return
|
|
121
|
+
fromBytes(b: Uint8Array, options?: Partial<ThumbprintOptions>) {
|
|
122
|
+
return thumbprint.build.fromBytes(b, options).sigil
|
|
109
123
|
},
|
|
110
124
|
},
|
|
111
125
|
}
|
|
112
126
|
|
|
127
|
+
/** @deprecated renamed to `thumbprint` */
|
|
128
|
+
export const Thumbprint = thumbprint
|
|
129
|
+
|
package/s/data/bytes.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
export const
|
|
2
|
+
export const bytes = Object.freeze({
|
|
3
3
|
eq(a: Uint8Array, b: Uint8Array) {
|
|
4
4
|
if (a.length !== b.length)
|
|
5
5
|
return false
|
|
@@ -15,3 +15,6 @@ export const Bytes = Object.freeze({
|
|
|
15
15
|
},
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
+
/** @deprecated renamed to `bytes` */
|
|
19
|
+
export const Bytes = bytes
|
|
20
|
+
|
package/s/data/data.test.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
|
|
2
2
|
import {Science, test, expect} from "@e280/science"
|
|
3
3
|
import {ob} from "../ob.js"
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {Bytes} from "./bytes.js"
|
|
4
|
+
import {txt} from "./txt.js"
|
|
5
|
+
import {bytes} from "./bytes.js"
|
|
7
6
|
import {BaseX} from "./base-x.js"
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import
|
|
7
|
+
import {base58, base64, base64url, hex} from "./base-x-codecs.js"
|
|
8
|
+
import bytename from "./bytename/bytename.test.js"
|
|
9
|
+
import thumbprint from "./bytename/thumbprint.test.js"
|
|
11
10
|
|
|
12
|
-
const sampleBytes =
|
|
11
|
+
const sampleBytes = hex.toBytes("9960cd633a46acfe8307d8a400e842da0d930a75fb8188e0f5da264e4b6b4e5b")
|
|
13
12
|
|
|
14
13
|
type ByteUtil = {
|
|
15
14
|
toBytes: (string: string) => Uint8Array
|
|
@@ -25,7 +24,7 @@ function testBytes(util: ByteUtil) {
|
|
|
25
24
|
return async() => {
|
|
26
25
|
const string = util.fromBytes(sampleBytes)
|
|
27
26
|
const recreated = util.toBytes(string)
|
|
28
|
-
expect(
|
|
27
|
+
expect(bytes.eq(sampleBytes, recreated)).ok()
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
|
|
@@ -63,15 +62,18 @@ function testCompat(alpha: ByteUtil, bravo: ByteUtil) {
|
|
|
63
62
|
}
|
|
64
63
|
|
|
65
64
|
export default Science.suite({
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"
|
|
65
|
+
bytename,
|
|
66
|
+
thumbprint,
|
|
67
|
+
|
|
68
|
+
"Base58": testBytes(base58),
|
|
69
|
+
"Base64": testBytes(base64),
|
|
70
|
+
"Base64url": testBytes(base64url),
|
|
71
|
+
"Hex": testBytes(hex),
|
|
70
72
|
|
|
71
73
|
"Txt": test(async() => {
|
|
72
74
|
const original = `build or die. 💻>☠️ 命火工`
|
|
73
|
-
const bytes =
|
|
74
|
-
const recreated =
|
|
75
|
+
const bytes = txt.toBytes(original)
|
|
76
|
+
const recreated = txt.fromBytes(bytes)
|
|
75
77
|
expect(original).is(recreated)
|
|
76
78
|
}),
|
|
77
79
|
|
|
@@ -80,9 +82,9 @@ export default Science.suite({
|
|
|
80
82
|
ob(BaseX.lexicons).map(lex => testBoth(new BaseX(lex)))
|
|
81
83
|
),
|
|
82
84
|
compat: Science.suite({
|
|
83
|
-
"Hex": testCompat(
|
|
84
|
-
"Base64": testCompat(
|
|
85
|
-
"Base64url": testCompat(
|
|
85
|
+
"Hex": testCompat(hex, new BaseX(BaseX.lexicons.hex)),
|
|
86
|
+
"Base64": testCompat(base64, new BaseX(BaseX.lexicons.base64)),
|
|
87
|
+
"Base64url": testCompat(base64url, new BaseX(BaseX.lexicons.base64url)),
|
|
86
88
|
}),
|
|
87
89
|
"base64 has padding": test(async() => {
|
|
88
90
|
const s = new BaseX(BaseX.lexicons.base64).fromBytes(sampleBytes)
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import {Hex} from "./hex.js"
|
|
13
|
-
import {
|
|
13
|
+
import {bytes} from "../bytes.js"
|
|
14
14
|
|
|
15
15
|
const base = 58
|
|
16
16
|
const characters = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
|
17
17
|
|
|
18
|
+
/** @deprecated use `base58` instead */
|
|
18
19
|
export const Base58 = Object.freeze({
|
|
19
20
|
fromBytes(bytes: Uint8Array) {
|
|
20
21
|
let intVal = BigInt("0x" + Hex.fromBytes(bytes))
|
|
@@ -59,7 +60,7 @@ export const Base58 = Object.freeze({
|
|
|
59
60
|
},
|
|
60
61
|
|
|
61
62
|
random(count = 32) {
|
|
62
|
-
return this.fromBytes(
|
|
63
|
+
return this.fromBytes(bytes.random(count))
|
|
63
64
|
},
|
|
64
65
|
|
|
65
66
|
/** @deprecated renamed to `fromBytes` */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import {bytes} from "../bytes.js"
|
|
3
3
|
|
|
4
|
+
/** @deprecated use `base64` instead */
|
|
4
5
|
export const Base64 = Object.freeze({
|
|
5
6
|
fromBytes(bytes: Uint8Array) {
|
|
6
7
|
return (typeof btoa === "function")
|
|
@@ -15,7 +16,7 @@ export const Base64 = Object.freeze({
|
|
|
15
16
|
},
|
|
16
17
|
|
|
17
18
|
random(count = 32) {
|
|
18
|
-
return this.fromBytes(
|
|
19
|
+
return this.fromBytes(bytes.random(count))
|
|
19
20
|
},
|
|
20
21
|
|
|
21
22
|
/** @deprecated rename to "fromBytes" */
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import {bytes} from "../bytes.js"
|
|
3
3
|
import {Base64} from "./base64.js"
|
|
4
4
|
|
|
5
|
+
/** @deprecated use `base64url` instead */
|
|
5
6
|
export const Base64url = {
|
|
6
7
|
fromBytes(bytes: Uint8Array) {
|
|
7
8
|
return Base64.fromBytes(bytes)
|
|
@@ -20,7 +21,7 @@ export const Base64url = {
|
|
|
20
21
|
},
|
|
21
22
|
|
|
22
23
|
random(count = 32) {
|
|
23
|
-
return this.fromBytes(
|
|
24
|
+
return this.fromBytes(bytes.random(count))
|
|
24
25
|
},
|
|
25
26
|
|
|
26
27
|
/** @deprecated renamed to "fromBytes" */
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import {bytes} from "../bytes.js"
|
|
13
13
|
|
|
14
|
+
/** @deprecated use `hex` instead */
|
|
14
15
|
export const Hex = Object.freeze({
|
|
15
16
|
fromBytes(bytes: Uint8Array) {
|
|
16
17
|
return [...bytes]
|
|
@@ -29,7 +30,7 @@ export const Hex = Object.freeze({
|
|
|
29
30
|
|
|
30
31
|
/** generate a random hex string. byteCount defaults to 32. */
|
|
31
32
|
random(byteCount = 32) {
|
|
32
|
-
return this.fromBytes(
|
|
33
|
+
return this.fromBytes(bytes.random(byteCount))
|
|
33
34
|
},
|
|
34
35
|
|
|
35
36
|
/** @deprecated renamed to `fromBytes` */
|
package/s/data/nomen/grammar.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import {ob} from "../../ob.js"
|
|
3
|
-
import {
|
|
3
|
+
import {bytes} from "../bytes.js"
|
|
4
4
|
import {GrammarTemplate, PhraseFns} from "./types.js"
|
|
5
5
|
|
|
6
6
|
export class Grammar<P extends PhraseFns> {
|
|
@@ -34,7 +34,7 @@ export class Grammar<P extends PhraseFns> {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
random() {
|
|
37
|
-
const buffer =
|
|
37
|
+
const buffer = bytes.random(32)
|
|
38
38
|
return this.generate(buffer)
|
|
39
39
|
}
|
|
40
40
|
}
|
package/s/data/nomen/nomen.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import {bytes} from "../bytes.js"
|
|
3
3
|
import {Dictionary, Pattern} from "./types.js"
|
|
4
4
|
|
|
5
5
|
export class Nomen<D extends Dictionary> {
|
|
@@ -27,7 +27,7 @@ export class Nomen<D extends Dictionary> {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
random() {
|
|
30
|
-
const buffer =
|
|
30
|
+
const buffer = bytes.random(32)
|
|
31
31
|
return this.generate(buffer)
|
|
32
32
|
}
|
|
33
33
|
}
|
package/s/data/txt.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
export const
|
|
2
|
+
export const txt = Object.freeze({
|
|
3
3
|
fromBytes(bytes: Uint8Array) {
|
|
4
4
|
return new TextDecoder().decode(bytes)
|
|
5
5
|
},
|
|
@@ -10,12 +10,15 @@ export const Txt = Object.freeze({
|
|
|
10
10
|
|
|
11
11
|
/** @deprecated renamed to `fromBytes` */
|
|
12
12
|
string(bytes: Uint8Array) {
|
|
13
|
-
return
|
|
13
|
+
return txt.fromBytes(bytes)
|
|
14
14
|
},
|
|
15
15
|
|
|
16
16
|
/** @deprecated renamed to `toBytes` */
|
|
17
17
|
bytes(string: string) {
|
|
18
|
-
return
|
|
18
|
+
return txt.toBytes(string)
|
|
19
19
|
},
|
|
20
20
|
})
|
|
21
21
|
|
|
22
|
+
/** @deprecated renamed to `txt` */
|
|
23
|
+
export const Txt = txt
|
|
24
|
+
|
|
@@ -1,60 +1,60 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import {equal} from "./equal.js"
|
|
3
3
|
import {Science, expect} from "@e280/science"
|
|
4
4
|
|
|
5
5
|
export default Science.suite({
|
|
6
6
|
async "compare primitive types"() {
|
|
7
|
-
expect(
|
|
8
|
-
expect(
|
|
9
|
-
expect(
|
|
10
|
-
expect(
|
|
11
|
-
expect(
|
|
7
|
+
expect(equal(123, 123)).is(true)
|
|
8
|
+
expect(equal("abc", "abc")).is(true)
|
|
9
|
+
expect(equal(true, true)).is(true)
|
|
10
|
+
expect(equal(123, "123")).is(false)
|
|
11
|
+
expect(equal(true, 1)).is(false)
|
|
12
12
|
},
|
|
13
13
|
|
|
14
14
|
async "compare arrays"() {
|
|
15
15
|
const array1 = [1, 2, 3]
|
|
16
16
|
const array2 = [1, 2, 3]
|
|
17
17
|
const array3 = [1, 2, 4]
|
|
18
|
-
expect(
|
|
19
|
-
expect(
|
|
18
|
+
expect(equal(array1, array2)).is(true)
|
|
19
|
+
expect(equal(array1, array3)).is(false)
|
|
20
20
|
},
|
|
21
21
|
|
|
22
22
|
async "compare plain objects"() {
|
|
23
23
|
const obj1 = { foo: "bar", baz: 123 }
|
|
24
24
|
const obj2 = { foo: "bar", baz: 123 }
|
|
25
25
|
const obj3 = { foo: "bar", baz: 124 }
|
|
26
|
-
expect(
|
|
27
|
-
expect(
|
|
26
|
+
expect(equal(obj1, obj2)).is(true)
|
|
27
|
+
expect(equal(obj1, obj3)).is(false)
|
|
28
28
|
},
|
|
29
29
|
|
|
30
30
|
async "compare nested objects"() {
|
|
31
31
|
const obj1 = { foo: "bar", inner: { baz: 123, deeper: { qux: true }}}
|
|
32
32
|
const obj2 = { foo: "bar", inner: { baz: 123, deeper: { qux: true }}}
|
|
33
33
|
const obj3 = { foo: "bar", inner: { baz: 124, deeper: { qux: true }}}
|
|
34
|
-
expect(
|
|
35
|
-
expect(
|
|
34
|
+
expect(equal(obj1, obj2)).is(true)
|
|
35
|
+
expect(equal(obj1, obj3)).is(false)
|
|
36
36
|
},
|
|
37
37
|
|
|
38
38
|
async "compare array of objects"() {
|
|
39
39
|
const arr1 = [{ foo: "bar" }, { baz: 123 }, { qux: true }]
|
|
40
40
|
const arr2 = [{ foo: "bar" }, { baz: 123 }, { qux: true }]
|
|
41
41
|
const arr3 = [{ foo: "bar" }, { baz: 123 }, { qux: false }]
|
|
42
|
-
expect(
|
|
43
|
-
expect(
|
|
42
|
+
expect(equal(arr1, arr2)).is(true)
|
|
43
|
+
expect(equal(arr1, arr3)).is(false)
|
|
44
44
|
},
|
|
45
45
|
|
|
46
46
|
async "compare null and undefined"() {
|
|
47
|
-
expect(
|
|
48
|
-
expect(
|
|
49
|
-
expect(
|
|
47
|
+
expect(equal(null, null)).is(true)
|
|
48
|
+
expect(equal(undefined, undefined)).is(true)
|
|
49
|
+
expect(equal(null, undefined)).is(false)
|
|
50
50
|
},
|
|
51
51
|
|
|
52
52
|
async "compare with nested arrays"() {
|
|
53
53
|
const obj1 = { foo: "bar", array: [1, 2, [3, 4]] }
|
|
54
54
|
const obj2 = { foo: "bar", array: [1, 2, [3, 4]] }
|
|
55
55
|
const obj3 = { foo: "bar", array: [1, 2, [3, 5]] }
|
|
56
|
-
expect(
|
|
57
|
-
expect(
|
|
56
|
+
expect(equal(obj1, obj2)).is(true)
|
|
57
|
+
expect(equal(obj1, obj3)).is(false)
|
|
58
58
|
},
|
|
59
59
|
|
|
60
60
|
async "circularity is forbidden"() {
|
|
@@ -62,7 +62,7 @@ export default Science.suite({
|
|
|
62
62
|
const obj2 = {alpha: 1} as any
|
|
63
63
|
obj1.bravo = obj1
|
|
64
64
|
obj2.bravo = obj2
|
|
65
|
-
expect(() =>
|
|
65
|
+
expect(() => equal(obj1, obj2)).throws()
|
|
66
66
|
},
|
|
67
67
|
|
|
68
68
|
async "duplicate references are allowed"() {
|
|
@@ -70,8 +70,8 @@ export default Science.suite({
|
|
|
70
70
|
const obj1 = {alpha: 1, dupe}
|
|
71
71
|
const obj2 = {alpha: 1, dupe}
|
|
72
72
|
const obj3 = {alpha: 1, dupe: {a: 0}}
|
|
73
|
-
expect(
|
|
74
|
-
expect(
|
|
73
|
+
expect(equal(obj1, obj2)).is(true)
|
|
74
|
+
expect(equal(obj1, obj3)).is(false)
|
|
75
75
|
},
|
|
76
76
|
|
|
77
77
|
"maps and sets": {
|
|
@@ -79,32 +79,32 @@ export default Science.suite({
|
|
|
79
79
|
const map1 = new Map([['key1', 'value1'], ['key2', 'value2']])
|
|
80
80
|
const map2 = new Map([['key1', 'value1'], ['key2', 'value2']])
|
|
81
81
|
const map3 = new Map([['key1', 'value1'], ['key2', 'value3']])
|
|
82
|
-
expect(
|
|
83
|
-
expect(
|
|
82
|
+
expect(equal(map1, map2)).is(true)
|
|
83
|
+
expect(equal(map1, map3)).is(false)
|
|
84
84
|
},
|
|
85
85
|
|
|
86
86
|
async "compare sets"() {
|
|
87
87
|
const set1 = new Set([1, 2, 3])
|
|
88
88
|
const set2 = new Set([1, 2, 3])
|
|
89
89
|
const set3 = new Set([1, 2, 4])
|
|
90
|
-
expect(
|
|
91
|
-
expect(
|
|
90
|
+
expect(equal(set1, set2)).is(true)
|
|
91
|
+
expect(equal(set1, set3)).is(false)
|
|
92
92
|
},
|
|
93
93
|
|
|
94
94
|
async "compare nested maps and sets"() {
|
|
95
95
|
const obj1 = { map: new Map([['key', new Set([1, 2, 3])]]) }
|
|
96
96
|
const obj2 = { map: new Map([['key', new Set([1, 2, 3])]]) }
|
|
97
97
|
const obj3 = { map: new Map([['key', new Set([1, 2, 4])]]) }
|
|
98
|
-
expect(
|
|
99
|
-
expect(
|
|
98
|
+
expect(equal(obj1, obj2)).is(true)
|
|
99
|
+
expect(equal(obj1, obj3)).is(false)
|
|
100
100
|
},
|
|
101
101
|
|
|
102
102
|
async "compare complex structures"() {
|
|
103
103
|
const map1 = new Map([['set', new Set([{ a: 1 }, { b: 2 }])]])
|
|
104
104
|
const map2 = new Map([['set', new Set([{ a: 1 }, { b: 2 }])]])
|
|
105
105
|
const map3 = new Map([['set', new Set([{ a: 1 }, { b: 3 }])]])
|
|
106
|
-
expect(
|
|
107
|
-
expect(
|
|
106
|
+
expect(equal(map1, map2)).is(true)
|
|
107
|
+
expect(equal(map1, map3)).is(false)
|
|
108
108
|
},
|
|
109
109
|
|
|
110
110
|
async "compare edge cases"() {
|
|
@@ -114,9 +114,9 @@ export default Science.suite({
|
|
|
114
114
|
const emptySet2 = new Set()
|
|
115
115
|
const mixedMap1 = new Map([['b', 2], ['a', 1]])
|
|
116
116
|
const mixedMap2 = new Map([['a', 1], ['b', 2]])
|
|
117
|
-
expect(
|
|
118
|
-
expect(
|
|
119
|
-
expect(
|
|
117
|
+
expect(equal(emptyMap1, emptyMap2)).is(true)
|
|
118
|
+
expect(equal(emptySet1, emptySet2)).is(true)
|
|
119
|
+
expect(equal(mixedMap1, mixedMap2)).is(true)
|
|
120
120
|
},
|
|
121
121
|
},
|
|
122
122
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import {is} from "
|
|
2
|
+
import {is} from "../is.js"
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const equal = (alpha: any, bravo: any): boolean => {
|
|
5
5
|
|
|
6
6
|
function recurse(alpha: any, bravo: any, parents: object[]) {
|
|
7
7
|
if (!is.object(alpha) || !is.object(bravo))
|
package/s/deep/index.ts
ADDED
package/s/g/map.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
/** extended js map with handy methods like `require` and `guarantee` */
|
|
3
|
+
export class GMap<K, V> extends Map<K, V> {
|
|
4
|
+
static require<K, V>(map: Map<K, V>, key: K) {
|
|
5
|
+
if (map.has(key))
|
|
6
|
+
return map.get(key) as V
|
|
7
|
+
else
|
|
8
|
+
throw new Error(`required key not found: "${key}"`)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static guarantee<K, V>(map: Map<K, V>, key: K, make: () => V) {
|
|
12
|
+
if (map.has(key))
|
|
13
|
+
return map.get(key)!
|
|
14
|
+
else {
|
|
15
|
+
const value = make()
|
|
16
|
+
map.set(key, value)
|
|
17
|
+
return value
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
array() {
|
|
22
|
+
return [...this]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
require(key: K) {
|
|
26
|
+
return GMap.require(this, key)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
guarantee(key: K, make: () => V) {
|
|
30
|
+
return GMap.guarantee(this, key, make)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** @deprecated renamed to `GMap` */
|
|
35
|
+
export const MapG = GMap
|
|
36
|
+
|
package/s/g/pool.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
import {GMap} from "./map.js"
|
|
3
|
+
|
|
4
|
+
export type Identifiable<Id = any> = {id: Id}
|
|
5
|
+
|
|
6
|
+
/** js map but for things that have an `id` field */
|
|
7
|
+
export class GPool<V extends Identifiable> extends GMap<V["id"], V> {
|
|
8
|
+
got(value: V) {
|
|
9
|
+
return this.has(value.id)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
add(value: V) {
|
|
13
|
+
this.set(value.id, value)
|
|
14
|
+
return value
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
remove(value: V) {
|
|
18
|
+
return this.delete(value.id)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** @deprecated renamed to `GPool` */
|
|
23
|
+
export const PoolG = GPool
|
|
24
|
+
|
package/s/{set-g.ts → g/set.ts}
RENAMED