@lynxflow/seo-engine 2.0.1 → 2.1.1
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/README.md +1 -1
- package/dist/generation-tracker.d.ts +70 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +235 -27
- package/dist/index.mjs +235 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ High-Performance Universal Programmatic SEO & Structured Data Engine for Modern
|
|
|
4
4
|
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
[](LICENSE)
|
|
7
|
-
[](https://www.npmjs.com/package/@lynxflow/seo-engine)
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 📊 Page Generation & Multi-Cycle Regeneration Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks:
|
|
5
|
+
* 1. Unique Live Programmatic Pages in Index
|
|
6
|
+
* 2. Total Generation Cycles (Initial Creation + 2x, 3x+ Re-Optimizations)
|
|
7
|
+
* 3. Execution Mode: 'standard' (Deterministic 0€, 0 Token) vs 'ai-enhanced' (LLM Custom Copy with Token Billing)
|
|
8
|
+
* 4. Market Demand Signals & Emerging Country Opportunities (e.g. Brazil, US, Spain)
|
|
9
|
+
*/
|
|
10
|
+
export interface PageGenerationRecord {
|
|
11
|
+
urlPath: string;
|
|
12
|
+
service: string;
|
|
13
|
+
location: string;
|
|
14
|
+
country: string;
|
|
15
|
+
language: string;
|
|
16
|
+
generationCount: number;
|
|
17
|
+
mode: "standard" | "ai-enhanced";
|
|
18
|
+
tokensConsumed: number;
|
|
19
|
+
firstGeneratedAt: string;
|
|
20
|
+
lastGeneratedAt: string;
|
|
21
|
+
}
|
|
22
|
+
export interface MarketOpportunitySignal {
|
|
23
|
+
country: string;
|
|
24
|
+
countryCode: string;
|
|
25
|
+
detectedRequests: number;
|
|
26
|
+
activeIndexedPages: number;
|
|
27
|
+
coverageStatus: "optimal" | "underserved" | "opportunity_detected";
|
|
28
|
+
estimatedMonthlyTrafficUpside: number;
|
|
29
|
+
recommendation: string;
|
|
30
|
+
}
|
|
31
|
+
export interface GenerationMetricsReport {
|
|
32
|
+
uniquePagesCount: number;
|
|
33
|
+
totalGenerationCycles: number;
|
|
34
|
+
regenerationFrequency: {
|
|
35
|
+
singleGeneration: number;
|
|
36
|
+
doubleGeneration: number;
|
|
37
|
+
multiGeneration: number;
|
|
38
|
+
};
|
|
39
|
+
modeDistribution: {
|
|
40
|
+
standardDeterministicCount: number;
|
|
41
|
+
aiEnhancedCount: number;
|
|
42
|
+
};
|
|
43
|
+
totalAiTokensConsumed: number;
|
|
44
|
+
activeCountriesCount: number;
|
|
45
|
+
marketOpportunities: MarketOpportunitySignal[];
|
|
46
|
+
}
|
|
47
|
+
export declare class PageRegenerationTracker {
|
|
48
|
+
private records;
|
|
49
|
+
private demandSignals;
|
|
50
|
+
/**
|
|
51
|
+
* Records a page generation or regeneration event.
|
|
52
|
+
*/
|
|
53
|
+
recordGeneration(params: {
|
|
54
|
+
urlPath: string;
|
|
55
|
+
service?: string;
|
|
56
|
+
location?: string;
|
|
57
|
+
country?: string;
|
|
58
|
+
language?: string;
|
|
59
|
+
mode?: "standard" | "ai-enhanced";
|
|
60
|
+
tokensConsumed?: number;
|
|
61
|
+
}): PageGenerationRecord;
|
|
62
|
+
/**
|
|
63
|
+
* Ingests external traffic or search demand signals (e.g. from Cloudflare / Nginx Edge / Google Search Console).
|
|
64
|
+
*/
|
|
65
|
+
recordMarketDemand(country: string, requestVolume?: number): void;
|
|
66
|
+
/**
|
|
67
|
+
* Computes comprehensive analytics report for admin dashboards.
|
|
68
|
+
*/
|
|
69
|
+
getMetricsReport(): GenerationMetricsReport;
|
|
70
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -110,6 +110,7 @@ import { LynxRateLimitedTranslator } from "./rate-limited-translator";
|
|
|
110
110
|
import { InternalPageRankEngine } from "./internal-pagerank-graph";
|
|
111
111
|
import { GeoCitationScorer } from "./geo-citation-scorer";
|
|
112
112
|
import { MarketingSkillsEngine } from "./marketing-skills-engine";
|
|
113
|
+
import { PageRegenerationTracker } from "./generation-tracker";
|
|
113
114
|
export declare function createLynxSeoEngine(config: EngineConfig): LynxSeoEngine;
|
|
114
115
|
export declare const LynxSeo: {
|
|
115
116
|
createEngine: typeof createLynxSeoEngine;
|
|
@@ -157,7 +158,9 @@ export declare const LynxSeo: {
|
|
|
157
158
|
pageRankGraph: typeof InternalPageRankEngine;
|
|
158
159
|
geoCitation: typeof GeoCitationScorer;
|
|
159
160
|
marketingSkills: typeof MarketingSkillsEngine;
|
|
161
|
+
regenerationTracker: typeof PageRegenerationTracker;
|
|
160
162
|
};
|
|
163
|
+
export * from "./generation-tracker";
|
|
161
164
|
export * from "./internal-pagerank-graph";
|
|
162
165
|
export * from "./geo-citation-scorer";
|
|
163
166
|
export * from "./marketing-skills-engine";
|
package/dist/index.js
CHANGED
|
@@ -3787,7 +3787,7 @@ class PseoMatrixEngine {
|
|
|
3787
3787
|
])
|
|
3788
3788
|
]
|
|
3789
3789
|
};
|
|
3790
|
-
|
|
3790
|
+
const pageItem = {
|
|
3791
3791
|
matrixFamily: "local-geo",
|
|
3792
3792
|
urlPath,
|
|
3793
3793
|
canonicalUrl: fullUrl,
|
|
@@ -3799,7 +3799,9 @@ class PseoMatrixEngine {
|
|
|
3799
3799
|
neighboringLinks: neighborLinks,
|
|
3800
3800
|
service: s,
|
|
3801
3801
|
location: loc
|
|
3802
|
-
}
|
|
3802
|
+
};
|
|
3803
|
+
pageItem.ogImageUrl = OgImageGenerator.generateOgImageUrl(cleanDomain, pageItem, options.brandName);
|
|
3804
|
+
pages.push(pageItem);
|
|
3803
3805
|
}
|
|
3804
3806
|
}
|
|
3805
3807
|
return pages;
|
|
@@ -4145,7 +4147,7 @@ class PseoMatrixEngine {
|
|
|
4145
4147
|
generateAllMatrices(domain, data, options) {
|
|
4146
4148
|
const allPages = [];
|
|
4147
4149
|
if (data.services) {
|
|
4148
|
-
const locs = data.locations && data.locations.length > 0 ? data.locations : resolveBuiltInLocations(options.
|
|
4150
|
+
const locs = data.locations && data.locations.length > 0 ? data.locations : resolveBuiltInLocations(options.allowedCountries || options.countries || options.territories || "us");
|
|
4149
4151
|
allPages.push(...this.generateLocalGeoMatrix(domain, data.services, locs, options));
|
|
4150
4152
|
}
|
|
4151
4153
|
if (data.competitors) {
|
|
@@ -4212,30 +4214,113 @@ class PseoMatrixEngine {
|
|
|
4212
4214
|
}
|
|
4213
4215
|
resolvePage(slugOrPath, domain, data, options) {
|
|
4214
4216
|
const path = typeof slugOrPath === "string" ? slugOrPath.startsWith("/") ? slugOrPath : `/${slugOrPath}` : `/${slugOrPath.join("/")}`;
|
|
4215
|
-
const
|
|
4216
|
-
const existing = pages.find((p) => p.urlPath === path);
|
|
4217
|
-
if (existing)
|
|
4218
|
-
return existing;
|
|
4217
|
+
const lang = options.language || "en";
|
|
4219
4218
|
const segments = path.split("/").filter(Boolean);
|
|
4220
|
-
if (segments.length
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4219
|
+
if (segments.length === 0)
|
|
4220
|
+
return;
|
|
4221
|
+
const vsPrefix = this.getPrefix("vs", lang).replace(/^\//, "");
|
|
4222
|
+
if (segments[0] === vsPrefix && segments[1] && data.competitors) {
|
|
4223
|
+
const compSlug = segments[1];
|
|
4224
|
+
const matched = data.competitors.find((c) => cleanSeoSlug(c.slug, { language: lang }) === compSlug || c.slug === compSlug);
|
|
4225
|
+
if (matched) {
|
|
4226
|
+
return this.generateVsMatrix(domain, [matched], options)[0];
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
const altPrefix = this.getPrefix("alternative", lang).replace(/^\//, "");
|
|
4230
|
+
if (segments[0] === altPrefix && segments[1] && data.competitors) {
|
|
4231
|
+
const compSlug = segments[1];
|
|
4232
|
+
const matched = data.competitors.find((c) => cleanSeoSlug(c.slug, { language: lang }) === compSlug || c.slug === compSlug);
|
|
4233
|
+
if (matched) {
|
|
4234
|
+
return this.generateAlternativesMatrix(domain, [matched], options)[0];
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4237
|
+
const pricingPrefix = this.getPrefix("pricing", lang).replace(/^\//, "");
|
|
4238
|
+
if (segments[0] === pricingPrefix && segments[1] && data.competitors) {
|
|
4239
|
+
const compSlug = segments[1];
|
|
4240
|
+
const matched = data.competitors.find((c) => cleanSeoSlug(c.slug, { language: lang }) === compSlug || c.slug === compSlug);
|
|
4241
|
+
if (matched) {
|
|
4242
|
+
return this.generatePricingMatrix(domain, [matched], options)[0];
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
const targetPrefix = this.getPrefix("target", lang).replace(/^\//, "");
|
|
4246
|
+
if (segments[0] === targetPrefix && segments[1] && data.targets) {
|
|
4247
|
+
const targetSlug = segments[1];
|
|
4248
|
+
const matched = data.targets.find((t) => cleanSeoSlug(t.slug, { language: lang }) === targetSlug || t.slug === targetSlug);
|
|
4249
|
+
if (matched) {
|
|
4250
|
+
return this.generateTargetMatrix(domain, [matched], options)[0];
|
|
4251
|
+
}
|
|
4252
|
+
}
|
|
4253
|
+
const integPrefix = this.getPrefix("integration", lang).replace(/^\//, "");
|
|
4254
|
+
if (segments[0] === integPrefix && segments[1] && data.integrations) {
|
|
4255
|
+
const integSlug = segments[1];
|
|
4256
|
+
const matched = data.integrations.find((i) => cleanSeoSlug(i.slug, { language: lang }) === integSlug || i.slug === integSlug);
|
|
4257
|
+
if (matched) {
|
|
4258
|
+
return this.generateIntegrationMatrix(domain, [matched], options)[0];
|
|
4259
|
+
}
|
|
4260
|
+
}
|
|
4261
|
+
const useCasePrefix = this.getPrefix("useCase", lang).replace(/^\//, "");
|
|
4262
|
+
if (segments[0] === useCasePrefix && segments[1] && data.useCases) {
|
|
4263
|
+
const ucSlug = segments[1];
|
|
4264
|
+
const matched = data.useCases.find((u) => cleanSeoSlug(u.slug, { language: lang }) === ucSlug || u.slug === ucSlug);
|
|
4265
|
+
if (matched) {
|
|
4266
|
+
return this.generateUseCaseMatrix(domain, [matched], options)[0];
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
const templatePrefix = this.getPrefix("template", lang).replace(/^\//, "");
|
|
4270
|
+
if (segments[0] === templatePrefix && segments[1] && data.templates) {
|
|
4271
|
+
const tSlug = segments[1];
|
|
4272
|
+
const matched = data.templates.find((t) => cleanSeoSlug(t.slug, { language: lang }) === tSlug || t.slug === tSlug);
|
|
4273
|
+
if (matched) {
|
|
4274
|
+
return this.generateTemplateMatrix(domain, [matched], options)[0];
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4277
|
+
const glossaryPrefix = this.getPrefix("glossary", lang).replace(/^\//, "");
|
|
4278
|
+
if (segments[0] === glossaryPrefix && segments[1] && data.glossaryTerms) {
|
|
4279
|
+
const gSlug = segments[1];
|
|
4280
|
+
const matched = data.glossaryTerms.find((g) => cleanSeoSlug(g.slug, { language: lang }) === gSlug || g.slug === gSlug);
|
|
4281
|
+
if (matched) {
|
|
4282
|
+
return this.generateGlossaryMatrix(domain, [matched], options)[0];
|
|
4283
|
+
}
|
|
4284
|
+
}
|
|
4285
|
+
const calcPrefix = this.getPrefix("calculator", lang).replace(/^\//, "");
|
|
4286
|
+
if (segments[0] === calcPrefix && segments[1] && data.calculators) {
|
|
4287
|
+
const cSlug = segments[1];
|
|
4288
|
+
const matched = data.calculators.find((c) => cleanSeoSlug(c.slug, { language: lang }) === cSlug || c.slug === cSlug);
|
|
4289
|
+
if (matched) {
|
|
4290
|
+
return this.generateCalculatorMatrix(domain, [matched], options)[0];
|
|
4291
|
+
}
|
|
4292
|
+
}
|
|
4293
|
+
if (data.services && data.services.length > 0) {
|
|
4294
|
+
let serviceSlug = "";
|
|
4295
|
+
let locationSlug = "";
|
|
4296
|
+
if (segments.length === 2 && options.cleanDirectRoutes !== false) {
|
|
4297
|
+
serviceSlug = segments[0];
|
|
4298
|
+
locationSlug = segments[1];
|
|
4299
|
+
} else if (segments.length >= 3 && segments[0] === this.getPrefix("solutions", lang).replace(/^\//, "")) {
|
|
4300
|
+
serviceSlug = segments[1];
|
|
4301
|
+
locationSlug = segments[segments.length - 1];
|
|
4302
|
+
}
|
|
4303
|
+
if (serviceSlug && locationSlug) {
|
|
4304
|
+
const matchedService = data.services.find((s) => cleanSeoSlug(s.slug, { language: lang }) === serviceSlug || s.slug === serviceSlug);
|
|
4305
|
+
if (matchedService) {
|
|
4306
|
+
let resolvedLoc = (data.locations || []).find((l) => cleanSeoSlug(l.slug, { language: lang }) === locationSlug || l.slug === locationSlug);
|
|
4307
|
+
if (!resolvedLoc) {
|
|
4308
|
+
const countryList = options.allowedCountries || options.countries;
|
|
4309
|
+
const fallbackCountry = Array.isArray(countryList) ? countryList[0] : typeof countryList === "string" && countryList !== "international" ? countryList : "United States";
|
|
4310
|
+
resolvedLoc = createDynamicLocation(locationSlug, fallbackCountry, {
|
|
4311
|
+
currency: options.defaultCurrency,
|
|
4312
|
+
currencySymbol: options.defaultCurrencySymbol
|
|
4313
|
+
});
|
|
4314
|
+
if (options.strictCountryBoundary && countryList) {
|
|
4315
|
+
const allowed = (Array.isArray(countryList) ? countryList : [countryList]).map((c) => c.toLowerCase());
|
|
4316
|
+
if (!allowed.includes("international") && !allowed.some((c) => resolvedLoc.country.toLowerCase().includes(c))) {
|
|
4317
|
+
return;
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4235
4320
|
}
|
|
4321
|
+
const dynamicPages = this.generateLocalGeoMatrix(domain, [matchedService], [resolvedLoc], options);
|
|
4322
|
+
return dynamicPages[0];
|
|
4236
4323
|
}
|
|
4237
|
-
const dynamicPages = this.generateLocalGeoMatrix(domain, [matchedService], [dynamicLoc], options);
|
|
4238
|
-
return dynamicPages.find((p) => p.urlPath === path) || dynamicPages[0];
|
|
4239
4324
|
}
|
|
4240
4325
|
}
|
|
4241
4326
|
return;
|
|
@@ -5045,7 +5130,20 @@ When discovering product modules, features, or services to build the SEO matrice
|
|
|
5045
5130
|
|
|
5046
5131
|
---
|
|
5047
5132
|
|
|
5048
|
-
### \
|
|
5133
|
+
### \uD83D\uDEA8 2. CRITICAL RULE: ZERO STATIC PRE-COMPILATION AT BUILD TIME (PURE RUNTIME ON-DEMAND)
|
|
5134
|
+
|
|
5135
|
+
- **❌ NEVER PRE-COMPILE CITIES OR PAGES AT BUILD TIME (\`generateStaticParams\` / \`getStaticPaths\`):**
|
|
5136
|
+
- DO NOT create static loops over 365, 61, or any hardcoded list of cities during \`next build\`.
|
|
5137
|
+
- DO NOT freeze pages into static HTML files on disk. That is NOT how high-scale programmatic SEO works.
|
|
5138
|
+
- Doing so breaks infinite dynamic expansion, causes build memory crashes, and falsely caps the website to a tiny subset of pages.
|
|
5139
|
+
- **✅ ALWAYS USE 100% RUNTIME IN-MEMORY RESOLUTION (\`resolvePage\`):**
|
|
5140
|
+
- In Next.js App Router: Always set \`export const dynamic = "force-dynamic"\` and \`export const dynamicParams = true\`.
|
|
5141
|
+
- When an incoming request arrives (e.g. \`/solutions/ac-repair/austin\`, \`/solutions/ac-repair/paris\`, \`/solutions/ac-repair/90210\`), the server executes \`matrixEngine.resolvePage([service, location], ...)\` in RAM in \`< 0.05ms\`.
|
|
5142
|
+
- Build time remains **under 3 seconds** because 0 localized landing pages are built ahead of time. Every page is synthesized on demand.
|
|
5143
|
+
|
|
5144
|
+
---
|
|
5145
|
+
|
|
5146
|
+
### \uD83C\uDF10 3. ARCHITECTURAL RULE: THE WEBSITE OWNS ITS LANGUAGES (i18n)
|
|
5049
5147
|
|
|
5050
5148
|
- **The Website (Application) is the sole owner of its languages, routes, and translations:**
|
|
5051
5149
|
- The website provides its own localized routes (e.g. \`app/[locale]/[...slug]/page.tsx\`) and dictionary files (\`next-intl\`, \`i18next\`, Astro i18n).
|
|
@@ -5308,7 +5406,7 @@ The SDK equips applications with 9 enterprise-grade SEO engines:
|
|
|
5308
5406
|
- Boosts dwell time, organic backlinks, and visitor-to-customer conversion.
|
|
5309
5407
|
|
|
5310
5408
|
8. **\uD83C\uDFDB️ Google Schema.org Rich Graphs (\`ExtendedSchemaGraphBuilder\`):**
|
|
5311
|
-
- \`buildAggregateRating\` (Google
|
|
5409
|
+
- \`buildAggregateRating\` (Verified live reviews synced from Google Places / Trustpilot / WooCommerce), \`buildAggregateOffer\` (price ranges), \`buildLocalBusiness\` (GPS & opening hours), \`buildSoftwareApplication\`, \`buildHowTo\`, \`buildFAQPage\`, \`buildBreadcrumbs\`.
|
|
5312
5410
|
|
|
5313
5411
|
9. **\uD83D\uDD0D URL Decomposition & Analysis (\`UrlyticsEngine\`):**
|
|
5314
5412
|
- Deep structural directory decomposition, depth tracking, query parameter analysis, and slug tokenization (inspired by advertools).
|
|
@@ -9457,6 +9555,114 @@ class MarketingSkillsEngine {
|
|
|
9457
9555
|
}
|
|
9458
9556
|
}
|
|
9459
9557
|
|
|
9558
|
+
// src/generation-tracker.ts
|
|
9559
|
+
class PageRegenerationTracker {
|
|
9560
|
+
records = new Map;
|
|
9561
|
+
demandSignals = new Map;
|
|
9562
|
+
recordGeneration(params) {
|
|
9563
|
+
const key = params.urlPath.trim().toLowerCase();
|
|
9564
|
+
const existing = this.records.get(key);
|
|
9565
|
+
const now = new Date().toISOString();
|
|
9566
|
+
const country = params.country || existing?.country || "United States";
|
|
9567
|
+
const language = params.language || existing?.language || "en";
|
|
9568
|
+
const service = params.service || existing?.service || "General Service";
|
|
9569
|
+
const location = params.location || existing?.location || "National";
|
|
9570
|
+
const mode = params.mode || "standard";
|
|
9571
|
+
const tokens = params.tokensConsumed || 0;
|
|
9572
|
+
if (existing) {
|
|
9573
|
+
existing.generationCount += 1;
|
|
9574
|
+
existing.mode = mode;
|
|
9575
|
+
existing.tokensConsumed += tokens;
|
|
9576
|
+
existing.lastGeneratedAt = now;
|
|
9577
|
+
this.records.set(key, existing);
|
|
9578
|
+
return existing;
|
|
9579
|
+
}
|
|
9580
|
+
const newRecord = {
|
|
9581
|
+
urlPath: key,
|
|
9582
|
+
service,
|
|
9583
|
+
location,
|
|
9584
|
+
country,
|
|
9585
|
+
language,
|
|
9586
|
+
generationCount: 1,
|
|
9587
|
+
mode,
|
|
9588
|
+
tokensConsumed: tokens,
|
|
9589
|
+
firstGeneratedAt: now,
|
|
9590
|
+
lastGeneratedAt: now
|
|
9591
|
+
};
|
|
9592
|
+
this.records.set(key, newRecord);
|
|
9593
|
+
const countryKey = country.toLowerCase();
|
|
9594
|
+
const currentSignal = this.demandSignals.get(countryKey) || { requests: 0, country };
|
|
9595
|
+
currentSignal.requests += 1;
|
|
9596
|
+
this.demandSignals.set(countryKey, currentSignal);
|
|
9597
|
+
return newRecord;
|
|
9598
|
+
}
|
|
9599
|
+
recordMarketDemand(country, requestVolume = 1) {
|
|
9600
|
+
const countryKey = country.trim().toLowerCase();
|
|
9601
|
+
const current = this.demandSignals.get(countryKey) || { requests: 0, country };
|
|
9602
|
+
current.requests += requestVolume;
|
|
9603
|
+
this.demandSignals.set(countryKey, current);
|
|
9604
|
+
}
|
|
9605
|
+
getMetricsReport() {
|
|
9606
|
+
let singleGen = 0;
|
|
9607
|
+
let doubleGen = 0;
|
|
9608
|
+
let multiGen = 0;
|
|
9609
|
+
let standardCount = 0;
|
|
9610
|
+
let aiCount = 0;
|
|
9611
|
+
let totalTokens = 0;
|
|
9612
|
+
const countriesSet = new Set;
|
|
9613
|
+
const countryPageCounts = new Map;
|
|
9614
|
+
for (const record of this.records.values()) {
|
|
9615
|
+
if (record.generationCount === 1)
|
|
9616
|
+
singleGen++;
|
|
9617
|
+
else if (record.generationCount === 2)
|
|
9618
|
+
doubleGen++;
|
|
9619
|
+
else
|
|
9620
|
+
multiGen++;
|
|
9621
|
+
if (record.mode === "ai-enhanced") {
|
|
9622
|
+
aiCount++;
|
|
9623
|
+
totalTokens += record.tokensConsumed;
|
|
9624
|
+
} else {
|
|
9625
|
+
standardCount++;
|
|
9626
|
+
}
|
|
9627
|
+
countriesSet.add(record.country);
|
|
9628
|
+
const cKey = record.country.toLowerCase();
|
|
9629
|
+
countryPageCounts.set(cKey, (countryPageCounts.get(cKey) || 0) + 1);
|
|
9630
|
+
}
|
|
9631
|
+
const marketOpportunities = [];
|
|
9632
|
+
for (const [countryKey, signal] of this.demandSignals.entries()) {
|
|
9633
|
+
const indexedPages = countryPageCounts.get(countryKey) || 0;
|
|
9634
|
+
const countryFormatted = signal.country.charAt(0).toUpperCase() + signal.country.slice(1);
|
|
9635
|
+
if (signal.requests > 100 && indexedPages < 20) {
|
|
9636
|
+
marketOpportunities.push({
|
|
9637
|
+
country: countryFormatted,
|
|
9638
|
+
countryCode: countryKey.slice(0, 2).toUpperCase(),
|
|
9639
|
+
detectedRequests: signal.requests,
|
|
9640
|
+
activeIndexedPages: indexedPages,
|
|
9641
|
+
coverageStatus: "opportunity_detected",
|
|
9642
|
+
estimatedMonthlyTrafficUpside: Math.round(signal.requests * 3.4),
|
|
9643
|
+
recommendation: `High demand detected in ${countryFormatted} (${signal.requests} hits). Upgrade to Pro Growth or activate ${countryFormatted} in SEO_CONFIG to capture +${Math.round(signal.requests * 3.4)} visits/month.`
|
|
9644
|
+
});
|
|
9645
|
+
}
|
|
9646
|
+
}
|
|
9647
|
+
return {
|
|
9648
|
+
uniquePagesCount: this.records.size,
|
|
9649
|
+
totalGenerationCycles: singleGen + doubleGen * 2 + multiGen * 3,
|
|
9650
|
+
regenerationFrequency: {
|
|
9651
|
+
singleGeneration: singleGen,
|
|
9652
|
+
doubleGeneration: doubleGen,
|
|
9653
|
+
multiGeneration: multiGen
|
|
9654
|
+
},
|
|
9655
|
+
modeDistribution: {
|
|
9656
|
+
standardDeterministicCount: standardCount,
|
|
9657
|
+
aiEnhancedCount: aiCount
|
|
9658
|
+
},
|
|
9659
|
+
totalAiTokensConsumed: totalTokens,
|
|
9660
|
+
activeCountriesCount: countriesSet.size,
|
|
9661
|
+
marketOpportunities
|
|
9662
|
+
};
|
|
9663
|
+
}
|
|
9664
|
+
}
|
|
9665
|
+
|
|
9460
9666
|
// src/index.ts
|
|
9461
9667
|
function createLynxSeoEngine(config) {
|
|
9462
9668
|
return new LynxSeoEngine(config);
|
|
@@ -9506,7 +9712,8 @@ var LynxSeo = {
|
|
|
9506
9712
|
translator: LynxRateLimitedTranslator,
|
|
9507
9713
|
pageRankGraph: InternalPageRankEngine,
|
|
9508
9714
|
geoCitation: GeoCitationScorer,
|
|
9509
|
-
marketingSkills: MarketingSkillsEngine
|
|
9715
|
+
marketingSkills: MarketingSkillsEngine,
|
|
9716
|
+
regenerationTracker: PageRegenerationTracker
|
|
9510
9717
|
};
|
|
9511
9718
|
var src_default = LynxSeo;
|
|
9512
9719
|
export {
|
|
@@ -9546,6 +9753,7 @@ export {
|
|
|
9546
9753
|
PublicRoutesManifestEngine,
|
|
9547
9754
|
PseoMatrixEngine,
|
|
9548
9755
|
PowerWordsPsychologyEngine,
|
|
9756
|
+
PageRegenerationTracker,
|
|
9549
9757
|
PSEO_AGENT_SYSTEM_PROMPT,
|
|
9550
9758
|
OgImageGenerator,
|
|
9551
9759
|
NGramDensityAnalyzer,
|
package/dist/index.mjs
CHANGED
|
@@ -3787,7 +3787,7 @@ class PseoMatrixEngine {
|
|
|
3787
3787
|
])
|
|
3788
3788
|
]
|
|
3789
3789
|
};
|
|
3790
|
-
|
|
3790
|
+
const pageItem = {
|
|
3791
3791
|
matrixFamily: "local-geo",
|
|
3792
3792
|
urlPath,
|
|
3793
3793
|
canonicalUrl: fullUrl,
|
|
@@ -3799,7 +3799,9 @@ class PseoMatrixEngine {
|
|
|
3799
3799
|
neighboringLinks: neighborLinks,
|
|
3800
3800
|
service: s,
|
|
3801
3801
|
location: loc
|
|
3802
|
-
}
|
|
3802
|
+
};
|
|
3803
|
+
pageItem.ogImageUrl = OgImageGenerator.generateOgImageUrl(cleanDomain, pageItem, options.brandName);
|
|
3804
|
+
pages.push(pageItem);
|
|
3803
3805
|
}
|
|
3804
3806
|
}
|
|
3805
3807
|
return pages;
|
|
@@ -4145,7 +4147,7 @@ class PseoMatrixEngine {
|
|
|
4145
4147
|
generateAllMatrices(domain, data, options) {
|
|
4146
4148
|
const allPages = [];
|
|
4147
4149
|
if (data.services) {
|
|
4148
|
-
const locs = data.locations && data.locations.length > 0 ? data.locations : resolveBuiltInLocations(options.
|
|
4150
|
+
const locs = data.locations && data.locations.length > 0 ? data.locations : resolveBuiltInLocations(options.allowedCountries || options.countries || options.territories || "us");
|
|
4149
4151
|
allPages.push(...this.generateLocalGeoMatrix(domain, data.services, locs, options));
|
|
4150
4152
|
}
|
|
4151
4153
|
if (data.competitors) {
|
|
@@ -4212,30 +4214,113 @@ class PseoMatrixEngine {
|
|
|
4212
4214
|
}
|
|
4213
4215
|
resolvePage(slugOrPath, domain, data, options) {
|
|
4214
4216
|
const path = typeof slugOrPath === "string" ? slugOrPath.startsWith("/") ? slugOrPath : `/${slugOrPath}` : `/${slugOrPath.join("/")}`;
|
|
4215
|
-
const
|
|
4216
|
-
const existing = pages.find((p) => p.urlPath === path);
|
|
4217
|
-
if (existing)
|
|
4218
|
-
return existing;
|
|
4217
|
+
const lang = options.language || "en";
|
|
4219
4218
|
const segments = path.split("/").filter(Boolean);
|
|
4220
|
-
if (segments.length
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4219
|
+
if (segments.length === 0)
|
|
4220
|
+
return;
|
|
4221
|
+
const vsPrefix = this.getPrefix("vs", lang).replace(/^\//, "");
|
|
4222
|
+
if (segments[0] === vsPrefix && segments[1] && data.competitors) {
|
|
4223
|
+
const compSlug = segments[1];
|
|
4224
|
+
const matched = data.competitors.find((c) => cleanSeoSlug(c.slug, { language: lang }) === compSlug || c.slug === compSlug);
|
|
4225
|
+
if (matched) {
|
|
4226
|
+
return this.generateVsMatrix(domain, [matched], options)[0];
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
const altPrefix = this.getPrefix("alternative", lang).replace(/^\//, "");
|
|
4230
|
+
if (segments[0] === altPrefix && segments[1] && data.competitors) {
|
|
4231
|
+
const compSlug = segments[1];
|
|
4232
|
+
const matched = data.competitors.find((c) => cleanSeoSlug(c.slug, { language: lang }) === compSlug || c.slug === compSlug);
|
|
4233
|
+
if (matched) {
|
|
4234
|
+
return this.generateAlternativesMatrix(domain, [matched], options)[0];
|
|
4235
|
+
}
|
|
4236
|
+
}
|
|
4237
|
+
const pricingPrefix = this.getPrefix("pricing", lang).replace(/^\//, "");
|
|
4238
|
+
if (segments[0] === pricingPrefix && segments[1] && data.competitors) {
|
|
4239
|
+
const compSlug = segments[1];
|
|
4240
|
+
const matched = data.competitors.find((c) => cleanSeoSlug(c.slug, { language: lang }) === compSlug || c.slug === compSlug);
|
|
4241
|
+
if (matched) {
|
|
4242
|
+
return this.generatePricingMatrix(domain, [matched], options)[0];
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
const targetPrefix = this.getPrefix("target", lang).replace(/^\//, "");
|
|
4246
|
+
if (segments[0] === targetPrefix && segments[1] && data.targets) {
|
|
4247
|
+
const targetSlug = segments[1];
|
|
4248
|
+
const matched = data.targets.find((t) => cleanSeoSlug(t.slug, { language: lang }) === targetSlug || t.slug === targetSlug);
|
|
4249
|
+
if (matched) {
|
|
4250
|
+
return this.generateTargetMatrix(domain, [matched], options)[0];
|
|
4251
|
+
}
|
|
4252
|
+
}
|
|
4253
|
+
const integPrefix = this.getPrefix("integration", lang).replace(/^\//, "");
|
|
4254
|
+
if (segments[0] === integPrefix && segments[1] && data.integrations) {
|
|
4255
|
+
const integSlug = segments[1];
|
|
4256
|
+
const matched = data.integrations.find((i) => cleanSeoSlug(i.slug, { language: lang }) === integSlug || i.slug === integSlug);
|
|
4257
|
+
if (matched) {
|
|
4258
|
+
return this.generateIntegrationMatrix(domain, [matched], options)[0];
|
|
4259
|
+
}
|
|
4260
|
+
}
|
|
4261
|
+
const useCasePrefix = this.getPrefix("useCase", lang).replace(/^\//, "");
|
|
4262
|
+
if (segments[0] === useCasePrefix && segments[1] && data.useCases) {
|
|
4263
|
+
const ucSlug = segments[1];
|
|
4264
|
+
const matched = data.useCases.find((u) => cleanSeoSlug(u.slug, { language: lang }) === ucSlug || u.slug === ucSlug);
|
|
4265
|
+
if (matched) {
|
|
4266
|
+
return this.generateUseCaseMatrix(domain, [matched], options)[0];
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
const templatePrefix = this.getPrefix("template", lang).replace(/^\//, "");
|
|
4270
|
+
if (segments[0] === templatePrefix && segments[1] && data.templates) {
|
|
4271
|
+
const tSlug = segments[1];
|
|
4272
|
+
const matched = data.templates.find((t) => cleanSeoSlug(t.slug, { language: lang }) === tSlug || t.slug === tSlug);
|
|
4273
|
+
if (matched) {
|
|
4274
|
+
return this.generateTemplateMatrix(domain, [matched], options)[0];
|
|
4275
|
+
}
|
|
4276
|
+
}
|
|
4277
|
+
const glossaryPrefix = this.getPrefix("glossary", lang).replace(/^\//, "");
|
|
4278
|
+
if (segments[0] === glossaryPrefix && segments[1] && data.glossaryTerms) {
|
|
4279
|
+
const gSlug = segments[1];
|
|
4280
|
+
const matched = data.glossaryTerms.find((g) => cleanSeoSlug(g.slug, { language: lang }) === gSlug || g.slug === gSlug);
|
|
4281
|
+
if (matched) {
|
|
4282
|
+
return this.generateGlossaryMatrix(domain, [matched], options)[0];
|
|
4283
|
+
}
|
|
4284
|
+
}
|
|
4285
|
+
const calcPrefix = this.getPrefix("calculator", lang).replace(/^\//, "");
|
|
4286
|
+
if (segments[0] === calcPrefix && segments[1] && data.calculators) {
|
|
4287
|
+
const cSlug = segments[1];
|
|
4288
|
+
const matched = data.calculators.find((c) => cleanSeoSlug(c.slug, { language: lang }) === cSlug || c.slug === cSlug);
|
|
4289
|
+
if (matched) {
|
|
4290
|
+
return this.generateCalculatorMatrix(domain, [matched], options)[0];
|
|
4291
|
+
}
|
|
4292
|
+
}
|
|
4293
|
+
if (data.services && data.services.length > 0) {
|
|
4294
|
+
let serviceSlug = "";
|
|
4295
|
+
let locationSlug = "";
|
|
4296
|
+
if (segments.length === 2 && options.cleanDirectRoutes !== false) {
|
|
4297
|
+
serviceSlug = segments[0];
|
|
4298
|
+
locationSlug = segments[1];
|
|
4299
|
+
} else if (segments.length >= 3 && segments[0] === this.getPrefix("solutions", lang).replace(/^\//, "")) {
|
|
4300
|
+
serviceSlug = segments[1];
|
|
4301
|
+
locationSlug = segments[segments.length - 1];
|
|
4302
|
+
}
|
|
4303
|
+
if (serviceSlug && locationSlug) {
|
|
4304
|
+
const matchedService = data.services.find((s) => cleanSeoSlug(s.slug, { language: lang }) === serviceSlug || s.slug === serviceSlug);
|
|
4305
|
+
if (matchedService) {
|
|
4306
|
+
let resolvedLoc = (data.locations || []).find((l) => cleanSeoSlug(l.slug, { language: lang }) === locationSlug || l.slug === locationSlug);
|
|
4307
|
+
if (!resolvedLoc) {
|
|
4308
|
+
const countryList = options.allowedCountries || options.countries;
|
|
4309
|
+
const fallbackCountry = Array.isArray(countryList) ? countryList[0] : typeof countryList === "string" && countryList !== "international" ? countryList : "United States";
|
|
4310
|
+
resolvedLoc = createDynamicLocation(locationSlug, fallbackCountry, {
|
|
4311
|
+
currency: options.defaultCurrency,
|
|
4312
|
+
currencySymbol: options.defaultCurrencySymbol
|
|
4313
|
+
});
|
|
4314
|
+
if (options.strictCountryBoundary && countryList) {
|
|
4315
|
+
const allowed = (Array.isArray(countryList) ? countryList : [countryList]).map((c) => c.toLowerCase());
|
|
4316
|
+
if (!allowed.includes("international") && !allowed.some((c) => resolvedLoc.country.toLowerCase().includes(c))) {
|
|
4317
|
+
return;
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4235
4320
|
}
|
|
4321
|
+
const dynamicPages = this.generateLocalGeoMatrix(domain, [matchedService], [resolvedLoc], options);
|
|
4322
|
+
return dynamicPages[0];
|
|
4236
4323
|
}
|
|
4237
|
-
const dynamicPages = this.generateLocalGeoMatrix(domain, [matchedService], [dynamicLoc], options);
|
|
4238
|
-
return dynamicPages.find((p) => p.urlPath === path) || dynamicPages[0];
|
|
4239
4324
|
}
|
|
4240
4325
|
}
|
|
4241
4326
|
return;
|
|
@@ -5045,7 +5130,20 @@ When discovering product modules, features, or services to build the SEO matrice
|
|
|
5045
5130
|
|
|
5046
5131
|
---
|
|
5047
5132
|
|
|
5048
|
-
### \
|
|
5133
|
+
### \uD83D\uDEA8 2. CRITICAL RULE: ZERO STATIC PRE-COMPILATION AT BUILD TIME (PURE RUNTIME ON-DEMAND)
|
|
5134
|
+
|
|
5135
|
+
- **❌ NEVER PRE-COMPILE CITIES OR PAGES AT BUILD TIME (\`generateStaticParams\` / \`getStaticPaths\`):**
|
|
5136
|
+
- DO NOT create static loops over 365, 61, or any hardcoded list of cities during \`next build\`.
|
|
5137
|
+
- DO NOT freeze pages into static HTML files on disk. That is NOT how high-scale programmatic SEO works.
|
|
5138
|
+
- Doing so breaks infinite dynamic expansion, causes build memory crashes, and falsely caps the website to a tiny subset of pages.
|
|
5139
|
+
- **✅ ALWAYS USE 100% RUNTIME IN-MEMORY RESOLUTION (\`resolvePage\`):**
|
|
5140
|
+
- In Next.js App Router: Always set \`export const dynamic = "force-dynamic"\` and \`export const dynamicParams = true\`.
|
|
5141
|
+
- When an incoming request arrives (e.g. \`/solutions/ac-repair/austin\`, \`/solutions/ac-repair/paris\`, \`/solutions/ac-repair/90210\`), the server executes \`matrixEngine.resolvePage([service, location], ...)\` in RAM in \`< 0.05ms\`.
|
|
5142
|
+
- Build time remains **under 3 seconds** because 0 localized landing pages are built ahead of time. Every page is synthesized on demand.
|
|
5143
|
+
|
|
5144
|
+
---
|
|
5145
|
+
|
|
5146
|
+
### \uD83C\uDF10 3. ARCHITECTURAL RULE: THE WEBSITE OWNS ITS LANGUAGES (i18n)
|
|
5049
5147
|
|
|
5050
5148
|
- **The Website (Application) is the sole owner of its languages, routes, and translations:**
|
|
5051
5149
|
- The website provides its own localized routes (e.g. \`app/[locale]/[...slug]/page.tsx\`) and dictionary files (\`next-intl\`, \`i18next\`, Astro i18n).
|
|
@@ -5308,7 +5406,7 @@ The SDK equips applications with 9 enterprise-grade SEO engines:
|
|
|
5308
5406
|
- Boosts dwell time, organic backlinks, and visitor-to-customer conversion.
|
|
5309
5407
|
|
|
5310
5408
|
8. **\uD83C\uDFDB️ Google Schema.org Rich Graphs (\`ExtendedSchemaGraphBuilder\`):**
|
|
5311
|
-
- \`buildAggregateRating\` (Google
|
|
5409
|
+
- \`buildAggregateRating\` (Verified live reviews synced from Google Places / Trustpilot / WooCommerce), \`buildAggregateOffer\` (price ranges), \`buildLocalBusiness\` (GPS & opening hours), \`buildSoftwareApplication\`, \`buildHowTo\`, \`buildFAQPage\`, \`buildBreadcrumbs\`.
|
|
5312
5410
|
|
|
5313
5411
|
9. **\uD83D\uDD0D URL Decomposition & Analysis (\`UrlyticsEngine\`):**
|
|
5314
5412
|
- Deep structural directory decomposition, depth tracking, query parameter analysis, and slug tokenization (inspired by advertools).
|
|
@@ -9457,6 +9555,114 @@ class MarketingSkillsEngine {
|
|
|
9457
9555
|
}
|
|
9458
9556
|
}
|
|
9459
9557
|
|
|
9558
|
+
// src/generation-tracker.ts
|
|
9559
|
+
class PageRegenerationTracker {
|
|
9560
|
+
records = new Map;
|
|
9561
|
+
demandSignals = new Map;
|
|
9562
|
+
recordGeneration(params) {
|
|
9563
|
+
const key = params.urlPath.trim().toLowerCase();
|
|
9564
|
+
const existing = this.records.get(key);
|
|
9565
|
+
const now = new Date().toISOString();
|
|
9566
|
+
const country = params.country || existing?.country || "United States";
|
|
9567
|
+
const language = params.language || existing?.language || "en";
|
|
9568
|
+
const service = params.service || existing?.service || "General Service";
|
|
9569
|
+
const location = params.location || existing?.location || "National";
|
|
9570
|
+
const mode = params.mode || "standard";
|
|
9571
|
+
const tokens = params.tokensConsumed || 0;
|
|
9572
|
+
if (existing) {
|
|
9573
|
+
existing.generationCount += 1;
|
|
9574
|
+
existing.mode = mode;
|
|
9575
|
+
existing.tokensConsumed += tokens;
|
|
9576
|
+
existing.lastGeneratedAt = now;
|
|
9577
|
+
this.records.set(key, existing);
|
|
9578
|
+
return existing;
|
|
9579
|
+
}
|
|
9580
|
+
const newRecord = {
|
|
9581
|
+
urlPath: key,
|
|
9582
|
+
service,
|
|
9583
|
+
location,
|
|
9584
|
+
country,
|
|
9585
|
+
language,
|
|
9586
|
+
generationCount: 1,
|
|
9587
|
+
mode,
|
|
9588
|
+
tokensConsumed: tokens,
|
|
9589
|
+
firstGeneratedAt: now,
|
|
9590
|
+
lastGeneratedAt: now
|
|
9591
|
+
};
|
|
9592
|
+
this.records.set(key, newRecord);
|
|
9593
|
+
const countryKey = country.toLowerCase();
|
|
9594
|
+
const currentSignal = this.demandSignals.get(countryKey) || { requests: 0, country };
|
|
9595
|
+
currentSignal.requests += 1;
|
|
9596
|
+
this.demandSignals.set(countryKey, currentSignal);
|
|
9597
|
+
return newRecord;
|
|
9598
|
+
}
|
|
9599
|
+
recordMarketDemand(country, requestVolume = 1) {
|
|
9600
|
+
const countryKey = country.trim().toLowerCase();
|
|
9601
|
+
const current = this.demandSignals.get(countryKey) || { requests: 0, country };
|
|
9602
|
+
current.requests += requestVolume;
|
|
9603
|
+
this.demandSignals.set(countryKey, current);
|
|
9604
|
+
}
|
|
9605
|
+
getMetricsReport() {
|
|
9606
|
+
let singleGen = 0;
|
|
9607
|
+
let doubleGen = 0;
|
|
9608
|
+
let multiGen = 0;
|
|
9609
|
+
let standardCount = 0;
|
|
9610
|
+
let aiCount = 0;
|
|
9611
|
+
let totalTokens = 0;
|
|
9612
|
+
const countriesSet = new Set;
|
|
9613
|
+
const countryPageCounts = new Map;
|
|
9614
|
+
for (const record of this.records.values()) {
|
|
9615
|
+
if (record.generationCount === 1)
|
|
9616
|
+
singleGen++;
|
|
9617
|
+
else if (record.generationCount === 2)
|
|
9618
|
+
doubleGen++;
|
|
9619
|
+
else
|
|
9620
|
+
multiGen++;
|
|
9621
|
+
if (record.mode === "ai-enhanced") {
|
|
9622
|
+
aiCount++;
|
|
9623
|
+
totalTokens += record.tokensConsumed;
|
|
9624
|
+
} else {
|
|
9625
|
+
standardCount++;
|
|
9626
|
+
}
|
|
9627
|
+
countriesSet.add(record.country);
|
|
9628
|
+
const cKey = record.country.toLowerCase();
|
|
9629
|
+
countryPageCounts.set(cKey, (countryPageCounts.get(cKey) || 0) + 1);
|
|
9630
|
+
}
|
|
9631
|
+
const marketOpportunities = [];
|
|
9632
|
+
for (const [countryKey, signal] of this.demandSignals.entries()) {
|
|
9633
|
+
const indexedPages = countryPageCounts.get(countryKey) || 0;
|
|
9634
|
+
const countryFormatted = signal.country.charAt(0).toUpperCase() + signal.country.slice(1);
|
|
9635
|
+
if (signal.requests > 100 && indexedPages < 20) {
|
|
9636
|
+
marketOpportunities.push({
|
|
9637
|
+
country: countryFormatted,
|
|
9638
|
+
countryCode: countryKey.slice(0, 2).toUpperCase(),
|
|
9639
|
+
detectedRequests: signal.requests,
|
|
9640
|
+
activeIndexedPages: indexedPages,
|
|
9641
|
+
coverageStatus: "opportunity_detected",
|
|
9642
|
+
estimatedMonthlyTrafficUpside: Math.round(signal.requests * 3.4),
|
|
9643
|
+
recommendation: `High demand detected in ${countryFormatted} (${signal.requests} hits). Upgrade to Pro Growth or activate ${countryFormatted} in SEO_CONFIG to capture +${Math.round(signal.requests * 3.4)} visits/month.`
|
|
9644
|
+
});
|
|
9645
|
+
}
|
|
9646
|
+
}
|
|
9647
|
+
return {
|
|
9648
|
+
uniquePagesCount: this.records.size,
|
|
9649
|
+
totalGenerationCycles: singleGen + doubleGen * 2 + multiGen * 3,
|
|
9650
|
+
regenerationFrequency: {
|
|
9651
|
+
singleGeneration: singleGen,
|
|
9652
|
+
doubleGeneration: doubleGen,
|
|
9653
|
+
multiGeneration: multiGen
|
|
9654
|
+
},
|
|
9655
|
+
modeDistribution: {
|
|
9656
|
+
standardDeterministicCount: standardCount,
|
|
9657
|
+
aiEnhancedCount: aiCount
|
|
9658
|
+
},
|
|
9659
|
+
totalAiTokensConsumed: totalTokens,
|
|
9660
|
+
activeCountriesCount: countriesSet.size,
|
|
9661
|
+
marketOpportunities
|
|
9662
|
+
};
|
|
9663
|
+
}
|
|
9664
|
+
}
|
|
9665
|
+
|
|
9460
9666
|
// src/index.ts
|
|
9461
9667
|
function createLynxSeoEngine(config) {
|
|
9462
9668
|
return new LynxSeoEngine(config);
|
|
@@ -9506,7 +9712,8 @@ var LynxSeo = {
|
|
|
9506
9712
|
translator: LynxRateLimitedTranslator,
|
|
9507
9713
|
pageRankGraph: InternalPageRankEngine,
|
|
9508
9714
|
geoCitation: GeoCitationScorer,
|
|
9509
|
-
marketingSkills: MarketingSkillsEngine
|
|
9715
|
+
marketingSkills: MarketingSkillsEngine,
|
|
9716
|
+
regenerationTracker: PageRegenerationTracker
|
|
9510
9717
|
};
|
|
9511
9718
|
var src_default = LynxSeo;
|
|
9512
9719
|
export {
|
|
@@ -9546,6 +9753,7 @@ export {
|
|
|
9546
9753
|
PublicRoutesManifestEngine,
|
|
9547
9754
|
PseoMatrixEngine,
|
|
9548
9755
|
PowerWordsPsychologyEngine,
|
|
9756
|
+
PageRegenerationTracker,
|
|
9549
9757
|
PSEO_AGENT_SYSTEM_PROMPT,
|
|
9550
9758
|
OgImageGenerator,
|
|
9551
9759
|
NGramDensityAnalyzer,
|