@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.
Files changed (148) hide show
  1. package/README.md +275 -24
  2. package/package.json +13 -9
  3. package/s/coalesce.ts +1 -0
  4. package/s/constructor.ts +15 -0
  5. package/s/data/base-x.ts +170 -0
  6. package/s/data/base58.ts +15 -5
  7. package/s/data/base64.ts +15 -6
  8. package/s/data/base64url.ts +15 -6
  9. package/s/data/bytename/bytename.test.ts +12 -12
  10. package/s/data/bytename/bytename.ts +13 -6
  11. package/s/data/bytename/index.ts +1 -1
  12. package/s/data/bytename/thumbprint.test.ts +53 -0
  13. package/s/data/bytename/thumbprint.ts +112 -0
  14. package/s/data/bytes.ts +2 -2
  15. package/s/data/data.test.ts +98 -0
  16. package/s/data/hex.ts +15 -5
  17. package/s/data/txt.ts +14 -4
  18. package/s/deadline.ts +5 -6
  19. package/s/{defer-promise.ts → defer.ts} +2 -2
  20. package/s/drill.ts +2 -4
  21. package/s/ev.ts +20 -0
  22. package/s/id-counter.ts +9 -0
  23. package/s/index.ts +12 -1
  24. package/s/is.ts +10 -4
  25. package/s/map-g.ts +9 -10
  26. package/s/nap.ts +1 -0
  27. package/s/once.ts +14 -0
  28. package/s/pipe.ts +7 -8
  29. package/s/pubsub.ts +24 -6
  30. package/s/queue/queue.test.ts +67 -0
  31. package/s/queue/queue.ts +21 -0
  32. package/s/repeat.ts +25 -0
  33. package/s/scope.ts +108 -0
  34. package/s/templating.ts +22 -0
  35. package/s/tests.test.ts +14 -10
  36. package/s/time.ts +22 -0
  37. package/x/coalesce.d.ts +1 -0
  38. package/x/coalesce.js +1 -0
  39. package/x/coalesce.js.map +1 -1
  40. package/x/constructor.d.ts +3 -0
  41. package/x/constructor.js +4 -0
  42. package/x/constructor.js.map +1 -0
  43. package/x/data/base-x.d.ts +47 -0
  44. package/x/data/base-x.js +147 -0
  45. package/x/data/base-x.js.map +1 -0
  46. package/x/data/base58.d.ts +5 -1
  47. package/x/data/base58.js +13 -5
  48. package/x/data/base58.js.map +1 -1
  49. package/x/data/base64.d.ts +7 -3
  50. package/x/data/base64.js +13 -5
  51. package/x/data/base64.js.map +1 -1
  52. package/x/data/base64url.d.ts +5 -1
  53. package/x/data/base64url.js +13 -5
  54. package/x/data/base64url.js.map +1 -1
  55. package/x/data/bytename/bytename.d.ts +9 -3
  56. package/x/data/bytename/bytename.js +13 -6
  57. package/x/data/bytename/bytename.js.map +1 -1
  58. package/x/data/bytename/bytename.test.js +12 -12
  59. package/x/data/bytename/bytename.test.js.map +1 -1
  60. package/x/data/bytename/index.d.ts +1 -1
  61. package/x/data/bytename/index.js +1 -1
  62. package/x/data/bytename/index.js.map +1 -1
  63. package/x/data/bytename/thumbprint.d.ts +36 -0
  64. package/x/data/bytename/thumbprint.js +79 -0
  65. package/x/data/bytename/thumbprint.js.map +1 -0
  66. package/x/data/bytename/{badge.test.d.ts → thumbprint.test.d.ts} +2 -2
  67. package/x/data/bytename/thumbprint.test.js +45 -0
  68. package/x/data/bytename/thumbprint.test.js.map +1 -0
  69. package/x/data/bytes.d.ts +2 -2
  70. package/x/data/bytes.js +2 -2
  71. package/x/data/bytes.js.map +1 -1
  72. package/x/data/data.test.d.ts +69 -0
  73. package/x/data/data.test.js +77 -0
  74. package/x/data/data.test.js.map +1 -0
  75. package/x/data/hex.d.ts +8 -4
  76. package/x/data/hex.js +13 -5
  77. package/x/data/hex.js.map +1 -1
  78. package/x/data/txt.d.ts +6 -2
  79. package/x/data/txt.js +12 -4
  80. package/x/data/txt.js.map +1 -1
  81. package/x/deadline.d.ts +2 -2
  82. package/x/deadline.js +4 -4
  83. package/x/deadline.js.map +1 -1
  84. package/x/{defer-promise.d.ts → defer.d.ts} +2 -2
  85. package/x/{defer-promise.js → defer.js} +2 -2
  86. package/x/defer.js.map +1 -0
  87. package/x/drill.d.ts +1 -3
  88. package/x/drill.js +2 -4
  89. package/x/drill.js.map +1 -1
  90. package/x/ev.d.ts +6 -0
  91. package/x/ev.js +10 -0
  92. package/x/ev.js.map +1 -0
  93. package/x/id-counter.d.ts +5 -0
  94. package/x/id-counter.js +10 -0
  95. package/x/id-counter.js.map +1 -0
  96. package/x/index.d.ts +11 -1
  97. package/x/index.js +11 -1
  98. package/x/index.js.map +1 -1
  99. package/x/is.d.ts +6 -4
  100. package/x/is.js +6 -4
  101. package/x/is.js.map +1 -1
  102. package/x/map-g.d.ts +3 -3
  103. package/x/map-g.js +9 -8
  104. package/x/map-g.js.map +1 -1
  105. package/x/nap.d.ts +1 -0
  106. package/x/nap.js +1 -0
  107. package/x/nap.js.map +1 -1
  108. package/x/once.d.ts +1 -0
  109. package/x/once.js +12 -0
  110. package/x/once.js.map +1 -0
  111. package/x/pipe.d.ts +3 -3
  112. package/x/pipe.js +5 -5
  113. package/x/pipe.js.map +1 -1
  114. package/x/pubsub.d.ts +12 -1
  115. package/x/pubsub.js +7 -5
  116. package/x/pubsub.js.map +1 -1
  117. package/x/queue/queue.d.ts +4 -0
  118. package/x/queue/queue.js +14 -0
  119. package/x/queue/queue.js.map +1 -0
  120. package/x/queue/queue.test.d.ts +8 -0
  121. package/x/queue/queue.test.js +57 -0
  122. package/x/queue/queue.test.js.map +1 -0
  123. package/x/repeat.d.ts +5 -0
  124. package/x/repeat.js +23 -0
  125. package/x/repeat.js.map +1 -0
  126. package/x/scope.d.ts +37 -0
  127. package/x/scope.js +82 -0
  128. package/x/scope.js.map +1 -0
  129. package/x/templating.d.ts +6 -0
  130. package/x/templating.js +11 -0
  131. package/x/templating.js.map +1 -0
  132. package/x/tests.test.js +14 -10
  133. package/x/tests.test.js.map +1 -1
  134. package/x/time.d.ts +18 -0
  135. package/x/time.js +19 -0
  136. package/x/time.js.map +1 -0
  137. package/s/data/anka.ts +0 -66
  138. package/s/data/bytename/badge.test.ts +0 -53
  139. package/s/data/bytename/badge.ts +0 -81
  140. package/x/data/anka.d.ts +0 -5
  141. package/x/data/anka.js +0 -53
  142. package/x/data/anka.js.map +0 -1
  143. package/x/data/bytename/badge.d.ts +0 -27
  144. package/x/data/bytename/badge.js +0 -57
  145. package/x/data/bytename/badge.js.map +0 -1
  146. package/x/data/bytename/badge.test.js +0 -45
  147. package/x/data/bytename/badge.test.js.map +0 -1
  148. package/x/defer-promise.js.map +0 -1
package/x/pubsub.js CHANGED
@@ -1,4 +1,4 @@
1
- import { deferPromise } from "./defer-promise.js";
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 once() {
12
- const { promise, resolve } = deferPromise();
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.once = once;
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.once = once;
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,YAAY,EAAC,MAAM,oBAAoB,CAAA;AAmB/C,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,YAAY,EAAK,CAAA;QAC5C,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,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,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"}
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"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * create a job queue that ensures the given fn is always called in sequence (not concurrently).
3
+ */
4
+ export declare function queue<Args extends any[], Result>(fn: (...args: Args) => Promise<Result>): (...args: Args) => Promise<Result>;
@@ -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
@@ -0,0 +1,5 @@
1
+ /**
2
+ * repeat the given async function over and over.
3
+ * - consider using `nap` in your fn to create a delay
4
+ */
5
+ export declare function repeat(fn: (stop: () => void) => Promise<void>): () => void;
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
@@ -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;
@@ -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 cloneTest from "./clone/clone.test.js";
3
- import badgeTest from "./data/bytename/badge.test.js";
4
- import debounceTest from "./debounce/debounce.test.js";
5
- import bytenameTest from "./data/bytename/bytename.test.js";
6
- import deepTest from "./deep/deep.test.js";
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: cloneTest,
9
- bytename: bytenameTest,
10
- badge: badgeTest,
11
- debounce: debounceTest,
12
- deep: deepTest,
10
+ clone,
11
+ bytename,
12
+ thumbprint,
13
+ debounce,
14
+ deep,
15
+ data,
16
+ queue,
13
17
  });
14
18
  //# sourceMappingURL=tests.test.js.map
@@ -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,SAAS,MAAM,uBAAuB,CAAA;AAC7C,OAAO,SAAS,MAAM,+BAA+B,CAAA;AACrD,OAAO,YAAY,MAAM,6BAA6B,CAAA;AACtD,OAAO,YAAY,MAAM,kCAAkC,CAAA;AAC3D,OAAO,QAAQ,MAAM,qBAAqB,CAAA;AAE1C,MAAM,OAAO,CAAC,GAAG,CAAC;IACjB,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,YAAY;IACtB,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,YAAY;IACtB,IAAI,EAAE,QAAQ;CACd,CAAC,CAAA"}
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
-
@@ -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
-
package/x/data/anka.d.ts DELETED
@@ -1,5 +0,0 @@
1
- export declare const Anka: Readonly<{
2
- string(bytes: Uint8Array): string;
3
- bytes(code: string): Uint8Array<ArrayBuffer>;
4
- random(count?: number): string;
5
- }>;