@inertiajs/core
Advanced tools
+1
-1
| // src/server.ts | ||
| import { originalPositionFor, TraceMap } from "@jridgewell/trace-mapping"; | ||
| import { createServer } from "http"; | ||
@@ -9,2 +8,3 @@ import cluster from "node:cluster"; | ||
| import * as process2 from "process"; | ||
| import { originalPositionFor, TraceMap } from "@jridgewell/trace-mapping"; | ||
@@ -11,0 +11,0 @@ // src/ssrErrors.ts |
| { | ||
| "version": 3, | ||
| "sources": ["../src/server.ts", "../src/ssrErrors.ts"], | ||
| "sourcesContent": ["import { originalPositionFor, TraceMap } from '@jridgewell/trace-mapping'\nimport { createServer, IncomingMessage, ServerResponse } from 'http'\nimport cluster from 'node:cluster'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { availableParallelism } from 'node:os'\nimport path from 'node:path'\nimport * as process from 'process'\nimport { classifySSRError, formatConsoleError, setSourceMapResolver } from './ssrErrors'\nimport { InertiaAppResponse, Page } from './types'\n\n// Cache parsed sourcemaps for performance\nconst sourceMaps = new Map<string, TraceMap>()\n\nsetSourceMapResolver((file: string, line: number, column: number) => {\n // Only resolve for bundled SSR files\n if (!file.includes('/ssr/') || !file.endsWith('.js')) {\n return null\n }\n\n const mapFile = file + '.map'\n\n if (!existsSync(mapFile)) {\n return null\n }\n\n let traceMap = sourceMaps.get(mapFile)\n\n if (!traceMap) {\n try {\n const mapContent = readFileSync(mapFile, 'utf-8')\n traceMap = new TraceMap(mapContent)\n sourceMaps.set(mapFile, traceMap)\n } catch {\n return null\n }\n }\n\n const original = originalPositionFor(traceMap, { line, column })\n\n if (original.source) {\n // Resolve the source path relative to the sourcemap location\n const mapDir = path.dirname(mapFile)\n const resolvedPath = path.resolve(mapDir, original.source)\n\n return {\n file: resolvedPath,\n line: original.line ?? line,\n column: original.column ?? column,\n }\n }\n\n return null\n})\n\ntype AppCallback = (page: Page) => InertiaAppResponse\ntype RouteHandler = (request: IncomingMessage, response: ServerResponse) => Promise<unknown>\ntype ServerOptions = {\n port?: number\n host?: string\n cluster?: boolean\n formatErrors?: boolean\n}\ntype Port = number\n\nconst readableToString: (readable: IncomingMessage) => Promise<string> = (readable) =>\n new Promise((resolve, reject) => {\n let data = ''\n readable.on('data', (chunk) => (data += chunk))\n readable.on('end', () => resolve(data))\n readable.on('error', (err) => reject(err))\n })\n\nexport default (render: AppCallback, options?: Port | ServerOptions): AppCallback => {\n const opts = typeof options === 'number' ? { port: options } : options\n const { port = 13714, host = '0.0.0.0', cluster: useCluster = false, formatErrors = true } = opts ?? {}\n\n const log = (message: string) => {\n console.log(\n useCluster && !cluster.isPrimary\n ? `[${cluster.worker?.id ?? 'N/A'} / ${cluster.worker?.process?.pid ?? 'N/A'}] ${message}`\n : message,\n )\n }\n\n if (useCluster && cluster.isPrimary) {\n log('Primary Inertia SSR server process started...')\n\n for (let i = 0; i < availableParallelism(); i++) {\n cluster.fork()\n }\n\n cluster.on('message', (_worker, message) => {\n if (message === 'shutdown') {\n for (const id in cluster.workers) {\n cluster.workers[id]?.kill()\n }\n\n process.exit()\n }\n })\n\n return render\n }\n\n const handleRender = async (request: IncomingMessage, response: ServerResponse) => {\n const page: Page = JSON.parse(await readableToString(request))\n\n // Suppress framework warnings during render (they clutter the output)\n const originalWarn = console.warn\n\n if (formatErrors) {\n console.warn = () => {}\n }\n\n try {\n const result = await render(page)\n\n response.writeHead(200, { 'Content-Type': 'application/json', Server: 'Inertia.js SSR' })\n response.write(JSON.stringify(result))\n } catch (e) {\n const error = e as Error\n\n if (!formatErrors) {\n throw error\n }\n\n const classified = classifySSRError(error, page.component, page.url)\n console.error(formatConsoleError(classified))\n\n response.writeHead(500, { 'Content-Type': 'application/json', Server: 'Inertia.js SSR' })\n response.write(JSON.stringify(classified))\n } finally {\n console.warn = originalWarn\n }\n }\n\n const routes: Record<string, RouteHandler> = {\n '/health': async () => ({ status: 'OK', timestamp: Date.now() }),\n '/shutdown': async () => {\n if (cluster.isWorker) {\n process.send?.('shutdown')\n }\n\n process.exit()\n },\n '/render': handleRender,\n '/404': async () => ({ status: 'NOT_FOUND', timestamp: Date.now() }),\n }\n\n createServer(async (request, response) => {\n const dispatchRoute = routes[request.url as string] ?? routes['/404']\n const result = await dispatchRoute(request, response)\n\n if (!response.headersSent) {\n response.writeHead(200, { 'Content-Type': 'application/json', Server: 'Inertia.js SSR' })\n response.write(JSON.stringify(result))\n }\n\n response.end()\n }).listen({ port, host }, () => log('Inertia SSR server started.'))\n\n log(`Starting SSR server on port ${port}...`)\n\n // Return the render callback so it can be exported for Vite SSR dev mode\n return render\n}\n", "/**\n * SSR Error Classification\n *\n * This module detects common SSR errors and provides helpful hints\n * to developers on how to fix them. The most common issue is using\n * browser-specific APIs (like window, document) that don't exist\n * in the Node.js server environment.\n */\n\nexport type SSRErrorType = 'browser-api' | 'component-resolution' | 'render' | 'unknown'\n\ntype SourceMapResolver = (\n file: string,\n line: number,\n column: number,\n) => { file: string; line: number; column: number } | null\n\nlet sourceMapResolver: SourceMapResolver | null = null\n\nexport function setSourceMapResolver(resolver: SourceMapResolver | null): void {\n sourceMapResolver = resolver\n}\n\nexport interface ClassifiedSSRError {\n error: string\n type: SSRErrorType\n component?: string\n url?: string\n browserApi?: string\n hint: string\n stack?: string\n sourceLocation?: string\n timestamp: string\n}\n\nconst BROWSER_APIS: Record<string, string> = {\n // Global objects\n window: 'The global window object',\n document: 'The DOM document object',\n navigator: 'The navigator object',\n location: 'The location object',\n history: 'The browser history API',\n screen: 'The screen object',\n localStorage: 'Browser local storage',\n sessionStorage: 'Browser session storage',\n\n // Viewport properties (accessed via window.X)\n innerWidth: 'Browser viewport width',\n innerHeight: 'Browser viewport height',\n outerWidth: 'Browser window width',\n outerHeight: 'Browser window height',\n scrollX: 'Horizontal scroll position',\n scrollY: 'Vertical scroll position',\n devicePixelRatio: 'The device pixel ratio',\n matchMedia: 'The matchMedia function',\n\n // Observers (commonly instantiated at module level)\n IntersectionObserver: 'The IntersectionObserver API',\n ResizeObserver: 'The ResizeObserver API',\n MutationObserver: 'The MutationObserver API',\n\n // Timing functions (commonly called at module level)\n requestAnimationFrame: 'The requestAnimationFrame function',\n requestIdleCallback: 'The requestIdleCallback function',\n\n // Constructors that might be used at module level\n Image: 'The Image constructor',\n Audio: 'The Audio constructor',\n Worker: 'The Worker constructor',\n BroadcastChannel: 'The BroadcastChannel constructor',\n\n // Network (older Node.js versions)\n fetch: 'The fetch API',\n XMLHttpRequest: 'The XMLHttpRequest API',\n}\n\nfunction detectBrowserApi(error: Error): string | null {\n const message = error.message.toLowerCase()\n\n for (const api of Object.keys(BROWSER_APIS)) {\n const patterns = [\n `${api.toLowerCase()} is not defined`,\n `'${api.toLowerCase()}' is not defined`,\n `\"${api.toLowerCase()}\" is not defined`,\n `cannot read properties of undefined (reading '${api.toLowerCase()}')`,\n `cannot read property '${api.toLowerCase()}'`,\n ]\n\n if (patterns.some((pattern) => message.includes(pattern))) {\n return api\n }\n }\n\n return null\n}\n\nfunction isComponentResolutionError(error: Error): boolean {\n const message = error.message.toLowerCase()\n\n return (\n message.includes('cannot find module') ||\n message.includes('failed to resolve') ||\n message.includes('module not found') ||\n message.includes('could not resolve')\n )\n}\n\nconst LIFECYCLE_HOOKS = 'onMounted/useEffect/onMount'\n\nfunction getBrowserApiHint(api: string): string {\n const apiDescription = BROWSER_APIS[api] || `The \"${api}\" object`\n\n if (['localStorage', 'sessionStorage'].includes(api)) {\n return (\n `${apiDescription} doesn't exist in Node.js. ` +\n `Check \"typeof ${api} !== 'undefined'\" before using it, ` +\n `or move the code to a ${LIFECYCLE_HOOKS} lifecycle hook.`\n )\n }\n\n if (['window', 'document'].includes(api)) {\n return (\n `${apiDescription} doesn't exist in Node.js. ` +\n `Wrap browser-specific code in a ${LIFECYCLE_HOOKS} lifecycle hook, ` +\n `or check \"typeof ${api} !== 'undefined'\" before using it.`\n )\n }\n\n if (['IntersectionObserver', 'ResizeObserver', 'MutationObserver'].includes(api)) {\n return (\n `${apiDescription} doesn't exist in Node.js. ` +\n `Create observers inside a ${LIFECYCLE_HOOKS} lifecycle hook, not at the module level.`\n )\n }\n\n if (['fetch', 'XMLHttpRequest'].includes(api)) {\n return (\n `${apiDescription} may not be available in all Node.js versions. ` +\n `For SSR, ensure data fetching happens on the server (in your controller) ` +\n `and is passed as props, or use a ${LIFECYCLE_HOOKS} hook for client-side fetching.`\n )\n }\n\n return (\n `${apiDescription} doesn't exist in Node.js. ` +\n `Move this code to a ${LIFECYCLE_HOOKS} lifecycle hook, or guard it with ` +\n `\"typeof ${api} !== 'undefined'\".`\n )\n}\n\nfunction getComponentResolutionHint(component?: string): string {\n const componentPart = component ? ` \"${component}\"` : ''\n\n return (\n `Could not resolve component${componentPart}. ` +\n `Check that the file exists and the path is correct. ` +\n `Ensure the component name matches the file name exactly (case-sensitive).`\n )\n}\n\nfunction getRenderErrorHint(): string {\n return (\n 'An error occurred while rendering the component. ' +\n 'Check the component for browser-specific code that runs during initialization. ' +\n 'Move any code that accesses browser APIs to a lifecycle hook.'\n )\n}\n\nfunction extractSourceLocation(stack?: string): string | undefined {\n if (!stack) {\n return undefined\n }\n\n for (const line of stack.split('\\n')) {\n if (!line.includes('at ')) {\n continue\n }\n\n if (line.includes('node_modules') || line.includes('node:')) {\n continue\n }\n\n let match = line.match(/\\(([^)]+):(\\d+):(\\d+)\\)/)\n\n if (!match) {\n match = line.match(/at\\s+(?:file:\\/\\/)?(.+):(\\d+):(\\d+)\\s*$/)\n }\n\n if (match) {\n const file = match[1].replace(/^file:\\/\\//, '')\n const lineNum = parseInt(match[2], 10)\n const colNum = parseInt(match[3], 10)\n\n if (sourceMapResolver) {\n const resolved = sourceMapResolver(file, lineNum, colNum)\n\n if (resolved) {\n return `${resolved.file}:${resolved.line}:${resolved.column}`\n }\n }\n\n return `${file}:${lineNum}:${colNum}`\n }\n }\n\n return undefined\n}\n\nexport function classifySSRError(error: Error, component?: string, url?: string): ClassifiedSSRError {\n const timestamp = new Date().toISOString()\n const base = {\n error: error.message,\n component,\n url,\n stack: error.stack,\n sourceLocation: extractSourceLocation(error.stack),\n timestamp,\n }\n\n const browserApi = detectBrowserApi(error)\n\n if (browserApi) {\n return {\n ...base,\n type: 'browser-api',\n browserApi,\n hint: getBrowserApiHint(browserApi),\n }\n }\n\n if (isComponentResolutionError(error)) {\n return {\n ...base,\n type: 'component-resolution',\n hint: getComponentResolutionHint(component),\n }\n }\n\n return {\n ...base,\n type: 'render',\n hint: getRenderErrorHint(),\n }\n}\n\nconst colors = {\n reset: '\\x1b[0m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n cyan: '\\x1b[36m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n bgRed: '\\x1b[41m',\n white: '\\x1b[37m',\n}\n\nfunction makeRelative(path: string, root?: string): string {\n const base = root ?? process.cwd()\n\n if (path.startsWith(base + '/')) {\n return path.slice(base.length + 1)\n }\n\n return path\n}\n\nexport function formatConsoleError(\n classified: ClassifiedSSRError,\n root?: string,\n formatErrors: boolean = true,\n suppressedWarnings: string[] = [],\n): string {\n if (!formatErrors) {\n const component = classified.component ? `[${classified.component}]` : ''\n return `SSR Error ${component}: ${classified.error}`\n }\n\n const componentPart = classified.component ? ` ${colors.cyan}${classified.component}${colors.reset}` : ''\n\n const lines = [\n '',\n ` ${colors.bgRed}${colors.white}${colors.bold} SSR ERROR ${colors.reset}${componentPart}`,\n '',\n ` ${classified.error}`,\n ]\n\n if (classified.sourceLocation) {\n const relativePath = makeRelative(classified.sourceLocation, root)\n lines.push(` ${colors.dim}Source: ${relativePath}${colors.reset}`)\n }\n\n if (classified.url) {\n lines.push(` ${colors.dim}URL: ${classified.url}${colors.reset}`)\n }\n\n lines.push('', ` ${colors.yellow}Hint${colors.reset} ${classified.hint}`, '')\n\n if (classified.stack) {\n lines.push(` ${colors.dim}${classified.stack.split('\\n').join('\\n ')}${colors.reset}`, '')\n }\n\n if (suppressedWarnings.length > 0) {\n lines.push(` ${colors.dim}Suppressed ${suppressedWarnings.length} framework warning(s).${colors.reset}`, '')\n }\n\n return lines.join('\\n')\n}\n"], | ||
| "mappings": "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", | ||
| "sourcesContent": ["import { createServer, IncomingMessage, ServerResponse } from 'http'\nimport cluster from 'node:cluster'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { availableParallelism } from 'node:os'\nimport path from 'node:path'\nimport * as process from 'process'\nimport { originalPositionFor, TraceMap } from '@jridgewell/trace-mapping'\nimport { classifySSRError, formatConsoleError, setSourceMapResolver } from './ssrErrors'\nimport { InertiaAppResponse, Page } from './types'\n\n// Cache parsed sourcemaps for performance\nconst sourceMaps = new Map<string, TraceMap>()\n\nsetSourceMapResolver((file: string, line: number, column: number) => {\n // Only resolve for bundled SSR files\n if (!file.includes('/ssr/') || !file.endsWith('.js')) {\n return null\n }\n\n const mapFile = file + '.map'\n\n if (!existsSync(mapFile)) {\n return null\n }\n\n let traceMap = sourceMaps.get(mapFile)\n\n if (!traceMap) {\n try {\n const mapContent = readFileSync(mapFile, 'utf-8')\n traceMap = new TraceMap(mapContent)\n sourceMaps.set(mapFile, traceMap)\n } catch {\n return null\n }\n }\n\n const original = originalPositionFor(traceMap, { line, column })\n\n if (original.source) {\n // Resolve the source path relative to the sourcemap location\n const mapDir = path.dirname(mapFile)\n const resolvedPath = path.resolve(mapDir, original.source)\n\n return {\n file: resolvedPath,\n line: original.line ?? line,\n column: original.column ?? column,\n }\n }\n\n return null\n})\n\ntype AppCallback = (page: Page) => InertiaAppResponse\ntype RouteHandler = (request: IncomingMessage, response: ServerResponse) => Promise<unknown>\ntype ServerOptions = {\n port?: number\n host?: string\n cluster?: boolean\n formatErrors?: boolean\n}\ntype Port = number\n\nconst readableToString: (readable: IncomingMessage) => Promise<string> = (readable) =>\n new Promise((resolve, reject) => {\n let data = ''\n readable.on('data', (chunk) => (data += chunk))\n readable.on('end', () => resolve(data))\n readable.on('error', (err) => reject(err))\n })\n\nexport default (render: AppCallback, options?: Port | ServerOptions): AppCallback => {\n const opts = typeof options === 'number' ? { port: options } : options\n const { port = 13714, host = '0.0.0.0', cluster: useCluster = false, formatErrors = true } = opts ?? {}\n\n const log = (message: string) => {\n console.log(\n useCluster && !cluster.isPrimary\n ? `[${cluster.worker?.id ?? 'N/A'} / ${cluster.worker?.process?.pid ?? 'N/A'}] ${message}`\n : message,\n )\n }\n\n if (useCluster && cluster.isPrimary) {\n log('Primary Inertia SSR server process started...')\n\n for (let i = 0; i < availableParallelism(); i++) {\n cluster.fork()\n }\n\n cluster.on('message', (_worker, message) => {\n if (message === 'shutdown') {\n for (const id in cluster.workers) {\n cluster.workers[id]?.kill()\n }\n\n process.exit()\n }\n })\n\n return render\n }\n\n const handleRender = async (request: IncomingMessage, response: ServerResponse) => {\n const page: Page = JSON.parse(await readableToString(request))\n\n // Suppress framework warnings during render (they clutter the output)\n const originalWarn = console.warn\n\n if (formatErrors) {\n console.warn = () => {}\n }\n\n try {\n const result = await render(page)\n\n response.writeHead(200, { 'Content-Type': 'application/json', Server: 'Inertia.js SSR' })\n response.write(JSON.stringify(result))\n } catch (e) {\n const error = e as Error\n\n if (!formatErrors) {\n throw error\n }\n\n const classified = classifySSRError(error, page.component, page.url)\n console.error(formatConsoleError(classified))\n\n response.writeHead(500, { 'Content-Type': 'application/json', Server: 'Inertia.js SSR' })\n response.write(JSON.stringify(classified))\n } finally {\n console.warn = originalWarn\n }\n }\n\n const routes: Record<string, RouteHandler> = {\n '/health': async () => ({ status: 'OK', timestamp: Date.now() }),\n '/shutdown': async () => {\n if (cluster.isWorker) {\n process.send?.('shutdown')\n }\n\n process.exit()\n },\n '/render': handleRender,\n '/404': async () => ({ status: 'NOT_FOUND', timestamp: Date.now() }),\n }\n\n createServer(async (request, response) => {\n const dispatchRoute = routes[request.url as string] ?? routes['/404']\n const result = await dispatchRoute(request, response)\n\n if (!response.headersSent) {\n response.writeHead(200, { 'Content-Type': 'application/json', Server: 'Inertia.js SSR' })\n response.write(JSON.stringify(result))\n }\n\n response.end()\n }).listen({ port, host }, () => log('Inertia SSR server started.'))\n\n log(`Starting SSR server on port ${port}...`)\n\n // Return the render callback so it can be exported for Vite SSR dev mode\n return render\n}\n", "/**\n * SSR Error Classification\n *\n * This module detects common SSR errors and provides helpful hints\n * to developers on how to fix them. The most common issue is using\n * browser-specific APIs (like window, document) that don't exist\n * in the Node.js server environment.\n */\n\nexport type SSRErrorType = 'browser-api' | 'component-resolution' | 'render' | 'unknown'\n\ntype SourceMapResolver = (\n file: string,\n line: number,\n column: number,\n) => { file: string; line: number; column: number } | null\n\nlet sourceMapResolver: SourceMapResolver | null = null\n\nexport function setSourceMapResolver(resolver: SourceMapResolver | null): void {\n sourceMapResolver = resolver\n}\n\nexport interface ClassifiedSSRError {\n error: string\n type: SSRErrorType\n component?: string\n url?: string\n browserApi?: string\n hint: string\n stack?: string\n sourceLocation?: string\n timestamp: string\n}\n\nconst BROWSER_APIS: Record<string, string> = {\n // Global objects\n window: 'The global window object',\n document: 'The DOM document object',\n navigator: 'The navigator object',\n location: 'The location object',\n history: 'The browser history API',\n screen: 'The screen object',\n localStorage: 'Browser local storage',\n sessionStorage: 'Browser session storage',\n\n // Viewport properties (accessed via window.X)\n innerWidth: 'Browser viewport width',\n innerHeight: 'Browser viewport height',\n outerWidth: 'Browser window width',\n outerHeight: 'Browser window height',\n scrollX: 'Horizontal scroll position',\n scrollY: 'Vertical scroll position',\n devicePixelRatio: 'The device pixel ratio',\n matchMedia: 'The matchMedia function',\n\n // Observers (commonly instantiated at module level)\n IntersectionObserver: 'The IntersectionObserver API',\n ResizeObserver: 'The ResizeObserver API',\n MutationObserver: 'The MutationObserver API',\n\n // Timing functions (commonly called at module level)\n requestAnimationFrame: 'The requestAnimationFrame function',\n requestIdleCallback: 'The requestIdleCallback function',\n\n // Constructors that might be used at module level\n Image: 'The Image constructor',\n Audio: 'The Audio constructor',\n Worker: 'The Worker constructor',\n BroadcastChannel: 'The BroadcastChannel constructor',\n\n // Network (older Node.js versions)\n fetch: 'The fetch API',\n XMLHttpRequest: 'The XMLHttpRequest API',\n}\n\nfunction detectBrowserApi(error: Error): string | null {\n const message = error.message.toLowerCase()\n\n for (const api of Object.keys(BROWSER_APIS)) {\n const patterns = [\n `${api.toLowerCase()} is not defined`,\n `'${api.toLowerCase()}' is not defined`,\n `\"${api.toLowerCase()}\" is not defined`,\n `cannot read properties of undefined (reading '${api.toLowerCase()}')`,\n `cannot read property '${api.toLowerCase()}'`,\n ]\n\n if (patterns.some((pattern) => message.includes(pattern))) {\n return api\n }\n }\n\n return null\n}\n\nfunction isComponentResolutionError(error: Error): boolean {\n const message = error.message.toLowerCase()\n\n return (\n message.includes('cannot find module') ||\n message.includes('failed to resolve') ||\n message.includes('module not found') ||\n message.includes('could not resolve')\n )\n}\n\nconst LIFECYCLE_HOOKS = 'onMounted/useEffect/onMount'\n\nfunction getBrowserApiHint(api: string): string {\n const apiDescription = BROWSER_APIS[api] || `The \"${api}\" object`\n\n if (['localStorage', 'sessionStorage'].includes(api)) {\n return (\n `${apiDescription} doesn't exist in Node.js. ` +\n `Check \"typeof ${api} !== 'undefined'\" before using it, ` +\n `or move the code to a ${LIFECYCLE_HOOKS} lifecycle hook.`\n )\n }\n\n if (['window', 'document'].includes(api)) {\n return (\n `${apiDescription} doesn't exist in Node.js. ` +\n `Wrap browser-specific code in a ${LIFECYCLE_HOOKS} lifecycle hook, ` +\n `or check \"typeof ${api} !== 'undefined'\" before using it.`\n )\n }\n\n if (['IntersectionObserver', 'ResizeObserver', 'MutationObserver'].includes(api)) {\n return (\n `${apiDescription} doesn't exist in Node.js. ` +\n `Create observers inside a ${LIFECYCLE_HOOKS} lifecycle hook, not at the module level.`\n )\n }\n\n if (['fetch', 'XMLHttpRequest'].includes(api)) {\n return (\n `${apiDescription} may not be available in all Node.js versions. ` +\n `For SSR, ensure data fetching happens on the server (in your controller) ` +\n `and is passed as props, or use a ${LIFECYCLE_HOOKS} hook for client-side fetching.`\n )\n }\n\n return (\n `${apiDescription} doesn't exist in Node.js. ` +\n `Move this code to a ${LIFECYCLE_HOOKS} lifecycle hook, or guard it with ` +\n `\"typeof ${api} !== 'undefined'\".`\n )\n}\n\nfunction getComponentResolutionHint(component?: string): string {\n const componentPart = component ? ` \"${component}\"` : ''\n\n return (\n `Could not resolve component${componentPart}. ` +\n `Check that the file exists and the path is correct. ` +\n `Ensure the component name matches the file name exactly (case-sensitive).`\n )\n}\n\nfunction getRenderErrorHint(): string {\n return (\n 'An error occurred while rendering the component. ' +\n 'Check the component for browser-specific code that runs during initialization. ' +\n 'Move any code that accesses browser APIs to a lifecycle hook.'\n )\n}\n\nfunction extractSourceLocation(stack?: string): string | undefined {\n if (!stack) {\n return undefined\n }\n\n for (const line of stack.split('\\n')) {\n if (!line.includes('at ')) {\n continue\n }\n\n if (line.includes('node_modules') || line.includes('node:')) {\n continue\n }\n\n let match = line.match(/\\(([^)]+):(\\d+):(\\d+)\\)/)\n\n if (!match) {\n match = line.match(/at\\s+(?:file:\\/\\/)?(.+):(\\d+):(\\d+)\\s*$/)\n }\n\n if (match) {\n const file = match[1].replace(/^file:\\/\\//, '')\n const lineNum = parseInt(match[2], 10)\n const colNum = parseInt(match[3], 10)\n\n if (sourceMapResolver) {\n const resolved = sourceMapResolver(file, lineNum, colNum)\n\n if (resolved) {\n return `${resolved.file}:${resolved.line}:${resolved.column}`\n }\n }\n\n return `${file}:${lineNum}:${colNum}`\n }\n }\n\n return undefined\n}\n\nexport function classifySSRError(error: Error, component?: string, url?: string): ClassifiedSSRError {\n const timestamp = new Date().toISOString()\n const base = {\n error: error.message,\n component,\n url,\n stack: error.stack,\n sourceLocation: extractSourceLocation(error.stack),\n timestamp,\n }\n\n const browserApi = detectBrowserApi(error)\n\n if (browserApi) {\n return {\n ...base,\n type: 'browser-api',\n browserApi,\n hint: getBrowserApiHint(browserApi),\n }\n }\n\n if (isComponentResolutionError(error)) {\n return {\n ...base,\n type: 'component-resolution',\n hint: getComponentResolutionHint(component),\n }\n }\n\n return {\n ...base,\n type: 'render',\n hint: getRenderErrorHint(),\n }\n}\n\nconst colors = {\n reset: '\\x1b[0m',\n red: '\\x1b[31m',\n yellow: '\\x1b[33m',\n cyan: '\\x1b[36m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n bgRed: '\\x1b[41m',\n white: '\\x1b[37m',\n}\n\nfunction makeRelative(path: string, root?: string): string {\n const base = root ?? process.cwd()\n\n if (path.startsWith(base + '/')) {\n return path.slice(base.length + 1)\n }\n\n return path\n}\n\nexport function formatConsoleError(\n classified: ClassifiedSSRError,\n root?: string,\n formatErrors: boolean = true,\n suppressedWarnings: string[] = [],\n): string {\n if (!formatErrors) {\n const component = classified.component ? `[${classified.component}]` : ''\n return `SSR Error ${component}: ${classified.error}`\n }\n\n const componentPart = classified.component ? ` ${colors.cyan}${classified.component}${colors.reset}` : ''\n\n const lines = [\n '',\n ` ${colors.bgRed}${colors.white}${colors.bold} SSR ERROR ${colors.reset}${componentPart}`,\n '',\n ` ${classified.error}`,\n ]\n\n if (classified.sourceLocation) {\n const relativePath = makeRelative(classified.sourceLocation, root)\n lines.push(` ${colors.dim}Source: ${relativePath}${colors.reset}`)\n }\n\n if (classified.url) {\n lines.push(` ${colors.dim}URL: ${classified.url}${colors.reset}`)\n }\n\n lines.push('', ` ${colors.yellow}Hint${colors.reset} ${classified.hint}`, '')\n\n if (classified.stack) {\n lines.push(` ${colors.dim}${classified.stack.split('\\n').join('\\n ')}${colors.reset}`, '')\n }\n\n if (suppressedWarnings.length > 0) {\n lines.push(` ${colors.dim}Suppressed ${suppressedWarnings.length} framework warning(s).${colors.reset}`, '')\n }\n\n return lines.join('\\n')\n}\n"], | ||
| "mappings": ";AAAA,SAAS,oBAAqD;AAC9D,OAAO,aAAa;AACpB,SAAS,YAAY,oBAAoB;AACzC,SAAS,4BAA4B;AACrC,OAAO,UAAU;AACjB,YAAYA,cAAa;AACzB,SAAS,qBAAqB,gBAAgB;;;ACW9C,IAAI,oBAA8C;AAE3C,SAAS,qBAAqB,UAA0C;AAC7E,sBAAoB;AACtB;AAcA,IAAM,eAAuC;AAAA;AAAA,EAE3C,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,gBAAgB;AAAA;AAAA,EAGhB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,YAAY;AAAA;AAAA,EAGZ,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA;AAAA,EAGlB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA;AAAA,EAGrB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,kBAAkB;AAAA;AAAA,EAGlB,OAAO;AAAA,EACP,gBAAgB;AAClB;AAEA,SAAS,iBAAiB,OAA6B;AACrD,QAAM,UAAU,MAAM,QAAQ,YAAY;AAE1C,aAAW,OAAO,OAAO,KAAK,YAAY,GAAG;AAC3C,UAAM,WAAW;AAAA,MACf,GAAG,IAAI,YAAY,CAAC;AAAA,MACpB,IAAI,IAAI,YAAY,CAAC;AAAA,MACrB,IAAI,IAAI,YAAY,CAAC;AAAA,MACrB,iDAAiD,IAAI,YAAY,CAAC;AAAA,MAClE,yBAAyB,IAAI,YAAY,CAAC;AAAA,IAC5C;AAEA,QAAI,SAAS,KAAK,CAAC,YAAY,QAAQ,SAAS,OAAO,CAAC,GAAG;AACzD,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,2BAA2B,OAAuB;AACzD,QAAM,UAAU,MAAM,QAAQ,YAAY;AAE1C,SACE,QAAQ,SAAS,oBAAoB,KACrC,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,kBAAkB,KACnC,QAAQ,SAAS,mBAAmB;AAExC;AAEA,IAAM,kBAAkB;AAExB,SAAS,kBAAkB,KAAqB;AAC9C,QAAM,iBAAiB,aAAa,GAAG,KAAK,QAAQ,GAAG;AAEvD,MAAI,CAAC,gBAAgB,gBAAgB,EAAE,SAAS,GAAG,GAAG;AACpD,WACE,GAAG,cAAc,4CACA,GAAG,4DACK,eAAe;AAAA,EAE5C;AAEA,MAAI,CAAC,UAAU,UAAU,EAAE,SAAS,GAAG,GAAG;AACxC,WACE,GAAG,cAAc,8DACkB,eAAe,qCAC9B,GAAG;AAAA,EAE3B;AAEA,MAAI,CAAC,wBAAwB,kBAAkB,kBAAkB,EAAE,SAAS,GAAG,GAAG;AAChF,WACE,GAAG,cAAc,wDACY,eAAe;AAAA,EAEhD;AAEA,MAAI,CAAC,SAAS,gBAAgB,EAAE,SAAS,GAAG,GAAG;AAC7C,WACE,GAAG,cAAc,4JAEmB,eAAe;AAAA,EAEvD;AAEA,SACE,GAAG,cAAc,kDACM,eAAe,6CAC3B,GAAG;AAElB;AAEA,SAAS,2BAA2B,WAA4B;AAC9D,QAAM,gBAAgB,YAAY,KAAK,SAAS,MAAM;AAEtD,SACE,8BAA8B,aAAa;AAI/C;AAEA,SAAS,qBAA6B;AACpC,SACE;AAIJ;AAEA,SAAS,sBAAsB,OAAoC;AACjE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,aAAW,QAAQ,MAAM,MAAM,IAAI,GAAG;AACpC,QAAI,CAAC,KAAK,SAAS,KAAK,GAAG;AACzB;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,cAAc,KAAK,KAAK,SAAS,OAAO,GAAG;AAC3D;AAAA,IACF;AAEA,QAAI,QAAQ,KAAK,MAAM,yBAAyB;AAEhD,QAAI,CAAC,OAAO;AACV,cAAQ,KAAK,MAAM,yCAAyC;AAAA,IAC9D;AAEA,QAAI,OAAO;AACT,YAAM,OAAO,MAAM,CAAC,EAAE,QAAQ,cAAc,EAAE;AAC9C,YAAM,UAAU,SAAS,MAAM,CAAC,GAAG,EAAE;AACrC,YAAM,SAAS,SAAS,MAAM,CAAC,GAAG,EAAE;AAEpC,UAAI,mBAAmB;AACrB,cAAM,WAAW,kBAAkB,MAAM,SAAS,MAAM;AAExD,YAAI,UAAU;AACZ,iBAAO,GAAG,SAAS,IAAI,IAAI,SAAS,IAAI,IAAI,SAAS,MAAM;AAAA,QAC7D;AAAA,MACF;AAEA,aAAO,GAAG,IAAI,IAAI,OAAO,IAAI,MAAM;AAAA,IACrC;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,iBAAiB,OAAc,WAAoB,KAAkC;AACnG,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAM,OAAO;AAAA,IACX,OAAO,MAAM;AAAA,IACb;AAAA,IACA;AAAA,IACA,OAAO,MAAM;AAAA,IACb,gBAAgB,sBAAsB,MAAM,KAAK;AAAA,IACjD;AAAA,EACF;AAEA,QAAM,aAAa,iBAAiB,KAAK;AAEzC,MAAI,YAAY;AACd,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,MACN;AAAA,MACA,MAAM,kBAAkB,UAAU;AAAA,IACpC;AAAA,EACF;AAEA,MAAI,2BAA2B,KAAK,GAAG;AACrC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,MACN,MAAM,2BAA2B,SAAS;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM;AAAA,IACN,MAAM,mBAAmB;AAAA,EAC3B;AACF;AAEA,IAAM,SAAS;AAAA,EACb,OAAO;AAAA,EACP,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AACT;AAEA,SAAS,aAAaC,OAAc,MAAuB;AACzD,QAAM,OAAO,QAAQ,QAAQ,IAAI;AAEjC,MAAIA,MAAK,WAAW,OAAO,GAAG,GAAG;AAC/B,WAAOA,MAAK,MAAM,KAAK,SAAS,CAAC;AAAA,EACnC;AAEA,SAAOA;AACT;AAEO,SAAS,mBACd,YACA,MACA,eAAwB,MACxB,qBAA+B,CAAC,GACxB;AACR,MAAI,CAAC,cAAc;AACjB,UAAM,YAAY,WAAW,YAAY,IAAI,WAAW,SAAS,MAAM;AACvE,WAAO,aAAa,SAAS,KAAK,WAAW,KAAK;AAAA,EACpD;AAEA,QAAM,gBAAgB,WAAW,YAAY,KAAK,OAAO,IAAI,GAAG,WAAW,SAAS,GAAG,OAAO,KAAK,KAAK;AAExG,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,KAAK,OAAO,KAAK,GAAG,OAAO,KAAK,GAAG,OAAO,IAAI,cAAc,OAAO,KAAK,GAAG,aAAa;AAAA,IACxF;AAAA,IACA,KAAK,WAAW,KAAK;AAAA,EACvB;AAEA,MAAI,WAAW,gBAAgB;AAC7B,UAAM,eAAe,aAAa,WAAW,gBAAgB,IAAI;AACjE,UAAM,KAAK,KAAK,OAAO,GAAG,WAAW,YAAY,GAAG,OAAO,KAAK,EAAE;AAAA,EACpE;AAEA,MAAI,WAAW,KAAK;AAClB,UAAM,KAAK,KAAK,OAAO,GAAG,QAAQ,WAAW,GAAG,GAAG,OAAO,KAAK,EAAE;AAAA,EACnE;AAEA,QAAM,KAAK,IAAI,KAAK,OAAO,MAAM,OAAO,OAAO,KAAK,KAAK,WAAW,IAAI,IAAI,EAAE;AAE9E,MAAI,WAAW,OAAO;AACpB,UAAM,KAAK,KAAK,OAAO,GAAG,GAAG,WAAW,MAAM,MAAM,IAAI,EAAE,KAAK,MAAM,CAAC,GAAG,OAAO,KAAK,IAAI,EAAE;AAAA,EAC7F;AAEA,MAAI,mBAAmB,SAAS,GAAG;AACjC,UAAM,KAAK,KAAK,OAAO,GAAG,cAAc,mBAAmB,MAAM,yBAAyB,OAAO,KAAK,IAAI,EAAE;AAAA,EAC9G;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ADvSA,IAAM,aAAa,oBAAI,IAAsB;AAE7C,qBAAqB,CAAC,MAAc,MAAc,WAAmB;AAEnE,MAAI,CAAC,KAAK,SAAS,OAAO,KAAK,CAAC,KAAK,SAAS,KAAK,GAAG;AACpD,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,OAAO;AAEvB,MAAI,CAAC,WAAW,OAAO,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,WAAW,IAAI,OAAO;AAErC,MAAI,CAAC,UAAU;AACb,QAAI;AACF,YAAM,aAAa,aAAa,SAAS,OAAO;AAChD,iBAAW,IAAI,SAAS,UAAU;AAClC,iBAAW,IAAI,SAAS,QAAQ;AAAA,IAClC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,WAAW,oBAAoB,UAAU,EAAE,MAAM,OAAO,CAAC;AAE/D,MAAI,SAAS,QAAQ;AAEnB,UAAM,SAAS,KAAK,QAAQ,OAAO;AACnC,UAAM,eAAe,KAAK,QAAQ,QAAQ,SAAS,MAAM;AAEzD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,SAAS,QAAQ;AAAA,MACvB,QAAQ,SAAS,UAAU;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AACT,CAAC;AAYD,IAAM,mBAAmE,CAAC,aACxE,IAAI,QAAQ,CAAC,SAAS,WAAW;AAC/B,MAAI,OAAO;AACX,WAAS,GAAG,QAAQ,CAAC,UAAW,QAAQ,KAAM;AAC9C,WAAS,GAAG,OAAO,MAAM,QAAQ,IAAI,CAAC;AACtC,WAAS,GAAG,SAAS,CAAC,QAAQ,OAAO,GAAG,CAAC;AAC3C,CAAC;AAEH,IAAO,iBAAQ,CAAC,QAAqB,YAAgD;AACnF,QAAM,OAAO,OAAO,YAAY,WAAW,EAAE,MAAM,QAAQ,IAAI;AAC/D,QAAM,EAAE,OAAO,OAAO,OAAO,WAAW,SAAS,aAAa,OAAO,eAAe,KAAK,IAAI,QAAQ,CAAC;AAEtG,QAAM,MAAM,CAAC,YAAoB;AAC/B,YAAQ;AAAA,MACN,cAAc,CAAC,QAAQ,YACnB,IAAI,QAAQ,QAAQ,MAAM,KAAK,MAAM,QAAQ,QAAQ,SAAS,OAAO,KAAK,KAAK,OAAO,KACtF;AAAA,IACN;AAAA,EACF;AAEA,MAAI,cAAc,QAAQ,WAAW;AACnC,QAAI,+CAA+C;AAEnD,aAAS,IAAI,GAAG,IAAI,qBAAqB,GAAG,KAAK;AAC/C,cAAQ,KAAK;AAAA,IACf;AAEA,YAAQ,GAAG,WAAW,CAAC,SAAS,YAAY;AAC1C,UAAI,YAAY,YAAY;AAC1B,mBAAW,MAAM,QAAQ,SAAS;AAChC,kBAAQ,QAAQ,EAAE,GAAG,KAAK;AAAA,QAC5B;AAEA,QAAQ,cAAK;AAAA,MACf;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,OAAO,SAA0B,aAA6B;AACjF,UAAM,OAAa,KAAK,MAAM,MAAM,iBAAiB,OAAO,CAAC;AAG7D,UAAM,eAAe,QAAQ;AAE7B,QAAI,cAAc;AAChB,cAAQ,OAAO,MAAM;AAAA,MAAC;AAAA,IACxB;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,OAAO,IAAI;AAEhC,eAAS,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,QAAQ,iBAAiB,CAAC;AACxF,eAAS,MAAM,KAAK,UAAU,MAAM,CAAC;AAAA,IACvC,SAAS,GAAG;AACV,YAAM,QAAQ;AAEd,UAAI,CAAC,cAAc;AACjB,cAAM;AAAA,MACR;AAEA,YAAM,aAAa,iBAAiB,OAAO,KAAK,WAAW,KAAK,GAAG;AACnE,cAAQ,MAAM,mBAAmB,UAAU,CAAC;AAE5C,eAAS,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,QAAQ,iBAAiB,CAAC;AACxF,eAAS,MAAM,KAAK,UAAU,UAAU,CAAC;AAAA,IAC3C,UAAE;AACA,cAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,SAAuC;AAAA,IAC3C,WAAW,aAAa,EAAE,QAAQ,MAAM,WAAW,KAAK,IAAI,EAAE;AAAA,IAC9D,aAAa,YAAY;AACvB,UAAI,QAAQ,UAAU;AACpB,QAAQ,gBAAO,UAAU;AAAA,MAC3B;AAEA,MAAQ,cAAK;AAAA,IACf;AAAA,IACA,WAAW;AAAA,IACX,QAAQ,aAAa,EAAE,QAAQ,aAAa,WAAW,KAAK,IAAI,EAAE;AAAA,EACpE;AAEA,eAAa,OAAO,SAAS,aAAa;AACxC,UAAM,gBAAgB,OAAO,QAAQ,GAAa,KAAK,OAAO,MAAM;AACpE,UAAM,SAAS,MAAM,cAAc,SAAS,QAAQ;AAEpD,QAAI,CAAC,SAAS,aAAa;AACzB,eAAS,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,QAAQ,iBAAiB,CAAC;AACxF,eAAS,MAAM,KAAK,UAAU,MAAM,CAAC;AAAA,IACvC;AAEA,aAAS,IAAI;AAAA,EACf,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,GAAG,MAAM,IAAI,6BAA6B,CAAC;AAElE,MAAI,+BAA+B,IAAI,KAAK;AAG5C,SAAO;AACT;", | ||
| "names": ["process", "path"] | ||
| } |
+2
-2
| { | ||
| "name": "@inertiajs/core", | ||
| "version": "3.1.1", | ||
| "version": "3.2.0", | ||
| "license": "MIT", | ||
@@ -70,3 +70,3 @@ "description": "A framework for creating server-driven single page apps.", | ||
| "esbuild-node-externals": "^1.20.1", | ||
| "typescript": "^5.9.3", | ||
| "typescript": "^6.0.3", | ||
| "vitest": "^4.1.2" | ||
@@ -73,0 +73,0 @@ }, |
| import { UseInfiniteScrollDataManager } from '../types'; | ||
| export type InfiniteScrollPageIdentifier = string | number | null; | ||
| export type InfiniteScrollOnCompleteDetails = { | ||
| page: InfiniteScrollPageIdentifier; | ||
| completed: boolean; | ||
| }; | ||
| export declare const useInfiniteScrollData: (options: { | ||
@@ -7,5 +12,9 @@ getPropName: () => string; | ||
| onBeforeNextRequest: () => void; | ||
| onCompletePreviousRequest: (loadedPage: string | number | null) => void; | ||
| onCompleteNextRequest: (loadedPage: string | number | null) => void; | ||
| onCompletePreviousRequest: ( | ||
| /** @deprecated Use `details.page` instead. The positional `loadedPage` argument will be removed in the next major version. */ | ||
| loadedPage: InfiniteScrollPageIdentifier, details: InfiniteScrollOnCompleteDetails) => void; | ||
| onCompleteNextRequest: ( | ||
| /** @deprecated Use `details.page` instead. The positional `loadedPage` argument will be removed in the next major version. */ | ||
| loadedPage: InfiniteScrollPageIdentifier, details: InfiniteScrollOnCompleteDetails) => void; | ||
| onReset?: () => void; | ||
| }) => UseInfiniteScrollDataManager; |
+18
-3
| import { PollOptions } from './types'; | ||
| type PollHooks = { | ||
| onStart: (cancel: VoidFunction) => void; | ||
| onFinish: VoidFunction; | ||
| }; | ||
| export type PollCallback = (hooks: PollHooks) => void; | ||
| export declare class Poll { | ||
| protected id: number | null; | ||
| protected intervalId: number | null; | ||
| protected timeoutId: number | null; | ||
| protected throttle: boolean; | ||
| protected keepAlive: boolean; | ||
| protected cb: VoidFunction; | ||
| protected cb: PollCallback; | ||
| protected interval: number; | ||
| protected cbCount: number; | ||
| constructor(interval: number, cb: VoidFunction, options: PollOptions); | ||
| protected mode: 'overlap' | 'cancel' | 'rest'; | ||
| protected inFlight: boolean; | ||
| protected currentCancel: VoidFunction | null; | ||
| protected stopped: boolean; | ||
| protected instanceId: number; | ||
| constructor(interval: number, cb: PollCallback, options: PollOptions); | ||
| stop(): void; | ||
| start(): void; | ||
| isInBackground(hidden: boolean): void; | ||
| protected scheduleNext(): void; | ||
| protected tick(): void; | ||
| protected fire(): void; | ||
| } | ||
| export {}; |
+4
-2
@@ -1,2 +0,2 @@ | ||
| import { Poll } from './poll'; | ||
| import { Poll, PollCallback } from './poll'; | ||
| import { PollOptions } from './types'; | ||
@@ -6,5 +6,7 @@ declare class Polls { | ||
| constructor(); | ||
| add(interval: number, cb: VoidFunction, options: PollOptions): { | ||
| get count(): number; | ||
| add(interval: number, cb: PollCallback, options: PollOptions): { | ||
| stop: VoidFunction; | ||
| start: VoidFunction; | ||
| destroy: VoidFunction; | ||
| }; | ||
@@ -11,0 +13,0 @@ clear(): void; |
@@ -23,3 +23,5 @@ import Queue from './queue'; | ||
| on<TEventName extends GlobalEventNames>(type: TEventName, callback: (event: GlobalEvent<TEventName>) => GlobalEventResult<TEventName>): VoidFunction; | ||
| once<TEventName extends GlobalEventNames>(type: TEventName, callback: (event: GlobalEvent<TEventName>) => GlobalEventResult<TEventName>): VoidFunction; | ||
| hasPendingOptimistic(): boolean; | ||
| get activePolls(): number; | ||
| cancelAll({ async, prefetch, sync }?: { | ||
@@ -30,5 +32,6 @@ async?: boolean | undefined; | ||
| }): void; | ||
| poll(interval: number, requestOptions?: ReloadOptions, options?: PollOptions): { | ||
| poll(interval: number, requestOptions?: ReloadOptions | (() => ReloadOptions), options?: PollOptions): { | ||
| stop: VoidFunction; | ||
| start: VoidFunction; | ||
| destroy: VoidFunction; | ||
| }; | ||
@@ -35,0 +38,0 @@ visit<T extends RequestPayload = RequestPayload>(href: string | URL | UrlMethodPair, options?: VisitOptions<T>): void; |
+14
-9
| import { NamedInputEvent, ValidationConfig, Validator } from 'laravel-precognition'; | ||
| import type { HttpCancelledError, HttpNetworkError, HttpResponseError } from './httpErrors'; | ||
| import { InfiniteScrollOnCompleteDetails, InfiniteScrollPageIdentifier } from './infiniteScroll/data'; | ||
| import { Response } from './response'; | ||
@@ -26,2 +27,5 @@ export type HttpRequestHeaders = Record<string, unknown>; | ||
| } | ||
| export interface HttpExceptionResponse extends Omit<HttpResponse, 'data'> { | ||
| data: string | Record<string, unknown>; | ||
| } | ||
| export interface HttpClient { | ||
@@ -126,5 +130,5 @@ request(config: HttpRequestConfig): Promise<HttpResponse>; | ||
| pageName: string; | ||
| previousPage: number | string | null; | ||
| nextPage: number | string | null; | ||
| currentPage: number | string | null; | ||
| previousPage: InfiniteScrollPageIdentifier; | ||
| nextPage: InfiniteScrollPageIdentifier; | ||
| currentPage: InfiniteScrollPageIdentifier; | ||
| reset: boolean; | ||
@@ -287,5 +291,5 @@ }; | ||
| httpException: { | ||
| parameters: [HttpResponse]; | ||
| parameters: [HttpExceptionResponse]; | ||
| details: { | ||
| response: HttpResponse; | ||
| response: HttpExceptionResponse; | ||
| }; | ||
@@ -355,2 +359,3 @@ result: boolean | void; | ||
| autoStart?: boolean; | ||
| mode?: 'overlap' | 'cancel' | 'rest'; | ||
| }; | ||
@@ -594,8 +599,8 @@ export type VisitHelperOptions<T extends RequestPayload = RequestPayload> = Omit<VisitOptions<T>, 'method' | 'data'>; | ||
| onBeforeNextRequest: () => void; | ||
| onCompletePreviousRequest: () => void; | ||
| onCompleteNextRequest: () => void; | ||
| onCompletePreviousRequest: (details: InfiniteScrollOnCompleteDetails) => void; | ||
| onCompleteNextRequest: (details: InfiniteScrollOnCompleteDetails) => void; | ||
| onDataReset?: () => void; | ||
| } | ||
| export interface UseInfiniteScrollDataManager { | ||
| getLastLoadedPage: () => number | string | null; | ||
| getLastLoadedPage: () => InfiniteScrollPageIdentifier; | ||
| getPageName: () => string; | ||
@@ -616,3 +621,3 @@ getRequestCount: () => number; | ||
| processManuallyAddedElements: () => void; | ||
| processServerLoadedElements: (loadedPage: string | number | null) => void; | ||
| processServerLoadedElements: (loadedPage: InfiniteScrollPageIdentifier) => void; | ||
| } | ||
@@ -619,0 +624,0 @@ export interface UseInfiniteScrollProps { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
623627
1.59%7183
1.96%