@e280/stz 0.0.0-8 → 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/README.md +275 -24
- package/package.json +13 -9
- package/s/coalesce.ts +1 -0
- package/s/constructor.ts +15 -0
- package/s/data/base-x.ts +170 -0
- package/s/data/base58.ts +15 -5
- package/s/data/base64.ts +15 -6
- package/s/data/base64url.ts +15 -6
- package/s/data/bytename/bytename.test.ts +12 -12
- package/s/data/bytename/bytename.ts +13 -6
- package/s/data/bytename/index.ts +1 -1
- package/s/data/bytename/thumbprint.test.ts +53 -0
- package/s/data/bytename/thumbprint.ts +112 -0
- package/s/data/bytes.ts +2 -2
- package/s/data/data.test.ts +98 -0
- package/s/data/hex.ts +15 -5
- package/s/data/txt.ts +14 -4
- package/s/deadline.ts +5 -6
- package/s/{defer-promise.ts → defer.ts} +2 -2
- package/s/drill.ts +2 -4
- package/s/ev.ts +20 -0
- package/s/id-counter.ts +9 -0
- package/s/index.ts +12 -1
- package/s/is.ts +10 -4
- package/s/map-g.ts +9 -10
- package/s/nap.ts +1 -0
- package/s/once.ts +14 -0
- package/s/pipe.ts +7 -8
- package/s/pubsub.ts +24 -6
- package/s/queue/queue.test.ts +67 -0
- package/s/queue/queue.ts +21 -0
- package/s/repeat.ts +25 -0
- package/s/scope.ts +108 -0
- package/s/templating.ts +22 -0
- package/s/tests.test.ts +14 -10
- package/s/time.ts +22 -0
- package/x/coalesce.d.ts +1 -0
- package/x/coalesce.js +1 -0
- package/x/coalesce.js.map +1 -1
- package/x/constructor.d.ts +3 -0
- package/x/constructor.js +4 -0
- package/x/constructor.js.map +1 -0
- package/x/data/base-x.d.ts +47 -0
- package/x/data/base-x.js +147 -0
- package/x/data/base-x.js.map +1 -0
- package/x/data/base58.d.ts +5 -1
- package/x/data/base58.js +13 -5
- package/x/data/base58.js.map +1 -1
- package/x/data/base64.d.ts +7 -3
- package/x/data/base64.js +13 -5
- package/x/data/base64.js.map +1 -1
- package/x/data/base64url.d.ts +5 -1
- package/x/data/base64url.js +13 -5
- package/x/data/base64url.js.map +1 -1
- package/x/data/bytename/bytename.d.ts +9 -3
- package/x/data/bytename/bytename.js +13 -6
- package/x/data/bytename/bytename.js.map +1 -1
- package/x/data/bytename/bytename.test.js +12 -12
- package/x/data/bytename/bytename.test.js.map +1 -1
- package/x/data/bytename/index.d.ts +1 -1
- package/x/data/bytename/index.js +1 -1
- package/x/data/bytename/index.js.map +1 -1
- package/x/data/bytename/thumbprint.d.ts +36 -0
- package/x/data/bytename/thumbprint.js +79 -0
- package/x/data/bytename/thumbprint.js.map +1 -0
- package/x/data/bytename/{badge.test.d.ts → thumbprint.test.d.ts} +2 -2
- package/x/data/bytename/thumbprint.test.js +45 -0
- package/x/data/bytename/thumbprint.test.js.map +1 -0
- package/x/data/bytes.d.ts +2 -2
- package/x/data/bytes.js +2 -2
- package/x/data/bytes.js.map +1 -1
- package/x/data/data.test.d.ts +69 -0
- package/x/data/data.test.js +77 -0
- package/x/data/data.test.js.map +1 -0
- package/x/data/hex.d.ts +8 -4
- package/x/data/hex.js +13 -5
- package/x/data/hex.js.map +1 -1
- package/x/data/txt.d.ts +6 -2
- package/x/data/txt.js +12 -4
- package/x/data/txt.js.map +1 -1
- package/x/deadline.d.ts +2 -2
- package/x/deadline.js +4 -4
- package/x/deadline.js.map +1 -1
- package/x/{defer-promise.d.ts → defer.d.ts} +2 -2
- package/x/{defer-promise.js → defer.js} +2 -2
- package/x/defer.js.map +1 -0
- package/x/drill.d.ts +1 -3
- package/x/drill.js +2 -4
- package/x/drill.js.map +1 -1
- package/x/ev.d.ts +6 -0
- package/x/ev.js +10 -0
- package/x/ev.js.map +1 -0
- package/x/id-counter.d.ts +5 -0
- package/x/id-counter.js +10 -0
- package/x/id-counter.js.map +1 -0
- package/x/index.d.ts +11 -1
- package/x/index.js +11 -1
- package/x/index.js.map +1 -1
- package/x/is.d.ts +6 -4
- package/x/is.js +6 -4
- package/x/is.js.map +1 -1
- package/x/map-g.d.ts +3 -3
- package/x/map-g.js +9 -8
- package/x/map-g.js.map +1 -1
- package/x/nap.d.ts +1 -0
- package/x/nap.js +1 -0
- package/x/nap.js.map +1 -1
- package/x/once.d.ts +1 -0
- package/x/once.js +12 -0
- package/x/once.js.map +1 -0
- package/x/pipe.d.ts +3 -3
- package/x/pipe.js +5 -5
- package/x/pipe.js.map +1 -1
- package/x/pubsub.d.ts +12 -1
- package/x/pubsub.js +7 -5
- package/x/pubsub.js.map +1 -1
- package/x/queue/queue.d.ts +4 -0
- package/x/queue/queue.js +14 -0
- package/x/queue/queue.js.map +1 -0
- package/x/queue/queue.test.d.ts +8 -0
- package/x/queue/queue.test.js +57 -0
- package/x/queue/queue.test.js.map +1 -0
- package/x/repeat.d.ts +5 -0
- package/x/repeat.js +23 -0
- package/x/repeat.js.map +1 -0
- package/x/scope.d.ts +37 -0
- package/x/scope.js +82 -0
- package/x/scope.js.map +1 -0
- package/x/templating.d.ts +6 -0
- package/x/templating.js +11 -0
- package/x/templating.js.map +1 -0
- package/x/tests.test.js +14 -10
- package/x/tests.test.js.map +1 -1
- package/x/time.d.ts +18 -0
- package/x/time.js +19 -0
- package/x/time.js.map +1 -0
- package/s/data/anka.ts +0 -66
- package/s/data/bytename/badge.test.ts +0 -53
- package/s/data/bytename/badge.ts +0 -81
- package/x/data/anka.d.ts +0 -5
- package/x/data/anka.js +0 -53
- package/x/data/anka.js.map +0 -1
- package/x/data/bytename/badge.d.ts +0 -27
- package/x/data/bytename/badge.js +0 -57
- package/x/data/bytename/badge.js.map +0 -1
- package/x/data/bytename/badge.test.js +0 -45
- package/x/data/bytename/badge.test.js.map +0 -1
- package/x/defer-promise.js.map +0 -1
package/x/pubsub.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defer } from "./defer.js";
|
|
2
2
|
export function xub() {
|
|
3
3
|
const set = new Set();
|
|
4
4
|
function sub(fn) {
|
|
@@ -8,8 +8,8 @@ export function xub() {
|
|
|
8
8
|
async function pub(...a) {
|
|
9
9
|
await Promise.all([...set].map(fn => fn(...a)));
|
|
10
10
|
}
|
|
11
|
-
async function
|
|
12
|
-
const { promise, resolve } =
|
|
11
|
+
async function next() {
|
|
12
|
+
const { promise, resolve } = defer();
|
|
13
13
|
const unsubscribe = sub((...a) => {
|
|
14
14
|
resolve(a);
|
|
15
15
|
unsubscribe();
|
|
@@ -21,11 +21,13 @@ export function xub() {
|
|
|
21
21
|
}
|
|
22
22
|
sub.pub = pub;
|
|
23
23
|
sub.sub = sub;
|
|
24
|
-
sub.
|
|
24
|
+
sub.on = sub;
|
|
25
|
+
sub.next = next;
|
|
25
26
|
sub.clear = clear;
|
|
26
27
|
pub.pub = pub;
|
|
27
28
|
pub.sub = sub;
|
|
28
|
-
pub.
|
|
29
|
+
pub.on = sub;
|
|
30
|
+
pub.next = next;
|
|
29
31
|
pub.clear = clear;
|
|
30
32
|
return [pub, sub];
|
|
31
33
|
}
|
package/x/pubsub.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pubsub.js","sourceRoot":"","sources":["../s/pubsub.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"pubsub.js","sourceRoot":"","sources":["../s/pubsub.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAA;AAmChC,MAAM,UAAU,GAAG;IAClB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAe,CAAA;IAElC,SAAS,GAAG,CAAC,EAAe;QAC3B,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACX,OAAO,GAAG,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA,CAAC,CAAC,CAAA;IAChC,CAAC;IAED,KAAK,UAAU,GAAG,CAAC,GAAG,CAAI;QACzB,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAChD,CAAC;IAED,KAAK,UAAU,IAAI;QAClB,MAAM,EAAC,OAAO,EAAE,OAAO,EAAC,GAAG,KAAK,EAAK,CAAA;QACrC,MAAM,WAAW,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE;YAChC,OAAO,CAAC,CAAC,CAAC,CAAA;YACV,WAAW,EAAE,CAAA;QACd,CAAC,CAAC,CAAA;QACF,OAAO,OAAO,CAAA;IACf,CAAC;IAED,SAAS,KAAK;QACb,GAAG,CAAC,KAAK,EAAE,CAAA;IACZ,CAAC;IAED,GAAG,CAAC,GAAG,GAAG,GAAG,CAAA;IACb,GAAG,CAAC,GAAG,GAAG,GAAG,CAAA;IACb,GAAG,CAAC,EAAE,GAAG,GAAG,CAAA;IACZ,GAAG,CAAC,IAAI,GAAG,IAAI,CAAA;IACf,GAAG,CAAC,KAAK,GAAG,KAAK,CAAA;IAEjB,GAAG,CAAC,GAAG,GAAG,GAAG,CAAA;IACb,GAAG,CAAC,GAAG,GAAG,GAAG,CAAA;IACb,GAAG,CAAC,EAAE,GAAG,GAAG,CAAA;IACZ,GAAG,CAAC,IAAI,GAAG,IAAI,CAAA;IACf,GAAG,CAAC,KAAK,GAAG,KAAK,CAAA;IAEjB,OAAO,CAAC,GAAG,EAAE,GAAG,CAAqB,CAAA;AACtC,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,GAAG,CAAuB,QAAsB;IAC/D,MAAM,EAAE,GAAG,GAAG,EAAK,CAAC,CAAC,CAAC,CAAA;IACtB,IAAI,QAAQ;QACX,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACjB,OAAO,EAAE,CAAA;AACV,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,GAAG,CAAuB,QAAsB;IAC/D,MAAM,EAAE,GAAG,GAAG,EAAK,CAAC,CAAC,CAAC,CAAA;IACtB,IAAI,QAAQ;QACX,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACjB,OAAO,EAAE,CAAA;AACV,CAAC"}
|
package/x/queue/queue.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* create a job queue that ensures the given fn is always called in sequence (not concurrently).
|
|
3
|
+
*/
|
|
4
|
+
export function queue(fn) {
|
|
5
|
+
let last = Promise.resolve();
|
|
6
|
+
return (...args) => {
|
|
7
|
+
const job = () => fn(...args);
|
|
8
|
+
const current = last.then(job);
|
|
9
|
+
// prevent unhandled rejection breaking the chain
|
|
10
|
+
last = current.catch(() => { });
|
|
11
|
+
return current;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../s/queue/queue.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,MAAM,UAAU,KAAK,CACnB,EAAsC;IAGvC,IAAI,IAAI,GAAiB,OAAO,CAAC,OAAO,EAAE,CAAA;IAE1C,OAAO,CAAC,GAAG,IAAU,EAAmB,EAAE;QACzC,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAE9B,iDAAiD;QACjD,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAE9B,OAAO,OAAO,CAAA;IACf,CAAC,CAAA;AACF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Science } from "@e280/science";
|
|
2
|
+
declare const _default: {
|
|
3
|
+
"job runs": Science.Test;
|
|
4
|
+
"sequencing is enforced": Science.Test;
|
|
5
|
+
"params and return values seem to work": Science.Test;
|
|
6
|
+
"first job throws, second job unaffected": Science.Test;
|
|
7
|
+
};
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Science, expect } from "@e280/science";
|
|
2
|
+
import { nap } from "../nap.js";
|
|
3
|
+
import { queue } from "./queue.js";
|
|
4
|
+
export default Science.suite({
|
|
5
|
+
"job runs": Science.test(async () => {
|
|
6
|
+
let concurrent = 0;
|
|
7
|
+
const job = queue(async () => {
|
|
8
|
+
concurrent++;
|
|
9
|
+
await nap(100);
|
|
10
|
+
concurrent--;
|
|
11
|
+
});
|
|
12
|
+
const promise1 = job();
|
|
13
|
+
await nap(50);
|
|
14
|
+
expect(concurrent).is(1);
|
|
15
|
+
await promise1;
|
|
16
|
+
expect(concurrent).is(0);
|
|
17
|
+
}),
|
|
18
|
+
"sequencing is enforced": Science.test(async () => {
|
|
19
|
+
let concurrent = 0;
|
|
20
|
+
const job = queue(async () => {
|
|
21
|
+
concurrent++;
|
|
22
|
+
await nap(100);
|
|
23
|
+
concurrent--;
|
|
24
|
+
});
|
|
25
|
+
const promise1 = job();
|
|
26
|
+
const promise2 = job();
|
|
27
|
+
await nap(50);
|
|
28
|
+
expect(concurrent).is(1);
|
|
29
|
+
await promise1;
|
|
30
|
+
await nap(50);
|
|
31
|
+
expect(concurrent).is(1);
|
|
32
|
+
await promise2;
|
|
33
|
+
expect(concurrent).is(0);
|
|
34
|
+
}),
|
|
35
|
+
"params and return values seem to work": Science.test(async () => {
|
|
36
|
+
const add = queue(async (a, b) => {
|
|
37
|
+
await nap(100);
|
|
38
|
+
return a + b;
|
|
39
|
+
});
|
|
40
|
+
const promise1 = add(1, 2);
|
|
41
|
+
const promise2 = add(10, 20);
|
|
42
|
+
expect(await promise1).is(3);
|
|
43
|
+
expect(await promise2).is(30);
|
|
44
|
+
}),
|
|
45
|
+
"first job throws, second job unaffected": Science.test(async () => {
|
|
46
|
+
let run = 0;
|
|
47
|
+
const job = queue(async () => {
|
|
48
|
+
run++;
|
|
49
|
+
await nap(100);
|
|
50
|
+
if (run === 1)
|
|
51
|
+
throw new Error("first job failed");
|
|
52
|
+
});
|
|
53
|
+
expect(async () => job()).throwsAsync();
|
|
54
|
+
expect(async () => job()).not.throwsAsync();
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=queue.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.test.js","sourceRoot":"","sources":["../../s/queue/queue.test.ts"],"names":[],"mappings":"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"}
|
package/x/repeat.d.ts
ADDED
package/x/repeat.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* repeat the given async function over and over.
|
|
3
|
+
* - consider using `nap` in your fn to create a delay
|
|
4
|
+
*/
|
|
5
|
+
export function repeat(fn) {
|
|
6
|
+
let timeout;
|
|
7
|
+
let stopped = false;
|
|
8
|
+
const stop = () => {
|
|
9
|
+
stopped = true;
|
|
10
|
+
clearTimeout(timeout);
|
|
11
|
+
};
|
|
12
|
+
const tick = async () => {
|
|
13
|
+
if (stopped)
|
|
14
|
+
return;
|
|
15
|
+
await fn(stop);
|
|
16
|
+
if (stopped)
|
|
17
|
+
return;
|
|
18
|
+
timeout = setTimeout(tick, 0);
|
|
19
|
+
};
|
|
20
|
+
tick();
|
|
21
|
+
return stop;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=repeat.js.map
|
package/x/repeat.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repeat.js","sourceRoot":"","sources":["../s/repeat.ts"],"names":[],"mappings":"AACA;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,EAAuC;IAC7D,IAAI,OAAY,CAAA;IAChB,IAAI,OAAO,GAAG,KAAK,CAAA;IAEnB,MAAM,IAAI,GAAG,GAAG,EAAE;QACjB,OAAO,GAAG,IAAI,CAAA;QACd,YAAY,CAAC,OAAO,CAAC,CAAA;IACtB,CAAC,CAAA;IAED,MAAM,IAAI,GAAG,KAAK,IAAG,EAAE;QACtB,IAAI,OAAO;YAAE,OAAM;QACnB,MAAM,EAAE,CAAC,IAAI,CAAC,CAAA;QACd,IAAI,OAAO;YAAE,OAAM;QACnB,OAAO,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAC9B,CAAC,CAAA;IAED,IAAI,EAAE,CAAA;IACN,OAAO,IAAI,CAAA;AACZ,CAAC"}
|
package/x/scope.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Constructor } from "./constructor.js";
|
|
2
|
+
export type Scoped<Item> = [item: Item, dispose: () => void];
|
|
3
|
+
export type Disposable = {
|
|
4
|
+
dispose(): void;
|
|
5
|
+
};
|
|
6
|
+
export declare function scoped<Item>(item: Item, dispose: () => void): Scoped<Item>;
|
|
7
|
+
/**
|
|
8
|
+
* a trashcan you can fill with garbage, then call `scope.dispose()` to dump it all
|
|
9
|
+
* - `add/stow/scoped` methods are for dealing with disposer fns
|
|
10
|
+
* - `keep` methods are for dealing with disposable objects (with a dispose method)
|
|
11
|
+
* - `sub` for creating nested sub-scopes
|
|
12
|
+
*/
|
|
13
|
+
export declare class Scope implements Disposable {
|
|
14
|
+
#private;
|
|
15
|
+
/** add disposer fn */
|
|
16
|
+
add(dispose: () => void): this;
|
|
17
|
+
/** add disposer, return item */
|
|
18
|
+
stow<Item>(item: Item, dispose: () => void): Item;
|
|
19
|
+
/** add scoped disposer, return item */
|
|
20
|
+
scoped<Item>([item, dispose]: Scoped<Item>): Item;
|
|
21
|
+
/** add and return a disposable object */
|
|
22
|
+
keep<D extends Disposable>(disposable: D): D;
|
|
23
|
+
/** wrap a fn, auto-add returned disposers */
|
|
24
|
+
scopedFn<Params extends any[], Item>(fn: (...params: Params) => Scoped<Item>): (...a: Params) => Item;
|
|
25
|
+
/** wrap an async fn, auto-add returned disposers */
|
|
26
|
+
scopedFnAsync<Params extends any[], Item>(fn: (...params: Params) => Promise<Scoped<Item>>): (...a: Params) => Promise<Item>;
|
|
27
|
+
/** wrap a fn, auto-add returned disposables */
|
|
28
|
+
keepFn<Params extends any[], D extends Disposable>(fn: (...params: Params) => D): (...a: Params) => D;
|
|
29
|
+
/** wrap an async fn, auto-add returned disposables */
|
|
30
|
+
keepFnAsync<Params extends any[], D extends Disposable>(fn: (...params: Params) => Promise<D>): (...a: Params) => Promise<D>;
|
|
31
|
+
/** wrap a constructor, auto-add returned disposables */
|
|
32
|
+
keepConstructor<C extends Constructor<Disposable>>(Ctor: C): C;
|
|
33
|
+
/** create a subscope, child gets disposed when parent does */
|
|
34
|
+
sub(): Scope;
|
|
35
|
+
/** dispose everything in this scope, in reverse order */
|
|
36
|
+
dispose(): void;
|
|
37
|
+
}
|
package/x/scope.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export function scoped(item, dispose) {
|
|
2
|
+
return [item, dispose];
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* a trashcan you can fill with garbage, then call `scope.dispose()` to dump it all
|
|
6
|
+
* - `add/stow/scoped` methods are for dealing with disposer fns
|
|
7
|
+
* - `keep` methods are for dealing with disposable objects (with a dispose method)
|
|
8
|
+
* - `sub` for creating nested sub-scopes
|
|
9
|
+
*/
|
|
10
|
+
export class Scope {
|
|
11
|
+
#disposers = [];
|
|
12
|
+
/** add disposer fn */
|
|
13
|
+
add(dispose) {
|
|
14
|
+
this.#disposers.push(dispose);
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
/** add disposer, return item */
|
|
18
|
+
stow(item, dispose) {
|
|
19
|
+
this.add(dispose);
|
|
20
|
+
return item;
|
|
21
|
+
}
|
|
22
|
+
/** add scoped disposer, return item */
|
|
23
|
+
scoped([item, dispose]) {
|
|
24
|
+
this.add(dispose);
|
|
25
|
+
return item;
|
|
26
|
+
}
|
|
27
|
+
/** add and return a disposable object */
|
|
28
|
+
keep(disposable) {
|
|
29
|
+
this.add(() => disposable.dispose());
|
|
30
|
+
return disposable;
|
|
31
|
+
}
|
|
32
|
+
/** wrap a fn, auto-add returned disposers */
|
|
33
|
+
scopedFn(fn) {
|
|
34
|
+
return (...a) => {
|
|
35
|
+
const scoped = fn(...a);
|
|
36
|
+
return this.scoped(scoped);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** wrap an async fn, auto-add returned disposers */
|
|
40
|
+
scopedFnAsync(fn) {
|
|
41
|
+
return async (...a) => {
|
|
42
|
+
const scoped = await fn(...a);
|
|
43
|
+
return this.scoped(scoped);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** wrap a fn, auto-add returned disposables */
|
|
47
|
+
keepFn(fn) {
|
|
48
|
+
return (...a) => {
|
|
49
|
+
const disposable = fn(...a);
|
|
50
|
+
return this.keep(disposable);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** wrap an async fn, auto-add returned disposables */
|
|
54
|
+
keepFnAsync(fn) {
|
|
55
|
+
return async (...a) => {
|
|
56
|
+
const disposable = await fn(...a);
|
|
57
|
+
return this.keep(disposable);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/** wrap a constructor, auto-add returned disposables */
|
|
61
|
+
keepConstructor(Ctor) {
|
|
62
|
+
const scope = this;
|
|
63
|
+
return class extends Ctor {
|
|
64
|
+
constructor(...p) {
|
|
65
|
+
super(...p);
|
|
66
|
+
scope.keep(this);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** create a subscope, child gets disposed when parent does */
|
|
71
|
+
sub() {
|
|
72
|
+
const subscope = new Scope();
|
|
73
|
+
return this.stow(subscope, () => subscope.dispose());
|
|
74
|
+
}
|
|
75
|
+
/** dispose everything in this scope, in reverse order */
|
|
76
|
+
dispose() {
|
|
77
|
+
for (const fn of this.#disposers.reverse())
|
|
78
|
+
fn();
|
|
79
|
+
this.#disposers = [];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=scope.js.map
|
package/x/scope.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../s/scope.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,MAAM,CAAO,IAAU,EAAE,OAAmB;IAC3D,OAAO,CAAC,IAAI,EAAE,OAAO,CAAiB,CAAA;AACvC,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,KAAK;IACjB,UAAU,GAAmB,EAAE,CAAA;IAE/B,sBAAsB;IACtB,GAAG,CAAC,OAAmB;QACtB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,gCAAgC;IAChC,IAAI,CAAO,IAAU,EAAE,OAAmB;QACzC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjB,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,uCAAuC;IACvC,MAAM,CAAO,CAAC,IAAI,EAAE,OAAO,CAAe;QACzC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjB,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,yCAAyC;IACzC,IAAI,CAAuB,UAAa;QACvC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAA;QACpC,OAAO,UAAU,CAAA;IAClB,CAAC;IAED,6CAA6C;IAC7C,QAAQ,CACN,EAAuC;QAExC,OAAO,CAAC,GAAG,CAAS,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YACvB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC3B,CAAC,CAAA;IACF,CAAC;IAED,oDAAoD;IACpD,aAAa,CACX,EAAgD;QAEjD,OAAO,KAAK,EAAC,GAAG,CAAS,EAAE,EAAE;YAC5B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC3B,CAAC,CAAA;IACF,CAAC;IAED,+CAA+C;IAC/C,MAAM,CACJ,EAA4B;QAE7B,OAAO,CAAC,GAAG,CAAS,EAAE,EAAE;YACvB,MAAM,UAAU,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YAC3B,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC7B,CAAC,CAAA;IACF,CAAC;IAED,sDAAsD;IACtD,WAAW,CACT,EAAqC;QAEtC,OAAO,KAAK,EAAC,GAAG,CAAS,EAAE,EAAE;YAC5B,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YACjC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAC7B,CAAC,CAAA;IACF,CAAC;IAED,wDAAwD;IACxD,eAAe,CAAoC,IAAO;QACzD,MAAM,KAAK,GAAG,IAAI,CAAA;QAClB,OAAO,KAAM,SAAQ,IAAI;YACxB,YAAY,GAAG,CAAQ;gBACtB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;gBACX,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACjB,CAAC;SACI,CAAA;IACP,CAAC;IAED,8DAA8D;IAC9D,GAAG;QACF,MAAM,QAAQ,GAAG,IAAI,KAAK,EAAE,CAAA;QAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACrD,CAAC;IAED,yDAAyD;IACzD,OAAO;QACN,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE;YACzC,EAAE,EAAE,CAAA;QACL,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;IACrB,CAAC;CACD"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type TemplateParts = {
|
|
2
|
+
strings: TemplateStringsArray;
|
|
3
|
+
values: any[];
|
|
4
|
+
};
|
|
5
|
+
export declare function templateParts(strings: TemplateStringsArray, ...values: any[]): TemplateParts;
|
|
6
|
+
export declare function templateString(strings: TemplateStringsArray, ...values: any[]): string;
|
package/x/templating.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function templateParts(strings, ...values) {
|
|
2
|
+
return { strings, values };
|
|
3
|
+
}
|
|
4
|
+
export function templateString(strings, ...values) {
|
|
5
|
+
const lastIndex = strings.length - 1;
|
|
6
|
+
return strings
|
|
7
|
+
.slice(0, lastIndex)
|
|
8
|
+
.reduce((a, b, c) => a + b + values[c], "")
|
|
9
|
+
+ strings[lastIndex];
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=templating.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templating.js","sourceRoot":"","sources":["../s/templating.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,aAAa,CAC3B,OAA6B,EAC7B,GAAG,MAAa;IAGjB,OAAO,EAAC,OAAO,EAAE,MAAM,EAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAA6B,EAAE,GAAG,MAAa;IAC7E,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAA;IACpC,OAAO,OAAO;SACZ,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;UACxC,OAAO,CAAC,SAAS,CAAC,CAAA;AACvB,CAAC"}
|
package/x/tests.test.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { Science } from "@e280/science";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
2
|
+
import clone from "./clone/clone.test.js";
|
|
3
|
+
import thumbprint from "./data/bytename/thumbprint.test.js";
|
|
4
|
+
import debounce from "./debounce/debounce.test.js";
|
|
5
|
+
import bytename from "./data/bytename/bytename.test.js";
|
|
6
|
+
import deep from "./deep/deep.test.js";
|
|
7
|
+
import data from "./data/data.test.js";
|
|
8
|
+
import queue from "./queue/queue.test.js";
|
|
7
9
|
await Science.run({
|
|
8
|
-
clone
|
|
9
|
-
bytename
|
|
10
|
-
|
|
11
|
-
debounce
|
|
12
|
-
deep
|
|
10
|
+
clone,
|
|
11
|
+
bytename,
|
|
12
|
+
thumbprint,
|
|
13
|
+
debounce,
|
|
14
|
+
deep,
|
|
15
|
+
data,
|
|
16
|
+
queue,
|
|
13
17
|
});
|
|
14
18
|
//# sourceMappingURL=tests.test.js.map
|
package/x/tests.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tests.test.js","sourceRoot":"","sources":["../s/tests.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAA;AAErC,OAAO,
|
|
1
|
+
{"version":3,"file":"tests.test.js","sourceRoot":"","sources":["../s/tests.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAA;AAErC,OAAO,KAAK,MAAM,uBAAuB,CAAA;AACzC,OAAO,UAAU,MAAM,oCAAoC,CAAA;AAC3D,OAAO,QAAQ,MAAM,6BAA6B,CAAA;AAClD,OAAO,QAAQ,MAAM,kCAAkC,CAAA;AACvD,OAAO,IAAI,MAAM,qBAAqB,CAAA;AACtC,OAAO,IAAI,MAAM,qBAAqB,CAAA;AACtC,OAAO,KAAK,MAAM,uBAAuB,CAAA;AAEzC,MAAM,OAAO,CAAC,GAAG,CAAC;IACjB,KAAK;IACL,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,IAAI;IACJ,IAAI;IACJ,KAAK;CACL,CAAC,CAAA"}
|
package/x/time.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const Time: {
|
|
2
|
+
seconds: (n: number) => number;
|
|
3
|
+
minutes: (n: number) => number;
|
|
4
|
+
hours: (n: number) => number;
|
|
5
|
+
days: (n: number) => number;
|
|
6
|
+
future: {
|
|
7
|
+
seconds: (n: number) => number;
|
|
8
|
+
minutes: (n: number) => number;
|
|
9
|
+
hours: (n: number) => number;
|
|
10
|
+
days: (n: number) => number;
|
|
11
|
+
};
|
|
12
|
+
past: {
|
|
13
|
+
seconds: (n: number) => number;
|
|
14
|
+
minutes: (n: number) => number;
|
|
15
|
+
hours: (n: number) => number;
|
|
16
|
+
days: (n: number) => number;
|
|
17
|
+
};
|
|
18
|
+
};
|
package/x/time.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const Time = {
|
|
2
|
+
seconds: (n) => (n * 1000),
|
|
3
|
+
minutes: (n) => (n * Time.seconds(60)),
|
|
4
|
+
hours: (n) => (n * Time.minutes(60)),
|
|
5
|
+
days: (n) => (n * Time.hours(24)),
|
|
6
|
+
future: {
|
|
7
|
+
seconds: (n) => (Date.now() + Time.seconds(n)),
|
|
8
|
+
minutes: (n) => (Date.now() + Time.minutes(n)),
|
|
9
|
+
hours: (n) => (Date.now() + Time.hours(n)),
|
|
10
|
+
days: (n) => (Date.now() + Time.days(n)),
|
|
11
|
+
},
|
|
12
|
+
past: {
|
|
13
|
+
seconds: (n) => (Date.now() - Time.seconds(n)),
|
|
14
|
+
minutes: (n) => (Date.now() - Time.minutes(n)),
|
|
15
|
+
hours: (n) => (Date.now() - Time.hours(n)),
|
|
16
|
+
days: (n) => (Date.now() - Time.days(n)),
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=time.js.map
|
package/x/time.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../s/time.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,IAAI,GAAG;IACnB,OAAO,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9C,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAEzC,MAAM,EAAE;QACP,OAAO,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtD,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KAChD;IAED,IAAI,EAAE;QACL,OAAO,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtD,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KAChD;CACD,CAAA"}
|
package/s/data/anka.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/*
|
|
3
|
-
|
|
4
|
-
"anka" is an alternative to base64 that i totally made up.
|
|
5
|
-
- it looks cool because it features characters from the indian subcontinent.
|
|
6
|
-
- each byte is represented by one character, which makes a 256 bit id incomparably short at only 32 characters.
|
|
7
|
-
- however, it's probably a bad idea, for these negative reasons:
|
|
8
|
-
1. many of these characters are actually 2-or-3-byte sequences (so even though anka is visually more compact than base64 to the user, it's actually more data in terms of bytes).
|
|
9
|
-
2. it's horrible for url-encoding.
|
|
10
|
-
3. it's horrible for trying to manually copy by typing.
|
|
11
|
-
|
|
12
|
-
256-bit anka ids look like this:
|
|
13
|
-
|
|
14
|
-
ஒഐওଆઊসਅവஎଉखਬശயഘसചവਭଏரঊझഠடଓઐഴঠണവઞ
|
|
15
|
-
ठକநइஎਦਏஒഊটਹஜഴयભকயঙਪഉजकঝഐवઠসഏਓਡਟऋ
|
|
16
|
-
થঞठખஉધഫரਜऐફരਪਙਗഭਣഎफઇমએরଔડਉதਤஅदઘച
|
|
17
|
-
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import {Bytes} from "./bytes.js"
|
|
21
|
-
|
|
22
|
-
const characters = [...new Set([
|
|
23
|
-
// devanagari
|
|
24
|
-
..."अआइईउऊऋएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलवशषसह",
|
|
25
|
-
|
|
26
|
-
// tamil
|
|
27
|
-
..."அஆஇஈஉஊஎஏஐஒஓகஙசஜஞடணதநபமயரலவழளறன",
|
|
28
|
-
|
|
29
|
-
// bengali
|
|
30
|
-
..."অআইঈউঊএঐওকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ",
|
|
31
|
-
|
|
32
|
-
// gurmukhi
|
|
33
|
-
..."ਅਆਇਈਉਊਏਐਓਕਖਗਘਙਚਛਜਝਞਟਠਡਢਣਤਥਦਧਨਪਫਬਭਮਯਰਲਵਸਹ",
|
|
34
|
-
|
|
35
|
-
// malayalam
|
|
36
|
-
..."അആഇഈഉഊഎഏഐഒഓകഖഗഘങചഛജഝഞടഠഡഢണതഥദധനപഫബഭമയരലവശസഹളഴറ",
|
|
37
|
-
|
|
38
|
-
// gujarati
|
|
39
|
-
..."અઆઇઈઉઊએઐઓકખગઘઙચછજઝઞટઠડઢણતથદધનપફબભમયરલવશષસહ",
|
|
40
|
-
|
|
41
|
-
// odia
|
|
42
|
-
..."ଅଆଇଈଉଊଏଐଓଔକଖଗଘଙଚଛଜଝଞଟଠଡଢଣତଥଦଧନପଫବଭମଯରଲଶଷସହ",
|
|
43
|
-
])]
|
|
44
|
-
|
|
45
|
-
export const Anka = Object.freeze({
|
|
46
|
-
|
|
47
|
-
string(bytes: Uint8Array) {
|
|
48
|
-
return [...bytes]
|
|
49
|
-
.map(int => characters.at(int))
|
|
50
|
-
.join("")
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
bytes(code: string) {
|
|
54
|
-
return new Uint8Array([...code].map(char => {
|
|
55
|
-
const index = characters.indexOf(char)
|
|
56
|
-
if (index === -1)
|
|
57
|
-
throw new Error(`invalid anka character "${char}"`)
|
|
58
|
-
return index
|
|
59
|
-
}))
|
|
60
|
-
},
|
|
61
|
-
|
|
62
|
-
random(count = 32) {
|
|
63
|
-
return this.string(Bytes.random(count))
|
|
64
|
-
},
|
|
65
|
-
})
|
|
66
|
-
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import {Hex} from "../hex.js"
|
|
3
|
-
import {Badge} from "./badge.js"
|
|
4
|
-
import {Bytes} from "../bytes.js"
|
|
5
|
-
import {Science, test, expect} from "@e280/science"
|
|
6
|
-
|
|
7
|
-
const sampleBadge = "nodlyn.fasrep:39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k"
|
|
8
|
-
const sampleHex = "88e8c3fad1028fcf6ce5ac491578850f4d833336feca03b608265501c3019d59"
|
|
9
|
-
const sampleBytes = Hex.bytes(sampleHex)
|
|
10
|
-
|
|
11
|
-
function good(bytes: Uint8Array) {
|
|
12
|
-
expect(Bytes.eq(bytes, sampleBytes)).ok()
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export default Science.suite({
|
|
16
|
-
"bytes->string->bytes": test(async() => {
|
|
17
|
-
const text = Badge.string(sampleBytes)
|
|
18
|
-
expect(text).is(sampleBadge)
|
|
19
|
-
good(Badge.bytes(text))
|
|
20
|
-
}),
|
|
21
|
-
|
|
22
|
-
"zero bytes": test(async() => {
|
|
23
|
-
const text = Badge.string(new Uint8Array([]))
|
|
24
|
-
expect(text).is("")
|
|
25
|
-
expect(Bytes.eq(Badge.bytes(text), new Uint8Array([]))).ok()
|
|
26
|
-
}),
|
|
27
|
-
|
|
28
|
-
"one byte": test(async() => {
|
|
29
|
-
const text = Badge.string(new Uint8Array([0x00]))
|
|
30
|
-
expect(text).is("doz")
|
|
31
|
-
expect(Bytes.eq(Badge.bytes(text), new Uint8Array([0x00]))).ok()
|
|
32
|
-
}),
|
|
33
|
-
|
|
34
|
-
"partially": Science.suite({
|
|
35
|
-
"normal": test(async() => expect(Badge.bytes("nodlyn.fasrep:39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k").length).ok()),
|
|
36
|
-
"nothing": test(async() => expect(Badge.bytes("").length).is(0)),
|
|
37
|
-
"no-rest": test(async() => expect(Badge.bytes("nodlyn.fasrep").length).ok()),
|
|
38
|
-
"one-byte": test(async() => expect(Badge.bytes("nod").length).is(1)),
|
|
39
|
-
"three-byte": test(async() => expect(Badge.bytes("nodlynfas").length).is(3)),
|
|
40
|
-
"one-byte-lead": test(async() => expect(Badge.bytes("nod:39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k").length).ok()),
|
|
41
|
-
}),
|
|
42
|
-
|
|
43
|
-
"tolerance": Science.suite({
|
|
44
|
-
"normal": test(async() => good(Badge.bytes("nodlyn.fasrep:39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k"))),
|
|
45
|
-
"coolio": test(async() => good(Badge.bytes("nodlyn.fasrep..39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k"))),
|
|
46
|
-
"spaces": test(async() => good(Badge.bytes("nodlyn fasrep 39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k"))),
|
|
47
|
-
"dots": test(async() => good(Badge.bytes("nodlyn.fasrep.39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k"))),
|
|
48
|
-
"one-space": test(async() => good(Badge.bytes("nodlynfasrep 39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k"))),
|
|
49
|
-
"one-newline": test(async() => good(Badge.bytes("nodlynfasrep\n39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k"))),
|
|
50
|
-
"whitespace": test(async() => good(Badge.bytes("\t\n nodlyn\n fasrep \n\n\t\n 39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k\n\t"))),
|
|
51
|
-
}),
|
|
52
|
-
})
|
|
53
|
-
|
package/s/data/bytename/badge.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import {Hex} from "../hex.js"
|
|
3
|
-
import {Base58} from "../base58.js"
|
|
4
|
-
import {Bytename} from "./bytename.js"
|
|
5
|
-
|
|
6
|
-
export type BadgeOptions = {
|
|
7
|
-
leadBytes: number
|
|
8
|
-
leadSeparator: string
|
|
9
|
-
restSeparator: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type ParsedBadge = {
|
|
13
|
-
lead: string
|
|
14
|
-
rest: string
|
|
15
|
-
bytes: Uint8Array
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Badge is a human-friendly presentation format for arbitrary binary data.
|
|
20
|
-
* - looks like "nodlyn.fasrep:39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k"
|
|
21
|
-
* - the first lead bytes are shown in bytename format
|
|
22
|
-
* - the rest of the data is in base58
|
|
23
|
-
* - designed to be a nice way to present 256-bit passport thumbprints
|
|
24
|
-
* - can actually represent any number of bytes
|
|
25
|
-
* - "nodlyn.fasrep:39gfeGFAAnBzH5pkT7EdoETMUMAekG9h1iymk6k"
|
|
26
|
-
*/
|
|
27
|
-
export const Badge = {
|
|
28
|
-
defaults: (<BadgeOptions>{
|
|
29
|
-
leadBytes: 4,
|
|
30
|
-
leadSeparator: ".",
|
|
31
|
-
restSeparator: ":",
|
|
32
|
-
}),
|
|
33
|
-
|
|
34
|
-
string(bytes: Uint8Array, options: Partial<BadgeOptions> = {}) {
|
|
35
|
-
const {leadBytes, leadSeparator, restSeparator}
|
|
36
|
-
= {...Badge.defaults, ...options}
|
|
37
|
-
|
|
38
|
-
const appetizer = Bytename.string(bytes.slice(0, leadBytes), {
|
|
39
|
-
wordSeparator: leadSeparator,
|
|
40
|
-
groupSeparator: leadSeparator,
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
return (bytes.length > leadBytes)
|
|
44
|
-
? `${appetizer}${restSeparator}${Base58.string(bytes.slice(leadBytes))}`
|
|
45
|
-
: appetizer
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
parse(badge: string): ParsedBadge {
|
|
49
|
-
badge = badge.trim()
|
|
50
|
-
const parts = badge.split(/[^a-zA-Z0-9]+/m)
|
|
51
|
-
.filter(Boolean)
|
|
52
|
-
.map(s => s.trim())
|
|
53
|
-
|
|
54
|
-
if (parts.length < 2) {
|
|
55
|
-
const lead = parts.join(".")
|
|
56
|
-
const bytes = Bytename.bytes(lead)
|
|
57
|
-
return {lead, rest: "", bytes}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const rest = parts.pop()!
|
|
61
|
-
const lead = parts.join(".")
|
|
62
|
-
const bytes = new Uint8Array([
|
|
63
|
-
...Bytename.bytes(lead),
|
|
64
|
-
...Base58.bytes(rest),
|
|
65
|
-
])
|
|
66
|
-
return {lead, rest, bytes}
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
bytes(badge: string) {
|
|
70
|
-
return Badge.parse(badge).bytes
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
hex(badge: string) {
|
|
74
|
-
return Hex.string(Badge.bytes(badge))
|
|
75
|
-
},
|
|
76
|
-
|
|
77
|
-
fromHex(hex: string, options?: Partial<BadgeOptions>) {
|
|
78
|
-
return Badge.string(Hex.bytes(hex), options)
|
|
79
|
-
},
|
|
80
|
-
}
|
|
81
|
-
|