veryfront 0.1.748 → 0.1.749
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/esm/cli/templates/manifest.js +2 -2
- package/esm/deno.js +1 -1
- package/esm/src/build/production-build/static-generation.d.ts.map +1 -1
- package/esm/src/build/production-build/static-generation.js +2 -0
- package/esm/src/cache/backends/disk.d.ts +1 -1
- package/esm/src/cache/backends/disk.d.ts.map +1 -1
- package/esm/src/cache/backends/disk.js +41 -13
- package/esm/src/cache/backends/glob.d.ts +6 -0
- package/esm/src/cache/backends/glob.d.ts.map +1 -0
- package/esm/src/cache/backends/glob.js +41 -0
- package/esm/src/cache/backends/memory.d.ts +1 -1
- package/esm/src/cache/backends/memory.d.ts.map +1 -1
- package/esm/src/cache/backends/memory.js +14 -12
- package/esm/src/cache/backends/redis.d.ts.map +1 -1
- package/esm/src/cache/backends/redis.js +33 -7
- package/esm/src/cache/dependency-graph.d.ts +1 -0
- package/esm/src/cache/dependency-graph.d.ts.map +1 -1
- package/esm/src/cache/dependency-graph.js +15 -1
- package/esm/src/cache/paths.d.ts.map +1 -1
- package/esm/src/cache/paths.js +5 -0
- package/esm/src/embedding/index.d.ts +4 -1
- package/esm/src/embedding/index.d.ts.map +1 -1
- package/esm/src/embedding/index.js +3 -1
- package/esm/src/embedding/rag-store.d.ts.map +1 -1
- package/esm/src/embedding/rag-store.js +157 -8
- package/esm/src/embedding/react/use-uploads.d.ts +1 -0
- package/esm/src/embedding/react/use-uploads.d.ts.map +1 -1
- package/esm/src/embedding/react/use-uploads.js +4 -1
- package/esm/src/embedding/upload-handler.d.ts +29 -8
- package/esm/src/embedding/upload-handler.d.ts.map +1 -1
- package/esm/src/embedding/upload-handler.js +66 -6
- package/esm/src/html/html-shell-generator.js +5 -5
- package/esm/src/html/nonce-injection.d.ts.map +1 -1
- package/esm/src/html/nonce-injection.js +11 -4
- package/esm/src/html/utils.d.ts +5 -0
- package/esm/src/html/utils.d.ts.map +1 -1
- package/esm/src/html/utils.js +19 -9
- package/esm/src/modules/react-loader/ssr-module-loader/import-rewriter.d.ts.map +1 -1
- package/esm/src/modules/react-loader/ssr-module-loader/import-rewriter.js +12 -5
- package/esm/src/modules/server/module-batch-handler.d.ts +1 -0
- package/esm/src/modules/server/module-batch-handler.d.ts.map +1 -1
- package/esm/src/modules/server/module-batch-handler.js +52 -26
- package/esm/src/modules/server/module-server.d.ts.map +1 -1
- package/esm/src/modules/server/module-server.js +87 -69
- package/esm/src/modules/server/module-source-resolution-cache.d.ts +16 -0
- package/esm/src/modules/server/module-source-resolution-cache.d.ts.map +1 -0
- package/esm/src/modules/server/module-source-resolution-cache.js +43 -0
- package/esm/src/oauth/providers/base.d.ts +0 -2
- package/esm/src/oauth/providers/base.d.ts.map +1 -1
- package/esm/src/oauth/providers/base.js +35 -10
- package/esm/src/oauth/token-store/memory.d.ts +7 -0
- package/esm/src/oauth/token-store/memory.d.ts.map +1 -1
- package/esm/src/oauth/token-store/memory.js +14 -1
- package/esm/src/observability/file-log-subscriber.d.ts +1 -0
- package/esm/src/observability/file-log-subscriber.d.ts.map +1 -1
- package/esm/src/observability/file-log-subscriber.js +2 -1
- package/esm/src/observability/tracing/api-shim.d.ts +1 -0
- package/esm/src/observability/tracing/api-shim.d.ts.map +1 -1
- package/esm/src/observability/tracing/api-shim.js +7 -0
- package/esm/src/observability/tracing/otlp-setup.d.ts.map +1 -1
- package/esm/src/observability/tracing/otlp-setup.js +17 -7
- package/esm/src/proxy/handler.d.ts +5 -2
- package/esm/src/proxy/handler.d.ts.map +1 -1
- package/esm/src/proxy/handler.js +26 -25
- package/esm/src/proxy/main.js +8 -11
- package/esm/src/rendering/renderer.d.ts.map +1 -1
- package/esm/src/rendering/renderer.js +32 -12
- package/esm/src/server/context/cache-invalidation.d.ts.map +1 -1
- package/esm/src/server/context/cache-invalidation.js +2 -0
- package/esm/src/server/handlers/dev/scripts/error-overlay.d.ts.map +1 -1
- package/esm/src/server/handlers/dev/scripts/error-overlay.js +32 -18
- package/esm/src/server/handlers/monitoring/client-log.handler.d.ts +1 -0
- package/esm/src/server/handlers/monitoring/client-log.handler.d.ts.map +1 -1
- package/esm/src/server/handlers/monitoring/client-log.handler.js +39 -5
- package/esm/src/server/handlers/request/module/batch-module-handler.d.ts.map +1 -1
- package/esm/src/server/handlers/request/module/batch-module-handler.js +2 -1
- package/esm/src/utils/logger/redact.d.ts.map +1 -1
- package/esm/src/utils/logger/redact.js +13 -1
- package/esm/src/utils/redis-client.d.ts +1 -0
- package/esm/src/utils/redis-client.d.ts.map +1 -1
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
|
@@ -50,8 +50,8 @@ export default {
|
|
|
50
50
|
"agents/rag.ts": "import { agent } from \"veryfront/agent\";\n\nexport default agent({\n id: \"rag\",\n system:\n `You answer questions using the provided documents. ` +\n `Always cite your sources by referencing the document title. ` +\n `If the search results don't contain a clear answer, say so honestly.`,\n});\n",
|
|
51
51
|
"app/api/ag-ui/route.ts": "import { createAgUiHandler } from \"veryfront/agent\";\nimport { store } from \"../../../store.ts\";\n\nexport const POST = createAgUiHandler(\"rag\", {\n beforeStream: async ({ lastUserText }) => {\n const query = lastUserText.trim();\n if (!query) return;\n\n try {\n const results = await store.search(query, { topK: 5 });\n if (results.length === 0) return;\n\n const contextBlock = results\n .map(\n (result) =>\n `[${result.title}] (score: ${\n result.score.toFixed(2)\n })\\n${result.text}`,\n )\n .join(\"\\n\\n---\\n\\n\");\n\n return {\n prepend: [\n {\n role: \"system\",\n parts: [\n {\n type: \"text\",\n text:\n `Here are relevant documents retrieved for your question:\\n\\n${contextBlock}\\n\\n` +\n \"Use these documents to answer. Cite the document title when referencing information.\",\n },\n ],\n },\n ],\n };\n } catch (e) {\n console.error(\"[RAG] Retrieval failed:\", e);\n return;\n }\n },\n});\n",
|
|
52
52
|
"app/api/ingest/route.ts": "import { store } from \"../../../store.ts\";\n\nexport async function POST() {\n await store.indexContentDir();\n return Response.json({ ok: true });\n}\n",
|
|
53
|
-
"app/api/uploads/[id]/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../../store.ts\";\n\nexport const { DELETE } = createUploadHandler(store);\n",
|
|
54
|
-
"app/api/uploads/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../store.ts\";\n\nexport const { POST, GET } = createUploadHandler(store);\n",
|
|
53
|
+
"app/api/uploads/[id]/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../../store.ts\";\n\nexport const { DELETE } = createUploadHandler(store, {\n auth: { type: \"none\", allowUnauthenticated: true },\n});\n",
|
|
54
|
+
"app/api/uploads/route.ts": "import { createUploadHandler } from \"veryfront/embedding\";\nimport { store } from \"../../../store.ts\";\n\nexport const { POST, GET } = createUploadHandler(store, {\n auth: { type: \"none\", allowUnauthenticated: true },\n});\n",
|
|
55
55
|
"app/layout.tsx": "import \"../globals.css\";\nimport { Head } from \"veryfront/head\";\n\nexport default function RootLayout({ children }: { children: React.ReactNode }): React.ReactNode {\n return (\n <>\n <Head><title>Docs Agent</title></Head>\n <div className=\"flex flex-col h-screen\">\n {children}\n </div>\n </>\n );\n}\n",
|
|
56
56
|
"app/page.tsx": "'use client'\n\nimport { useState, useEffect, useCallback, useMemo } from 'react'\nimport { ChatWithSidebar, useChat, type QuickAction } from 'veryfront/chat'\n\nconst UPLOAD_API = '/api/uploads'\nconst ACCEPT = '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.csv,.txt,.md,.mdx,.html,.rtf,.epub,.json,.xml'\n\nconst QUICK_ACTIONS: QuickAction[] = [\n { id: 'ask-question', label: 'Ask Question', prompt: 'I have a question about this document: ' },\n { id: 'extract-insights', label: 'Extract Insights', prompt: 'Extract the key insights from the uploaded documents.' },\n { id: 'find-sources', label: 'Find Sources', prompt: 'Find relevant sources and references in the documents for: ' },\n]\n\ninterface Doc { id: string; title: string; source: string; url?: string }\n\nfunction useUploads(api: string) {\n const [docs, setDocs] = useState<Doc[]>([])\n const [uploading, setUploading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const refresh = useCallback(async () => {\n try {\n const res = await fetch(api)\n if (res.ok) {\n const data = await res.json()\n setDocs(Array.isArray(data) ? data : data.uploads ?? [])\n }\n } catch { /* ignore */ }\n }, [api])\n\n useEffect(() => { refresh() }, [refresh])\n\n const upload = useCallback(async (file: File) => {\n setUploading(true)\n setError(null)\n try {\n const form = new FormData()\n form.append('file', file)\n const res = await fetch(api, { method: 'POST', body: form })\n if (!res.ok) throw new Error(await res.text())\n await refresh()\n } catch (e) {\n setError(e instanceof Error ? e.message : 'Upload failed')\n } finally {\n setUploading(false)\n }\n }, [api, refresh])\n\n const remove = useCallback(async (id: string) => {\n await fetch(`${api}/${id}`, { method: 'DELETE' })\n await refresh()\n }, [api, refresh])\n\n const uploads = useMemo(\n () => docs.filter((d) => d.source.startsWith('upload:')),\n [docs],\n )\n\n return { uploads, uploading, error, upload, remove }\n}\n\nexport default function DocsChat() {\n const chat = useChat({ api: '/api/ag-ui' })\n const docs = useUploads(UPLOAD_API)\n\n const attachmentItems = useMemo(() => {\n const items = docs.uploads.map((d) => ({\n id: d.id,\n name: d.title,\n status: 'ready' as const,\n }))\n if (docs.uploading) {\n items.push({ id: '__uploading', name: 'Uploading...', status: 'uploading' as const })\n }\n return items\n }, [docs.uploads, docs.uploading])\n\n const uploadFiles = useMemo(\n () => docs.uploads.map((d) => ({ id: d.id, name: d.title, url: d.url })),\n [docs.uploads],\n )\n\n const handleAttach = useCallback((files: FileList) => {\n for (const file of Array.from(files)) {\n docs.upload(file)\n }\n }, [docs.upload])\n\n const handleQuickAction = useCallback((action: QuickAction) => {\n if (action.prompt) chat.setInput(action.prompt)\n }, [chat.setInput])\n\n return (\n <ChatWithSidebar\n chat={chat}\n sidebar={{ storageKey: 'rag-threads' }}\n features={{ steps: true, tabs: true, sources: true, export: true }}\n models={{\n options: [\n {\n value: 'anthropic/claude-sonnet-4-6',\n label: 'Claude Sonnet',\n },\n {\n value: 'openai/gpt-4.1-mini',\n label: 'GPT-4.1 Mini',\n },\n {\n value: 'google/gemini-2.5-flash',\n label: 'Gemini 2.5 Flash',\n badge: 'Fast',\n },\n ],\n }}\n attachments={{\n uploads: uploadFiles,\n onRemoveUpload: docs.remove,\n onAttach: handleAttach,\n accept: ACCEPT,\n items: attachmentItems,\n onRemoveItem: docs.remove,\n }}\n quickActions={{\n actions: QUICK_ACTIONS,\n onAction: handleQuickAction,\n }}\n message={{\n renderTool: () => null,\n }}\n className=\"flex-1 min-h-0\"\n placeholder=\"Ask anything about your documents...\"\n emptyState={{ title: 'Docs Agent', description: 'Upload files and ask questions' }}\n />\n )\n}\n",
|
|
57
57
|
"content/architecture.md": "# Architecture\n\nAcme Platform uses a modular, event-driven architecture.\n\n## Core Components\n\n### API Gateway\nRoutes incoming requests to the appropriate microservice. Handles authentication, rate limiting, and request validation.\n\n### Event Bus\nAsynchronous message broker connecting all services. Supports pub/sub and point-to-point messaging patterns.\n\n### Data Layer\nMulti-tenant data storage with automatic sharding. Supports PostgreSQL for relational data and Redis for caching.\n\n## Request Flow\n\n1. Client sends request to API Gateway\n2. Gateway validates authentication token\n3. Request is routed to the target service\n4. Service processes request and publishes events\n5. Response is returned through the gateway\n\n## Scaling\n\nEach component scales independently. The API Gateway uses horizontal scaling with load balancing. Services auto-scale based on queue depth and CPU utilization.\n\n## Security\n\n- All inter-service communication uses mTLS\n- API tokens are rotated every 24 hours\n- Data at rest is encrypted with AES-256\n- Audit logs are retained for 90 days\n",
|
package/esm/deno.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-generation.d.ts","sourceRoot":"","sources":["../../../../src/src/build/production-build/static-generation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAa3E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,KAAK,GAAG,WAAW,CAAC;KAC3B,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,mGAAmG;IACnG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAClE,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAsHD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EAAE,EACnB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"static-generation.d.ts","sourceRoot":"","sources":["../../../../src/src/build/production-build/static-generation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAa3E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,KAAK,GAAG,WAAW,CAAC;KAC3B,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,mGAAmG;IACnG,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAClE,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAsHD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EAAE,EACnB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,QAAQ,CAAC,CAqGnB;AAED,wBAAsB,cAAc,CAClC,SAAS,EAAE,YAAY,EAAE,EACzB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,QAAQ,CAAC,CAkDnB"}
|
|
@@ -134,12 +134,14 @@ ${clientStyles}
|
|
|
134
134
|
if (dryRun) {
|
|
135
135
|
stats.pages++;
|
|
136
136
|
stats.totalSize += getByteLength(enhancedHtml);
|
|
137
|
+
stats.ssgPaths.push(route.path);
|
|
137
138
|
logger.debug(`Built page: ${route.slug}`);
|
|
138
139
|
continue;
|
|
139
140
|
}
|
|
140
141
|
await traceStep(`write:${route.slug}`, () => adapter.fs.writeFile(outputPath, enhancedHtml));
|
|
141
142
|
stats.pages++;
|
|
142
143
|
stats.totalSize += getByteLength(enhancedHtml);
|
|
144
|
+
stats.ssgPaths.push(route.path);
|
|
143
145
|
const pageData = {
|
|
144
146
|
slug: route.slug,
|
|
145
147
|
path: route.path,
|
|
@@ -2,7 +2,7 @@ import type { CacheBackend } from "../types.js";
|
|
|
2
2
|
export declare class DiskCacheBackend implements CacheBackend {
|
|
3
3
|
readonly type: "disk";
|
|
4
4
|
private dir;
|
|
5
|
-
private
|
|
5
|
+
private globCache;
|
|
6
6
|
constructor(baseDir?: string, keyPrefix?: string);
|
|
7
7
|
private filePath;
|
|
8
8
|
private ensureDir;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disk.d.ts","sourceRoot":"","sources":["../../../../src/src/cache/backends/disk.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"disk.d.ts","sourceRoot":"","sources":["../../../../src/src/cache/backends/disk.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgDhD,qBAAa,gBAAiB,YAAW,YAAY;IACnD,QAAQ,CAAC,IAAI,EAAG,MAAM,CAAU;IAChC,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,SAAS,CAAgC;gBAErC,OAAO,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;IAKhD,OAAO,CAAC,QAAQ;YAIF,SAAS;IAKjB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA8BxC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB/B,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA4CrD"}
|
|
@@ -2,9 +2,30 @@ import * as dntShim from "../../../_dnt.shims.js";
|
|
|
2
2
|
import { join } from "../../platform/compat/path/index.js";
|
|
3
3
|
import { getCacheBaseDir } from "../../utils/cache-dir.js";
|
|
4
4
|
import { logger } from "../../utils/index.js";
|
|
5
|
+
import { compileCacheGlob } from "./glob.js";
|
|
5
6
|
const CACHE_SUBDIR = "veryfront-files";
|
|
6
|
-
const
|
|
7
|
+
const MAX_GLOB_CACHE_SIZE = 100;
|
|
7
8
|
const fsPromises = import("node:fs/promises");
|
|
9
|
+
function isRecord(value) {
|
|
10
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11
|
+
}
|
|
12
|
+
function parseDiskCacheEnvelope(value) {
|
|
13
|
+
if (!isRecord(value))
|
|
14
|
+
return null;
|
|
15
|
+
if (typeof value.key !== "string")
|
|
16
|
+
return null;
|
|
17
|
+
if (typeof value.value !== "string")
|
|
18
|
+
return null;
|
|
19
|
+
if (value.expiresAt !== undefined &&
|
|
20
|
+
(typeof value.expiresAt !== "number" || !Number.isFinite(value.expiresAt))) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
key: value.key,
|
|
25
|
+
value: value.value,
|
|
26
|
+
expiresAt: value.expiresAt,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
8
29
|
function hashKey(input) {
|
|
9
30
|
const seeds = [0x811c9dc5, 0x6c62272e, 0x2e726c6f, 0x636f6465];
|
|
10
31
|
return seeds
|
|
@@ -21,7 +42,7 @@ function hashKey(input) {
|
|
|
21
42
|
export class DiskCacheBackend {
|
|
22
43
|
type = "disk";
|
|
23
44
|
dir;
|
|
24
|
-
|
|
45
|
+
globCache = new Map();
|
|
25
46
|
constructor(baseDir, keyPrefix) {
|
|
26
47
|
const base = join(baseDir ?? getCacheBaseDir(), CACHE_SUBDIR);
|
|
27
48
|
this.dir = keyPrefix ? join(base, keyPrefix) : base;
|
|
@@ -37,7 +58,9 @@ export class DiskCacheBackend {
|
|
|
37
58
|
try {
|
|
38
59
|
const { readFile } = await fsPromises;
|
|
39
60
|
const raw = await readFile(this.filePath(key), "utf-8");
|
|
40
|
-
const envelope = JSON.parse(raw);
|
|
61
|
+
const envelope = parseDiskCacheEnvelope(JSON.parse(raw));
|
|
62
|
+
if (!envelope)
|
|
63
|
+
return null;
|
|
41
64
|
if (envelope.key !== key)
|
|
42
65
|
return null;
|
|
43
66
|
if (envelope.expiresAt != null && Date.now() > envelope.expiresAt) {
|
|
@@ -106,16 +129,17 @@ export class DiskCacheBackend {
|
|
|
106
129
|
}
|
|
107
130
|
}
|
|
108
131
|
async delByPattern(pattern) {
|
|
109
|
-
let
|
|
110
|
-
if (!
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
132
|
+
let glob = this.globCache.get(pattern);
|
|
133
|
+
if (!glob) {
|
|
134
|
+
glob = compileCacheGlob(pattern) ?? undefined;
|
|
135
|
+
if (!glob)
|
|
136
|
+
return 0;
|
|
137
|
+
if (this.globCache.size >= MAX_GLOB_CACHE_SIZE) {
|
|
138
|
+
const firstKey = this.globCache.keys().next().value;
|
|
115
139
|
if (firstKey)
|
|
116
|
-
this.
|
|
140
|
+
this.globCache.delete(firstKey);
|
|
117
141
|
}
|
|
118
|
-
this.
|
|
142
|
+
this.globCache.set(pattern, glob);
|
|
119
143
|
}
|
|
120
144
|
let deleted = 0;
|
|
121
145
|
try {
|
|
@@ -127,8 +151,12 @@ export class DiskCacheBackend {
|
|
|
127
151
|
try {
|
|
128
152
|
const filePath = join(this.dir, file);
|
|
129
153
|
const raw = await readFile(filePath, "utf-8");
|
|
130
|
-
const envelope = JSON.parse(raw);
|
|
131
|
-
if (
|
|
154
|
+
const envelope = parseDiskCacheEnvelope(JSON.parse(raw));
|
|
155
|
+
if (!envelope) {
|
|
156
|
+
logger.error("[DiskCache] Skip invalid cache file", { file });
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (glob.test(envelope.key)) {
|
|
132
160
|
await unlink(filePath);
|
|
133
161
|
deleted++;
|
|
134
162
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../../../src/src/cache/backends/glob.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9B;AAsCD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CASlE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const MAX_CACHE_GLOB_WILDCARDS = 64;
|
|
2
|
+
function matchesGlob(pattern, value) {
|
|
3
|
+
let patternIndex = 0;
|
|
4
|
+
let valueIndex = 0;
|
|
5
|
+
let starIndex = -1;
|
|
6
|
+
let starValueIndex = 0;
|
|
7
|
+
while (valueIndex < value.length) {
|
|
8
|
+
const patternChar = pattern[patternIndex];
|
|
9
|
+
if (patternChar === "?" || patternChar === value[valueIndex]) {
|
|
10
|
+
patternIndex++;
|
|
11
|
+
valueIndex++;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
if (patternChar === "*") {
|
|
15
|
+
starIndex = patternIndex;
|
|
16
|
+
starValueIndex = valueIndex;
|
|
17
|
+
patternIndex++;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (starIndex !== -1) {
|
|
21
|
+
patternIndex = starIndex + 1;
|
|
22
|
+
starValueIndex++;
|
|
23
|
+
valueIndex = starValueIndex;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
while (pattern[patternIndex] === "*")
|
|
29
|
+
patternIndex++;
|
|
30
|
+
return patternIndex === pattern.length;
|
|
31
|
+
}
|
|
32
|
+
export function compileCacheGlob(pattern) {
|
|
33
|
+
const wildcardCount = (pattern.match(/[*?]/g) ?? []).length;
|
|
34
|
+
if (wildcardCount > MAX_CACHE_GLOB_WILDCARDS)
|
|
35
|
+
return null;
|
|
36
|
+
return {
|
|
37
|
+
test(value) {
|
|
38
|
+
return matchesGlob(pattern, value);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -2,7 +2,7 @@ import type { CacheBackend } from "../types.js";
|
|
|
2
2
|
export declare class MemoryCacheBackend implements CacheBackend {
|
|
3
3
|
readonly type: "memory";
|
|
4
4
|
private store;
|
|
5
|
-
private
|
|
5
|
+
private globCache;
|
|
6
6
|
private maxEntries;
|
|
7
7
|
private readonly maxSizeBytes;
|
|
8
8
|
private currentSizeBytes;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../../src/src/cache/backends/memory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../../src/src/cache/backends/memory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAOhD,qBAAa,kBAAmB,YAAW,YAAY;IACrD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,KAAK,CAA8E;IAC3F,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,gBAAgB,CAAK;gBAEjB,UAAU,SAA2B,EAAE,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;IAKtF,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,WAAW;IAQnB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAaxC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAmB7D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,SAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BhF,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCrF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/B,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0B9C,KAAK,IAAI,IAAI;IAMb,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { MEMORY_CACHE_MAX_ENTRIES, MEMORY_CACHE_MAX_SIZE_BYTES, } from "../../utils/constants/cache.js";
|
|
2
2
|
import { buildBatchResults } from "../batch-results.js";
|
|
3
|
+
import { compileCacheGlob } from "./glob.js";
|
|
3
4
|
const DEFAULT_TTL_SECONDS = 300;
|
|
4
|
-
const
|
|
5
|
+
const MAX_GLOB_CACHE_SIZE = 100;
|
|
5
6
|
export class MemoryCacheBackend {
|
|
6
7
|
type = "memory";
|
|
7
8
|
store = new Map();
|
|
8
|
-
|
|
9
|
+
globCache = new Map();
|
|
9
10
|
maxEntries;
|
|
10
11
|
maxSizeBytes;
|
|
11
12
|
currentSizeBytes = 0;
|
|
@@ -103,20 +104,21 @@ export class MemoryCacheBackend {
|
|
|
103
104
|
return Promise.resolve();
|
|
104
105
|
}
|
|
105
106
|
delByPattern(pattern) {
|
|
106
|
-
let
|
|
107
|
-
if (!
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
let glob = this.globCache.get(pattern);
|
|
108
|
+
if (!glob) {
|
|
109
|
+
glob = compileCacheGlob(pattern) ?? undefined;
|
|
110
|
+
if (!glob)
|
|
111
|
+
return Promise.resolve(0);
|
|
112
|
+
if (this.globCache.size >= MAX_GLOB_CACHE_SIZE) {
|
|
113
|
+
const firstKey = this.globCache.keys().next().value;
|
|
112
114
|
if (firstKey)
|
|
113
|
-
this.
|
|
115
|
+
this.globCache.delete(firstKey);
|
|
114
116
|
}
|
|
115
|
-
this.
|
|
117
|
+
this.globCache.set(pattern, glob);
|
|
116
118
|
}
|
|
117
119
|
let deleted = 0;
|
|
118
120
|
for (const key of this.store.keys()) {
|
|
119
|
-
if (!
|
|
121
|
+
if (!glob.test(key))
|
|
120
122
|
continue;
|
|
121
123
|
const entry = this.store.get(key);
|
|
122
124
|
if (entry)
|
|
@@ -128,7 +130,7 @@ export class MemoryCacheBackend {
|
|
|
128
130
|
}
|
|
129
131
|
clear() {
|
|
130
132
|
this.store.clear();
|
|
131
|
-
this.
|
|
133
|
+
this.globCache.clear();
|
|
132
134
|
this.currentSizeBytes = 0;
|
|
133
135
|
}
|
|
134
136
|
get size() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../../../src/src/cache/backends/redis.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,iBAAiB,EAElB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../../../src/src/cache/backends/redis.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,iBAAiB,EAElB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQhD,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B,qBAAa,iBAAkB,YAAW,YAAY;IACpD,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IACjC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,SAAS,CAAS;gBAEd,SAAS,SAAc;IAInC,OAAO,CAAC,SAAS;IAIjB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAoBxB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAWxC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IA8B7D,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,SAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/B,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAsCrD"}
|
|
@@ -4,6 +4,8 @@ import { SpanNames } from "../../observability/tracing/span-names.js";
|
|
|
4
4
|
import { getRedisClient, isRedisConfigured, } from "../../utils/redis-client.js";
|
|
5
5
|
import { buildBatchResults } from "../batch-results.js";
|
|
6
6
|
const logger = baseLogger.component("redis-cache-backend");
|
|
7
|
+
const REDIS_PATTERN_DELETE_SCAN_COUNT = 100;
|
|
8
|
+
const REDIS_PATTERN_DELETE_BATCH_SIZE = 1000;
|
|
7
9
|
// Re-export for use by factory
|
|
8
10
|
export { isRedisConfigured };
|
|
9
11
|
export class RedisCacheBackend {
|
|
@@ -50,8 +52,18 @@ export class RedisCacheBackend {
|
|
|
50
52
|
return buildBatchResults(keys, () => null);
|
|
51
53
|
}
|
|
52
54
|
try {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
+
const prefixedKeys = keys.map((key) => this.prefixKey(key));
|
|
56
|
+
let fetched;
|
|
57
|
+
try {
|
|
58
|
+
fetched = await this.client.mGet(prefixedKeys);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
logger.debug("GetBatch MGET failed, falling back to GET", { keyCount: keys.length, error });
|
|
62
|
+
const fallbackFetched = await Promise.all(keys.map(async (key) => [key, await this.get(key)]));
|
|
63
|
+
const fallbackValues = new Map(fallbackFetched);
|
|
64
|
+
return buildBatchResults(keys, (key) => fallbackValues.get(key) ?? null);
|
|
65
|
+
}
|
|
66
|
+
const values = new Map(keys.map((key, index) => [key, fetched[index] ?? null]));
|
|
55
67
|
return buildBatchResults(keys, (key) => values.get(key) ?? null);
|
|
56
68
|
}
|
|
57
69
|
catch (error) {
|
|
@@ -93,18 +105,32 @@ export class RedisCacheBackend {
|
|
|
93
105
|
if (!this.client)
|
|
94
106
|
return 0;
|
|
95
107
|
try {
|
|
108
|
+
const client = this.client;
|
|
96
109
|
const fullPattern = this.prefixKey(pattern);
|
|
97
110
|
let cursor = 0;
|
|
98
111
|
const keysToDelete = [];
|
|
112
|
+
let deletedCount = 0;
|
|
113
|
+
const flushDeleteBatch = async () => {
|
|
114
|
+
if (!keysToDelete.length)
|
|
115
|
+
return;
|
|
116
|
+
deletedCount += await client.del(keysToDelete.splice(0, keysToDelete.length));
|
|
117
|
+
};
|
|
99
118
|
do {
|
|
100
|
-
const result = await
|
|
119
|
+
const result = await client.scan(cursor, {
|
|
120
|
+
MATCH: fullPattern,
|
|
121
|
+
COUNT: REDIS_PATTERN_DELETE_SCAN_COUNT,
|
|
122
|
+
});
|
|
101
123
|
cursor = result.cursor;
|
|
102
|
-
if (result.keys.length)
|
|
124
|
+
if (result.keys.length) {
|
|
103
125
|
keysToDelete.push(...result.keys);
|
|
126
|
+
}
|
|
127
|
+
while (keysToDelete.length >= REDIS_PATTERN_DELETE_BATCH_SIZE) {
|
|
128
|
+
const batch = keysToDelete.splice(0, REDIS_PATTERN_DELETE_BATCH_SIZE);
|
|
129
|
+
deletedCount += await client.del(batch);
|
|
130
|
+
}
|
|
104
131
|
} while (cursor !== 0);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return await this.client.del(keysToDelete);
|
|
132
|
+
await flushDeleteBatch();
|
|
133
|
+
return deletedCount;
|
|
108
134
|
}
|
|
109
135
|
catch (error) {
|
|
110
136
|
logger.debug("DelByPattern failed", { pattern, error });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-graph.d.ts","sourceRoot":"","sources":["../../../src/src/cache/dependency-graph.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,UAAU,CAAkC;IAEpD,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI;IAczD,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAIjD,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAUrD,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAUzC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAInD,KAAK,IAAI,IAAI;IAKb,aAAa,IAAI,MAAM,EAAE;IAIzB,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,iBAAiB;CAgB1B;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGpE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAWjE;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,CAsBR;AAMD,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EAC7C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
|
1
|
+
{"version":3,"file":"dependency-graph.d.ts","sourceRoot":"","sources":["../../../src/src/cache/dependency-graph.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,UAAU,CAAkC;IAEpD,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI;IAczD,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAIjD,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAUrD,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAUzC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAInD,KAAK,IAAI,IAAI;IAKb,aAAa,IAAI,MAAM,EAAE;IAIzB,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,uBAAuB;IAsB/B,OAAO,CAAC,iBAAiB;CAgB1B;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGpE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAWjE;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,MAAM,CAsBR;AAMD,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EAC7C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
|
|
@@ -35,7 +35,7 @@ export class DependencyGraph {
|
|
|
35
35
|
return Array.from(visited);
|
|
36
36
|
}
|
|
37
37
|
wouldCreateCycle(from, to) {
|
|
38
|
-
return this.
|
|
38
|
+
return this.hasTransitiveDependency(to, from, new Set(), new Set());
|
|
39
39
|
}
|
|
40
40
|
clear() {
|
|
41
41
|
this.dependencies.clear();
|
|
@@ -54,6 +54,20 @@ export class DependencyGraph {
|
|
|
54
54
|
}
|
|
55
55
|
path.delete(filePath);
|
|
56
56
|
}
|
|
57
|
+
hasTransitiveDependency(filePath, target, visited, path) {
|
|
58
|
+
if (path.has(filePath) || visited.has(filePath))
|
|
59
|
+
return false;
|
|
60
|
+
visited.add(filePath);
|
|
61
|
+
path.add(filePath);
|
|
62
|
+
for (const dep of this.dependencies.get(filePath) ?? []) {
|
|
63
|
+
if (dep === target || this.hasTransitiveDependency(dep, target, visited, path)) {
|
|
64
|
+
path.delete(filePath);
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
path.delete(filePath);
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
57
71
|
collectDependents(filePath, visited, path) {
|
|
58
72
|
if (path.has(filePath) || visited.has(filePath))
|
|
59
73
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/src/cache/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAKxE,qCAAqC;AACrC,eAAO,MAAM,eAAe,qBAAqB,CAAC;AA+BlD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/src/cache/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAKxE,qCAAqC;AACrC,eAAO,MAAM,eAAe,qBAAqB,CAAC;AA+BlD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAM5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAK9E;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqB9D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAKhF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAC;AAErC;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAQrD"}
|
package/esm/src/cache/paths.js
CHANGED
|
@@ -46,6 +46,11 @@ const HARDCODED_PATH_PATTERNS = [
|
|
|
46
46
|
* Check if code contains hardcoded cache paths that should be tokenized.
|
|
47
47
|
*/
|
|
48
48
|
export function hasHardcodedCachePaths(code) {
|
|
49
|
+
// Fast reject: every pattern requires a "file://" prefix, so if the code
|
|
50
|
+
// contains no file:// URL at all we skip the 12 full-string regex scans.
|
|
51
|
+
// This runs on every cache write over whole (often 50-200KB) modules.
|
|
52
|
+
if (!code.includes("file://"))
|
|
53
|
+
return false;
|
|
49
54
|
return HARDCODED_PATH_PATTERNS.some((pattern) => pattern.test(code));
|
|
50
55
|
}
|
|
51
56
|
/**
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* import { ragStore, createUploadHandler } from "veryfront/embedding";
|
|
9
9
|
*
|
|
10
10
|
* const store = ragStore({});
|
|
11
|
-
* export const { POST, GET, DELETE } = createUploadHandler(store
|
|
11
|
+
* export const { POST, GET, DELETE } = createUploadHandler(store, {
|
|
12
|
+
* auth: { type: "none", allowUnauthenticated: true },
|
|
13
|
+
* });
|
|
12
14
|
* ```
|
|
13
15
|
*/
|
|
14
16
|
import "../../_dnt.polyfills.js";
|
|
@@ -23,4 +25,5 @@ export { useUploads } from "./react/use-uploads.js";
|
|
|
23
25
|
export type { UseUploadsOptions, UseUploadsResult } from "./react/use-uploads.js";
|
|
24
26
|
export { clearEmbeddingProviders, registerEmbeddingProvider, resolveEmbeddingModel, } from "./resolve.js";
|
|
25
27
|
export type { ChunkOptions, Embedding, EmbeddingConfig, RagChunk, RagDocumentMeta, RagSearchOptions, RagSearchResult, RagStore, RagStoreBackend, RagStoreConfig, RagStoreData, SearchOptions, SearchResult, VectorStore, VectorStoreConfig, } from "./types.js";
|
|
28
|
+
export type { UploadAuthorizationResult, UploadAuthorize, UploadHandlerAuthConfig, UploadHandlerConfig, } from "./upload-handler.js";
|
|
26
29
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,yBAAyB,CAAC;AAGjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,gBAAgB,IAAI,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAClF,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,YAAY,EACZ,SAAS,EACT,eAAe,EACf,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,QAAQ,EACR,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,yBAAyB,EACzB,eAAe,EACf,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC"}
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* import { ragStore, createUploadHandler } from "veryfront/embedding";
|
|
9
9
|
*
|
|
10
10
|
* const store = ragStore({});
|
|
11
|
-
* export const { POST, GET, DELETE } = createUploadHandler(store
|
|
11
|
+
* export const { POST, GET, DELETE } = createUploadHandler(store, {
|
|
12
|
+
* auth: { type: "none", allowUnauthenticated: true },
|
|
13
|
+
* });
|
|
12
14
|
* ```
|
|
13
15
|
*/
|
|
14
16
|
import "../../_dnt.polyfills.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rag-store.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/rag-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rag-store.d.ts","sourceRoot":"","sources":["../../../src/src/embedding/rag-store.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAKV,QAAQ,EAER,cAAc,EAEf,MAAM,YAAY,CAAC;AA2HpB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAkCzD"}
|