@gscdump/sdk 0.38.2 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +140 -122
- package/dist/v1/index.mjs +34 -16
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -49,6 +49,9 @@ function tablesQuery(tablesOrOptions, options) {
|
|
|
49
49
|
...dateRangeOptionsQuery(source)
|
|
50
50
|
};
|
|
51
51
|
if (tables) query.tables = Array.isArray(tables) ? [...new Set(tables.filter(Boolean))].sort().join(",") : [...new Set(tables.split(",").map((t) => t.trim()).filter(Boolean))].sort().join(",");
|
|
52
|
+
if (source?.maxBytes != null) query.maxBytes = String(Math.max(1, Math.floor(source.maxBytes)));
|
|
53
|
+
if (source?.maxRows != null) query.maxRows = String(Math.max(1, Math.floor(source.maxRows)));
|
|
54
|
+
if (source?.maxFiles != null) query.maxFiles = String(Math.max(1, Math.floor(source.maxFiles)));
|
|
52
55
|
return query;
|
|
53
56
|
}
|
|
54
57
|
function dataQuery(state, options) {
|
|
@@ -1133,19 +1136,26 @@ function coerceRowMetrics(row) {
|
|
|
1133
1136
|
};
|
|
1134
1137
|
}
|
|
1135
1138
|
function summarizeDailyRows(raw) {
|
|
1136
|
-
const daily =
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
sum_position:
|
|
1141
|
-
|
|
1139
|
+
const daily = [];
|
|
1140
|
+
for (let index = 0; index < raw.length; index++) {
|
|
1141
|
+
const row = raw[index];
|
|
1142
|
+
const position = row.position ?? 0;
|
|
1143
|
+
const sumPosition = row.sum_position ?? (position > 0 ? (position - 1) * row.impressions : 0);
|
|
1144
|
+
daily.push({
|
|
1145
|
+
date: row.date,
|
|
1146
|
+
clicks: row.clicks,
|
|
1147
|
+
impressions: row.impressions,
|
|
1148
|
+
sum_position: sumPosition
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
daily.sort((a, b) => a.date.localeCompare(b.date));
|
|
1142
1152
|
let clicks = 0;
|
|
1143
1153
|
let impressions = 0;
|
|
1144
1154
|
let weightedPosition = 0;
|
|
1145
|
-
for (const
|
|
1146
|
-
clicks +=
|
|
1147
|
-
impressions +=
|
|
1148
|
-
weightedPosition +=
|
|
1155
|
+
for (const row of daily) {
|
|
1156
|
+
clicks += row.clicks;
|
|
1157
|
+
impressions += row.impressions;
|
|
1158
|
+
weightedPosition += row.sum_position;
|
|
1149
1159
|
}
|
|
1150
1160
|
return {
|
|
1151
1161
|
daily,
|
|
@@ -1893,120 +1903,123 @@ function totalSitemapErrors(sitemaps) {
|
|
|
1893
1903
|
function signedPct1(value) {
|
|
1894
1904
|
return `${value >= 0 ? "+" : ""}${value.toFixed(1)}%`;
|
|
1895
1905
|
}
|
|
1906
|
+
const SEARCH_CONSOLE_STAGES = {
|
|
1907
|
+
not_connected: {
|
|
1908
|
+
label: "Not connected",
|
|
1909
|
+
severity: "neutral",
|
|
1910
|
+
summary: "Search Console is not connected for this site yet.",
|
|
1911
|
+
primaryAction: "Connect Google Search Console so we can read discovery, indexing, and performance data.",
|
|
1912
|
+
nextStage: "waiting_for_data",
|
|
1913
|
+
sprintFindingTypes: []
|
|
1914
|
+
},
|
|
1915
|
+
waiting_for_data: {
|
|
1916
|
+
label: "Waiting for data",
|
|
1917
|
+
severity: "info",
|
|
1918
|
+
summary: "Search Console is connected, but there is not enough indexing data to diagnose the site yet.",
|
|
1919
|
+
primaryAction: "Let the first sync finish, then make sure a sitemap is submitted.",
|
|
1920
|
+
nextStage: "weak_discovery",
|
|
1921
|
+
sprintFindingTypes: []
|
|
1922
|
+
},
|
|
1923
|
+
weak_discovery: {
|
|
1924
|
+
label: "Weak discovery",
|
|
1925
|
+
severity: "warning",
|
|
1926
|
+
summary: "Google does not have a clean map of the pages you want indexed.",
|
|
1927
|
+
primaryAction: "Submit a clean sitemap that contains only canonical, indexable 200 URLs.",
|
|
1928
|
+
nextStage: "discovery_backlog",
|
|
1929
|
+
sprintFindingTypes: ["search-console-stage", "sitemap-missing"]
|
|
1930
|
+
},
|
|
1931
|
+
discovery_backlog: {
|
|
1932
|
+
label: "Discovery backlog",
|
|
1933
|
+
severity: "warning",
|
|
1934
|
+
summary: "Google knows these pages exist, but is not crawling them fast enough.",
|
|
1935
|
+
primaryAction: "Add internal links from indexed pages and remove low-value URLs from the sitemap.",
|
|
1936
|
+
nextStage: "crawl_blocked",
|
|
1937
|
+
sprintFindingTypes: ["search-console-stage"]
|
|
1938
|
+
},
|
|
1939
|
+
crawl_blocked: {
|
|
1940
|
+
label: "Crawl blocked",
|
|
1941
|
+
severity: "error",
|
|
1942
|
+
summary: "Google is trying to access pages, but technical access problems are blocking progress.",
|
|
1943
|
+
primaryAction: "Fix robots.txt blocks, server errors, broken URLs, and access failures before content work.",
|
|
1944
|
+
nextStage: "indexability_blocked",
|
|
1945
|
+
sprintFindingTypes: ["search-console-stage", "noindex-block"]
|
|
1946
|
+
},
|
|
1947
|
+
indexability_blocked: {
|
|
1948
|
+
label: "Indexability blocked",
|
|
1949
|
+
severity: "error",
|
|
1950
|
+
summary: "Google can reach pages, but index directives or canonical signals are preventing clean indexing.",
|
|
1951
|
+
primaryAction: "Remove accidental noindex directives and make canonical signals agree.",
|
|
1952
|
+
nextStage: "index_rejection",
|
|
1953
|
+
sprintFindingTypes: [
|
|
1954
|
+
"search-console-stage",
|
|
1955
|
+
"noindex-block",
|
|
1956
|
+
"canonicalisation"
|
|
1957
|
+
]
|
|
1958
|
+
},
|
|
1959
|
+
index_rejection: {
|
|
1960
|
+
label: "Index rejection",
|
|
1961
|
+
severity: "warning",
|
|
1962
|
+
summary: "Google is crawling pages but skipping too many of them from the index.",
|
|
1963
|
+
primaryAction: "Improve or consolidate crawled-but-not-indexed pages before publishing more.",
|
|
1964
|
+
nextStage: "partially_indexed",
|
|
1965
|
+
sprintFindingTypes: ["search-console-stage", "pages-not-indexed"]
|
|
1966
|
+
},
|
|
1967
|
+
partially_indexed: {
|
|
1968
|
+
label: "Partially indexed",
|
|
1969
|
+
severity: "warning",
|
|
1970
|
+
summary: "A meaningful share of the site is indexed, but coverage is still below a healthy level.",
|
|
1971
|
+
primaryAction: "Work through the largest remaining indexing blocker first.",
|
|
1972
|
+
nextStage: "indexed_invisible",
|
|
1973
|
+
sprintFindingTypes: ["search-console-stage", "pages-not-indexed"]
|
|
1974
|
+
},
|
|
1975
|
+
indexed_invisible: {
|
|
1976
|
+
label: "Indexed but invisible",
|
|
1977
|
+
severity: "warning",
|
|
1978
|
+
summary: "Pages are indexed, but too many are not earning impressions in Search.",
|
|
1979
|
+
primaryAction: "Improve query targeting, titles, headings, internal links, and page depth.",
|
|
1980
|
+
nextStage: "visible_not_clicked",
|
|
1981
|
+
sprintFindingTypes: ["search-console-stage"]
|
|
1982
|
+
},
|
|
1983
|
+
visible_not_clicked: {
|
|
1984
|
+
label: "Visible but not clicked",
|
|
1985
|
+
severity: "warning",
|
|
1986
|
+
summary: "Google is showing your pages, but searchers are not clicking often enough.",
|
|
1987
|
+
primaryAction: "Rewrite titles and descriptions for the queries already producing impressions.",
|
|
1988
|
+
nextStage: "ranking_stalled",
|
|
1989
|
+
sprintFindingTypes: ["search-console-stage", "ctr-outliers"]
|
|
1990
|
+
},
|
|
1991
|
+
ranking_stalled: {
|
|
1992
|
+
label: "Ranking but stalled",
|
|
1993
|
+
severity: "info",
|
|
1994
|
+
summary: "The site has search visibility, but many pages are not yet ranking in useful positions.",
|
|
1995
|
+
primaryAction: "Prioritise striking-distance pages, refresh content, and add internal links.",
|
|
1996
|
+
nextStage: "healthy_growth_ready",
|
|
1997
|
+
sprintFindingTypes: ["striking-distance", "internal-linking"]
|
|
1998
|
+
},
|
|
1999
|
+
declining_visibility: {
|
|
2000
|
+
label: "Declining visibility",
|
|
2001
|
+
severity: "error",
|
|
2002
|
+
summary: "Search visibility is dropping compared with the previous period.",
|
|
2003
|
+
primaryAction: "Review affected pages, recent releases, competitors, and SERP changes before expanding.",
|
|
2004
|
+
nextStage: "healthy_growth_ready",
|
|
2005
|
+
sprintFindingTypes: ["search-console-stage", "negative-movers"]
|
|
2006
|
+
},
|
|
2007
|
+
healthy_growth_ready: {
|
|
2008
|
+
label: "Healthy",
|
|
2009
|
+
severity: "success",
|
|
2010
|
+
summary: "Google can discover, index, and show your pages.",
|
|
2011
|
+
primaryAction: "Push striking-distance pages (positions 11 to 20) and close content gaps to grow impressions.",
|
|
2012
|
+
nextStage: null,
|
|
2013
|
+
sprintFindingTypes: ["striking-distance", "competitor-content-gap"]
|
|
2014
|
+
}
|
|
2015
|
+
};
|
|
1896
2016
|
function stage(key, evidence) {
|
|
2017
|
+
const definition = SEARCH_CONSOLE_STAGES[key];
|
|
1897
2018
|
return {
|
|
1898
2019
|
key,
|
|
1899
2020
|
evidence,
|
|
1900
|
-
...
|
|
1901
|
-
|
|
1902
|
-
label: "Not connected",
|
|
1903
|
-
severity: "neutral",
|
|
1904
|
-
summary: "Search Console is not connected for this site yet.",
|
|
1905
|
-
primaryAction: "Connect Google Search Console so we can read discovery, indexing, and performance data.",
|
|
1906
|
-
nextStage: "waiting_for_data",
|
|
1907
|
-
sprintFindingTypes: []
|
|
1908
|
-
},
|
|
1909
|
-
waiting_for_data: {
|
|
1910
|
-
label: "Waiting for data",
|
|
1911
|
-
severity: "info",
|
|
1912
|
-
summary: "Search Console is connected, but there is not enough indexing data to diagnose the site yet.",
|
|
1913
|
-
primaryAction: "Let the first sync finish, then make sure a sitemap is submitted.",
|
|
1914
|
-
nextStage: "weak_discovery",
|
|
1915
|
-
sprintFindingTypes: []
|
|
1916
|
-
},
|
|
1917
|
-
weak_discovery: {
|
|
1918
|
-
label: "Weak discovery",
|
|
1919
|
-
severity: "warning",
|
|
1920
|
-
summary: "Google does not have a clean map of the pages you want indexed.",
|
|
1921
|
-
primaryAction: "Submit a clean sitemap that contains only canonical, indexable 200 URLs.",
|
|
1922
|
-
nextStage: "discovery_backlog",
|
|
1923
|
-
sprintFindingTypes: ["search-console-stage", "sitemap-missing"]
|
|
1924
|
-
},
|
|
1925
|
-
discovery_backlog: {
|
|
1926
|
-
label: "Discovery backlog",
|
|
1927
|
-
severity: "warning",
|
|
1928
|
-
summary: "Google knows these pages exist, but is not crawling them fast enough.",
|
|
1929
|
-
primaryAction: "Add internal links from indexed pages and remove low-value URLs from the sitemap.",
|
|
1930
|
-
nextStage: "crawl_blocked",
|
|
1931
|
-
sprintFindingTypes: ["search-console-stage"]
|
|
1932
|
-
},
|
|
1933
|
-
crawl_blocked: {
|
|
1934
|
-
label: "Crawl blocked",
|
|
1935
|
-
severity: "error",
|
|
1936
|
-
summary: "Google is trying to access pages, but technical access problems are blocking progress.",
|
|
1937
|
-
primaryAction: "Fix robots.txt blocks, server errors, broken URLs, and access failures before content work.",
|
|
1938
|
-
nextStage: "indexability_blocked",
|
|
1939
|
-
sprintFindingTypes: ["search-console-stage", "noindex-block"]
|
|
1940
|
-
},
|
|
1941
|
-
indexability_blocked: {
|
|
1942
|
-
label: "Indexability blocked",
|
|
1943
|
-
severity: "error",
|
|
1944
|
-
summary: "Google can reach pages, but index directives or canonical signals are preventing clean indexing.",
|
|
1945
|
-
primaryAction: "Remove accidental noindex directives and make canonical signals agree.",
|
|
1946
|
-
nextStage: "index_rejection",
|
|
1947
|
-
sprintFindingTypes: [
|
|
1948
|
-
"search-console-stage",
|
|
1949
|
-
"noindex-block",
|
|
1950
|
-
"canonicalisation"
|
|
1951
|
-
]
|
|
1952
|
-
},
|
|
1953
|
-
index_rejection: {
|
|
1954
|
-
label: "Index rejection",
|
|
1955
|
-
severity: "warning",
|
|
1956
|
-
summary: "Google is crawling pages but skipping too many of them from the index.",
|
|
1957
|
-
primaryAction: "Improve or consolidate crawled-but-not-indexed pages before publishing more.",
|
|
1958
|
-
nextStage: "partially_indexed",
|
|
1959
|
-
sprintFindingTypes: ["search-console-stage", "pages-not-indexed"]
|
|
1960
|
-
},
|
|
1961
|
-
partially_indexed: {
|
|
1962
|
-
label: "Partially indexed",
|
|
1963
|
-
severity: "warning",
|
|
1964
|
-
summary: "A meaningful share of the site is indexed, but coverage is still below a healthy level.",
|
|
1965
|
-
primaryAction: "Work through the largest remaining indexing blocker first.",
|
|
1966
|
-
nextStage: "indexed_invisible",
|
|
1967
|
-
sprintFindingTypes: ["search-console-stage", "pages-not-indexed"]
|
|
1968
|
-
},
|
|
1969
|
-
indexed_invisible: {
|
|
1970
|
-
label: "Indexed but invisible",
|
|
1971
|
-
severity: "warning",
|
|
1972
|
-
summary: "Pages are indexed, but too many are not earning impressions in Search.",
|
|
1973
|
-
primaryAction: "Improve query targeting, titles, headings, internal links, and page depth.",
|
|
1974
|
-
nextStage: "visible_not_clicked",
|
|
1975
|
-
sprintFindingTypes: ["search-console-stage"]
|
|
1976
|
-
},
|
|
1977
|
-
visible_not_clicked: {
|
|
1978
|
-
label: "Visible but not clicked",
|
|
1979
|
-
severity: "warning",
|
|
1980
|
-
summary: "Google is showing your pages, but searchers are not clicking often enough.",
|
|
1981
|
-
primaryAction: "Rewrite titles and descriptions for the queries already producing impressions.",
|
|
1982
|
-
nextStage: "ranking_stalled",
|
|
1983
|
-
sprintFindingTypes: ["search-console-stage", "ctr-outliers"]
|
|
1984
|
-
},
|
|
1985
|
-
ranking_stalled: {
|
|
1986
|
-
label: "Ranking but stalled",
|
|
1987
|
-
severity: "info",
|
|
1988
|
-
summary: "The site has search visibility, but many pages are not yet ranking in useful positions.",
|
|
1989
|
-
primaryAction: "Prioritise striking-distance pages, refresh content, and add internal links.",
|
|
1990
|
-
nextStage: "healthy_growth_ready",
|
|
1991
|
-
sprintFindingTypes: ["striking-distance", "internal-linking"]
|
|
1992
|
-
},
|
|
1993
|
-
declining_visibility: {
|
|
1994
|
-
label: "Declining visibility",
|
|
1995
|
-
severity: "error",
|
|
1996
|
-
summary: "Search visibility is dropping compared with the previous period.",
|
|
1997
|
-
primaryAction: "Review affected pages, recent releases, competitors, and SERP changes before expanding.",
|
|
1998
|
-
nextStage: "healthy_growth_ready",
|
|
1999
|
-
sprintFindingTypes: ["search-console-stage", "negative-movers"]
|
|
2000
|
-
},
|
|
2001
|
-
healthy_growth_ready: {
|
|
2002
|
-
label: "Healthy",
|
|
2003
|
-
severity: "success",
|
|
2004
|
-
summary: "Google can discover, index, and show your pages.",
|
|
2005
|
-
primaryAction: "Push striking-distance pages (positions 11 to 20) and close content gaps to grow impressions.",
|
|
2006
|
-
nextStage: null,
|
|
2007
|
-
sprintFindingTypes: ["striking-distance", "competitor-content-gap"]
|
|
2008
|
-
}
|
|
2009
|
-
}[key]
|
|
2021
|
+
...definition,
|
|
2022
|
+
sprintFindingTypes: [...definition.sprintFindingTypes]
|
|
2010
2023
|
};
|
|
2011
2024
|
}
|
|
2012
2025
|
const ESTABLISHED_IMPRESSIONS_28D$1 = 2e4;
|
|
@@ -2039,8 +2052,13 @@ function classifySearchConsoleStage(input) {
|
|
|
2039
2052
|
const crawled = countSearchConsoleIssues(issues, "crawled_not_indexed");
|
|
2040
2053
|
const hardBlocks = countSearchConsoleIssues(issues, "blocked_robots", "server_error", "access_denied", "forbidden") + (input.crawlAuditBlockerCount ?? 0);
|
|
2041
2054
|
const canonicalMismatches = Math.min(notIndexed, input.canonicalMismatchCount ?? countSearchConsoleIssues(issues, "canonical_mismatch"));
|
|
2042
|
-
|
|
2043
|
-
|
|
2055
|
+
let visibleNoClickPages = 0;
|
|
2056
|
+
let poorPositionPages = 0;
|
|
2057
|
+
for (const page of input.pageInventory ?? []) {
|
|
2058
|
+
if (page.impressions < 50) continue;
|
|
2059
|
+
if (page.clicks === 0) visibleNoClickPages++;
|
|
2060
|
+
if ((page.position ?? 0) > 20) poorPositionPages++;
|
|
2061
|
+
}
|
|
2044
2062
|
const ctrOutlierCount = input.ctrOutlierCount ?? 0;
|
|
2045
2063
|
const traj = input.trajectory ?? null;
|
|
2046
2064
|
const impressions28d = input.impressions28d ?? null;
|
package/dist/v1/index.mjs
CHANGED
|
@@ -155,11 +155,12 @@ async function resolveBaseHeaders(resolver) {
|
|
|
155
155
|
}
|
|
156
156
|
async function buildRequestHeaders(options, operation, prepared, executeOptions) {
|
|
157
157
|
try {
|
|
158
|
-
const
|
|
158
|
+
const [baseHeaders, credential] = await Promise.all([resolveBaseHeaders(options.headers), resolveCredential(options.credential)]);
|
|
159
|
+
const headers = new Headers(baseHeaders);
|
|
159
160
|
for (const [key, value] of Object.entries(prepared.headers)) if (value !== void 0) headers.set(key, String(value));
|
|
160
161
|
headers.delete("x-api-key");
|
|
161
162
|
headers.set("accept", "application/json");
|
|
162
|
-
headers.set("authorization", `Bearer ${
|
|
163
|
+
headers.set("authorization", `Bearer ${credential}`);
|
|
163
164
|
if (executeOptions.idempotencyKey) headers.set("idempotency-key", executeOptions.idempotencyKey);
|
|
164
165
|
if (prepared.body !== void 0) headers.set("content-type", "application/json");
|
|
165
166
|
return headers;
|
|
@@ -367,6 +368,19 @@ function createGscdumpV1Client(options) {
|
|
|
367
368
|
createRealtimeTicket: (input, executeOptions) => execute("realtime.tickets.create", input, executeOptions)
|
|
368
369
|
};
|
|
369
370
|
}
|
|
371
|
+
function utf8Size(value) {
|
|
372
|
+
let bytes = 0;
|
|
373
|
+
for (let index = 0; index < value.length; index++) {
|
|
374
|
+
const code = value.charCodeAt(index);
|
|
375
|
+
if (code <= 127) bytes++;
|
|
376
|
+
else if (code <= 2047) bytes += 2;
|
|
377
|
+
else if (code >= 55296 && code <= 56319 && index + 1 < value.length && value.charCodeAt(index + 1) >= 56320 && value.charCodeAt(index + 1) <= 57343) {
|
|
378
|
+
bytes += 4;
|
|
379
|
+
index++;
|
|
380
|
+
} else bytes += 3;
|
|
381
|
+
}
|
|
382
|
+
return bytes;
|
|
383
|
+
}
|
|
370
384
|
const GSCDUMP_REALTIME_V1_SDK_VERSION = "0.37.7";
|
|
371
385
|
var GscdumpRealtimeV1Error = class extends Error {
|
|
372
386
|
tag = "GscdumpRealtimeV1Error";
|
|
@@ -417,13 +431,14 @@ function defaultRuntime() {
|
|
|
417
431
|
now: () => Date.now()
|
|
418
432
|
};
|
|
419
433
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
434
|
+
const UTF8_DECODER = new TextDecoder();
|
|
435
|
+
const REALTIME_EVENT_NAMES = new Set(REALTIME_V1_EVENT_NAMES);
|
|
436
|
+
const REALTIME_RESOURCE_TYPES = new Set(REALTIME_V1_RESOURCE_TYPES);
|
|
437
|
+
const APPLIED_EVENT_CACHE_MAX = 1e4;
|
|
423
438
|
async function messageText(raw) {
|
|
424
439
|
if (typeof raw === "string") return raw;
|
|
425
|
-
if (raw instanceof ArrayBuffer) return
|
|
426
|
-
if (ArrayBuffer.isView(raw)) return
|
|
440
|
+
if (raw instanceof ArrayBuffer) return UTF8_DECODER.decode(raw);
|
|
441
|
+
if (ArrayBuffer.isView(raw)) return UTF8_DECODER.decode(new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength));
|
|
427
442
|
if (typeof Blob !== "undefined" && raw instanceof Blob) return raw.text();
|
|
428
443
|
throw new TypeError("Realtime frames must be text or UTF-8 binary data.");
|
|
429
444
|
}
|
|
@@ -472,6 +487,7 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
472
487
|
const eventFailures = /* @__PURE__ */ new Map();
|
|
473
488
|
const appliedEventIds = /* @__PURE__ */ new Set();
|
|
474
489
|
const appliedEventOrder = [];
|
|
490
|
+
let appliedEventCursor = 0;
|
|
475
491
|
function getSnapshot() {
|
|
476
492
|
return {
|
|
477
493
|
transport,
|
|
@@ -605,23 +621,25 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
605
621
|
const key = eventDedupeKey(stream, id);
|
|
606
622
|
if (appliedEventIds.has(key)) return;
|
|
607
623
|
appliedEventIds.add(key);
|
|
608
|
-
appliedEventOrder.push(key);
|
|
609
|
-
|
|
610
|
-
const oldest = appliedEventOrder
|
|
624
|
+
if (appliedEventOrder.length < APPLIED_EVENT_CACHE_MAX) appliedEventOrder.push(key);
|
|
625
|
+
else {
|
|
626
|
+
const oldest = appliedEventOrder[appliedEventCursor];
|
|
611
627
|
if (oldest) appliedEventIds.delete(oldest);
|
|
628
|
+
appliedEventOrder[appliedEventCursor] = key;
|
|
629
|
+
appliedEventCursor = (appliedEventCursor + 1) % APPLIED_EVENT_CACHE_MAX;
|
|
612
630
|
}
|
|
613
631
|
}
|
|
614
632
|
function eventFailureKey(event) {
|
|
615
633
|
return `${event.cursor?.streamId ?? "ephemeral"}:${event.id}:${event.cursor?.sequence ?? "ephemeral"}`;
|
|
616
634
|
}
|
|
617
635
|
function eventForRequiredEffect(event) {
|
|
618
|
-
return
|
|
636
|
+
return REALTIME_EVENT_NAMES.has(event.name) && event.eventVersion === 1 ? event : {
|
|
619
637
|
...event,
|
|
620
638
|
data: null
|
|
621
639
|
};
|
|
622
640
|
}
|
|
623
641
|
function eventAdvisories(event) {
|
|
624
|
-
if (!
|
|
642
|
+
if (!REALTIME_EVENT_NAMES.has(event.name)) observe({
|
|
625
643
|
type: "advisory",
|
|
626
644
|
code: "unknown_event",
|
|
627
645
|
event
|
|
@@ -631,7 +649,7 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
631
649
|
code: "unsupported_event_version",
|
|
632
650
|
event
|
|
633
651
|
});
|
|
634
|
-
if (event.changes.some((change) => !
|
|
652
|
+
if (event.changes.some((change) => !REALTIME_RESOURCE_TYPES.has(change.type))) observe({
|
|
635
653
|
type: "advisory",
|
|
636
654
|
code: "unknown_resource",
|
|
637
655
|
event
|
|
@@ -1058,7 +1076,8 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
1058
1076
|
context.lastPongAt = runtime.now();
|
|
1059
1077
|
return;
|
|
1060
1078
|
}
|
|
1061
|
-
|
|
1079
|
+
const textBytes = utf8Size(text);
|
|
1080
|
+
if (textBytes > GSCDUMP_REALTIME_LIMITS.outboundFrameMaxBytes) throw new GscdumpRealtimeV1Error({
|
|
1062
1081
|
code: "protocol_error",
|
|
1063
1082
|
message: "A server frame exceeded the v1 outbound frame limit.",
|
|
1064
1083
|
retryable: false,
|
|
@@ -1086,8 +1105,7 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
1086
1105
|
cause: parsed.error
|
|
1087
1106
|
});
|
|
1088
1107
|
if (parsed.data.type === "event") {
|
|
1089
|
-
|
|
1090
|
-
if (utf8Size(text) > eventLimit) throw new GscdumpRealtimeV1Error({
|
|
1108
|
+
if (textBytes > (parsed.data.delivery === "durable" ? GSCDUMP_REALTIME_LIMITS.durableEventMaxBytes : GSCDUMP_REALTIME_LIMITS.ephemeralEventMaxBytes)) throw new GscdumpRealtimeV1Error({
|
|
1091
1109
|
code: "protocol_error",
|
|
1092
1110
|
message: `A ${parsed.data.delivery} event exceeded its v1 size limit.`,
|
|
1093
1111
|
retryable: false,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/sdk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.39.0",
|
|
5
5
|
"description": "Consumer SDK for hosted gscdump.com integrations.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
"date-fns": "^4.4.0",
|
|
50
50
|
"ofetch": "^1.5.1",
|
|
51
51
|
"zod": "^4.4.3",
|
|
52
|
-
"@gscdump/contracts": "0.
|
|
53
|
-
"@gscdump/
|
|
54
|
-
"gscdump": "0.
|
|
55
|
-
"
|
|
52
|
+
"@gscdump/contracts": "0.39.0",
|
|
53
|
+
"@gscdump/analysis": "0.39.0",
|
|
54
|
+
"@gscdump/engine": "0.39.0",
|
|
55
|
+
"gscdump": "0.39.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"typescript": "^6.0.3",
|