@cogcoin/client 0.5.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 (289) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +136 -0
  3. package/dist/app-paths.d.ts +38 -0
  4. package/dist/app-paths.js +121 -0
  5. package/dist/art/banner.txt +13 -0
  6. package/dist/art/scroll.txt +13 -0
  7. package/dist/art/train-car.txt +6 -0
  8. package/dist/art/train-smoke.txt +6 -0
  9. package/dist/art/train.txt +6 -0
  10. package/dist/bitcoind/bootstrap/chainstate.d.ts +4 -0
  11. package/dist/bitcoind/bootstrap/chainstate.js +13 -0
  12. package/dist/bitcoind/bootstrap/constants.d.ts +7 -0
  13. package/dist/bitcoind/bootstrap/constants.js +12 -0
  14. package/dist/bitcoind/bootstrap/controller.d.ts +29 -0
  15. package/dist/bitcoind/bootstrap/controller.js +101 -0
  16. package/dist/bitcoind/bootstrap/download.d.ts +2 -0
  17. package/dist/bitcoind/bootstrap/download.js +196 -0
  18. package/dist/bitcoind/bootstrap/headers.d.ts +13 -0
  19. package/dist/bitcoind/bootstrap/headers.js +61 -0
  20. package/dist/bitcoind/bootstrap/paths.d.ts +4 -0
  21. package/dist/bitcoind/bootstrap/paths.js +15 -0
  22. package/dist/bitcoind/bootstrap/snapshot-file.d.ts +7 -0
  23. package/dist/bitcoind/bootstrap/snapshot-file.js +42 -0
  24. package/dist/bitcoind/bootstrap/state.d.ts +40 -0
  25. package/dist/bitcoind/bootstrap/state.js +70 -0
  26. package/dist/bitcoind/bootstrap/types.d.ts +28 -0
  27. package/dist/bitcoind/bootstrap/types.js +1 -0
  28. package/dist/bitcoind/bootstrap.d.ts +8 -0
  29. package/dist/bitcoind/bootstrap.js +7 -0
  30. package/dist/bitcoind/client/factory.d.ts +3 -0
  31. package/dist/bitcoind/client/factory.js +57 -0
  32. package/dist/bitcoind/client/follow-block-times.d.ts +8 -0
  33. package/dist/bitcoind/client/follow-block-times.js +25 -0
  34. package/dist/bitcoind/client/follow-loop.d.ts +10 -0
  35. package/dist/bitcoind/client/follow-loop.js +57 -0
  36. package/dist/bitcoind/client/internal-types.d.ts +63 -0
  37. package/dist/bitcoind/client/internal-types.js +18 -0
  38. package/dist/bitcoind/client/managed-client.d.ts +20 -0
  39. package/dist/bitcoind/client/managed-client.js +197 -0
  40. package/dist/bitcoind/client/rate-tracker.d.ts +2 -0
  41. package/dist/bitcoind/client/rate-tracker.js +24 -0
  42. package/dist/bitcoind/client/sync-engine.d.ts +3 -0
  43. package/dist/bitcoind/client/sync-engine.js +143 -0
  44. package/dist/bitcoind/client.d.ts +1 -0
  45. package/dist/bitcoind/client.js +1 -0
  46. package/dist/bitcoind/errors.d.ts +1 -0
  47. package/dist/bitcoind/errors.js +49 -0
  48. package/dist/bitcoind/index.d.ts +2 -0
  49. package/dist/bitcoind/index.js +1 -0
  50. package/dist/bitcoind/indexer-daemon-main.d.ts +1 -0
  51. package/dist/bitcoind/indexer-daemon-main.js +472 -0
  52. package/dist/bitcoind/indexer-daemon.d.ts +107 -0
  53. package/dist/bitcoind/indexer-daemon.js +391 -0
  54. package/dist/bitcoind/node.d.ts +8 -0
  55. package/dist/bitcoind/node.js +219 -0
  56. package/dist/bitcoind/normalize.d.ts +3 -0
  57. package/dist/bitcoind/normalize.js +47 -0
  58. package/dist/bitcoind/progress/assets.d.ts +10 -0
  59. package/dist/bitcoind/progress/assets.js +90 -0
  60. package/dist/bitcoind/progress/constants.d.ts +48 -0
  61. package/dist/bitcoind/progress/constants.js +53 -0
  62. package/dist/bitcoind/progress/controller.d.ts +28 -0
  63. package/dist/bitcoind/progress/controller.js +188 -0
  64. package/dist/bitcoind/progress/follow-scene.d.ts +40 -0
  65. package/dist/bitcoind/progress/follow-scene.js +367 -0
  66. package/dist/bitcoind/progress/formatting.d.ts +23 -0
  67. package/dist/bitcoind/progress/formatting.js +227 -0
  68. package/dist/bitcoind/progress/quote-scene.d.ts +4 -0
  69. package/dist/bitcoind/progress/quote-scene.js +137 -0
  70. package/dist/bitcoind/progress/train-scene.d.ts +9 -0
  71. package/dist/bitcoind/progress/train-scene.js +92 -0
  72. package/dist/bitcoind/progress/tty-renderer.d.ts +18 -0
  73. package/dist/bitcoind/progress/tty-renderer.js +150 -0
  74. package/dist/bitcoind/progress.d.ts +7 -0
  75. package/dist/bitcoind/progress.js +7 -0
  76. package/dist/bitcoind/quotes.d.ts +24 -0
  77. package/dist/bitcoind/quotes.js +195 -0
  78. package/dist/bitcoind/rpc.d.ts +71 -0
  79. package/dist/bitcoind/rpc.js +322 -0
  80. package/dist/bitcoind/service-paths.d.ts +19 -0
  81. package/dist/bitcoind/service-paths.js +49 -0
  82. package/dist/bitcoind/service.d.ts +40 -0
  83. package/dist/bitcoind/service.js +735 -0
  84. package/dist/bitcoind/testing.d.ts +9 -0
  85. package/dist/bitcoind/testing.js +9 -0
  86. package/dist/bitcoind/types.d.ts +396 -0
  87. package/dist/bitcoind/types.js +3 -0
  88. package/dist/bytes.d.ts +9 -0
  89. package/dist/bytes.js +36 -0
  90. package/dist/cli/commands/follow.d.ts +2 -0
  91. package/dist/cli/commands/follow.js +43 -0
  92. package/dist/cli/commands/mining-admin.d.ts +2 -0
  93. package/dist/cli/commands/mining-admin.js +92 -0
  94. package/dist/cli/commands/mining-read.d.ts +2 -0
  95. package/dist/cli/commands/mining-read.js +173 -0
  96. package/dist/cli/commands/mining-runtime.d.ts +2 -0
  97. package/dist/cli/commands/mining-runtime.js +108 -0
  98. package/dist/cli/commands/status.d.ts +2 -0
  99. package/dist/cli/commands/status.js +31 -0
  100. package/dist/cli/commands/sync.d.ts +2 -0
  101. package/dist/cli/commands/sync.js +52 -0
  102. package/dist/cli/commands/wallet-admin.d.ts +2 -0
  103. package/dist/cli/commands/wallet-admin.js +175 -0
  104. package/dist/cli/commands/wallet-mutation.d.ts +2 -0
  105. package/dist/cli/commands/wallet-mutation.js +681 -0
  106. package/dist/cli/commands/wallet-read.d.ts +2 -0
  107. package/dist/cli/commands/wallet-read.js +265 -0
  108. package/dist/cli/context.d.ts +3 -0
  109. package/dist/cli/context.js +75 -0
  110. package/dist/cli/io.d.ts +3 -0
  111. package/dist/cli/io.js +12 -0
  112. package/dist/cli/mining-format.d.ts +5 -0
  113. package/dist/cli/mining-format.js +156 -0
  114. package/dist/cli/mining-json.d.ts +49 -0
  115. package/dist/cli/mining-json.js +89 -0
  116. package/dist/cli/mutation-command-groups.d.ts +15 -0
  117. package/dist/cli/mutation-command-groups.js +71 -0
  118. package/dist/cli/mutation-json.d.ts +430 -0
  119. package/dist/cli/mutation-json.js +311 -0
  120. package/dist/cli/mutation-resolved-json.d.ts +124 -0
  121. package/dist/cli/mutation-resolved-json.js +129 -0
  122. package/dist/cli/mutation-success.d.ts +20 -0
  123. package/dist/cli/mutation-success.js +47 -0
  124. package/dist/cli/mutation-text-format.d.ts +22 -0
  125. package/dist/cli/mutation-text-format.js +171 -0
  126. package/dist/cli/mutation-text-write.d.ts +13 -0
  127. package/dist/cli/mutation-text-write.js +16 -0
  128. package/dist/cli/output.d.ts +185 -0
  129. package/dist/cli/output.js +1085 -0
  130. package/dist/cli/parse.d.ts +3 -0
  131. package/dist/cli/parse.js +971 -0
  132. package/dist/cli/preview-json.d.ts +416 -0
  133. package/dist/cli/preview-json.js +293 -0
  134. package/dist/cli/prompt.d.ts +3 -0
  135. package/dist/cli/prompt.js +33 -0
  136. package/dist/cli/read-json.d.ts +187 -0
  137. package/dist/cli/read-json.js +675 -0
  138. package/dist/cli/runner.d.ts +2 -0
  139. package/dist/cli/runner.js +129 -0
  140. package/dist/cli/signals.d.ts +3 -0
  141. package/dist/cli/signals.js +63 -0
  142. package/dist/cli/status-format.d.ts +2 -0
  143. package/dist/cli/status-format.js +48 -0
  144. package/dist/cli/types.d.ts +148 -0
  145. package/dist/cli/types.js +2 -0
  146. package/dist/cli/wallet-format.d.ts +29 -0
  147. package/dist/cli/wallet-format.js +637 -0
  148. package/dist/cli/workflow-hints.d.ts +13 -0
  149. package/dist/cli/workflow-hints.js +94 -0
  150. package/dist/cli-runner.d.ts +3 -0
  151. package/dist/cli-runner.js +3 -0
  152. package/dist/cli.d.ts +2 -0
  153. package/dist/cli.js +6 -0
  154. package/dist/client/default-client.d.ts +11 -0
  155. package/dist/client/default-client.js +118 -0
  156. package/dist/client/factory.d.ts +2 -0
  157. package/dist/client/factory.js +15 -0
  158. package/dist/client/initialization.d.ts +6 -0
  159. package/dist/client/initialization.js +30 -0
  160. package/dist/client/persistence.d.ts +5 -0
  161. package/dist/client/persistence.js +28 -0
  162. package/dist/client/store-adapter.d.ts +3 -0
  163. package/dist/client/store-adapter.js +20 -0
  164. package/dist/client.d.ts +2 -0
  165. package/dist/client.js +2 -0
  166. package/dist/index.d.ts +2 -0
  167. package/dist/index.js +1 -0
  168. package/dist/passive-status.d.ts +36 -0
  169. package/dist/passive-status.js +100 -0
  170. package/dist/sqlite/better-sqlite3.d.ts +26 -0
  171. package/dist/sqlite/better-sqlite3.js +4 -0
  172. package/dist/sqlite/checkpoints.d.ts +11 -0
  173. package/dist/sqlite/checkpoints.js +27 -0
  174. package/dist/sqlite/driver.d.ts +17 -0
  175. package/dist/sqlite/driver.js +98 -0
  176. package/dist/sqlite/index.d.ts +4 -0
  177. package/dist/sqlite/index.js +9 -0
  178. package/dist/sqlite/migrate.d.ts +2 -0
  179. package/dist/sqlite/migrate.js +37 -0
  180. package/dist/sqlite/store.d.ts +3 -0
  181. package/dist/sqlite/store.js +122 -0
  182. package/dist/sqlite/tip-meta.d.ts +26 -0
  183. package/dist/sqlite/tip-meta.js +97 -0
  184. package/dist/sqlite/types.d.ts +10 -0
  185. package/dist/sqlite/types.js +1 -0
  186. package/dist/types.d.ts +55 -0
  187. package/dist/types.js +1 -0
  188. package/dist/wallet/archive.d.ts +4 -0
  189. package/dist/wallet/archive.js +39 -0
  190. package/dist/wallet/cogop/constants.d.ts +32 -0
  191. package/dist/wallet/cogop/constants.js +32 -0
  192. package/dist/wallet/cogop/index.d.ts +32 -0
  193. package/dist/wallet/cogop/index.js +213 -0
  194. package/dist/wallet/cogop/numeric.d.ts +3 -0
  195. package/dist/wallet/cogop/numeric.js +24 -0
  196. package/dist/wallet/cogop/scriptpubkey.d.ts +2 -0
  197. package/dist/wallet/cogop/scriptpubkey.js +13 -0
  198. package/dist/wallet/cogop/validate-name.d.ts +2 -0
  199. package/dist/wallet/cogop/validate-name.js +18 -0
  200. package/dist/wallet/fs/atomic.d.ts +6 -0
  201. package/dist/wallet/fs/atomic.js +46 -0
  202. package/dist/wallet/fs/lock.d.ts +19 -0
  203. package/dist/wallet/fs/lock.js +61 -0
  204. package/dist/wallet/fs/status-file.d.ts +1 -0
  205. package/dist/wallet/fs/status-file.js +4 -0
  206. package/dist/wallet/lifecycle.d.ts +193 -0
  207. package/dist/wallet/lifecycle.js +1475 -0
  208. package/dist/wallet/material.d.ts +45 -0
  209. package/dist/wallet/material.js +118 -0
  210. package/dist/wallet/mining/config.d.ts +18 -0
  211. package/dist/wallet/mining/config.js +44 -0
  212. package/dist/wallet/mining/constants.d.ts +24 -0
  213. package/dist/wallet/mining/constants.js +24 -0
  214. package/dist/wallet/mining/control.d.ts +53 -0
  215. package/dist/wallet/mining/control.js +758 -0
  216. package/dist/wallet/mining/coordination.d.ts +40 -0
  217. package/dist/wallet/mining/coordination.js +121 -0
  218. package/dist/wallet/mining/hook-protocol.d.ts +47 -0
  219. package/dist/wallet/mining/hook-protocol.js +161 -0
  220. package/dist/wallet/mining/hook-runner.d.ts +1 -0
  221. package/dist/wallet/mining/hook-runner.js +52 -0
  222. package/dist/wallet/mining/hooks.d.ts +38 -0
  223. package/dist/wallet/mining/hooks.js +520 -0
  224. package/dist/wallet/mining/index.d.ts +8 -0
  225. package/dist/wallet/mining/index.js +6 -0
  226. package/dist/wallet/mining/runner.d.ts +155 -0
  227. package/dist/wallet/mining/runner.js +2574 -0
  228. package/dist/wallet/mining/runtime-artifacts.d.ts +17 -0
  229. package/dist/wallet/mining/runtime-artifacts.js +166 -0
  230. package/dist/wallet/mining/sentences.d.ts +23 -0
  231. package/dist/wallet/mining/sentences.js +281 -0
  232. package/dist/wallet/mining/state.d.ts +9 -0
  233. package/dist/wallet/mining/state.js +75 -0
  234. package/dist/wallet/mining/types.d.ts +141 -0
  235. package/dist/wallet/mining/types.js +1 -0
  236. package/dist/wallet/mining/visualizer.d.ts +19 -0
  237. package/dist/wallet/mining/visualizer.js +134 -0
  238. package/dist/wallet/mining/worker-main.d.ts +1 -0
  239. package/dist/wallet/mining/worker-main.js +17 -0
  240. package/dist/wallet/read/context.d.ts +20 -0
  241. package/dist/wallet/read/context.js +532 -0
  242. package/dist/wallet/read/filter.d.ts +9 -0
  243. package/dist/wallet/read/filter.js +42 -0
  244. package/dist/wallet/read/index.d.ts +4 -0
  245. package/dist/wallet/read/index.js +3 -0
  246. package/dist/wallet/read/project.d.ts +11 -0
  247. package/dist/wallet/read/project.js +300 -0
  248. package/dist/wallet/read/types.d.ts +144 -0
  249. package/dist/wallet/read/types.js +1 -0
  250. package/dist/wallet/runtime.d.ts +26 -0
  251. package/dist/wallet/runtime.js +28 -0
  252. package/dist/wallet/state/crypto.d.ts +31 -0
  253. package/dist/wallet/state/crypto.js +127 -0
  254. package/dist/wallet/state/provider.d.ts +37 -0
  255. package/dist/wallet/state/provider.js +312 -0
  256. package/dist/wallet/state/session.d.ts +12 -0
  257. package/dist/wallet/state/session.js +23 -0
  258. package/dist/wallet/state/storage.d.ts +19 -0
  259. package/dist/wallet/state/storage.js +55 -0
  260. package/dist/wallet/tx/anchor.d.ts +40 -0
  261. package/dist/wallet/tx/anchor.js +1210 -0
  262. package/dist/wallet/tx/cog.d.ts +92 -0
  263. package/dist/wallet/tx/cog.js +1055 -0
  264. package/dist/wallet/tx/common.d.ts +89 -0
  265. package/dist/wallet/tx/common.js +156 -0
  266. package/dist/wallet/tx/confirm.d.ts +15 -0
  267. package/dist/wallet/tx/confirm.js +24 -0
  268. package/dist/wallet/tx/domain-admin.d.ts +105 -0
  269. package/dist/wallet/tx/domain-admin.js +869 -0
  270. package/dist/wallet/tx/domain-market.d.ts +112 -0
  271. package/dist/wallet/tx/domain-market.js +1365 -0
  272. package/dist/wallet/tx/field.d.ts +101 -0
  273. package/dist/wallet/tx/field.js +1853 -0
  274. package/dist/wallet/tx/identity-selector.d.ts +12 -0
  275. package/dist/wallet/tx/identity-selector.js +52 -0
  276. package/dist/wallet/tx/index.d.ts +7 -0
  277. package/dist/wallet/tx/index.js +7 -0
  278. package/dist/wallet/tx/journal.d.ts +5 -0
  279. package/dist/wallet/tx/journal.js +31 -0
  280. package/dist/wallet/tx/register.d.ts +68 -0
  281. package/dist/wallet/tx/register.js +952 -0
  282. package/dist/wallet/tx/reputation.d.ts +72 -0
  283. package/dist/wallet/tx/reputation.js +693 -0
  284. package/dist/wallet/tx/targets.d.ts +7 -0
  285. package/dist/wallet/tx/targets.js +122 -0
  286. package/dist/wallet/types.d.ts +249 -0
  287. package/dist/wallet/types.js +1 -0
  288. package/dist/writing_quotes.json +1654 -0
  289. package/package.json +78 -0
@@ -0,0 +1,90 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { ART_HEIGHT, ART_WIDTH, FOLLOW_CAR_HEIGHT, FOLLOW_CAR_WIDTH, TRAIN_SPRITE_HEIGHT, TRAIN_SPRITE_WIDTH, } from "./constants.js";
3
+ const ART_TEMPLATE_CACHE = {};
4
+ const SPRITE_CACHE = {};
5
+ let FOLLOW_CAR_TEMPLATE_CACHE = null;
6
+ function normalizeArtTemplate(raw, name) {
7
+ const lines = raw.replaceAll("\r\n", "\n").split("\n");
8
+ if (lines[lines.length - 1] === "") {
9
+ lines.pop();
10
+ }
11
+ if (lines.length !== ART_HEIGHT) {
12
+ throw new Error(`art_template_height_invalid_${name}_${lines.length}`);
13
+ }
14
+ for (const line of lines) {
15
+ if (line.length !== ART_WIDTH) {
16
+ throw new Error(`art_template_width_invalid_${name}_${line.length}`);
17
+ }
18
+ }
19
+ return lines;
20
+ }
21
+ export function loadArtTemplate(name) {
22
+ const cached = ART_TEMPLATE_CACHE[name];
23
+ if (cached !== undefined) {
24
+ return cached;
25
+ }
26
+ const lines = normalizeArtTemplate(readFileSync(new URL(`../../art/${name}.txt`, import.meta.url), "utf8"), name);
27
+ ART_TEMPLATE_CACHE[name] = lines;
28
+ return lines;
29
+ }
30
+ function normalizeSprite(raw, name) {
31
+ const lines = raw.replaceAll("\r\n", "\n").split("\n");
32
+ if (lines[lines.length - 1] === "") {
33
+ lines.pop();
34
+ }
35
+ if (lines.length !== TRAIN_SPRITE_HEIGHT) {
36
+ throw new Error(`sprite_height_invalid_${name}_${lines.length}`);
37
+ }
38
+ return lines.map((line) => {
39
+ if (line.length > TRAIN_SPRITE_WIDTH) {
40
+ throw new Error(`sprite_width_invalid_${name}_${line.length}`);
41
+ }
42
+ return line.padEnd(TRAIN_SPRITE_WIDTH, " ");
43
+ });
44
+ }
45
+ export function loadSprite(name) {
46
+ const cached = SPRITE_CACHE[name];
47
+ if (cached !== undefined) {
48
+ return cached;
49
+ }
50
+ const lines = normalizeSprite(readFileSync(new URL(`../../art/${name}.txt`, import.meta.url), "utf8"), name);
51
+ SPRITE_CACHE[name] = lines;
52
+ return lines;
53
+ }
54
+ function normalizeFollowCarTemplate(raw) {
55
+ const lines = raw.replaceAll("\r\n", "\n").split("\n");
56
+ if (lines[lines.length - 1] === "") {
57
+ lines.pop();
58
+ }
59
+ if (lines.length !== FOLLOW_CAR_HEIGHT) {
60
+ throw new Error(`sprite_height_invalid_train-car_${lines.length}`);
61
+ }
62
+ return lines.map((line) => {
63
+ if (line.length > FOLLOW_CAR_WIDTH) {
64
+ throw new Error(`sprite_width_invalid_train-car_${line.length}`);
65
+ }
66
+ return line.padEnd(FOLLOW_CAR_WIDTH, " ");
67
+ });
68
+ }
69
+ export function loadFollowCarTemplate() {
70
+ if (FOLLOW_CAR_TEMPLATE_CACHE !== null) {
71
+ return FOLLOW_CAR_TEMPLATE_CACHE;
72
+ }
73
+ FOLLOW_CAR_TEMPLATE_CACHE = normalizeFollowCarTemplate(readFileSync(new URL("../../art/train-car.txt", import.meta.url), "utf8"));
74
+ return FOLLOW_CAR_TEMPLATE_CACHE;
75
+ }
76
+ export function loadBannerArtForTesting() {
77
+ return [...loadArtTemplate("banner")];
78
+ }
79
+ export function loadScrollArtForTesting() {
80
+ return [...loadArtTemplate("scroll")];
81
+ }
82
+ export function loadTrainSmokeArtForTesting() {
83
+ return [...loadSprite("train-smoke")];
84
+ }
85
+ export function loadTrainArtForTesting() {
86
+ return [...loadSprite("train")];
87
+ }
88
+ export function loadTrainCarArtForTesting() {
89
+ return [...loadFollowCarTemplate()];
90
+ }
@@ -0,0 +1,48 @@
1
+ export declare const PROGRESS_TICK_MS = 250;
2
+ export declare const PREPARING_SYNC_LINE = "Preparing managed Cogcoin sync...";
3
+ export declare const ART_WIDTH = 80;
4
+ export declare const ART_HEIGHT = 13;
5
+ export declare const INTRO_ENTRY_MS = 5000;
6
+ export declare const INTRO_PAUSE_MS = 5000;
7
+ export declare const INTRO_EXIT_MS = 5000;
8
+ export declare const INTRO_TOTAL_MS: number;
9
+ export declare const STATUS_ELLIPSIS_WIDTH = 3;
10
+ export declare const STATUS_ELLIPSIS_TICK_MS = 500;
11
+ export declare const NEUTRAL_MESSAGE_TITLE = "\u26ED C O G C O I N \u26ED";
12
+ export declare const MESSAGE_FIELD_ROW = 1;
13
+ export declare const STATUS_FIELD_ROW = 12;
14
+ export declare const FIELD_LEFT = 8;
15
+ export declare const FIELD_WIDTH = 64;
16
+ export declare const SCROLL_WINDOW_LEFT = 7;
17
+ export declare const SCROLL_WINDOW_TOP = 3;
18
+ export declare const SCROLL_WINDOW_WIDTH = 65;
19
+ export declare const SCROLL_WINDOW_HEIGHT = 8;
20
+ export declare const TRAIN_CLIP_MIN_COLUMN = -1;
21
+ export declare const TRAIN_CLIP_MAX_COLUMN = 65;
22
+ export declare const MAX_QUOTE_LINES = 6;
23
+ export declare const TRAIN_SPRITE_WIDTH = 64;
24
+ export declare const TRAIN_SPRITE_HEIGHT = 6;
25
+ export declare const TRAIN_SPRITE_TOP: number;
26
+ export declare const TRAIN_CENTER_X: number;
27
+ export declare const TRAIN_OFFSCREEN_LEFT_X: number;
28
+ export declare const TRAIN_OFFSCREEN_RIGHT_X: number;
29
+ export declare const FOLLOW_CAR_WIDTH = 9;
30
+ export declare const FOLLOW_CAR_PITCH = 8;
31
+ export declare const FOLLOW_CAR_HEIGHT = 6;
32
+ export declare const FOLLOW_WINDOW_LEFT: number;
33
+ export declare const FOLLOW_WINDOW_WIDTH: number;
34
+ export declare const FOLLOW_CAR_TOP: number;
35
+ export declare const FOLLOW_AGE_ROW: number;
36
+ export declare const FOLLOW_CENTER_SLOT_X: number;
37
+ export declare const FOLLOW_CONNECTION_SLOT_X: number;
38
+ export declare const FOLLOW_PENDING_SLOT_X = 0;
39
+ export declare const FOLLOW_PENDING_OFFSCREEN_LEFT_X: number;
40
+ export declare const FOLLOW_CLIP_MIN_COLUMN = 0;
41
+ export declare const FOLLOW_CLIP_MAX_COLUMN: number;
42
+ export declare const FOLLOW_RIGHT_SLOT_XS: readonly [number, number, number, number];
43
+ export declare const FOLLOW_PENDING_LABEL = "~10 min";
44
+ export declare const FOLLOW_PENDING_ENTER_MS = 1000;
45
+ export declare const FOLLOW_APPROACH_MS = 3000;
46
+ export declare const FOLLOW_FAST_APPROACH_MS = 1000;
47
+ export declare const FOLLOW_SHIFT_MS = 1000;
48
+ export declare const FOLLOW_FAST_SHIFT_MS = 1000;
@@ -0,0 +1,53 @@
1
+ export const PROGRESS_TICK_MS = 250;
2
+ export const PREPARING_SYNC_LINE = "Preparing managed Cogcoin sync...";
3
+ export const ART_WIDTH = 80;
4
+ export const ART_HEIGHT = 13;
5
+ export const INTRO_ENTRY_MS = 5_000;
6
+ export const INTRO_PAUSE_MS = 5_000;
7
+ export const INTRO_EXIT_MS = 5_000;
8
+ export const INTRO_TOTAL_MS = INTRO_ENTRY_MS + INTRO_PAUSE_MS + INTRO_EXIT_MS;
9
+ export const STATUS_ELLIPSIS_WIDTH = 3;
10
+ export const STATUS_ELLIPSIS_TICK_MS = 500;
11
+ export const NEUTRAL_MESSAGE_TITLE = "⛭ C O G C O I N ⛭";
12
+ export const MESSAGE_FIELD_ROW = 1;
13
+ export const STATUS_FIELD_ROW = 12;
14
+ export const FIELD_LEFT = 8;
15
+ export const FIELD_WIDTH = 64;
16
+ export const SCROLL_WINDOW_LEFT = 7;
17
+ export const SCROLL_WINDOW_TOP = 3;
18
+ export const SCROLL_WINDOW_WIDTH = 65;
19
+ export const SCROLL_WINDOW_HEIGHT = 8;
20
+ export const TRAIN_CLIP_MIN_COLUMN = -1;
21
+ export const TRAIN_CLIP_MAX_COLUMN = SCROLL_WINDOW_WIDTH;
22
+ export const MAX_QUOTE_LINES = 6;
23
+ export const TRAIN_SPRITE_WIDTH = 64;
24
+ export const TRAIN_SPRITE_HEIGHT = 6;
25
+ export const TRAIN_SPRITE_TOP = SCROLL_WINDOW_TOP + Math.floor((SCROLL_WINDOW_HEIGHT - TRAIN_SPRITE_HEIGHT) / 2);
26
+ export const TRAIN_CENTER_X = Math.round((SCROLL_WINDOW_WIDTH - TRAIN_SPRITE_WIDTH) / 2);
27
+ export const TRAIN_OFFSCREEN_LEFT_X = -TRAIN_SPRITE_WIDTH - 1;
28
+ export const TRAIN_OFFSCREEN_RIGHT_X = SCROLL_WINDOW_WIDTH + 1;
29
+ export const FOLLOW_CAR_WIDTH = 9;
30
+ export const FOLLOW_CAR_PITCH = 8;
31
+ export const FOLLOW_CAR_HEIGHT = 6;
32
+ export const FOLLOW_WINDOW_LEFT = SCROLL_WINDOW_LEFT - 1;
33
+ export const FOLLOW_WINDOW_WIDTH = SCROLL_WINDOW_WIDTH + 3;
34
+ export const FOLLOW_CAR_TOP = SCROLL_WINDOW_TOP + Math.floor((SCROLL_WINDOW_HEIGHT - FOLLOW_CAR_HEIGHT) / 2) - 2;
35
+ export const FOLLOW_AGE_ROW = FOLLOW_CAR_TOP + FOLLOW_CAR_HEIGHT;
36
+ export const FOLLOW_CENTER_SLOT_X = Math.floor((FOLLOW_WINDOW_WIDTH - FOLLOW_CAR_WIDTH) / 2);
37
+ export const FOLLOW_CONNECTION_SLOT_X = FOLLOW_CENTER_SLOT_X - FOLLOW_CAR_PITCH;
38
+ export const FOLLOW_PENDING_SLOT_X = 0;
39
+ export const FOLLOW_PENDING_OFFSCREEN_LEFT_X = -FOLLOW_CAR_WIDTH;
40
+ export const FOLLOW_CLIP_MIN_COLUMN = 0;
41
+ export const FOLLOW_CLIP_MAX_COLUMN = FOLLOW_WINDOW_WIDTH - 1;
42
+ export const FOLLOW_RIGHT_SLOT_XS = [
43
+ FOLLOW_CENTER_SLOT_X + FOLLOW_CAR_PITCH,
44
+ FOLLOW_CENTER_SLOT_X + (FOLLOW_CAR_PITCH * 2),
45
+ FOLLOW_CENTER_SLOT_X + (FOLLOW_CAR_PITCH * 3),
46
+ FOLLOW_CENTER_SLOT_X + (FOLLOW_CAR_PITCH * 4),
47
+ ];
48
+ export const FOLLOW_PENDING_LABEL = "~10 min";
49
+ export const FOLLOW_PENDING_ENTER_MS = 1_000;
50
+ export const FOLLOW_APPROACH_MS = 3_000;
51
+ export const FOLLOW_FAST_APPROACH_MS = 1_000;
52
+ export const FOLLOW_SHIFT_MS = 1_000;
53
+ export const FOLLOW_FAST_SHIFT_MS = 1_000;
@@ -0,0 +1,28 @@
1
+ import type { BootstrapPhase, BootstrapProgress, ManagedBitcoindProgressEvent, ProgressOutputMode, SnapshotMetadata, WritingQuote } from "../types.js";
2
+ interface ProgressControllerOptions {
3
+ onProgress?: (event: ManagedBitcoindProgressEvent) => void;
4
+ progressOutput?: ProgressOutputMode;
5
+ quoteStatePath: string;
6
+ snapshot: SnapshotMetadata;
7
+ }
8
+ export declare class ManagedProgressController {
9
+ #private;
10
+ constructor(options: ProgressControllerOptions);
11
+ start(): Promise<void>;
12
+ close(): Promise<void>;
13
+ enableFollowVisualMode(indexedHeight?: number | null, blockTimesByHeight?: Record<number, number>): Promise<void>;
14
+ setFollowBlockTime(height: number, blockTime: number): void;
15
+ replaceFollowBlockTimes(blockTimesByHeight: Record<number, number>): void;
16
+ playCompletionScene(): Promise<void>;
17
+ setPhase(phase: BootstrapPhase, patch?: Partial<Omit<BootstrapProgress, "phase" | "updatedAt">>): Promise<void>;
18
+ setCogcoinSync(height: number | null, targetHeight: number | null, etaSeconds?: number | null): Promise<void>;
19
+ getStatusSnapshot(): {
20
+ bootstrapPhase: BootstrapPhase;
21
+ bootstrapProgress: BootstrapProgress;
22
+ cogcoinSyncHeight: number | null;
23
+ cogcoinSyncTargetHeight: number | null;
24
+ currentQuote: WritingQuote | null;
25
+ snapshot: SnapshotMetadata;
26
+ };
27
+ }
28
+ export {};
@@ -0,0 +1,188 @@
1
+ import { WritingQuoteRotator as QuoteRotator } from "../quotes.js";
2
+ import { INTRO_TOTAL_MS, PROGRESS_TICK_MS } from "./constants.js";
3
+ import { advanceFollowSceneState, createFollowSceneState, replaceFollowBlockTimes, setFollowBlockTime, syncFollowSceneState, } from "./follow-scene.js";
4
+ import { createBootstrapProgress, createDefaultMessage, resolveStatusFieldText, } from "./formatting.js";
5
+ import { TtyProgressRenderer } from "./tty-renderer.js";
6
+ export class ManagedProgressController {
7
+ #options;
8
+ #snapshot;
9
+ #outputMode;
10
+ #quoteRotator = null;
11
+ #renderer = null;
12
+ #ticker = null;
13
+ #currentQuote = null;
14
+ #currentDisplayPhase = "banner";
15
+ #currentDisplayStartedAt = 0;
16
+ #cogcoinSyncHeight = null;
17
+ #cogcoinSyncTargetHeight = null;
18
+ #progress;
19
+ #started = false;
20
+ #followVisualMode = false;
21
+ #followScene = createFollowSceneState();
22
+ constructor(options) {
23
+ this.#options = options;
24
+ this.#snapshot = options.snapshot;
25
+ this.#outputMode = options.progressOutput ?? "auto";
26
+ this.#progress = createBootstrapProgress("paused", options.snapshot);
27
+ }
28
+ async start() {
29
+ if (this.#started) {
30
+ return;
31
+ }
32
+ this.#started = true;
33
+ this.#quoteRotator = await QuoteRotator.create(this.#options.quoteStatePath);
34
+ if (this.#shouldRenderToTty()) {
35
+ this.#renderer = new TtyProgressRenderer();
36
+ }
37
+ await this.#refresh();
38
+ this.#ticker = setInterval(() => {
39
+ void this.#refresh();
40
+ }, PROGRESS_TICK_MS);
41
+ }
42
+ async close() {
43
+ if (this.#ticker !== null) {
44
+ clearInterval(this.#ticker);
45
+ this.#ticker = null;
46
+ }
47
+ this.#renderer?.close();
48
+ this.#renderer = null;
49
+ this.#started = false;
50
+ }
51
+ async enableFollowVisualMode(indexedHeight = null, blockTimesByHeight = {}) {
52
+ this.#followVisualMode = true;
53
+ this.#followScene = createFollowSceneState(indexedHeight, blockTimesByHeight);
54
+ this.#currentQuote = null;
55
+ if (this.#started) {
56
+ await this.#refresh();
57
+ }
58
+ }
59
+ setFollowBlockTime(height, blockTime) {
60
+ if (!this.#followVisualMode) {
61
+ return;
62
+ }
63
+ setFollowBlockTime(this.#followScene, height, blockTime);
64
+ }
65
+ replaceFollowBlockTimes(blockTimesByHeight) {
66
+ if (!this.#followVisualMode) {
67
+ return;
68
+ }
69
+ replaceFollowBlockTimes(this.#followScene, blockTimesByHeight);
70
+ }
71
+ async playCompletionScene() {
72
+ if (!this.#started || this.#renderer === null) {
73
+ return;
74
+ }
75
+ if (this.#ticker !== null) {
76
+ clearInterval(this.#ticker);
77
+ this.#ticker = null;
78
+ }
79
+ const startedAt = Date.now();
80
+ while (true) {
81
+ const elapsedMs = Math.min(INTRO_TOTAL_MS, Date.now() - startedAt);
82
+ this.#renderer.renderTrainScene("completion", this.#progress, this.#cogcoinSyncHeight, this.#cogcoinSyncTargetHeight, elapsedMs);
83
+ if (elapsedMs >= INTRO_TOTAL_MS) {
84
+ break;
85
+ }
86
+ await new Promise((resolve) => {
87
+ setTimeout(resolve, PROGRESS_TICK_MS);
88
+ });
89
+ }
90
+ }
91
+ async setPhase(phase, patch = {}) {
92
+ this.#progress = {
93
+ ...this.#progress,
94
+ ...patch,
95
+ phase,
96
+ message: patch.message ?? createDefaultMessage(phase),
97
+ updatedAt: Date.now(),
98
+ };
99
+ if (phase !== "cogcoin_sync" && phase !== "follow_tip") {
100
+ this.#cogcoinSyncHeight = null;
101
+ this.#cogcoinSyncTargetHeight = null;
102
+ }
103
+ if (this.#followVisualMode) {
104
+ syncFollowSceneState(this.#followScene, {
105
+ indexedHeight: phase === "follow_tip" ? this.#cogcoinSyncHeight : undefined,
106
+ nodeHeight: this.#progress.blocks,
107
+ liveActivated: phase === "follow_tip" || this.#followScene.liveActivated,
108
+ });
109
+ }
110
+ await this.#refresh();
111
+ }
112
+ async setCogcoinSync(height, targetHeight, etaSeconds = null) {
113
+ this.#cogcoinSyncHeight = height;
114
+ this.#cogcoinSyncTargetHeight = targetHeight;
115
+ this.#progress = {
116
+ ...this.#progress,
117
+ phase: "cogcoin_sync",
118
+ message: createDefaultMessage("cogcoin_sync"),
119
+ etaSeconds,
120
+ updatedAt: Date.now(),
121
+ };
122
+ if (this.#followVisualMode) {
123
+ syncFollowSceneState(this.#followScene, {
124
+ indexedHeight: height,
125
+ nodeHeight: targetHeight,
126
+ liveActivated: this.#followScene.liveActivated,
127
+ });
128
+ }
129
+ await this.#refresh();
130
+ }
131
+ getStatusSnapshot() {
132
+ return {
133
+ bootstrapPhase: this.#progress.phase,
134
+ bootstrapProgress: { ...this.#progress },
135
+ cogcoinSyncHeight: this.#cogcoinSyncHeight,
136
+ cogcoinSyncTargetHeight: this.#cogcoinSyncTargetHeight,
137
+ currentQuote: this.#currentQuote,
138
+ snapshot: this.#snapshot,
139
+ };
140
+ }
141
+ async #refresh() {
142
+ if (!this.#started || this.#quoteRotator === null) {
143
+ return;
144
+ }
145
+ const now = Date.now();
146
+ if (this.#followVisualMode) {
147
+ advanceFollowSceneState(this.#followScene, now);
148
+ this.#currentQuote = null;
149
+ }
150
+ else {
151
+ const snapshot = await this.#quoteRotator.current(now);
152
+ this.#currentDisplayPhase = snapshot.displayPhase;
153
+ this.#currentDisplayStartedAt = snapshot.displayStartedAt;
154
+ this.#currentQuote = snapshot.displayPhase === "scroll"
155
+ ? snapshot.currentQuote
156
+ : null;
157
+ }
158
+ const event = {
159
+ phase: this.#progress.phase,
160
+ progress: { ...this.#progress },
161
+ snapshot: this.#snapshot,
162
+ currentQuote: this.#currentQuote,
163
+ cogcoinSyncHeight: this.#cogcoinSyncHeight,
164
+ cogcoinSyncTargetHeight: this.#cogcoinSyncTargetHeight,
165
+ };
166
+ try {
167
+ this.#options.onProgress?.(event);
168
+ }
169
+ catch {
170
+ // User progress callbacks should never break managed sync.
171
+ }
172
+ const statusFieldText = resolveStatusFieldText(this.#progress, this.#snapshot.height, now);
173
+ if (this.#followVisualMode) {
174
+ this.#renderer?.renderFollowScene(this.#progress, this.#cogcoinSyncHeight, this.#cogcoinSyncTargetHeight, this.#followScene, statusFieldText);
175
+ return;
176
+ }
177
+ this.#renderer?.render(this.#currentDisplayPhase, this.#currentQuote, this.#progress, this.#cogcoinSyncHeight, this.#cogcoinSyncTargetHeight, Math.max(0, now - this.#currentDisplayStartedAt), statusFieldText);
178
+ }
179
+ #shouldRenderToTty() {
180
+ if (this.#outputMode === "none") {
181
+ return false;
182
+ }
183
+ if (this.#outputMode === "tty") {
184
+ return true;
185
+ }
186
+ return process.stderr.isTTY === true;
187
+ }
188
+ }
@@ -0,0 +1,40 @@
1
+ export type FollowAnimationKind = "placeholder_enter" | "tip_approach" | "convoy_shift";
2
+ export interface FollowAnimation {
3
+ kind: FollowAnimationKind;
4
+ startedAt: number;
5
+ height: number | null;
6
+ durationMs: number;
7
+ }
8
+ export interface FollowSceneStateForTesting {
9
+ liveActivated: boolean;
10
+ indexedHeight: number | null;
11
+ displayedCenterHeight: number | null;
12
+ observedNodeHeight: number | null;
13
+ blockTimesByHeight: Record<number, number>;
14
+ queuedHeights: number[];
15
+ pendingLabel: string | null;
16
+ pendingStaticX: number | null;
17
+ animation: FollowAnimation | null;
18
+ }
19
+ export declare function createFollowSceneState(indexedHeight?: number | null, blockTimesByHeight?: Record<number, number>): FollowSceneStateForTesting;
20
+ export declare function setFollowBlockTime(state: FollowSceneStateForTesting, height: number, blockTime: number): void;
21
+ export declare function replaceFollowBlockTimes(state: FollowSceneStateForTesting, blockTimesByHeight: Record<number, number>): void;
22
+ export declare function formatCompactFollowAgeLabel(blockTime: number, now: number): string;
23
+ export declare const formatCompactFollowAgeLabelForTesting: typeof formatCompactFollowAgeLabel;
24
+ export declare function syncFollowSceneState(state: FollowSceneStateForTesting, { indexedHeight, nodeHeight, liveActivated, }: {
25
+ indexedHeight?: number | null;
26
+ nodeHeight?: number | null;
27
+ liveActivated?: boolean;
28
+ }): void;
29
+ export declare function advanceFollowSceneState(state: FollowSceneStateForTesting, now: number): void;
30
+ export declare function renderFollowFrame(state: FollowSceneStateForTesting, statusFieldText: string, now: number): string[];
31
+ export declare function createFollowSceneStateForTesting(indexedHeight?: number | null, blockTimesByHeight?: Record<number, number>): FollowSceneStateForTesting;
32
+ export declare function setFollowBlockTimesForTesting(state: FollowSceneStateForTesting, blockTimesByHeight: Record<number, number>): FollowSceneStateForTesting;
33
+ export declare function setFollowBlockTimeForTesting(state: FollowSceneStateForTesting, height: number, blockTime: number): FollowSceneStateForTesting;
34
+ export declare function syncFollowSceneStateForTesting(state: FollowSceneStateForTesting, options: {
35
+ indexedHeight?: number | null;
36
+ nodeHeight?: number | null;
37
+ liveActivated?: boolean;
38
+ }): FollowSceneStateForTesting;
39
+ export declare function advanceFollowSceneStateForTesting(state: FollowSceneStateForTesting, now: number): FollowSceneStateForTesting;
40
+ export declare function renderFollowFrameForTesting(state: FollowSceneStateForTesting, statusFieldText?: string, now?: number): string[];