nuxt-ai-ready 0.7.8 → 0.7.9

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/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "nuxt": ">=4.0.0"
5
5
  },
6
6
  "configKey": "aiReady",
7
- "version": "0.7.8",
7
+ "version": "0.7.9",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { mkdir, writeFile, appendFile, stat, access } from 'node:fs/promises';
2
2
  import { join, dirname } from 'node:path';
3
- import { useLogger, useNuxt, addTypeTemplate, defineNuxtModule, createResolver, hasNuxtModule, addServerHandler, addPlugin } from '@nuxt/kit';
3
+ import { useLogger, useNuxt, addTemplate, addTypeTemplate, defineNuxtModule, createResolver, hasNuxtModule, addServerHandler, addPlugin } from '@nuxt/kit';
4
4
  import defu from 'defu';
5
5
  import { useSiteConfig, installNuxtSiteConfig, withSiteUrl } from 'nuxt-site-config/kit';
6
6
  import { readPackageJSON } from 'pkg-types';
@@ -333,9 +333,21 @@ function setupPrerenderHandler(dbPath, siteInfo, llmsTxtConfig) {
333
333
  }
334
334
 
335
335
  function registerTypeTemplates(_ctx) {
336
+ addTemplate({
337
+ filename: "types/ai-ready-adapter.d.ts",
338
+ getContents: () => `declare module '#ai-ready/adapter' {
339
+ import type { Connector } from 'db0'
340
+ const connector: (config: unknown) => Connector
341
+ export default connector
342
+ }
343
+ `
344
+ });
336
345
  addTypeTemplate({
337
- filename: "types/nuxt-ai-ready.d.ts",
346
+ filename: "types/nuxt-ai-ready-augments.d.ts",
338
347
  getContents: () => `// Generated by nuxt-ai-ready
348
+ /// <reference path="./ai-ready-adapter.d.ts" />
349
+ /// <reference path="./ai-ready-virtual.d.ts" />
350
+ /// <reference path="./ai-ready-db-provider.d.ts" />
339
351
  import type { MarkdownContext, PageIndexedContext } from 'nuxt-ai-ready'
340
352
  import type { HTMLToMarkdownOptions } from 'mdream'
341
353
 
@@ -347,7 +359,12 @@ declare module 'nitropack/types' {
347
359
  }
348
360
  }
349
361
 
350
- declare module '#ai-ready-virtual/read-page-data.mjs' {
362
+ export {}
363
+ `
364
+ });
365
+ addTemplate({
366
+ filename: "types/ai-ready-virtual.d.ts",
367
+ getContents: () => `declare module '#ai-ready-virtual/read-page-data.mjs' {
351
368
  export function readPageDataFromFilesystem(): Promise<{
352
369
  pages: Array<{
353
370
  route: string
@@ -365,20 +382,15 @@ declare module '#ai-ready-virtual/read-page-data.mjs' {
365
382
  declare module '#ai-ready-virtual/page-data.mjs' {
366
383
  export const pages: never[]
367
384
  }
368
-
369
- declare module '#ai-ready/adapter' {
370
- import type { Connector } from 'db0'
371
- const connector: (config: unknown) => Connector
372
- export default connector
373
- }
374
-
375
- declare module '#ai-ready/db-provider' {
385
+ `
386
+ });
387
+ addTemplate({
388
+ filename: "types/ai-ready-db-provider.d.ts",
389
+ getContents: () => `declare module '#ai-ready/db-provider' {
376
390
  import type { H3Event } from 'h3'
377
391
  import type { Connector } from 'db0'
378
392
  export function createConnector(event?: H3Event): Promise<Connector>
379
393
  }
380
-
381
- export {}
382
394
  `
383
395
  });
384
396
  }
@@ -655,7 +667,6 @@ export const errorRoutes = []`;
655
667
  indexNowKey
656
668
  };
657
669
  nuxt.options.nitro.plugins = nuxt.options.nitro.plugins || [];
658
- nuxt.options.nitro.plugins.push(resolve("./runtime/server/plugins/db-restore"));
659
670
  if (runtimeSyncEnabled)
660
671
  nuxt.options.nitro.plugins.push(resolve("./runtime/server/plugins/sitemap-seeder"));
661
672
  addServerHandler({
@@ -1,8 +1,8 @@
1
1
  import type { H3Event } from 'h3';
2
2
  import type { DatabaseAdapter } from './shared.js';
3
3
  /**
4
- * Get the database adapter instance
5
- * Cached on nitro context for request lifecycle
4
+ * Get the database adapter instance (lazy init per-request)
5
+ * No global caching to avoid async operations at global scope
6
6
  */
7
7
  export declare function useDatabase(event?: H3Event): Promise<DatabaseAdapter>;
8
8
  export type { DatabaseAdapter } from './shared.js';
@@ -1,15 +1,6 @@
1
1
  import { createConnector } from "#ai-ready/db-provider";
2
- import { useNitroApp } from "nitropack/runtime";
3
2
  import { createAdapter, initSchema } from "./shared.js";
4
- const DB_KEY = "_aiReadyDb";
5
- export function useDatabase(event) {
6
- const nitro = useNitroApp();
7
- if (!nitro[DB_KEY]) {
8
- nitro[DB_KEY] = initDatabase(event);
9
- }
10
- return nitro[DB_KEY];
11
- }
12
- async function initDatabase(event) {
3
+ export async function useDatabase(event) {
13
4
  const connector = await createConnector(event);
14
5
  if (!connector) {
15
6
  throw new Error("Failed to initialize database connector");
@@ -13,7 +13,7 @@ export interface DatabaseAdapter {
13
13
  */
14
14
  export declare function createAdapter(connector: Connector): DatabaseAdapter;
15
15
  /**
16
- * Initialize database schema with version checking
16
+ * Initialize database schema with version checking and lazy restore
17
17
  */
18
18
  export declare function initSchema(db: DatabaseAdapter): Promise<void>;
19
19
  /**
@@ -35,6 +35,33 @@ export async function initSchema(db) {
35
35
  "INSERT OR REPLACE INTO _ai_ready_info (id, version) VALUES (?, ?)",
36
36
  ["schema", SCHEMA_VERSION]
37
37
  );
38
+ if (!import.meta.prerender && !import.meta.dev) {
39
+ await restoreFromDumpIfEmpty(db);
40
+ }
41
+ }
42
+ async function restoreFromDumpIfEmpty(db) {
43
+ const row = await db.first("SELECT COUNT(*) as count FROM ai_ready_pages");
44
+ if (row && row.count > 0)
45
+ return;
46
+ try {
47
+ let dumpData = null;
48
+ const cfEnv = globalThis.__env__;
49
+ if (cfEnv?.ASSETS) {
50
+ const response = await cfEnv.ASSETS.fetch("https://placeholder/__ai-ready/pages.dump");
51
+ if (response.ok)
52
+ dumpData = await response.text();
53
+ }
54
+ if (!dumpData) {
55
+ dumpData = await globalThis.$fetch("/__ai-ready/pages.dump", {
56
+ responseType: "text"
57
+ });
58
+ }
59
+ if (!dumpData)
60
+ return;
61
+ const rows = await decompressFromBase64(dumpData);
62
+ await importDbDump(db, rows);
63
+ } catch {
64
+ }
38
65
  }
39
66
  async function checkSchemaVersion(db) {
40
67
  const info = await db.first(
@@ -8,10 +8,7 @@ export default defineTask({
8
8
  async run({ payload }) {
9
9
  if (import.meta.dev)
10
10
  return { result: {} };
11
- const mockEvent = {
12
- $fetch: globalThis.$fetch
13
- };
14
- const result = await runCron(mockEvent, {
11
+ const result = await runCron(void 0, {
15
12
  batchSize: payload?.limit
16
13
  });
17
14
  return { result };
@@ -23,4 +23,4 @@ export interface BatchIndexResult {
23
23
  * Batch index pending pages (max 50 per batch)
24
24
  * Shared logic used by poll endpoint and scheduled task
25
25
  */
26
- export declare function batchIndexPages(event: H3Event, options?: BatchIndexOptions): Promise<BatchIndexResult>;
26
+ export declare function batchIndexPages(event: H3Event | undefined, options?: BatchIndexOptions): Promise<BatchIndexResult>;
@@ -19,4 +19,4 @@ export declare function submitToIndexNow(routes: string[], config: {
19
19
  * Submit pending pages to IndexNow
20
20
  * Queries DB for pages needing sync, submits, marks as synced
21
21
  */
22
- export declare function syncToIndexNow(event: H3Event, limit?: number): Promise<IndexNowResult>;
22
+ export declare function syncToIndexNow(event: H3Event | undefined, limit?: number): Promise<IndexNowResult>;
@@ -16,6 +16,6 @@ export interface CronResult {
16
16
  /**
17
17
  * Run cron job logic - shared between scheduled task and HTTP endpoint
18
18
  */
19
- export declare function runCron(event: H3Event, options?: {
19
+ export declare function runCron(event: H3Event | undefined, options?: {
20
20
  batchSize?: number;
21
21
  }): Promise<CronResult>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-ai-ready",
3
3
  "type": "module",
4
- "version": "0.7.8",
4
+ "version": "0.7.9",
5
5
  "description": "Best practice AI & LLM discoverability for Nuxt sites.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -57,10 +57,10 @@
57
57
  "pathe": "^2.0.3",
58
58
  "pkg-types": "^2.3.0",
59
59
  "std-env": "3.10.0",
60
- "ufo": "^1.6.2"
60
+ "ufo": "^1.6.3"
61
61
  },
62
62
  "devDependencies": {
63
- "@antfu/eslint-config": "^7.0.0",
63
+ "@antfu/eslint-config": "^7.0.1",
64
64
  "@arethetypeswrong/cli": "^0.18.2",
65
65
  "@headlessui/vue": "^1.7.23",
66
66
  "@nuxt/content": "^3.10.0",
@@ -78,12 +78,12 @@
78
78
  "@vue/test-utils": "^2.4.6",
79
79
  "@vueuse/nuxt": "^14.1.0",
80
80
  "agents": "^0.3.5",
81
- "ai": "^6.0.33",
81
+ "ai": "^6.0.35",
82
82
  "better-sqlite3": "^12.6.0",
83
83
  "bumpp": "^10.4.0",
84
84
  "eslint": "^9.39.2",
85
85
  "execa": "^9.6.1",
86
- "happy-dom": "^20.1.0",
86
+ "happy-dom": "^20.3.0",
87
87
  "nuxt": "^4.2.2",
88
88
  "nuxt-site-config": "^3.2.17",
89
89
  "playwright": "^1.57.0",
@@ -1,2 +0,0 @@
1
- declare const _default: import("nitropack/types").NitroAppPlugin;
2
- export default _default;
@@ -1,26 +0,0 @@
1
- import { defineNitroPlugin } from "nitropack/runtime";
2
- import { useDatabase } from "../db/index.js";
3
- import { countPages } from "../db/queries.js";
4
- import { decompressFromBase64, importDbDump } from "../db/shared.js";
5
- import { logger } from "../logger.js";
6
- export default defineNitroPlugin(async () => {
7
- if (import.meta.prerender)
8
- return;
9
- if (import.meta.dev)
10
- return;
11
- if (await countPages() > 0) {
12
- logger.debug("[db-restore] Database already has data, skipping restore");
13
- return;
14
- }
15
- const dumpData = await globalThis.$fetch("/__ai-ready/pages.dump", {
16
- responseType: "text"
17
- }).catch(() => null);
18
- if (!dumpData) {
19
- logger.debug("[db-restore] No dump found, starting with empty database");
20
- return;
21
- }
22
- const db = await useDatabase();
23
- const rows = await decompressFromBase64(dumpData);
24
- await importDbDump(db, rows);
25
- logger.info(`[db-restore] Restored ${rows.length} pages from dump`);
26
- });