@gscdump/analysis 0.25.6 → 0.25.7
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/analyzer/index.mjs +50 -48
- package/dist/default-registry.mjs +44 -42
- package/dist/index.mjs +44 -42
- package/package.json +4 -4
package/dist/analyzer/index.mjs
CHANGED
|
@@ -2388,6 +2388,34 @@ const dataQueryAnalyzer = defineAnalyzer({
|
|
|
2388
2388
|
};
|
|
2389
2389
|
}
|
|
2390
2390
|
});
|
|
2391
|
+
const DEFAULT_LIMIT = 1e3;
|
|
2392
|
+
const MAX_LIMIT = 5e4;
|
|
2393
|
+
function clampLimit(limit, fallback = DEFAULT_LIMIT) {
|
|
2394
|
+
const n = Number(limit ?? fallback);
|
|
2395
|
+
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
2396
|
+
return Math.min(n, MAX_LIMIT);
|
|
2397
|
+
}
|
|
2398
|
+
function clampOffset(offset) {
|
|
2399
|
+
const n = Number(offset ?? 0);
|
|
2400
|
+
if (!Number.isFinite(n) || n < 0) return 0;
|
|
2401
|
+
return Math.floor(n);
|
|
2402
|
+
}
|
|
2403
|
+
function paginateClause(input) {
|
|
2404
|
+
const l = clampLimit(input.limit);
|
|
2405
|
+
const o = clampOffset(input.offset);
|
|
2406
|
+
return o > 0 ? `LIMIT ${l} OFFSET ${o}` : `LIMIT ${l}`;
|
|
2407
|
+
}
|
|
2408
|
+
function paginateInMemory(rows, input) {
|
|
2409
|
+
const l = clampLimit(input.limit, rows.length);
|
|
2410
|
+
const o = clampOffset(input.offset);
|
|
2411
|
+
return rows.slice(o, o + l);
|
|
2412
|
+
}
|
|
2413
|
+
function resolveSort(input, allowed, defaults) {
|
|
2414
|
+
return {
|
|
2415
|
+
sortBy: input.sortBy && allowed.includes(input.sortBy) ? input.sortBy : defaults.sortBy,
|
|
2416
|
+
sortDir: input.sortDir === "asc" || input.sortDir === "desc" ? input.sortDir : defaults.sortDir
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2391
2419
|
const sortResults$1 = createMetricSorter("lostClicks", {
|
|
2392
2420
|
lostClicks: "desc",
|
|
2393
2421
|
declinePercent: "desc",
|
|
@@ -2441,7 +2469,6 @@ const decayAnalyzer = defineAnalyzer({
|
|
|
2441
2469
|
const { current: cur, previous: prev } = comparisonOf(params);
|
|
2442
2470
|
const minPreviousClicks = params.minPreviousClicks ?? 50;
|
|
2443
2471
|
const threshold = params.threshold ?? .2;
|
|
2444
|
-
const limit = params.limit ?? 2e3;
|
|
2445
2472
|
return {
|
|
2446
2473
|
sql: `
|
|
2447
2474
|
WITH cur AS (
|
|
@@ -2505,7 +2532,7 @@ const decayAnalyzer = defineAnalyzer({
|
|
|
2505
2532
|
FROM joined
|
|
2506
2533
|
WHERE declinePercent >= ? AND lostClicks > 0
|
|
2507
2534
|
ORDER BY lostClicks DESC
|
|
2508
|
-
LIMIT
|
|
2535
|
+
LIMIT 2000
|
|
2509
2536
|
`,
|
|
2510
2537
|
params: [
|
|
2511
2538
|
cur.startDate,
|
|
@@ -2529,25 +2556,28 @@ const decayAnalyzer = defineAnalyzer({
|
|
|
2529
2556
|
}
|
|
2530
2557
|
};
|
|
2531
2558
|
},
|
|
2532
|
-
reduceSql(rows) {
|
|
2533
|
-
const
|
|
2559
|
+
reduceSql(rows, params) {
|
|
2560
|
+
const mapped = (Array.isArray(rows) ? rows : []).map((r) => ({
|
|
2561
|
+
page: str$12(r.page),
|
|
2562
|
+
currentClicks: num(r.currentClicks),
|
|
2563
|
+
previousClicks: num(r.previousClicks),
|
|
2564
|
+
lostClicks: num(r.lostClicks),
|
|
2565
|
+
declinePercent: num(r.declinePercent),
|
|
2566
|
+
currentPosition: num(r.currentPosition),
|
|
2567
|
+
previousPosition: num(r.previousPosition),
|
|
2568
|
+
positionDrop: num(r.positionDrop),
|
|
2569
|
+
series: parseJsonList$8(r.seriesJson).map((s) => ({
|
|
2570
|
+
week: str$12(s.week),
|
|
2571
|
+
clicks: num(s.clicks),
|
|
2572
|
+
impressions: num(s.impressions)
|
|
2573
|
+
}))
|
|
2574
|
+
}));
|
|
2534
2575
|
return {
|
|
2535
|
-
results:
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
declinePercent: num(r.declinePercent),
|
|
2541
|
-
currentPosition: num(r.currentPosition),
|
|
2542
|
-
previousPosition: num(r.previousPosition),
|
|
2543
|
-
positionDrop: num(r.positionDrop),
|
|
2544
|
-
series: parseJsonList$8(r.seriesJson).map((s) => ({
|
|
2545
|
-
week: str$12(s.week),
|
|
2546
|
-
clicks: num(s.clicks),
|
|
2547
|
-
impressions: num(s.impressions)
|
|
2548
|
-
}))
|
|
2549
|
-
})),
|
|
2550
|
-
meta: { total: arr.length }
|
|
2576
|
+
results: paginateInMemory(mapped, {
|
|
2577
|
+
limit: params.limit ?? 2e3,
|
|
2578
|
+
offset: params.offset
|
|
2579
|
+
}),
|
|
2580
|
+
meta: { total: mapped.length }
|
|
2551
2581
|
};
|
|
2552
2582
|
},
|
|
2553
2583
|
buildRows(params) {
|
|
@@ -3426,34 +3456,6 @@ const moversAnalyzer = defineAnalyzer({
|
|
|
3426
3456
|
})), [], params);
|
|
3427
3457
|
}
|
|
3428
3458
|
});
|
|
3429
|
-
const DEFAULT_LIMIT = 1e3;
|
|
3430
|
-
const MAX_LIMIT = 5e4;
|
|
3431
|
-
function clampLimit(limit, fallback = DEFAULT_LIMIT) {
|
|
3432
|
-
const n = Number(limit ?? fallback);
|
|
3433
|
-
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
3434
|
-
return Math.min(n, MAX_LIMIT);
|
|
3435
|
-
}
|
|
3436
|
-
function clampOffset(offset) {
|
|
3437
|
-
const n = Number(offset ?? 0);
|
|
3438
|
-
if (!Number.isFinite(n) || n < 0) return 0;
|
|
3439
|
-
return Math.floor(n);
|
|
3440
|
-
}
|
|
3441
|
-
function paginateClause(input) {
|
|
3442
|
-
const l = clampLimit(input.limit);
|
|
3443
|
-
const o = clampOffset(input.offset);
|
|
3444
|
-
return o > 0 ? `LIMIT ${l} OFFSET ${o}` : `LIMIT ${l}`;
|
|
3445
|
-
}
|
|
3446
|
-
function paginateInMemory(rows, input) {
|
|
3447
|
-
const l = clampLimit(input.limit, rows.length);
|
|
3448
|
-
const o = clampOffset(input.offset);
|
|
3449
|
-
return rows.slice(o, o + l);
|
|
3450
|
-
}
|
|
3451
|
-
function resolveSort(input, allowed, defaults) {
|
|
3452
|
-
return {
|
|
3453
|
-
sortBy: input.sortBy && allowed.includes(input.sortBy) ? input.sortBy : defaults.sortBy,
|
|
3454
|
-
sortDir: input.sortDir === "asc" || input.sortDir === "desc" ? input.sortDir : defaults.sortDir
|
|
3455
|
-
};
|
|
3456
|
-
}
|
|
3457
3459
|
const EXPECTED_CTR_BY_POSITION = {
|
|
3458
3460
|
1: .3,
|
|
3459
3461
|
2: .15,
|
|
@@ -2388,6 +2388,28 @@ const dataQueryAnalyzer = defineAnalyzer({
|
|
|
2388
2388
|
};
|
|
2389
2389
|
}
|
|
2390
2390
|
});
|
|
2391
|
+
const DEFAULT_LIMIT = 1e3;
|
|
2392
|
+
const MAX_LIMIT = 5e4;
|
|
2393
|
+
function clampLimit(limit, fallback = DEFAULT_LIMIT) {
|
|
2394
|
+
const n = Number(limit ?? fallback);
|
|
2395
|
+
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
2396
|
+
return Math.min(n, MAX_LIMIT);
|
|
2397
|
+
}
|
|
2398
|
+
function clampOffset(offset) {
|
|
2399
|
+
const n = Number(offset ?? 0);
|
|
2400
|
+
if (!Number.isFinite(n) || n < 0) return 0;
|
|
2401
|
+
return Math.floor(n);
|
|
2402
|
+
}
|
|
2403
|
+
function paginateClause(input) {
|
|
2404
|
+
const l = clampLimit(input.limit);
|
|
2405
|
+
const o = clampOffset(input.offset);
|
|
2406
|
+
return o > 0 ? `LIMIT ${l} OFFSET ${o}` : `LIMIT ${l}`;
|
|
2407
|
+
}
|
|
2408
|
+
function paginateInMemory(rows, input) {
|
|
2409
|
+
const l = clampLimit(input.limit, rows.length);
|
|
2410
|
+
const o = clampOffset(input.offset);
|
|
2411
|
+
return rows.slice(o, o + l);
|
|
2412
|
+
}
|
|
2391
2413
|
const sortResults$1 = createMetricSorter("lostClicks", {
|
|
2392
2414
|
lostClicks: "desc",
|
|
2393
2415
|
declinePercent: "desc",
|
|
@@ -2441,7 +2463,6 @@ const decayAnalyzer = defineAnalyzer({
|
|
|
2441
2463
|
const { current: cur, previous: prev } = comparisonOf(params);
|
|
2442
2464
|
const minPreviousClicks = params.minPreviousClicks ?? 50;
|
|
2443
2465
|
const threshold = params.threshold ?? .2;
|
|
2444
|
-
const limit = params.limit ?? 2e3;
|
|
2445
2466
|
return {
|
|
2446
2467
|
sql: `
|
|
2447
2468
|
WITH cur AS (
|
|
@@ -2505,7 +2526,7 @@ const decayAnalyzer = defineAnalyzer({
|
|
|
2505
2526
|
FROM joined
|
|
2506
2527
|
WHERE declinePercent >= ? AND lostClicks > 0
|
|
2507
2528
|
ORDER BY lostClicks DESC
|
|
2508
|
-
LIMIT
|
|
2529
|
+
LIMIT 2000
|
|
2509
2530
|
`,
|
|
2510
2531
|
params: [
|
|
2511
2532
|
cur.startDate,
|
|
@@ -2529,25 +2550,28 @@ const decayAnalyzer = defineAnalyzer({
|
|
|
2529
2550
|
}
|
|
2530
2551
|
};
|
|
2531
2552
|
},
|
|
2532
|
-
reduceSql(rows) {
|
|
2533
|
-
const
|
|
2553
|
+
reduceSql(rows, params) {
|
|
2554
|
+
const mapped = (Array.isArray(rows) ? rows : []).map((r) => ({
|
|
2555
|
+
page: str$12(r.page),
|
|
2556
|
+
currentClicks: num(r.currentClicks),
|
|
2557
|
+
previousClicks: num(r.previousClicks),
|
|
2558
|
+
lostClicks: num(r.lostClicks),
|
|
2559
|
+
declinePercent: num(r.declinePercent),
|
|
2560
|
+
currentPosition: num(r.currentPosition),
|
|
2561
|
+
previousPosition: num(r.previousPosition),
|
|
2562
|
+
positionDrop: num(r.positionDrop),
|
|
2563
|
+
series: parseJsonList$8(r.seriesJson).map((s) => ({
|
|
2564
|
+
week: str$12(s.week),
|
|
2565
|
+
clicks: num(s.clicks),
|
|
2566
|
+
impressions: num(s.impressions)
|
|
2567
|
+
}))
|
|
2568
|
+
}));
|
|
2534
2569
|
return {
|
|
2535
|
-
results:
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
declinePercent: num(r.declinePercent),
|
|
2541
|
-
currentPosition: num(r.currentPosition),
|
|
2542
|
-
previousPosition: num(r.previousPosition),
|
|
2543
|
-
positionDrop: num(r.positionDrop),
|
|
2544
|
-
series: parseJsonList$8(r.seriesJson).map((s) => ({
|
|
2545
|
-
week: str$12(s.week),
|
|
2546
|
-
clicks: num(s.clicks),
|
|
2547
|
-
impressions: num(s.impressions)
|
|
2548
|
-
}))
|
|
2549
|
-
})),
|
|
2550
|
-
meta: { total: arr.length }
|
|
2570
|
+
results: paginateInMemory(mapped, {
|
|
2571
|
+
limit: params.limit ?? 2e3,
|
|
2572
|
+
offset: params.offset
|
|
2573
|
+
}),
|
|
2574
|
+
meta: { total: mapped.length }
|
|
2551
2575
|
};
|
|
2552
2576
|
},
|
|
2553
2577
|
buildRows(params) {
|
|
@@ -3426,28 +3450,6 @@ const moversAnalyzer = defineAnalyzer({
|
|
|
3426
3450
|
})), [], params);
|
|
3427
3451
|
}
|
|
3428
3452
|
});
|
|
3429
|
-
const DEFAULT_LIMIT = 1e3;
|
|
3430
|
-
const MAX_LIMIT = 5e4;
|
|
3431
|
-
function clampLimit(limit, fallback = DEFAULT_LIMIT) {
|
|
3432
|
-
const n = Number(limit ?? fallback);
|
|
3433
|
-
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
3434
|
-
return Math.min(n, MAX_LIMIT);
|
|
3435
|
-
}
|
|
3436
|
-
function clampOffset(offset) {
|
|
3437
|
-
const n = Number(offset ?? 0);
|
|
3438
|
-
if (!Number.isFinite(n) || n < 0) return 0;
|
|
3439
|
-
return Math.floor(n);
|
|
3440
|
-
}
|
|
3441
|
-
function paginateClause(input) {
|
|
3442
|
-
const l = clampLimit(input.limit);
|
|
3443
|
-
const o = clampOffset(input.offset);
|
|
3444
|
-
return o > 0 ? `LIMIT ${l} OFFSET ${o}` : `LIMIT ${l}`;
|
|
3445
|
-
}
|
|
3446
|
-
function paginateInMemory(rows, input) {
|
|
3447
|
-
const l = clampLimit(input.limit, rows.length);
|
|
3448
|
-
const o = clampOffset(input.offset);
|
|
3449
|
-
return rows.slice(o, o + l);
|
|
3450
|
-
}
|
|
3451
3453
|
const EXPECTED_CTR_BY_POSITION = {
|
|
3452
3454
|
1: .3,
|
|
3453
3455
|
2: .15,
|
package/dist/index.mjs
CHANGED
|
@@ -2754,6 +2754,28 @@ const dataQueryAnalyzer = defineAnalyzer$1({
|
|
|
2754
2754
|
};
|
|
2755
2755
|
}
|
|
2756
2756
|
});
|
|
2757
|
+
const DEFAULT_LIMIT$1 = 1e3;
|
|
2758
|
+
const MAX_LIMIT = 5e4;
|
|
2759
|
+
function clampLimit(limit, fallback = DEFAULT_LIMIT$1) {
|
|
2760
|
+
const n = Number(limit ?? fallback);
|
|
2761
|
+
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
2762
|
+
return Math.min(n, MAX_LIMIT);
|
|
2763
|
+
}
|
|
2764
|
+
function clampOffset(offset) {
|
|
2765
|
+
const n = Number(offset ?? 0);
|
|
2766
|
+
if (!Number.isFinite(n) || n < 0) return 0;
|
|
2767
|
+
return Math.floor(n);
|
|
2768
|
+
}
|
|
2769
|
+
function paginateClause(input) {
|
|
2770
|
+
const l = clampLimit(input.limit);
|
|
2771
|
+
const o = clampOffset(input.offset);
|
|
2772
|
+
return o > 0 ? `LIMIT ${l} OFFSET ${o}` : `LIMIT ${l}`;
|
|
2773
|
+
}
|
|
2774
|
+
function paginateInMemory(rows, input) {
|
|
2775
|
+
const l = clampLimit(input.limit, rows.length);
|
|
2776
|
+
const o = clampOffset(input.offset);
|
|
2777
|
+
return rows.slice(o, o + l);
|
|
2778
|
+
}
|
|
2757
2779
|
const sortResults$1 = createMetricSorter("lostClicks", {
|
|
2758
2780
|
lostClicks: "desc",
|
|
2759
2781
|
declinePercent: "desc",
|
|
@@ -2807,7 +2829,6 @@ const decayAnalyzer = defineAnalyzer$1({
|
|
|
2807
2829
|
const { current: cur, previous: prev } = comparisonOf$1(params);
|
|
2808
2830
|
const minPreviousClicks = params.minPreviousClicks ?? 50;
|
|
2809
2831
|
const threshold = params.threshold ?? .2;
|
|
2810
|
-
const limit = params.limit ?? 2e3;
|
|
2811
2832
|
return {
|
|
2812
2833
|
sql: `
|
|
2813
2834
|
WITH cur AS (
|
|
@@ -2871,7 +2892,7 @@ const decayAnalyzer = defineAnalyzer$1({
|
|
|
2871
2892
|
FROM joined
|
|
2872
2893
|
WHERE declinePercent >= ? AND lostClicks > 0
|
|
2873
2894
|
ORDER BY lostClicks DESC
|
|
2874
|
-
LIMIT
|
|
2895
|
+
LIMIT 2000
|
|
2875
2896
|
`,
|
|
2876
2897
|
params: [
|
|
2877
2898
|
cur.startDate,
|
|
@@ -2895,25 +2916,28 @@ const decayAnalyzer = defineAnalyzer$1({
|
|
|
2895
2916
|
}
|
|
2896
2917
|
};
|
|
2897
2918
|
},
|
|
2898
|
-
reduceSql(rows) {
|
|
2899
|
-
const
|
|
2919
|
+
reduceSql(rows, params) {
|
|
2920
|
+
const mapped = (Array.isArray(rows) ? rows : []).map((r) => ({
|
|
2921
|
+
page: str$12(r.page),
|
|
2922
|
+
currentClicks: num$1(r.currentClicks),
|
|
2923
|
+
previousClicks: num$1(r.previousClicks),
|
|
2924
|
+
lostClicks: num$1(r.lostClicks),
|
|
2925
|
+
declinePercent: num$1(r.declinePercent),
|
|
2926
|
+
currentPosition: num$1(r.currentPosition),
|
|
2927
|
+
previousPosition: num$1(r.previousPosition),
|
|
2928
|
+
positionDrop: num$1(r.positionDrop),
|
|
2929
|
+
series: parseJsonList$8(r.seriesJson).map((s) => ({
|
|
2930
|
+
week: str$12(s.week),
|
|
2931
|
+
clicks: num$1(s.clicks),
|
|
2932
|
+
impressions: num$1(s.impressions)
|
|
2933
|
+
}))
|
|
2934
|
+
}));
|
|
2900
2935
|
return {
|
|
2901
|
-
results:
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
declinePercent: num$1(r.declinePercent),
|
|
2907
|
-
currentPosition: num$1(r.currentPosition),
|
|
2908
|
-
previousPosition: num$1(r.previousPosition),
|
|
2909
|
-
positionDrop: num$1(r.positionDrop),
|
|
2910
|
-
series: parseJsonList$8(r.seriesJson).map((s) => ({
|
|
2911
|
-
week: str$12(s.week),
|
|
2912
|
-
clicks: num$1(s.clicks),
|
|
2913
|
-
impressions: num$1(s.impressions)
|
|
2914
|
-
}))
|
|
2915
|
-
})),
|
|
2916
|
-
meta: { total: arr.length }
|
|
2936
|
+
results: paginateInMemory(mapped, {
|
|
2937
|
+
limit: params.limit ?? 2e3,
|
|
2938
|
+
offset: params.offset
|
|
2939
|
+
}),
|
|
2940
|
+
meta: { total: mapped.length }
|
|
2917
2941
|
};
|
|
2918
2942
|
},
|
|
2919
2943
|
buildRows(params) {
|
|
@@ -3788,28 +3812,6 @@ const moversAnalyzer = defineAnalyzer$1({
|
|
|
3788
3812
|
})), [], params);
|
|
3789
3813
|
}
|
|
3790
3814
|
});
|
|
3791
|
-
const DEFAULT_LIMIT$1 = 1e3;
|
|
3792
|
-
const MAX_LIMIT = 5e4;
|
|
3793
|
-
function clampLimit(limit, fallback = DEFAULT_LIMIT$1) {
|
|
3794
|
-
const n = Number(limit ?? fallback);
|
|
3795
|
-
if (!Number.isFinite(n) || n <= 0) return fallback;
|
|
3796
|
-
return Math.min(n, MAX_LIMIT);
|
|
3797
|
-
}
|
|
3798
|
-
function clampOffset(offset) {
|
|
3799
|
-
const n = Number(offset ?? 0);
|
|
3800
|
-
if (!Number.isFinite(n) || n < 0) return 0;
|
|
3801
|
-
return Math.floor(n);
|
|
3802
|
-
}
|
|
3803
|
-
function paginateClause(input) {
|
|
3804
|
-
const l = clampLimit(input.limit);
|
|
3805
|
-
const o = clampOffset(input.offset);
|
|
3806
|
-
return o > 0 ? `LIMIT ${l} OFFSET ${o}` : `LIMIT ${l}`;
|
|
3807
|
-
}
|
|
3808
|
-
function paginateInMemory(rows, input) {
|
|
3809
|
-
const l = clampLimit(input.limit, rows.length);
|
|
3810
|
-
const o = clampOffset(input.offset);
|
|
3811
|
-
return rows.slice(o, o + l);
|
|
3812
|
-
}
|
|
3813
3815
|
const EXPECTED_CTR_BY_POSITION = {
|
|
3814
3816
|
1: .3,
|
|
3815
3817
|
2: .15,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/analysis",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.25.
|
|
4
|
+
"version": "0.25.7",
|
|
5
5
|
"description": "GSC analyzers — striking-distance, opportunity, movers, decay, brand, clustering, concentration, seasonality. Pure row-based + DuckDB-native.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
72
|
"drizzle-orm": "1.0.0-rc.3",
|
|
73
|
-
"@gscdump/engine": "0.25.
|
|
74
|
-
"@gscdump/engine-gsc-api": "0.25.
|
|
75
|
-
"gscdump": "0.25.
|
|
73
|
+
"@gscdump/engine": "0.25.7",
|
|
74
|
+
"@gscdump/engine-gsc-api": "0.25.7",
|
|
75
|
+
"gscdump": "0.25.7"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"vitest": "^4.1.7"
|