@brozarti/spincome 0.1.3 → 0.1.5
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/dist/animate.js +44 -0
- package/dist/display.js +3 -2
- package/dist/hook.js +3 -2
- package/package.json +1 -1
- package/src/animate.ts +49 -0
- package/src/display.ts +3 -2
- package/src/hook.ts +7 -3
package/dist/animate.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.animateWhileLoading = animateWhileLoading;
|
|
4
|
+
const HIDE_CURSOR = "\x1b[?25l";
|
|
5
|
+
const SHOW_CURSOR = "\x1b[?25h";
|
|
6
|
+
const CLEAR_LINE = "\x1b[2K\r";
|
|
7
|
+
const UP_ONE = "\x1b[1A";
|
|
8
|
+
const GREEN = "\x1b[32m";
|
|
9
|
+
const BRIGHT_GREEN = "\x1b[92m";
|
|
10
|
+
const DIM = "\x1b[2m";
|
|
11
|
+
const BOLD = "\x1b[1m";
|
|
12
|
+
const R = "\x1b[0m";
|
|
13
|
+
const SPINNER = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
14
|
+
const COIN = ["◐", "◓", "◑", "◒"];
|
|
15
|
+
const LOGO = `${BOLD}${GREEN}$${R}${BOLD} spincome${R}`;
|
|
16
|
+
async function animateWhileLoading(work) {
|
|
17
|
+
process.stderr.write(HIDE_CURSOR);
|
|
18
|
+
let frame = 0;
|
|
19
|
+
let dots = 0;
|
|
20
|
+
let done = false;
|
|
21
|
+
let result;
|
|
22
|
+
const tick = setInterval(() => {
|
|
23
|
+
if (done)
|
|
24
|
+
return;
|
|
25
|
+
const spinner = BRIGHT_GREEN + SPINNER[frame % SPINNER.length] + R;
|
|
26
|
+
const coin = GREEN + COIN[frame % COIN.length] + R;
|
|
27
|
+
dots = (dots + 1) % 4;
|
|
28
|
+
const dotStr = DIM + ".".repeat(dots).padEnd(3) + R;
|
|
29
|
+
process.stderr.write(CLEAR_LINE +
|
|
30
|
+
` ${spinner} ${LOGO} ${coin} ${DIM}earning${R}${dotStr}`);
|
|
31
|
+
frame++;
|
|
32
|
+
}, 80);
|
|
33
|
+
try {
|
|
34
|
+
result = await work;
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
done = true;
|
|
38
|
+
clearInterval(tick);
|
|
39
|
+
process.stderr.write(CLEAR_LINE);
|
|
40
|
+
process.stderr.write(UP_ONE + CLEAR_LINE);
|
|
41
|
+
process.stderr.write(SHOW_CURSOR);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
package/dist/display.js
CHANGED
|
@@ -22,8 +22,9 @@ function ruler() {
|
|
|
22
22
|
return `${DIM}${"─".repeat(W)}${R}`;
|
|
23
23
|
}
|
|
24
24
|
function renderAd(ad, earnedCents, sessionCents, context) {
|
|
25
|
-
|
|
26
|
-
const
|
|
25
|
+
// earnedCents and sessionCents are stored in milli-cents (1 unit = $0.00001)
|
|
26
|
+
const earnedDollars = (earnedCents / 100000).toFixed(4);
|
|
27
|
+
const sessionDollars = (sessionCents / 100000).toFixed(4);
|
|
27
28
|
const contextTag = context?.fileExt
|
|
28
29
|
? ` · ${context.fileExt.toUpperCase()} dev`
|
|
29
30
|
: context?.toolName
|
package/dist/hook.js
CHANGED
|
@@ -8,6 +8,7 @@ const ad_js_1 = require("./ad.js");
|
|
|
8
8
|
const display_js_1 = require("./display.js");
|
|
9
9
|
const config_js_1 = require("./config.js");
|
|
10
10
|
const session_js_1 = require("./session.js");
|
|
11
|
+
const animate_js_1 = require("./animate.js");
|
|
11
12
|
const path_1 = __importDefault(require("path"));
|
|
12
13
|
function extractContext(payload) {
|
|
13
14
|
const toolName = payload.tool_name ?? undefined;
|
|
@@ -34,11 +35,11 @@ async function main() {
|
|
|
34
35
|
// empty or malformed stdin
|
|
35
36
|
}
|
|
36
37
|
const context = extractContext(payload);
|
|
38
|
+
// Fetch ad and record impression concurrently, animate while waiting
|
|
37
39
|
const ad = await (0, ad_js_1.fetchAd)(context);
|
|
38
40
|
if (!ad)
|
|
39
41
|
process.exit(0);
|
|
40
|
-
|
|
41
|
-
const earnedCents = await (0, ad_js_1.recordImpression)(ad.id, config.developerKey, ad.actualCpmCents, context);
|
|
42
|
+
const earnedCents = await (0, animate_js_1.animateWhileLoading)((0, ad_js_1.recordImpression)(ad.id, config.developerKey, ad.actualCpmCents, context));
|
|
42
43
|
const session = (0, session_js_1.addToSession)(earnedCents);
|
|
43
44
|
process.stdout.write((0, display_js_1.renderAd)(ad, earnedCents, session.totalCents, context));
|
|
44
45
|
}
|
package/package.json
CHANGED
package/src/animate.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const HIDE_CURSOR = "\x1b[?25l";
|
|
2
|
+
const SHOW_CURSOR = "\x1b[?25h";
|
|
3
|
+
const CLEAR_LINE = "\x1b[2K\r";
|
|
4
|
+
const UP_ONE = "\x1b[1A";
|
|
5
|
+
|
|
6
|
+
const GREEN = "\x1b[32m";
|
|
7
|
+
const BRIGHT_GREEN = "\x1b[92m";
|
|
8
|
+
const DIM = "\x1b[2m";
|
|
9
|
+
const BOLD = "\x1b[1m";
|
|
10
|
+
const R = "\x1b[0m";
|
|
11
|
+
|
|
12
|
+
const SPINNER = ["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];
|
|
13
|
+
const COIN = ["◐","◓","◑","◒"];
|
|
14
|
+
|
|
15
|
+
const LOGO = `${BOLD}${GREEN}$${R}${BOLD} spincome${R}`;
|
|
16
|
+
|
|
17
|
+
export async function animateWhileLoading<T>(work: Promise<T>): Promise<T> {
|
|
18
|
+
process.stderr.write(HIDE_CURSOR);
|
|
19
|
+
|
|
20
|
+
let frame = 0;
|
|
21
|
+
let dots = 0;
|
|
22
|
+
let done = false;
|
|
23
|
+
let result: T;
|
|
24
|
+
|
|
25
|
+
const tick = setInterval(() => {
|
|
26
|
+
if (done) return;
|
|
27
|
+
const spinner = BRIGHT_GREEN + SPINNER[frame % SPINNER.length] + R;
|
|
28
|
+
const coin = GREEN + COIN[frame % COIN.length] + R;
|
|
29
|
+
dots = (dots + 1) % 4;
|
|
30
|
+
const dotStr = DIM + ".".repeat(dots).padEnd(3) + R;
|
|
31
|
+
process.stderr.write(
|
|
32
|
+
CLEAR_LINE +
|
|
33
|
+
` ${spinner} ${LOGO} ${coin} ${DIM}earning${R}${dotStr}`
|
|
34
|
+
);
|
|
35
|
+
frame++;
|
|
36
|
+
}, 80);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
result = await work;
|
|
40
|
+
} finally {
|
|
41
|
+
done = true;
|
|
42
|
+
clearInterval(tick);
|
|
43
|
+
process.stderr.write(CLEAR_LINE);
|
|
44
|
+
process.stderr.write(UP_ONE + CLEAR_LINE);
|
|
45
|
+
process.stderr.write(SHOW_CURSOR);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return result!;
|
|
49
|
+
}
|
package/src/display.ts
CHANGED
|
@@ -26,8 +26,9 @@ function ruler(): string {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export function renderAd(ad: Ad, earnedCents: number, sessionCents: number, context?: { toolName?: string; fileExt?: string }): string {
|
|
29
|
-
|
|
30
|
-
const
|
|
29
|
+
// earnedCents and sessionCents are stored in milli-cents (1 unit = $0.00001)
|
|
30
|
+
const earnedDollars = (earnedCents / 100000).toFixed(4);
|
|
31
|
+
const sessionDollars = (sessionCents / 100000).toFixed(4);
|
|
31
32
|
|
|
32
33
|
const contextTag = context?.fileExt
|
|
33
34
|
? ` · ${context.fileExt.toUpperCase()} dev`
|
package/src/hook.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { fetchAd, recordImpression, type AdContext } from "./ad.js";
|
|
|
4
4
|
import { renderAd } from "./display.js";
|
|
5
5
|
import { readConfig } from "./config.js";
|
|
6
6
|
import { addToSession } from "./session.js";
|
|
7
|
+
import { animateWhileLoading } from "./animate.js";
|
|
7
8
|
import path from "path";
|
|
8
9
|
|
|
9
10
|
interface HookPayload {
|
|
@@ -42,13 +43,16 @@ async function main() {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
const context = extractContext(payload);
|
|
46
|
+
|
|
47
|
+
// Fetch ad and record impression concurrently, animate while waiting
|
|
45
48
|
const ad = await fetchAd(context);
|
|
46
49
|
if (!ad) process.exit(0);
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
const earnedCents = await animateWhileLoading(
|
|
52
|
+
recordImpression(ad.id, config.developerKey, ad.actualCpmCents, context)
|
|
53
|
+
);
|
|
51
54
|
|
|
55
|
+
const session = addToSession(earnedCents);
|
|
52
56
|
process.stdout.write(renderAd(ad, earnedCents, session.totalCents, context));
|
|
53
57
|
}
|
|
54
58
|
|