From 2201ccfb5e05f3690d5bb3dfb03c4d645e4a8e55 Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Wed, 2 Oct 2024 11:17:51 +0100 Subject: [PATCH 1/8] WIP HTTP VFS --- packages/pglite/examples/httpfs-worker.js | 23 + packages/pglite/examples/httpfs.html | 59 ++ packages/pglite/package.json | 5 + packages/pglite/src/fs/http.ts | 648 ++++++++++++++++++++++ packages/pglite/src/fs/opfs-ahp.ts | 1 + packages/pglite/src/fs/tarUtils.ts | 43 +- packages/pglite/tsup.config.ts | 1 + 7 files changed, 779 insertions(+), 1 deletion(-) create mode 100644 packages/pglite/examples/httpfs-worker.js create mode 100644 packages/pglite/examples/httpfs.html create mode 100644 packages/pglite/src/fs/http.ts diff --git a/packages/pglite/examples/httpfs-worker.js b/packages/pglite/examples/httpfs-worker.js new file mode 100644 index 000000000..024f0d2b2 --- /dev/null +++ b/packages/pglite/examples/httpfs-worker.js @@ -0,0 +1,23 @@ +import { PGlite } from "../dist/index.js"; +import { worker } from "../dist/worker/index.js"; +import { HttpFs } from "../dist/fs/http.js"; + +console.log("Starting worker..."); + +worker({ + async init() { + const start = performance.now(); + const pg = await PGlite.create({ + // debug: 1, + fs: new HttpFs("/pglite/examples/pgdata", { + // debug: true + fetchGranularity: 'file', // 'file' or 'page' + }), + }); + console.log("PGlite initialized in", performance.now() - start, "ms"); + // If you want run any specific setup code for the worker process, you can do it here. + return pg; + }, +}); + +console.log("Worker process started"); diff --git a/packages/pglite/examples/httpfs.html b/packages/pglite/examples/httpfs.html new file mode 100644 index 000000000..2ea652856 --- /dev/null +++ b/packages/pglite/examples/httpfs.html @@ -0,0 +1,59 @@ + + + + PGlite Worker Example + + + + + +

PGlite HTTP FS Example

+
+
+

Worker Thread - httpfs-worker.js

+
+

Main Thread

+ +
+
+
+ + diff --git a/packages/pglite/package.json b/packages/pglite/package.json index aeea65caa..7787aabb8 100644 --- a/packages/pglite/package.json +++ b/packages/pglite/package.json @@ -54,6 +54,11 @@ "require": "./dist/fs/opfs-ahp.cjs", "types": "./dist/fs/opfs-ahp.d.ts" }, + "./httpfs": { + "import": "./dist/fs/http.js", + "require": "./dist/fs/http.cjs", + "types": "./dist/fs/http.d.ts" + }, "./contrib/*": { "import": "./dist/contrib/*.js", "require": "./dist/contrib/*.cjs", diff --git a/packages/pglite/src/fs/http.ts b/packages/pglite/src/fs/http.ts new file mode 100644 index 000000000..45e00f36e --- /dev/null +++ b/packages/pglite/src/fs/http.ts @@ -0,0 +1,648 @@ +import type { PGlite } from '../pglite.js' +import type { PostgresMod } from '../postgresMod.js' +import { BaseFilesystem, FsStats, ERRNO_CODES } from './base.js' +import type { TarIndex, TarIndexFile } from './tarUtils.js' + +type Node = TarIndexFile & { + isDir: boolean + children: Node[] + data?: FilelikeInterface + handle?: number +} + +// These files are key to postgres starting up, it will page through the whole file +// so it's more efficient to load them all in full. +const fileToFullyLoad = new Set([ + '/postgresql.conf', + '/postgresql.auto.conf', + '/PG_VERSION', + '/postmaster.pid', + '/global/pg_control', +]) + +// Whether to fetch files in full or by page +export type FetchGranularity = 'page' | 'file' + +export interface HttpFsOptions { + debug?: boolean + fetchGranularity?: FetchGranularity +} + +/** + * A read-only filesystem that fetches files from a remote HTTP server. + * Requires an index.json file at the root of the filesystem with a list of + * files available to fetch + */ +export class HttpFs extends BaseFilesystem { + index?: TarIndex + tree?: Node + httpPaths = new Set() + #handleMap: Map = new Map() + #handleCounter = 0 + fetchGranularity: FetchGranularity + + constructor( + baseUrl: string, + { debug, fetchGranularity = 'page' }: HttpFsOptions, + ) { + super(baseUrl, { debug }) + this.fetchGranularity = fetchGranularity + } + + async init(pg: PGlite, opts: Partial) { + await this.#init() + return super.init(pg, opts) + } + + async closeFs(): Promise { + this.pg!.Module.FS.quit() + } + + async #init() { + const indexReq = await fetch(`${this.dataDir}/index.json`) + const index = await indexReq.json() + this.index = index + for (const file of index.files) { + this.httpPaths.add(file.name) + } + this.tree = buildTree(index) + } + + getNode(path: string): Node | null { + const parts = path.split('/').filter((part) => part !== '') + let currentNode: Node | undefined = this.tree! + for (const part of parts) { + currentNode = currentNode.children.find((child) => child.name === part) + if (!currentNode) { + return null + } + } + return currentNode + } + + resolvePath(path: string): Node { + const node = this.getNode(path) + if (!node) { + throw new FsError('ENOENT', 'No such file or directory') + } + return node + } + + createNode(path: string, mode: number, type: number) { + const node = this.getNode(path) + if (node) { + throw new Error('Node already exists') + } + const parts = path.split('/').filter((part) => part !== '') + const lastPart = parts.pop() + let currentNode: Node | undefined = this.tree! + for (const part of parts) { + currentNode = currentNode.children.find((child) => child.name === part) + if (!currentNode) { + // add the directory to the tree + currentNode = { + name: part, + isDir: true, + children: [], + mode, + size: 0, + type, + modifyTime: 0, + } + currentNode.children.push(currentNode) + } + } + const newNode = { + name: lastPart!, + isDir: type === 5, + children: [], + mode, + size: 0, + type, + modifyTime: Date.now(), + } + currentNode.children.push(newNode) + return newNode + } + + chmod(path: string, mode: number) { + const node = this.getNode(path) + if (!node) { + throw new Error('Node does not exist') + } + node.mode = mode + } + + close(_fd: number) { + // No-op + } + + #nodeStats(node: Node): FsStats { + const blksize = 4096 + const size = node.data?.size() ?? node.size + return { + dev: 0, + ino: 0, + mode: node.mode, + nlink: 1, + uid: 0, + gid: 0, + rdev: 0, + size, + blksize, + blocks: Math.ceil(size / blksize), + atime: node.modifyTime, + mtime: node.modifyTime, + ctime: node.modifyTime, + } + } + + fstat(fd: number) { + const node = this.#handleMap.get(fd) + if (!node) { + throw new Error('File descriptor not found') + } + return this.#nodeStats(node) + } + + lstat(path: string) { + const node = this.resolvePath(path) + return this.#nodeStats(node) + } + + mkdir(path: string, _options?: { recursive?: boolean; mode?: number }) { + const node = this.getNode(path) + if (node) { + throw new Error('Node already exists') + } + this.createNode(path, 16872, 1) + } + + open(path: string, _flags?: string, mode?: number) { + let node = this.getNode(path) + if (!node) { + node = this.createNode(path, mode!, 0) + } + if (!node.data && this.httpPaths.has(path)) { + node.data = new HttpFilelike( + `${this.dataDir}${path}`, + node.size, + this.fetchGranularity === 'file' || fileToFullyLoad.has(path), + ) + } else if (!node.data) { + node.data = new Filelike(new Uint8Array()) + } + if (!node.handle) { + node.handle = this.#handleCounter++ + this.#handleMap.set(node.handle, node) + } + return node.handle + } + + readdir(path: string) { + const node = this.getNode(path) + if (!node) { + throw new Error('Node does not exist') + } + if (!node.isDir) { + throw new Error('Node is not a directory') + } + return node.children.map((child) => child.name) + } + + read( + fd: number, + buffer: Int8Array, // Buffer to read into + offset: number, // Offset in buffer to start writing to + length: number, // Number of bytes to read + position: number, // Position in file to read from + ) { + const node = this.#handleMap.get(fd) + if (!node) { + throw new Error('File descriptor not found') + } + return node.data?.read(buffer, offset, length, position) ?? 0 + } + + rename(oldPath: string, newPath: string) { + const oldParts = oldPath.split('/').filter((part) => part !== '') + const oldFilename = oldParts.pop()! + const oldParent = this.getNode(oldParts.join('/')) + if (!oldParent) { + throw new Error('Parent directory does not exist') + } + const newParts = newPath.split('/').filter((part) => part !== '') + const newFilename = newParts.pop()! + const newParent = this.getNode(newParts.join('/')) + if (!newParent) { + throw new Error('Parent directory does not exist') + } + const oldNode = oldParent.children.find( + (child) => child.name === oldFilename, + ) + if (!oldNode) { + throw new Error('File does not exist') + } + oldNode.name = newFilename + oldParent.children = oldParent.children.filter( + (child) => child.name !== oldFilename, + ) + newParent.children.push(oldNode) + } + + rmdir(path: string) { + this.unlink(path) + } + + truncate( + path: string, + len = 0, // Length to truncate to - defaults to 0 + ) { + const node = this.getNode(path) + if (!node) { + throw new Error('Node does not exist') + } + if (node.data) { + node.data.truncate(len) + } else { + node.size = len + } + } + + unlink(path: string) { + const parts = path.split('/').filter((part) => part !== '') + const lastPart = parts.pop() + const parent = parts.join('/') + const parentNode = this.getNode(parent) + if (!parentNode) { + throw new Error('Node does not exist') + } + parentNode.children = parentNode.children.filter( + (child) => child.name !== lastPart, + ) + } + + utimes(path: string, _atime: number, mtime: number) { + const node = this.getNode(path) + if (!node) { + throw new Error('Node does not exist') + } + node.modifyTime = mtime + } + + writeFile( + path: string, + data: string | Int8Array, + options?: { encoding?: string; mode?: number; flag?: string }, + ) { + let node = this.getNode(path) + if (!node) { + node = this.createNode(path, options?.mode ?? 33184, 0) + } + node.data = new Filelike(new Uint8Array(data as Int8Array)) + } + + write( + fd: number, + buffer: Int8Array, // Buffer to read from + offset: number, // Offset in buffer to start reading from + length: number, // Number of bytes to write + position: number, // Position in file to write to + ) { + const node = this.#handleMap.get(fd) + if (!node) { + throw new Error('File descriptor not found') + } + return node.data?.write(buffer, offset, length, position) ?? 0 + } +} + +function buildTree(index: TarIndex): Node { + const root: Node = { + name: '/', + isDir: true, + children: [], + mode: 16872, + size: 0, + type: 5, + modifyTime: 0, + } + for (const file of index.files) { + const parts = file.name.split('/').filter((part) => part !== '') + let currentNode = root + + for (let i = 0; i < parts.length; i++) { + const part = parts[i] + const isLastPart = i === parts.length - 1 + + let childNode = currentNode.children.find((child) => child.name === part) + + if (!childNode) { + childNode = { + name: part, + isDir: !isLastPart, + children: [], + mode: 16872, + size: 0, + type: 5, + modifyTime: 0, + } + + if (isLastPart) { + childNode.size = file.size + childNode.mode = file.mode + childNode.modifyTime = file.modifyTime + childNode.isDir = file.type === 5 + childNode.type = file.type + } + + currentNode.children.push(childNode) + } + + currentNode = childNode + } + } + + return root +} + +interface FilelikeInterface { + read( + buffer: Int8Array, + offset: number, + length: number, + position: number, + ): number + write( + buffer: Int8Array, + offset: number, + length: number, + position: number, + ): number + size(): number + truncate(len: number): void +} + +/** + * A file like object for locally created files + */ +class Filelike implements FilelikeInterface { + private data: Uint8Array + + constructor(data: Uint8Array) { + this.data = data + } + + read( + buffer: Int8Array, + offset: number, + length: number, + position: number, + ): number { + const bytesToRead = Math.min(length, this.data.length - position) + buffer.set(this.data.slice(position, position + bytesToRead), offset) + return bytesToRead + } + + write( + buffer: Int8Array, + offset: number, + length: number, + position: number, + ): number { + if (position + length > this.data.length) { + // Grow the file to the new size + const newData = new Uint8Array(position + length) + newData.set(this.data) + this.data = newData + } + this.data.set( + new Uint8Array(buffer.slice(offset, offset + length)), + position, + ) + return length + } + + size(): number { + return this.data.length + } + + truncate(len: number): void { + if (len < this.data.length) { + this.data = this.data.slice(0, len) + } else if (len > this.data.length) { + const newData = new Uint8Array(len) + newData.set(this.data) + this.data = newData + } + } +} + +/** + * A file like object for files loaded from a remote HTTP server + * If fullyLoad is true, the file is loaded into memory when the file is first read + * Otherwise a range request is made to fetch the pages + * Writes are stored in memory and overlay the original file when it is read + */ +class HttpFilelike implements FilelikeInterface { + private data?: Uint8Array + private writtenChunks: Record = {} // indexed by offset + private url: string + private length: number + private fullyLoad: boolean + + constructor(url: string, length: number, fullyLoad: boolean) { + this.url = url + this.length = length + this.fullyLoad = fullyLoad + } + + load() { + if (this.data) { + return + } + const xhr = new XMLHttpRequest() + xhr.open('GET', this.url, false) + xhr.responseType = 'arraybuffer' + xhr.send(null) + if (xhr.status === 200) { + this.data = new Uint8Array(xhr.response) + } else { + throw new Error('Failed to load file') + } + } + + read( + buffer: Int8Array, + offset: number, + length: number, + position: number, + ): number { + if (this.fullyLoad) { + this.load() + } + + let bytesRead = 0 + + // First, read from the base data or HTTP if not fully loaded + if (!this.data) { + if (position >= this.length) { + return 0 + } + + const end = Math.min(this.length, position + length) - 1 + const xhr = new XMLHttpRequest() + xhr.open('GET', this.url, false) + xhr.responseType = 'arraybuffer' + xhr.setRequestHeader('Range', `bytes=${position}-${end}`) + xhr.send(null) + + if (xhr.status === 206) { + const data = new Uint8Array(xhr.response) + buffer.set(data, offset) + bytesRead = data.length + } else { + throw new Error('Failed to load file') + } + } else { + const bytesToRead = Math.min(length, this.length - position) + buffer.set(this.data.slice(position, position + bytesToRead), offset) + bytesRead = bytesToRead + } + + // Overlay written chunks + const chunkKeys = Object.keys(this.writtenChunks) + .map(Number) + .sort((a, b) => a - b) + for (const chunkStart of chunkKeys) { + const chunk = this.writtenChunks[chunkStart] + const chunkEnd = chunkStart + chunk.length + + // Check if this chunk overlaps with the current read range + if (position + length > chunkStart && position < chunkEnd) { + const readStart = Math.max(position, chunkStart) + const readEnd = Math.min(position + length, chunkEnd) + const chunkOffset = readStart - chunkStart + + buffer.set( + chunk.slice(chunkOffset, chunkOffset + (readEnd - readStart)), + offset + (readStart - position), + ) + } + } + + return bytesRead + } + + write( + buffer: Int8Array, + offset: number, + length: number, + position: number, + ): number { + // Overlay the new written data into `writtenChunks` + let chunkStart = position + let chunkEnd = position + length + let chunkData = new Uint8Array(buffer.slice(offset, offset + length)) + + // Check for existing overlaps with writtenChunks + const chunkKeys = Object.keys(this.writtenChunks) + .map(Number) + .sort((a, b) => a - b) + for (const key of chunkKeys) { + const existingChunkStart = key + const existingChunk = this.writtenChunks[existingChunkStart] + const existingChunkEnd = existingChunkStart + existingChunk.length + + // If new chunk completely overlaps an existing chunk, remove the existing chunk + if (chunkStart <= existingChunkStart && chunkEnd >= existingChunkEnd) { + delete this.writtenChunks[existingChunkStart] + } else if ( + chunkStart < existingChunkEnd && + chunkEnd > existingChunkStart + ) { + // If partial overlap, merge the chunks + const newStart = Math.min(chunkStart, existingChunkStart) + const newEnd = Math.max(chunkEnd, existingChunkEnd) + + const mergedChunk = new Uint8Array(newEnd - newStart) + + if (existingChunkStart < chunkStart) { + mergedChunk.set( + existingChunk.slice(0, chunkStart - existingChunkStart), + 0, + ) + } + + mergedChunk.set(chunkData, chunkStart - newStart) + + if (existingChunkEnd > chunkEnd) { + mergedChunk.set( + existingChunk.slice(chunkEnd - existingChunkStart), + chunkEnd - newStart, + ) + } + + chunkStart = newStart + chunkEnd = newEnd + chunkData = mergedChunk + } + } + + this.writtenChunks[chunkStart] = chunkData + + // Update the length of the file + this.length = Math.max(this.length, chunkEnd) + + return length + } + + truncate(len: number): void { + if (len === 0) { + this.data = new Uint8Array() + this.writtenChunks = {} + this.length = 0 + return + } + + this.load() + + if (len < this.data!.length) { + this.data = this.data!.slice(0, len) + } else if (len > this.data!.length) { + const newData = new Uint8Array(len) + newData.set(this.data!) + this.data = newData + } + + // Remove written chunks that exceed the new file length + for (const chunkStart of Object.keys(this.writtenChunks).map(Number)) { + if (chunkStart >= len) { + delete this.writtenChunks[chunkStart] + } else { + const chunk = this.writtenChunks[chunkStart] + if (chunkStart + chunk.length > len) { + this.writtenChunks[chunkStart] = chunk.slice(0, len - chunkStart) + } + } + } + + this.length = len + } + + size(): number { + return this.length + } +} + +class FsError extends Error { + code?: number + constructor(code: number | keyof typeof ERRNO_CODES | null, message: string) { + super(message) + if (typeof code === 'number') { + this.code = code + } else if (typeof code === 'string') { + this.code = ERRNO_CODES[code] + } + } +} diff --git a/packages/pglite/src/fs/opfs-ahp.ts b/packages/pglite/src/fs/opfs-ahp.ts index 5a22c6f9c..3cd1ffacc 100644 --- a/packages/pglite/src/fs/opfs-ahp.ts +++ b/packages/pglite/src/fs/opfs-ahp.ts @@ -424,6 +424,7 @@ export class OpfsAhpFS extends BaseFilesystem { } readdir(path: string): string[] { + console.log('readdir', path) const node = this.#resolvePath(path) if (node.type !== 'directory') { throw new FsError('ENOTDIR', 'Not a directory') diff --git a/packages/pglite/src/fs/tarUtils.ts b/packages/pglite/src/fs/tarUtils.ts index c4829e033..54c911652 100644 --- a/packages/pglite/src/fs/tarUtils.ts +++ b/packages/pglite/src/fs/tarUtils.ts @@ -3,6 +3,18 @@ import type { FS } from '../postgresMod.js' export type DumpTarCompressionOptions = 'none' | 'gzip' | 'auto' +export type TarIndex = { + files: TarIndexFile[] +} + +export type TarIndexFile = { + name: string + mode: number + size: number + type: number + modifyTime: number +} + export async function dumpTar( FS: FS, pgDataDir: string, @@ -49,6 +61,10 @@ export async function loadTar( const files = untar(tarball) for (const file of files) { + if (file.name === 'index.json') { + // Skip the index.json file + continue + } const filePath = pgDataDir + file.name // Ensure the directory structure exists @@ -107,7 +123,32 @@ function readDirectory(FS: FS, path: string) { } export function createTarball(FS: FS, directoryPath: string) { - const files = readDirectory(FS, directoryPath) + const files = readDirectory(FS, directoryPath).filter( + (file) => file.name !== 'index.json', + ) + + // Create an index.json file with the list of files in the tarball + // This is used by the HTTP VFS to provide a list of files to the client that + // can be downloaded. + const index: TarIndex = { + files: files.map((file) => ({ + name: file.name, + mode: file.mode!, + size: file.size!, + type: file.type!, + modifyTime: dateToUnixTimestamp(file.modifyTime), + })), + } + const indexData = new TextEncoder().encode(JSON.stringify(index)) + files.push({ + name: 'index.json', + mode: 33184, + size: indexData.length, + type: REGTYPE, + modifyTime: dateToUnixTimestamp(new Date()), + data: indexData, + }) + const tarball = tar(files) return tarball } diff --git a/packages/pglite/tsup.config.ts b/packages/pglite/tsup.config.ts index 9e598f3ad..f09cf2ce5 100644 --- a/packages/pglite/tsup.config.ts +++ b/packages/pglite/tsup.config.ts @@ -20,6 +20,7 @@ const entryPoints = [ 'src/index.ts', 'src/fs/nodefs.ts', 'src/fs/opfs-ahp.ts', + 'src/fs/http.ts', 'src/templating.ts', 'src/live/index.ts', 'src/vector/index.ts', From 63f4bd57f8ac7302dd71e0262ddfa994a2457713 Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Wed, 2 Oct 2024 12:16:25 +0100 Subject: [PATCH 2/8] Do a checkpoint before dumpDataDir --- packages/pglite/src/pglite.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/pglite/src/pglite.ts b/packages/pglite/src/pglite.ts index ea76d7257..e63ae5a18 100644 --- a/packages/pglite/src/pglite.ts +++ b/packages/pglite/src/pglite.ts @@ -742,6 +742,8 @@ export class PGlite async dumpDataDir( compression?: DumpTarCompressionOptions, ): Promise { + // Do a CHECKPOINT before dumping the database to ensure that the WAL is applied + await this.exec(`CHECKPOINT`) const dbname = this.dataDir?.split('/').pop() ?? 'pgdata' return this.fs!.dumpTar(dbname, compression) } From 553dff43e9be43d1e175561f306ade995a76bd06 Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Wed, 2 Oct 2024 12:22:32 +0100 Subject: [PATCH 3/8] Refactor to use a syncFetch method --- packages/pglite/src/fs/http.ts | 45 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/packages/pglite/src/fs/http.ts b/packages/pglite/src/fs/http.ts index 45e00f36e..36df0b4e6 100644 --- a/packages/pglite/src/fs/http.ts +++ b/packages/pglite/src/fs/http.ts @@ -461,15 +461,7 @@ class HttpFilelike implements FilelikeInterface { if (this.data) { return } - const xhr = new XMLHttpRequest() - xhr.open('GET', this.url, false) - xhr.responseType = 'arraybuffer' - xhr.send(null) - if (xhr.status === 200) { - this.data = new Uint8Array(xhr.response) - } else { - throw new Error('Failed to load file') - } + this.data = syncFetch(this.url) } read( @@ -489,21 +481,11 @@ class HttpFilelike implements FilelikeInterface { if (position >= this.length) { return 0 } - const end = Math.min(this.length, position + length) - 1 - const xhr = new XMLHttpRequest() - xhr.open('GET', this.url, false) - xhr.responseType = 'arraybuffer' - xhr.setRequestHeader('Range', `bytes=${position}-${end}`) - xhr.send(null) - - if (xhr.status === 206) { - const data = new Uint8Array(xhr.response) - buffer.set(data, offset) - bytesRead = data.length - } else { - throw new Error('Failed to load file') - } + const range = { start: position, end } + const data = syncFetch(this.url, range) + buffer.set(data, offset) + bytesRead = data.length } else { const bytesToRead = Math.min(length, this.length - position) buffer.set(this.data.slice(position, position + bytesToRead), offset) @@ -646,3 +628,20 @@ class FsError extends Error { } } } + +function syncFetch( + url: string, + range?: { start: number; end: number }, +): Uint8Array { + const xhr = new XMLHttpRequest() + xhr.open('GET', url, false) + if (range) { + xhr.setRequestHeader('Range', `bytes=${range.start}-${range.end}`) + } + xhr.responseType = 'arraybuffer' + xhr.send(null) + if (xhr.status !== 200 && xhr.status !== 206) { + throw new Error('Failed to load file') + } + return new Uint8Array(xhr.response) +} From 51c746bbd98afc89e288e2d5e93d1f2554e16771 Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Wed, 2 Oct 2024 15:07:34 +0100 Subject: [PATCH 4/8] WIP node sync fetch --- packages/pglite/src/sync-fetch/node-worker.ts | 96 +++++++++++++++++++ packages/pglite/src/sync-fetch/node.ts | 65 +++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 packages/pglite/src/sync-fetch/node-worker.ts create mode 100644 packages/pglite/src/sync-fetch/node.ts diff --git a/packages/pglite/src/sync-fetch/node-worker.ts b/packages/pglite/src/sync-fetch/node-worker.ts new file mode 100644 index 000000000..13244cf43 --- /dev/null +++ b/packages/pglite/src/sync-fetch/node-worker.ts @@ -0,0 +1,96 @@ +import { workerData } from 'worker_threads' +import * as http from 'http' +import * as https from 'https' +import { URL } from 'url' + +function fetch( + url: string, + range: { start: number; end: number } | undefined, + sharedBuffer: SharedArrayBuffer, + chunkSize: number, +) { + const parsedUrl = new URL(url) + const client = parsedUrl.protocol === 'https:' ? https : http + + const options = { + headers: range + ? { + Range: `bytes=${range.start}-${range.end}`, + } + : {}, + } + + try { + client + .get(url, options, (response) => { + const int32View = new Int32Array(sharedBuffer, 0, 1) // Used for synchronization + const dataView = new Uint8Array(sharedBuffer, 4) // Used to store each chunk of data + + if (range && response.statusCode !== 206) { + // Set a negative value to indicate an error to the main thread + Atomics.store(int32View, 0, -1) + Atomics.notify(int32View, 0) + return + } else if (!range && response.statusCode !== 200) { + // Set a negative value to indicate an error to the main thread + Atomics.store(int32View, 0, -1) + Atomics.notify(int32View, 0) + return + } + + response.on('data', (chunk) => { + if (Buffer.isBuffer(chunk)) { + let chunkOffset = 0 + const chunkBuffer = new Uint8Array(chunk) + + while (chunkOffset < chunkBuffer.length) { + const bytesToCopy = Math.min( + chunkSize, + chunkBuffer.length - chunkOffset, + ) + dataView.set( + chunkBuffer.slice(chunkOffset, chunkOffset + bytesToCopy), + ) + + // Notify the main thread that the chunk is ready + Atomics.store(int32View, 0, bytesToCopy) + Atomics.notify(int32View, 0) + + // Wait for the main thread to process this chunk + Atomics.wait(int32View, 0, bytesToCopy) + + // Move the chunk offset + chunkOffset += bytesToCopy + } + } + }) + + response.on('end', () => { + // Notify the main thread that no more data is coming + Atomics.store(int32View, 0, 0) + Atomics.notify(int32View, 0) + }) + + response.on('error', (_err) => { + // Set a negative value to indicate an error to the main thread + Atomics.store(int32View, 0, -1) + Atomics.notify(int32View, 0) + }) + }) + .on('error', (_err) => { + // Set a negative value to indicate an error to the main thread + const int32View = new Int32Array(sharedBuffer, 0, 1) + Atomics.store(int32View, 0, -1) + Atomics.notify(int32View, 0) + }) + } catch (error) { + // Handle any synchronous errors + const int32View = new Int32Array(sharedBuffer, 0, 1) + Atomics.store(int32View, 0, -1) + Atomics.notify(int32View, 0) + } +} + +// Run the fetch synchronously +const { url, range, sharedBuffer, chunkSize } = workerData +fetch(url, range, sharedBuffer, chunkSize) diff --git a/packages/pglite/src/sync-fetch/node.ts b/packages/pglite/src/sync-fetch/node.ts new file mode 100644 index 000000000..d8b07e2ca --- /dev/null +++ b/packages/pglite/src/sync-fetch/node.ts @@ -0,0 +1,65 @@ +import { Worker } from 'worker_threads' + +const CHUNK_SIZE = 64 * 1024 // 64KB + +// Helper function to run the worker synchronously and receive data chunks +export function runSyncFetch( + url: string, + range?: { start: number; end: number }, +): Uint8Array { + // Shared buffer for communication (chunk size + sync flag) + const sharedBuffer = new SharedArrayBuffer(CHUNK_SIZE + 4) // 4 extra bytes for synchronization + const int32View = new Int32Array(sharedBuffer, 0, 1) // Used for synchronization + const dataView = new Uint8Array(sharedBuffer, 4) // Used to store each chunk of data + + // Create a new worker + const worker = new Worker(new URL('./node-worker.js', import.meta.url), { + workerData: { url, range, sharedBuffer, chunkSize: CHUNK_SIZE }, + }) + + const receivedChunks: Uint8Array[] = [] + + try { + while (true) { + // Block the main thread until the worker signals that a chunk is ready or an error occurs + Atomics.wait(int32View, 0, 0) + + // Check for an error signal + const signal = Atomics.load(int32View, 0) + if (signal < 0) { + // Terminate the worker and throw an error if the signal indicates failure + worker.terminate() + throw new Error(`Failed to fetch data: ${url}`) + } + + // Check if the worker signaled completion + if (signal === 0) { + // If chunk length is 0, it means the worker has finished sending data + break + } + + // Store the chunk data + receivedChunks.push(dataView.slice(0, signal)) + + // Reset the sync flag for the next chunk + Atomics.store(int32View, 0, 0) + Atomics.notify(int32View, 0) // Signal worker that we're ready for the next chunk + } + + // Concatenate all the received chunks into a single Uint8Array + const totalLength = receivedChunks.reduce( + (sum, chunk) => sum + chunk.length, + 0, + ) + const result = new Uint8Array(totalLength) + let offset = 0 + for (const chunk of receivedChunks) { + result.set(chunk, offset) + offset += chunk.length + } + + return result + } finally { + worker.terminate() // Ensure the worker is terminated + } +} From c1c87ec849b4b63e7e73cfe0078825ef3770b925 Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Wed, 2 Oct 2024 19:21:51 +0100 Subject: [PATCH 5/8] Node HTTP VFS support --- packages/pglite/examples/httpfs-worker.js | 2 +- packages/pglite/examples/httpfs.js | 19 +++++++++++++ packages/pglite/src/fs/http.ts | 34 ++++++++++------------- packages/pglite/src/sync-fetch/browser.ts | 21 ++++++++++++++ packages/pglite/src/sync-fetch/index.ts | 16 +++++++++++ packages/pglite/src/sync-fetch/node.ts | 6 ++-- packages/pglite/src/sync-fetch/types.ts | 4 +++ packages/pglite/tsup.config.ts | 2 ++ pnpm-lock.yaml | 4 +-- 9 files changed, 82 insertions(+), 26 deletions(-) create mode 100644 packages/pglite/examples/httpfs.js create mode 100644 packages/pglite/src/sync-fetch/browser.ts create mode 100644 packages/pglite/src/sync-fetch/index.ts create mode 100644 packages/pglite/src/sync-fetch/types.ts diff --git a/packages/pglite/examples/httpfs-worker.js b/packages/pglite/examples/httpfs-worker.js index 024f0d2b2..0a36d2e5d 100644 --- a/packages/pglite/examples/httpfs-worker.js +++ b/packages/pglite/examples/httpfs-worker.js @@ -11,7 +11,7 @@ worker({ // debug: 1, fs: new HttpFs("/pglite/examples/pgdata", { // debug: true - fetchGranularity: 'file', // 'file' or 'page' + fetchGranularity: 'page', // 'file' or 'page' }), }); console.log("PGlite initialized in", performance.now() - start, "ms"); diff --git a/packages/pglite/examples/httpfs.js b/packages/pglite/examples/httpfs.js new file mode 100644 index 000000000..ace081cf2 --- /dev/null +++ b/packages/pglite/examples/httpfs.js @@ -0,0 +1,19 @@ +import { PGlite } from "../dist/index.js"; +import { HttpFs } from "../dist/fs/http.js"; + +console.log("Starting PGLite..."); +const pg = await PGlite.create({ + // debug: 1, + fs: new HttpFs("http://localhost/pglite/examples/pgdata", { + // debug: true + fetchGranularity: 'file', // 'file' or 'page' + }), +}); + +const start = performance.now(); +console.log("Selecting data..."); +const res = await pg.exec(` + SELECT * FROM test; +`); +console.log(res); +console.log("Query Took", performance.now() - start, "ms"); diff --git a/packages/pglite/src/fs/http.ts b/packages/pglite/src/fs/http.ts index 36df0b4e6..e7349b010 100644 --- a/packages/pglite/src/fs/http.ts +++ b/packages/pglite/src/fs/http.ts @@ -2,6 +2,7 @@ import type { PGlite } from '../pglite.js' import type { PostgresMod } from '../postgresMod.js' import { BaseFilesystem, FsStats, ERRNO_CODES } from './base.js' import type { TarIndex, TarIndexFile } from './tarUtils.js' +import { makeSyncFetch, type SyncFetch } from '../sync-fetch/index.js' type Node = TarIndexFile & { isDir: boolean @@ -40,6 +41,7 @@ export class HttpFs extends BaseFilesystem { #handleMap: Map = new Map() #handleCounter = 0 fetchGranularity: FetchGranularity + fetch?: SyncFetch constructor( baseUrl: string, @@ -51,6 +53,7 @@ export class HttpFs extends BaseFilesystem { async init(pg: PGlite, opts: Partial) { await this.#init() + this.fetch = await makeSyncFetch() return super.init(pg, opts) } @@ -188,6 +191,7 @@ export class HttpFs extends BaseFilesystem { `${this.dataDir}${path}`, node.size, this.fetchGranularity === 'file' || fileToFullyLoad.has(path), + this.fetch!, ) } else if (!node.data) { node.data = new Filelike(new Uint8Array()) @@ -450,18 +454,25 @@ class HttpFilelike implements FilelikeInterface { private url: string private length: number private fullyLoad: boolean + private fetch: SyncFetch - constructor(url: string, length: number, fullyLoad: boolean) { + constructor( + url: string, + length: number, + fullyLoad: boolean, + fetch: SyncFetch, + ) { this.url = url this.length = length this.fullyLoad = fullyLoad + this.fetch = fetch } load() { if (this.data) { return } - this.data = syncFetch(this.url) + this.data = this.fetch(this.url) } read( @@ -483,7 +494,7 @@ class HttpFilelike implements FilelikeInterface { } const end = Math.min(this.length, position + length) - 1 const range = { start: position, end } - const data = syncFetch(this.url, range) + const data = this.fetch(this.url, range) buffer.set(data, offset) bytesRead = data.length } else { @@ -628,20 +639,3 @@ class FsError extends Error { } } } - -function syncFetch( - url: string, - range?: { start: number; end: number }, -): Uint8Array { - const xhr = new XMLHttpRequest() - xhr.open('GET', url, false) - if (range) { - xhr.setRequestHeader('Range', `bytes=${range.start}-${range.end}`) - } - xhr.responseType = 'arraybuffer' - xhr.send(null) - if (xhr.status !== 200 && xhr.status !== 206) { - throw new Error('Failed to load file') - } - return new Uint8Array(xhr.response) -} diff --git a/packages/pglite/src/sync-fetch/browser.ts b/packages/pglite/src/sync-fetch/browser.ts new file mode 100644 index 000000000..3311d3024 --- /dev/null +++ b/packages/pglite/src/sync-fetch/browser.ts @@ -0,0 +1,21 @@ +import type { SyncFetch } from './types.js' + +/** + * Sync fetch function for browser using XMLHttpRequest + */ +export const syncFetchBrowser: SyncFetch = ( + url: string, + range?: { start: number; end: number }, +): Uint8Array => { + const xhr = new XMLHttpRequest() + xhr.open('GET', url, false) + if (range) { + xhr.setRequestHeader('Range', `bytes=${range.start}-${range.end}`) + } + xhr.responseType = 'arraybuffer' + xhr.send(null) + if (xhr.status !== 200 && xhr.status !== 206) { + throw new Error('Failed to load file') + } + return new Uint8Array(xhr.response) +} diff --git a/packages/pglite/src/sync-fetch/index.ts b/packages/pglite/src/sync-fetch/index.ts new file mode 100644 index 000000000..1ddca9aa3 --- /dev/null +++ b/packages/pglite/src/sync-fetch/index.ts @@ -0,0 +1,16 @@ +import { syncFetchBrowser } from './browser.js' +import type { SyncFetch } from './types.js' +import { IN_NODE } from '../utils.js' + +export type { SyncFetch } from './types.js' +/** + * Creates a sync fetch function for the current environment + */ +export async function makeSyncFetch(): Promise { + if (IN_NODE) { + const { syncFetchNode } = await import('./node.js') + return syncFetchNode + } else { + return syncFetchBrowser + } +} diff --git a/packages/pglite/src/sync-fetch/node.ts b/packages/pglite/src/sync-fetch/node.ts index d8b07e2ca..d45c409a1 100644 --- a/packages/pglite/src/sync-fetch/node.ts +++ b/packages/pglite/src/sync-fetch/node.ts @@ -1,12 +1,12 @@ import { Worker } from 'worker_threads' +import type { SyncFetch } from './types.js' const CHUNK_SIZE = 64 * 1024 // 64KB -// Helper function to run the worker synchronously and receive data chunks -export function runSyncFetch( +export const syncFetchNode: SyncFetch = ( url: string, range?: { start: number; end: number }, -): Uint8Array { +): Uint8Array => { // Shared buffer for communication (chunk size + sync flag) const sharedBuffer = new SharedArrayBuffer(CHUNK_SIZE + 4) // 4 extra bytes for synchronization const int32View = new Int32Array(sharedBuffer, 0, 1) // Used for synchronization diff --git a/packages/pglite/src/sync-fetch/types.ts b/packages/pglite/src/sync-fetch/types.ts new file mode 100644 index 000000000..e37755bbd --- /dev/null +++ b/packages/pglite/src/sync-fetch/types.ts @@ -0,0 +1,4 @@ +export type SyncFetch = ( + url: string, + range?: { start: number; end: number }, +) => Uint8Array diff --git a/packages/pglite/tsup.config.ts b/packages/pglite/tsup.config.ts index f09cf2ce5..dd6cecb73 100644 --- a/packages/pglite/tsup.config.ts +++ b/packages/pglite/tsup.config.ts @@ -25,6 +25,8 @@ const entryPoints = [ 'src/live/index.ts', 'src/vector/index.ts', 'src/worker/index.ts', + 'src/sync-fetch/node.ts', + 'src/sync-fetch/node-worker.ts', ] const contribDir = path.join(root, 'src', 'contrib') diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab4cbd195..b52695a3c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6281,7 +6281,7 @@ snapshots: magic-string: 0.30.11 msw: 2.3.5(typescript@5.5.4) sirv: 2.0.4 - vitest: 2.0.5(@types/node@22.4.1)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(jsdom@24.1.1)(terser@5.31.6) + vitest: 2.0.5(@types/node@20.14.15)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(jsdom@24.1.1)(terser@5.31.6) ws: 8.18.0 optionalDependencies: playwright: 1.46.0 @@ -6361,7 +6361,7 @@ snapshots: pathe: 1.1.2 sirv: 2.0.4 tinyrainbow: 1.2.0 - vitest: 2.0.5(@types/node@22.4.1)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(jsdom@24.1.1)(terser@5.31.6) + vitest: 2.0.5(@types/node@20.14.15)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(jsdom@24.1.1)(terser@5.31.6) optional: true '@vitest/utils@2.0.5': From 9cb47b295a7308c1d196cde6c339196ef671318e Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Thu, 3 Oct 2024 12:26:56 +0100 Subject: [PATCH 6/8] Move browser and node http fs into seporate imports --- packages/pglite/examples/httpfs-worker.js | 2 +- packages/pglite/examples/httpfs.js | 2 +- packages/pglite/package.json | 18 +++++++++++++----- .../pglite/src/fs/{http.ts => http/base.ts} | 15 +++++++-------- packages/pglite/src/fs/http/browser.ts | 6 ++++++ packages/pglite/src/fs/http/node.ts | 6 ++++++ packages/pglite/src/sync-fetch/node-worker.ts | 1 - packages/pglite/tsup.config.ts | 3 ++- 8 files changed, 36 insertions(+), 17 deletions(-) rename packages/pglite/src/fs/{http.ts => http/base.ts} (97%) create mode 100644 packages/pglite/src/fs/http/browser.ts create mode 100644 packages/pglite/src/fs/http/node.ts diff --git a/packages/pglite/examples/httpfs-worker.js b/packages/pglite/examples/httpfs-worker.js index 0a36d2e5d..b270b6032 100644 --- a/packages/pglite/examples/httpfs-worker.js +++ b/packages/pglite/examples/httpfs-worker.js @@ -1,6 +1,6 @@ import { PGlite } from "../dist/index.js"; import { worker } from "../dist/worker/index.js"; -import { HttpFs } from "../dist/fs/http.js"; +import { HttpFs } from "../dist/fs/http/browser.js"; console.log("Starting worker..."); diff --git a/packages/pglite/examples/httpfs.js b/packages/pglite/examples/httpfs.js index ace081cf2..c517e035d 100644 --- a/packages/pglite/examples/httpfs.js +++ b/packages/pglite/examples/httpfs.js @@ -1,5 +1,5 @@ import { PGlite } from "../dist/index.js"; -import { HttpFs } from "../dist/fs/http.js"; +import { HttpFs } from "../dist/fs/http/node.js"; console.log("Starting PGLite..."); const pg = await PGlite.create({ diff --git a/packages/pglite/package.json b/packages/pglite/package.json index 7787aabb8..c05e5986b 100644 --- a/packages/pglite/package.json +++ b/packages/pglite/package.json @@ -54,10 +54,15 @@ "require": "./dist/fs/opfs-ahp.cjs", "types": "./dist/fs/opfs-ahp.d.ts" }, - "./httpfs": { - "import": "./dist/fs/http.js", - "require": "./dist/fs/http.cjs", - "types": "./dist/fs/http.d.ts" + "./httpfs/browser": { + "import": "./dist/fs/http/browser.js", + "require": "./dist/fs/http/browser.cjs", + "types": "./dist/fs/http/browser.d.ts" + }, + "./httpfs/node": { + "import": "./dist/fs/http/node.js", + "require": "./dist/fs/http/node.cjs", + "types": "./dist/fs/http/node.d.ts" }, "./contrib/*": { "import": "./dist/contrib/*.js", @@ -120,6 +125,9 @@ "crypto": false, "ws": false, "child_process": false, - "module": false + "module": false, + "worker_threads": false, + "http": false, + "https": false } } diff --git a/packages/pglite/src/fs/http.ts b/packages/pglite/src/fs/http/base.ts similarity index 97% rename from packages/pglite/src/fs/http.ts rename to packages/pglite/src/fs/http/base.ts index e7349b010..3ada333e4 100644 --- a/packages/pglite/src/fs/http.ts +++ b/packages/pglite/src/fs/http/base.ts @@ -1,8 +1,8 @@ -import type { PGlite } from '../pglite.js' -import type { PostgresMod } from '../postgresMod.js' -import { BaseFilesystem, FsStats, ERRNO_CODES } from './base.js' -import type { TarIndex, TarIndexFile } from './tarUtils.js' -import { makeSyncFetch, type SyncFetch } from '../sync-fetch/index.js' +import type { PGlite } from '../../pglite.js' +import type { PostgresMod } from '../../postgresMod.js' +import { SyncFetch } from '../../sync-fetch/index.js' +import { BaseFilesystem, FsStats, ERRNO_CODES } from '../base.js' +import type { TarIndex, TarIndexFile } from '../tarUtils.js' type Node = TarIndexFile & { isDir: boolean @@ -34,14 +34,14 @@ export interface HttpFsOptions { * Requires an index.json file at the root of the filesystem with a list of * files available to fetch */ -export class HttpFs extends BaseFilesystem { +export abstract class HttpFsBase extends BaseFilesystem { index?: TarIndex tree?: Node httpPaths = new Set() #handleMap: Map = new Map() #handleCounter = 0 fetchGranularity: FetchGranularity - fetch?: SyncFetch + abstract fetch: SyncFetch constructor( baseUrl: string, @@ -53,7 +53,6 @@ export class HttpFs extends BaseFilesystem { async init(pg: PGlite, opts: Partial) { await this.#init() - this.fetch = await makeSyncFetch() return super.init(pg, opts) } diff --git a/packages/pglite/src/fs/http/browser.ts b/packages/pglite/src/fs/http/browser.ts new file mode 100644 index 000000000..648db09aa --- /dev/null +++ b/packages/pglite/src/fs/http/browser.ts @@ -0,0 +1,6 @@ +import { HttpFsBase } from './base.js' +import { syncFetchBrowser } from '../../sync-fetch/browser.js' + +export class HttpFs extends HttpFsBase { + fetch = syncFetchBrowser +} diff --git a/packages/pglite/src/fs/http/node.ts b/packages/pglite/src/fs/http/node.ts new file mode 100644 index 000000000..9a565f8da --- /dev/null +++ b/packages/pglite/src/fs/http/node.ts @@ -0,0 +1,6 @@ +import { HttpFsBase } from './base.js' +import { syncFetchNode } from '../../sync-fetch/node.js' + +export class HttpFs extends HttpFsBase { + fetch = syncFetchNode +} diff --git a/packages/pglite/src/sync-fetch/node-worker.ts b/packages/pglite/src/sync-fetch/node-worker.ts index 13244cf43..873ee5e59 100644 --- a/packages/pglite/src/sync-fetch/node-worker.ts +++ b/packages/pglite/src/sync-fetch/node-worker.ts @@ -1,7 +1,6 @@ import { workerData } from 'worker_threads' import * as http from 'http' import * as https from 'https' -import { URL } from 'url' function fetch( url: string, diff --git a/packages/pglite/tsup.config.ts b/packages/pglite/tsup.config.ts index dd6cecb73..d0180d7b0 100644 --- a/packages/pglite/tsup.config.ts +++ b/packages/pglite/tsup.config.ts @@ -20,7 +20,8 @@ const entryPoints = [ 'src/index.ts', 'src/fs/nodefs.ts', 'src/fs/opfs-ahp.ts', - 'src/fs/http.ts', + 'src/fs/http/browser.ts', + 'src/fs/http/node.ts', 'src/templating.ts', 'src/live/index.ts', 'src/vector/index.ts', From 994fa557ffb07b4c9047c5a1323df442b1379bde Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Thu, 3 Oct 2024 12:29:08 +0100 Subject: [PATCH 7/8] HTTP FS demo --- demos/pagila-httpvfs/.gitignore | 27 + demos/pagila-httpvfs/README.md | 25 + demos/pagila-httpvfs/eslint.config.js | 28 + demos/pagila-httpvfs/index.html | 13 + demos/pagila-httpvfs/package.json | 36 + demos/pagila-httpvfs/public/icon.svg | 4 + demos/pagila-httpvfs/scripts/make-database.ts | 60 ++ demos/pagila-httpvfs/src/App.css | 20 + demos/pagila-httpvfs/src/App.tsx | 51 + demos/pagila-httpvfs/src/index.css | 72 ++ demos/pagila-httpvfs/src/main.tsx | 10 + demos/pagila-httpvfs/src/pglite-worker.ts | 14 + demos/pagila-httpvfs/src/vite-env.d.ts | 1 + demos/pagila-httpvfs/tsconfig.app.json | 24 + demos/pagila-httpvfs/tsconfig.json | 7 + demos/pagila-httpvfs/tsconfig.node.json | 22 + demos/pagila-httpvfs/vite.config.ts | 13 + pnpm-lock.yaml | 993 +++++++++++++----- pnpm-workspace.yaml | 1 + 19 files changed, 1179 insertions(+), 242 deletions(-) create mode 100644 demos/pagila-httpvfs/.gitignore create mode 100644 demos/pagila-httpvfs/README.md create mode 100644 demos/pagila-httpvfs/eslint.config.js create mode 100644 demos/pagila-httpvfs/index.html create mode 100644 demos/pagila-httpvfs/package.json create mode 100644 demos/pagila-httpvfs/public/icon.svg create mode 100644 demos/pagila-httpvfs/scripts/make-database.ts create mode 100644 demos/pagila-httpvfs/src/App.css create mode 100644 demos/pagila-httpvfs/src/App.tsx create mode 100644 demos/pagila-httpvfs/src/index.css create mode 100644 demos/pagila-httpvfs/src/main.tsx create mode 100644 demos/pagila-httpvfs/src/pglite-worker.ts create mode 100644 demos/pagila-httpvfs/src/vite-env.d.ts create mode 100644 demos/pagila-httpvfs/tsconfig.app.json create mode 100644 demos/pagila-httpvfs/tsconfig.json create mode 100644 demos/pagila-httpvfs/tsconfig.node.json create mode 100644 demos/pagila-httpvfs/vite.config.ts diff --git a/demos/pagila-httpvfs/.gitignore b/demos/pagila-httpvfs/.gitignore new file mode 100644 index 000000000..7d3e88f8b --- /dev/null +++ b/demos/pagila-httpvfs/.gitignore @@ -0,0 +1,27 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +public/pagila +public/pagila.tar.gz diff --git a/demos/pagila-httpvfs/README.md b/demos/pagila-httpvfs/README.md new file mode 100644 index 000000000..522dae14a --- /dev/null +++ b/demos/pagila-httpvfs/README.md @@ -0,0 +1,25 @@ +# PGlite + HttpFs Demo + +This demo shows how to use PGlite, a WASM build of Postgres running entirely in the browser, with the WIP HttpFs to connect to a remote PGlite database. It's using HTTP range requests to fetch database file pages from the remote server on demand. + +The database in this demo is the Pagila sample database. + +## Development + +Install the dependencies: + +``` +pnpm install +``` + +Build the database: + +``` +pnpm make-database +``` + +Start the dev server: + +``` +pnpm dev +``` diff --git a/demos/pagila-httpvfs/eslint.config.js b/demos/pagila-httpvfs/eslint.config.js new file mode 100644 index 000000000..092408a9f --- /dev/null +++ b/demos/pagila-httpvfs/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/demos/pagila-httpvfs/index.html b/demos/pagila-httpvfs/index.html new file mode 100644 index 000000000..c7d99b9d5 --- /dev/null +++ b/demos/pagila-httpvfs/index.html @@ -0,0 +1,13 @@ + + + + + + + PGlite + HttpFs Demo + + +
+ + + diff --git a/demos/pagila-httpvfs/package.json b/demos/pagila-httpvfs/package.json new file mode 100644 index 000000000..f598d09ae --- /dev/null +++ b/demos/pagila-httpvfs/package.json @@ -0,0 +1,36 @@ +{ + "name": "pagila-httpvfs", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview", + "make-database": "tsx scripts/make-database.ts" + }, + "dependencies": { + "@electric-sql/pglite": "workspace:*", + "@electric-sql/pglite-react": "workspace:*", + "@electric-sql/pglite-repl": "workspace:*", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "tar": "^7.4.3", + "tsx": "^4.19.1" + }, + "devDependencies": { + "@eslint/js": "^9.9.0", + "@types/node": "^20.11.18", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "eslint": "^9.9.0", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.9", + "globals": "^15.9.0", + "typescript": "^5.5.3", + "typescript-eslint": "^8.0.1", + "vite": "^5.4.1" + } +} diff --git a/demos/pagila-httpvfs/public/icon.svg b/demos/pagila-httpvfs/public/icon.svg new file mode 100644 index 000000000..c648b0f64 --- /dev/null +++ b/demos/pagila-httpvfs/public/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/demos/pagila-httpvfs/scripts/make-database.ts b/demos/pagila-httpvfs/scripts/make-database.ts new file mode 100644 index 000000000..b8ce4d755 --- /dev/null +++ b/demos/pagila-httpvfs/scripts/make-database.ts @@ -0,0 +1,60 @@ +import { PGlite } from '@electric-sql/pglite' +import fs from 'node:fs/promises' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { extract as tarExtract } from 'tar' + +const SCHEMA_URL = + 'https://raw.githubusercontent.com/devrimgunduz/pagila/refs/heads/master/pagila-schema.sql' +const DATA_URL = + 'https://raw.githubusercontent.com/devrimgunduz/pagila/refs/heads/master/pagila-insert-data.sql' +const THIS_DIR = path.dirname(fileURLToPath(import.meta.url)) + +// Download the schema and data from the internet +console.log('Downloading schema...') +const schema = await fetch(SCHEMA_URL).then((r) => r.text()) +console.log('Downloading data...') +const data = await fetch(DATA_URL).then((r) => r.text()) + +// Create a new PGlite instance +console.log('Creating database...') +const pg = await PGlite.create() + +// Initialize the schema +console.log('Initializing database schema...') +await pg.exec(schema) + +// Split the data into lines and execute each line so as to not run out of memory +console.log('Inserting database data...') +const dataLines = data.split('\n').filter((line) => line.trim().length > 0 && !line.startsWith('--')) +for (const line of dataLines) { + try { + await pg.exec(line) + } catch (e) { + console.error(line) + console.error(e) + process.exit(1) + } +} + +console.log('Vacuuming database...') +await pg.exec('VACUUM ANALYZE') +await pg.exec('CHECKPOINT') + +console.log('Dumping database...') +const file = await pg.dumpDataDir() + +console.log('Writing database...') +await fs.writeFile( + path.join(THIS_DIR, '..', 'public', 'pagila.tar.gz'), + Buffer.from(await file.arrayBuffer()), +) + +console.log('Extracting database...') +await fs.mkdir(path.join(THIS_DIR, '..', 'public', 'pagila')) +await tarExtract({ + file: path.join(THIS_DIR, '..', 'public', 'pagila.tar.gz'), + cwd: path.join(THIS_DIR, '..', 'public', 'pagila'), +}) + +console.log('Done!') diff --git a/demos/pagila-httpvfs/src/App.css b/demos/pagila-httpvfs/src/App.css new file mode 100644 index 000000000..a9209b066 --- /dev/null +++ b/demos/pagila-httpvfs/src/App.css @@ -0,0 +1,20 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 1rem; + text-align: center; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; +} + +.PGliteRepl-root { + height: 60vh; + width: 100%; + text-align: left; +} + +.intro { + max-width: 60rem; +} \ No newline at end of file diff --git a/demos/pagila-httpvfs/src/App.tsx b/demos/pagila-httpvfs/src/App.tsx new file mode 100644 index 000000000..4e46b253a --- /dev/null +++ b/demos/pagila-httpvfs/src/App.tsx @@ -0,0 +1,51 @@ +import { PGliteWorker } from '@electric-sql/pglite/worker' +import { Repl } from '@electric-sql/pglite-repl' +import { useEffect, useState } from 'react' +import PGWorker from './pglite-worker.js?worker' +import './App.css' + +let pgPromise: Promise + +function App() { + pgPromise ??= PGliteWorker.create( + new PGWorker({ + name: 'pglite-worker', + }), + ) + const [pg, setPg] = useState(null) + useEffect(() => { + pgPromise.then(setPg) + }, []) + + return ( + <> +

+ PGlite +{' '} + + HttpFs + +

+
+

+ This demo shows how to use PGlite, a + WASM build of Postgres running entirely in the browser, with the WIP + HttpFs to connect to a remote PGlite database. It's using HTTP range + requests to fetch database file pages from the remote server on + demand. +

+

+ The database in this demo is the{' '} + Pagila sample + database. +

+

+ The REPL below supports the same \d commands as{' '} + psql. +

+
+ {pg ? :

Loading...

} + + ) +} + +export default App diff --git a/demos/pagila-httpvfs/src/index.css b/demos/pagila-httpvfs/src/index.css new file mode 100644 index 000000000..528eeaafd --- /dev/null +++ b/demos/pagila-httpvfs/src/index.css @@ -0,0 +1,72 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + font-size: 14px; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; +} + +h1 { + font-size: 1.5em; + line-height: 1.1; + font-weight: 600; +} + +h1 a { + font-weight: 600; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/demos/pagila-httpvfs/src/main.tsx b/demos/pagila-httpvfs/src/main.tsx new file mode 100644 index 000000000..6f4ac9bcc --- /dev/null +++ b/demos/pagila-httpvfs/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import App from './App.tsx' +import './index.css' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/demos/pagila-httpvfs/src/pglite-worker.ts b/demos/pagila-httpvfs/src/pglite-worker.ts new file mode 100644 index 000000000..538660a64 --- /dev/null +++ b/demos/pagila-httpvfs/src/pglite-worker.ts @@ -0,0 +1,14 @@ +import { worker } from "@electric-sql/pglite/worker"; +import { HttpFs } from "@electric-sql/pglite/httpfs/browser"; +import { PGlite } from "@electric-sql/pglite"; + +worker({ + async init() { + const pg = await PGlite.create({ + fs: new HttpFs("/pagila", { + fetchGranularity: 'page', // 'file' or 'page' + }), + }); + return pg; + }, +}); diff --git a/demos/pagila-httpvfs/src/vite-env.d.ts b/demos/pagila-httpvfs/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/demos/pagila-httpvfs/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/demos/pagila-httpvfs/tsconfig.app.json b/demos/pagila-httpvfs/tsconfig.app.json new file mode 100644 index 000000000..f0a235055 --- /dev/null +++ b/demos/pagila-httpvfs/tsconfig.app.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/demos/pagila-httpvfs/tsconfig.json b/demos/pagila-httpvfs/tsconfig.json new file mode 100644 index 000000000..1ffef600d --- /dev/null +++ b/demos/pagila-httpvfs/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/demos/pagila-httpvfs/tsconfig.node.json b/demos/pagila-httpvfs/tsconfig.node.json new file mode 100644 index 000000000..9987e4b06 --- /dev/null +++ b/demos/pagila-httpvfs/tsconfig.node.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["vite.config.ts", "scripts/**/*.ts"] +} diff --git a/demos/pagila-httpvfs/vite.config.ts b/demos/pagila-httpvfs/vite.config.ts new file mode 100644 index 000000000..a32f70d29 --- /dev/null +++ b/demos/pagila-httpvfs/vite.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + optimizeDeps: { + exclude: ['@electric-sql/pglite'], + }, + worker: { + format: 'es', + }, +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b52695a3c..2c2b5b7f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,7 +31,7 @@ importers: version: 3.2.5 tsup: specifier: ^8.1.0 - version: 8.2.4(@microsoft/api-extractor@7.47.4(@types/node@22.4.1))(postcss@8.4.41)(tsx@4.17.0)(typescript@5.5.4) + version: 8.2.4(@microsoft/api-extractor@7.47.4(@types/node@22.4.1))(postcss@8.4.47)(tsx@4.17.0)(typescript@5.5.4) tsx: specifier: ^4.8.1 version: 4.17.0 @@ -39,6 +39,67 @@ importers: specifier: ^5.3.3 version: 5.5.4 + demos/pagila-httpvfs: + dependencies: + '@electric-sql/pglite': + specifier: workspace:* + version: link:../../packages/pglite + '@electric-sql/pglite-react': + specifier: workspace:* + version: link:../../packages/pglite-react + '@electric-sql/pglite-repl': + specifier: workspace:* + version: link:../../packages/pglite-repl + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + tar: + specifier: ^7.4.3 + version: 7.4.3 + tsx: + specifier: ^4.19.1 + version: 4.19.1 + devDependencies: + '@eslint/js': + specifier: ^9.9.0 + version: 9.11.1 + '@types/node': + specifier: ^20.11.18 + version: 20.14.15 + '@types/react': + specifier: ^18.3.3 + version: 18.3.3 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.0 + '@vitejs/plugin-react': + specifier: ^4.3.1 + version: 4.3.1(vite@5.4.8(@types/node@20.14.15)(terser@5.31.6)) + eslint: + specifier: ^9.9.0 + version: 9.11.1 + eslint-plugin-react-hooks: + specifier: ^5.1.0-rc.0 + version: 5.1.0-rc-fb9a90fa48-20240614(eslint@9.11.1) + eslint-plugin-react-refresh: + specifier: ^0.4.9 + version: 0.4.9(eslint@9.11.1) + globals: + specifier: ^15.9.0 + version: 15.9.0 + typescript: + specifier: ^5.5.3 + version: 5.5.4 + typescript-eslint: + specifier: ^8.0.1 + version: 8.8.0(eslint@9.11.1)(typescript@5.5.4) + vite: + specifier: ^5.4.1 + version: 5.4.8(@types/node@20.14.15)(terser@5.31.6) + docs: dependencies: '@electric-sql/pglite': @@ -56,7 +117,7 @@ importers: devDependencies: vitepress: specifier: ^1.3.1 - version: 1.3.2(@algolia/client-search@4.24.0)(@types/node@22.4.1)(@types/react@18.3.3)(@vue/composition-api@1.7.2(vue@3.4.37(typescript@5.5.4)))(postcss@8.4.41)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.16.3)(terser@5.31.6)(typescript@5.5.4) + version: 1.3.2(@algolia/client-search@4.24.0)(@types/node@22.4.1)(@types/react@18.3.3)(@vue/composition-api@1.7.2(vue@3.4.37(typescript@5.5.4)))(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.16.3)(terser@5.31.6)(typescript@5.5.4) packages/benchmark: dependencies: @@ -135,7 +196,7 @@ importers: version: link:../pglite '@eslint-react/eslint-plugin': specifier: ^1.9.0 - version: 1.10.1(eslint@8.57.0)(typescript@5.5.4) + version: 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@testing-library/dom': specifier: ^10.4.0 version: 10.4.0 @@ -150,10 +211,10 @@ importers: version: 18.3.0 '@vitejs/plugin-react': specifier: ^4.2.1 - version: 4.3.1(vite@5.4.0(@types/node@22.4.1)(terser@5.31.6)) + version: 4.3.1(vite@5.4.8(@types/node@22.4.1)(terser@5.31.6)) eslint-plugin-react-compiler: specifier: 0.0.0-experimental-9ed098e-20240725 - version: 0.0.0-experimental-9ed098e-20240725(eslint@8.57.0) + version: 0.0.0-experimental-9ed098e-20240725(eslint@9.11.1) globals: specifier: ^15.9.0 version: 15.9.0 @@ -229,13 +290,13 @@ importers: version: 4.3.1(vite@5.4.0(@types/node@20.14.15)(terser@5.31.6)) eslint-plugin-react-compiler: specifier: 0.0.0-experimental-9ed098e-20240725 - version: 0.0.0-experimental-9ed098e-20240725(eslint@8.57.0) + version: 0.0.0-experimental-9ed098e-20240725(eslint@9.11.1) eslint-plugin-react-hooks: specifier: ^4.6.0 - version: 4.6.2(eslint@8.57.0) + version: 4.6.2(eslint@9.11.1) eslint-plugin-react-refresh: specifier: ^0.4.6 - version: 0.4.9(eslint@8.57.0) + version: 0.4.9(eslint@9.11.1) terser: specifier: ^5.31.1 version: 5.31.6 @@ -260,10 +321,10 @@ importers: version: link:../pglite '@eslint-react/eslint-plugin': specifier: ^1.14.2 - version: 1.14.2(eslint@8.57.0)(typescript@5.5.4) + version: 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@vitejs/plugin-react': specifier: ^4.2.1 - version: 4.3.1(vite@5.4.0(@types/node@22.4.1)(terser@5.31.6)) + version: 4.3.1(vite@5.4.8(@types/node@22.4.1)(terser@5.31.6)) globals: specifier: ^15.9.0 version: 15.9.0 @@ -282,7 +343,7 @@ importers: version: link:../pglite '@eslint-react/eslint-plugin': specifier: ^1.9.0 - version: 1.10.1(eslint@8.57.0)(typescript@5.5.4) + version: 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@testing-library/dom': specifier: ^10.4.0 version: 10.4.0 @@ -291,13 +352,13 @@ importers: version: 8.1.0(@vue/compiler-sfc@3.4.37)(vue@3.4.37(typescript@5.5.4)) '@vitejs/plugin-vue': specifier: ^5.1.2 - version: 5.1.2(vite@5.4.0(@types/node@22.4.1)(terser@5.31.6))(vue@3.4.37(typescript@5.5.4)) + version: 5.1.2(vite@5.4.8(@types/node@22.4.1)(terser@5.31.6))(vue@3.4.37(typescript@5.5.4)) '@vue/composition-api': specifier: 1.7.2 version: 1.7.2(vue@3.4.37(typescript@5.5.4)) eslint-plugin-vue: specifier: ^9.27.0 - version: 9.27.0(eslint@8.57.0) + version: 9.27.0(eslint@9.11.1) jsdom: specifier: ^24.1.1 version: 24.1.1 @@ -1035,6 +1096,14 @@ packages: '@eslint-react/var@1.14.2': resolution: {integrity: sha512-OOxwTPcWoNJbpaWnULpq+QJzsdZveU/QCHZ6Lb1oNIdVPBc6nCKz3PH97hqYFpk3q+gnnNx2q6qhNIAfeu/8Ug==} + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.6.0': + resolution: {integrity: sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1047,6 +1116,18 @@ packages: resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/js@9.11.1': + resolution: {integrity: sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.0': + resolution: {integrity: sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -1060,6 +1141,10 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} + engines: {node: '>=18.18'} + '@inquirer/confirm@3.1.22': resolution: {integrity: sha512-gsAKIOWBm2Q87CDfs9fEo7wJT3fwWIJfnDGMn9Qy74gBnNFOACDNfhUzovubbJjWnKLGBln7/NcSmZwj5DuEXg==} engines: {node: '>=18'} @@ -1080,6 +1165,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -1390,9 +1479,15 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/linkify-it@5.0.0': resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} @@ -1455,6 +1550,17 @@ packages: typescript: optional: true + '@typescript-eslint/eslint-plugin@8.8.0': + resolution: {integrity: sha512-wORFWjU30B2WJ/aXBfOm1LX9v9nyt9D3jsSOxC3cCaTQGCW5k4jNpmjFv3U7p/7s4yvdjHzwtv2Sd2dOyhjS0A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/parser@7.18.0': resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1465,6 +1571,16 @@ packages: typescript: optional: true + '@typescript-eslint/parser@8.8.0': + resolution: {integrity: sha512-uEFUsgR+tl8GmzmLjRqz+VrDv4eoaMqMXW7ruXfgThaAShO9JTciKpEsB+TvnfFfbg5IpujgMXVV36gOJRLtZg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/scope-manager@7.18.0': resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1477,6 +1593,10 @@ packages: resolution: {integrity: sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.8.0': + resolution: {integrity: sha512-EL8eaGC6gx3jDd8GwEFEV091210U97J0jeEHrAYvIYosmEGet4wJ+g0SYmLu+oRiAwbSA5AVrt6DxLHfdd+bUg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/type-utils@7.18.0': resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1505,6 +1625,15 @@ packages: typescript: optional: true + '@typescript-eslint/type-utils@8.8.0': + resolution: {integrity: sha512-IKwJSS7bCqyCeG4NVGxnOP6lLT9Okc3Zj8hLO96bpMkJab+10HIfJbMouLrlpyOr3yrQ1cA413YPFiGd1mW9/Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/types@7.18.0': resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1517,6 +1646,10 @@ packages: resolution: {integrity: sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.8.0': + resolution: {integrity: sha512-QJwc50hRCgBd/k12sTykOJbESe1RrzmX6COk8Y525C9l7oweZ+1lw9JiU56im7Amm8swlz00DRIlxMYLizr2Vw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@7.18.0': resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1544,6 +1677,15 @@ packages: typescript: optional: true + '@typescript-eslint/typescript-estree@8.8.0': + resolution: {integrity: sha512-ZaMJwc/0ckLz5DaAZ+pNLmHv8AMVGtfWxZe/x2JVEkD5LnmhWiQMMcYT7IY7gkdJuzJ9P14fRy28lUrlDSWYdw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/utils@7.18.0': resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1562,6 +1704,12 @@ packages: peerDependencies: eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/utils@8.8.0': + resolution: {integrity: sha512-QE2MgfOTem00qrlPgyByaCHay9yb1+9BjnMFnSFkUKQfu7adBXDTnCAivURnuPPAG/qiB+kzKkZKmKfaMT0zVg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + '@typescript-eslint/visitor-keys@7.18.0': resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} engines: {node: ^18.18.0 || >=20.0.0} @@ -1574,6 +1722,10 @@ packages: resolution: {integrity: sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.8.0': + resolution: {integrity: sha512-8mq51Lx6Hpmd7HnA2fcHQo3YgfX1qbccxQOgZcb4tvasu//zXRaA1j5ZRFeCw/VRAdFi4mRM9DnZw0Nu0Q2d1g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@uiw/codemirror-extensions-basic-setup@4.23.0': resolution: {integrity: sha512-+k5nkRpUWGaHr1JWT8jcKsVewlXw5qBgSopm9LW8fZ6KnSNZBycz8kHxh0+WSvckmXEESGptkIsb7dlkmJT/hQ==} peerDependencies: @@ -2033,6 +2185,7 @@ packages: bun@1.1.24: resolution: {integrity: sha512-vZt5zNVaoNTSlNprdVdQVZInBcGC2QSik6o9ZsMzuYiiUEAEqpRwwMXAYDUN85mt2FNnsGvmk/8xVlUXS7IzEw==} + cpu: [arm64, x64] os: [darwin, linux, win32] hasBin: true @@ -2099,6 +2252,10 @@ packages: chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -2468,6 +2625,12 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + eslint-plugin-react-hooks@5.1.0-rc-fb9a90fa48-20240614: + resolution: {integrity: sha512-xsiRwaDNF5wWNC4ZHLut+x/YcAxksUd9Rizt7LaEn3bV8VyYRpXnRJQlLOfYaVy9esk4DFP4zPPnoNVjq5Gc0w==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + eslint-plugin-react-naming-convention@1.10.1: resolution: {integrity: sha512-3Utp/5rIrnQJCe47P9lqB9ktwprk2qedTj4ArPNdy8StgNEbzXwAQdS0Fxkf1mKZu2w2RR/rCdyW+57mzZa4/w==} engines: {bun: '>=1.0.15', node: '>=18.18.0'} @@ -2533,6 +2696,10 @@ packages: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.1.0: + resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2546,6 +2713,16 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true + eslint@9.11.1: + resolution: {integrity: sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + espree@10.1.0: resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2629,6 +2806,10 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} @@ -2651,6 +2832,10 @@ packages: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} @@ -3265,6 +3450,10 @@ packages: minisearch@7.1.0: resolution: {integrity: sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==} + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -3275,6 +3464,11 @@ packages: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} @@ -3537,6 +3731,9 @@ packages: picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -3604,6 +3801,10 @@ packages: resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} engines: {node: ^10 || ^12 || >=14} + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + engines: {node: ^10 || ^12 || >=14} + postgres-array@2.0.0: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} @@ -3773,6 +3974,10 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + rollup@4.20.0: resolution: {integrity: sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -3900,6 +4105,10 @@ packages: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -4032,6 +4241,10 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} @@ -4148,6 +4361,11 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tsx@4.19.1: + resolution: {integrity: sha512-0flMz1lh74BR4wOvBjuh9olbnwqCPc35OOlfyzHba0Dc+QNUeWX/Gq2YTbnwcWPO3BMd8fkzRVrHcsR+a7z7rA==} + engines: {node: '>=18.0.0'} + hasBin: true + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -4171,6 +4389,15 @@ packages: resolution: {integrity: sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==} engines: {node: '>=16'} + typescript-eslint@8.8.0: + resolution: {integrity: sha512-BjIT/VwJ8+0rVO01ZQ2ZVnjE1svFBiRczcpr1t1Yxt7sT25VSbPfrJtDsQ8uQTy2pilX5nI9gwxhUyLULNentw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + typescript@5.4.2: resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} engines: {node: '>=14.17'} @@ -4283,6 +4510,37 @@ packages: terser: optional: true + vite@5.4.8: + resolution: {integrity: sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vitepress@1.3.2: resolution: {integrity: sha512-6gvecsCuR6b1Cid4w19KQiQ02qkpgzFRqiG0v1ZBekGkrZCzsxdDD5y4WH82HRXAOhU4iZIpzA1CsWqs719rqA==} hasBin: true @@ -4519,6 +4777,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -5269,15 +5531,20 @@ snapshots: eslint: 8.57.0 eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.4.0(eslint@9.11.1)': + dependencies: + eslint: 9.11.1 + eslint-visitor-keys: 3.4.3 + '@eslint-community/regexpp@4.11.0': {} - '@eslint-react/ast@1.10.1(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/ast@1.10.1(eslint@9.11.1)(typescript@5.5.4)': dependencies: '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.1.0 '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) birecord: 0.1.1 string-ts: 2.2.0 ts-pattern: 5.3.1 @@ -5286,13 +5553,13 @@ snapshots: - supports-color - typescript - '@eslint-react/ast@1.14.2(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/ast@1.14.2(eslint@9.11.1)(typescript@5.5.4)': dependencies: '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.7.0 '@typescript-eslint/typescript-estree': 8.7.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) birecord: 0.1.1 string-ts: 2.2.0 ts-pattern: 5.3.1 @@ -5301,18 +5568,18 @@ snapshots: - supports-color - typescript - '@eslint-react/core@1.10.1(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/core@1.10.1(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-react/ast': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/type-utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) short-unique-id: 5.2.0 ts-pattern: 5.3.1 transitivePeerDependencies: @@ -5320,18 +5587,18 @@ snapshots: - supports-color - typescript - '@eslint-react/core@1.14.2(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/core@1.14.2(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-react/ast': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 - '@typescript-eslint/type-utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) birecord: 0.1.1 short-unique-id: 5.2.0 ts-pattern: 5.3.1 @@ -5340,91 +5607,91 @@ snapshots: - supports-color - typescript - '@eslint-react/eslint-plugin@1.10.1(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/eslint-plugin@1.10.1(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-react/shared': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/shared': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/type-utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 - eslint-plugin-react-debug: 1.10.1(eslint@8.57.0)(typescript@5.5.4) - eslint-plugin-react-dom: 1.10.1(eslint@8.57.0)(typescript@5.5.4) - eslint-plugin-react-hooks-extra: 1.10.1(eslint@8.57.0)(typescript@5.5.4) - eslint-plugin-react-naming-convention: 1.10.1(eslint@8.57.0)(typescript@5.5.4) - eslint-plugin-react-x: 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 + eslint-plugin-react-debug: 1.10.1(eslint@9.11.1)(typescript@5.5.4) + eslint-plugin-react-dom: 1.10.1(eslint@9.11.1)(typescript@5.5.4) + eslint-plugin-react-hooks-extra: 1.10.1(eslint@9.11.1)(typescript@5.5.4) + eslint-plugin-react-naming-convention: 1.10.1(eslint@9.11.1)(typescript@5.5.4) + eslint-plugin-react-x: 1.10.1(eslint@9.11.1)(typescript@5.5.4) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@eslint-react/eslint-plugin@1.14.2(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/eslint-plugin@1.14.2(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-react/shared': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/shared': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 - '@typescript-eslint/type-utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 - eslint-plugin-react-debug: 1.14.2(eslint@8.57.0)(typescript@5.5.4) - eslint-plugin-react-dom: 1.14.2(eslint@8.57.0)(typescript@5.5.4) - eslint-plugin-react-hooks-extra: 1.14.2(eslint@8.57.0)(typescript@5.5.4) - eslint-plugin-react-naming-convention: 1.14.2(eslint@8.57.0)(typescript@5.5.4) - eslint-plugin-react-web-api: 1.14.2(eslint@8.57.0)(typescript@5.5.4) - eslint-plugin-react-x: 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 + eslint-plugin-react-debug: 1.14.2(eslint@9.11.1)(typescript@5.5.4) + eslint-plugin-react-dom: 1.14.2(eslint@9.11.1)(typescript@5.5.4) + eslint-plugin-react-hooks-extra: 1.14.2(eslint@9.11.1)(typescript@5.5.4) + eslint-plugin-react-naming-convention: 1.14.2(eslint@9.11.1)(typescript@5.5.4) + eslint-plugin-react-web-api: 1.14.2(eslint@9.11.1)(typescript@5.5.4) + eslint-plugin-react-x: 1.14.2(eslint@9.11.1)(typescript@5.5.4) optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@eslint-react/jsx@1.10.1(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/jsx@1.10.1(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-react/ast': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.1.0 '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) ts-pattern: 5.3.1 transitivePeerDependencies: - eslint - supports-color - typescript - '@eslint-react/jsx@1.14.2(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/jsx@1.14.2(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-react/ast': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) ts-pattern: 5.3.1 transitivePeerDependencies: - eslint - supports-color - typescript - '@eslint-react/shared@1.10.1(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/shared@1.10.1(eslint@9.11.1)(typescript@5.5.4)': dependencies: '@eslint-react/tools': 1.10.1 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) picomatch: 4.0.2 transitivePeerDependencies: - eslint - supports-color - typescript - '@eslint-react/shared@1.14.2(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/shared@1.14.2(eslint@9.11.1)(typescript@5.5.4)': dependencies: '@eslint-react/tools': 1.14.2 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) picomatch: 4.0.2 transitivePeerDependencies: - eslint @@ -5435,54 +5702,64 @@ snapshots: '@eslint-react/tools@1.14.2': {} - '@eslint-react/types@1.10.1(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/types@1.10.1(eslint@9.11.1)(typescript@5.5.4)': dependencies: '@eslint-react/tools': 1.10.1 '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) transitivePeerDependencies: - eslint - supports-color - typescript - '@eslint-react/types@1.14.2(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/types@1.14.2(eslint@9.11.1)(typescript@5.5.4)': dependencies: '@eslint-react/tools': 1.14.2 '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) transitivePeerDependencies: - eslint - supports-color - typescript - '@eslint-react/var@1.10.1(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/var@1.10.1(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-react/ast': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.1.0 '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) ts-pattern: 5.3.1 transitivePeerDependencies: - eslint - supports-color - typescript - '@eslint-react/var@1.14.2(eslint@8.57.0)(typescript@5.5.4)': + '@eslint-react/var@1.14.2(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-react/ast': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) ts-pattern: 5.3.1 transitivePeerDependencies: - eslint - supports-color - typescript + '@eslint/config-array@0.18.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.6 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.6.0': {} + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 @@ -5513,6 +5790,14 @@ snapshots: '@eslint/js@8.57.0': {} + '@eslint/js@9.11.1': {} + + '@eslint/object-schema@2.1.4': {} + + '@eslint/plugin-kit@0.2.0': + dependencies: + levn: 0.4.1 + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -5525,6 +5810,8 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} + '@humanwhocodes/retry@0.3.0': {} + '@inquirer/confirm@3.1.22': dependencies: '@inquirer/core': 9.0.10 @@ -5565,6 +5852,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -5954,10 +6245,14 @@ snapshots: '@types/estree@1.0.5': {} + '@types/estree@1.0.6': {} + '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.2 + '@types/json-schema@7.0.15': {} + '@types/linkify-it@5.0.0': {} '@types/markdown-it@14.1.2': @@ -6032,6 +6327,24 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/eslint-plugin@8.8.0(@typescript-eslint/parser@8.8.0(eslint@9.11.1)(typescript@5.5.4))(eslint@9.11.1)(typescript@5.5.4)': + dependencies: + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 8.8.0(eslint@9.11.1)(typescript@5.5.4) + '@typescript-eslint/scope-manager': 8.8.0 + '@typescript-eslint/type-utils': 8.8.0(eslint@9.11.1)(typescript@5.5.4) + '@typescript-eslint/utils': 8.8.0(eslint@9.11.1)(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 8.8.0 + eslint: 9.11.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 @@ -6045,6 +6358,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@8.8.0(eslint@9.11.1)(typescript@5.5.4)': + dependencies: + '@typescript-eslint/scope-manager': 8.8.0 + '@typescript-eslint/types': 8.8.0 + '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 8.8.0 + debug: 4.3.6 + eslint: 9.11.1 + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@7.18.0': dependencies: '@typescript-eslint/types': 7.18.0 @@ -6060,6 +6386,11 @@ snapshots: '@typescript-eslint/types': 8.7.0 '@typescript-eslint/visitor-keys': 8.7.0 + '@typescript-eslint/scope-manager@8.8.0': + dependencies: + '@typescript-eslint/types': 8.8.0 + '@typescript-eslint/visitor-keys': 8.8.0 + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) @@ -6072,10 +6403,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.1.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/type-utils@8.1.0(eslint@9.11.1)(typescript@5.5.4)': dependencies: '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) debug: 4.3.6 ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: @@ -6084,10 +6415,22 @@ snapshots: - eslint - supports-color - '@typescript-eslint/type-utils@8.7.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/type-utils@8.7.0(eslint@9.11.1)(typescript@5.5.4)': dependencies: '@typescript-eslint/typescript-estree': 8.7.0(typescript@5.5.4) - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) + debug: 4.3.6 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - eslint + - supports-color + + '@typescript-eslint/type-utils@8.8.0(eslint@9.11.1)(typescript@5.5.4)': + dependencies: + '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.5.4) + '@typescript-eslint/utils': 8.8.0(eslint@9.11.1)(typescript@5.5.4) debug: 4.3.6 ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: @@ -6102,6 +6445,8 @@ snapshots: '@typescript-eslint/types@8.7.0': {} + '@typescript-eslint/types@8.8.0': {} + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)': dependencies: '@typescript-eslint/types': 7.18.0 @@ -6147,6 +6492,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@8.8.0(typescript@5.5.4)': + dependencies: + '@typescript-eslint/types': 8.8.0 + '@typescript-eslint/visitor-keys': 8.8.0 + debug: 4.3.6 + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) @@ -6158,24 +6518,35 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@8.1.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/utils@8.1.0(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.11.1) '@typescript-eslint/scope-manager': 8.1.0 '@typescript-eslint/types': 8.1.0 '@typescript-eslint/typescript-estree': 8.1.0(typescript@5.5.4) - eslint: 8.57.0 + eslint: 9.11.1 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.7.0(eslint@8.57.0)(typescript@5.5.4)': + '@typescript-eslint/utils@8.7.0(eslint@9.11.1)(typescript@5.5.4)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.11.1) '@typescript-eslint/scope-manager': 8.7.0 '@typescript-eslint/types': 8.7.0 '@typescript-eslint/typescript-estree': 8.7.0(typescript@5.5.4) - eslint: 8.57.0 + eslint: 9.11.1 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@8.8.0(eslint@9.11.1)(typescript@5.5.4)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.11.1) + '@typescript-eslint/scope-manager': 8.8.0 + '@typescript-eslint/types': 8.8.0 + '@typescript-eslint/typescript-estree': 8.8.0(typescript@5.5.4) + eslint: 9.11.1 transitivePeerDependencies: - supports-color - typescript @@ -6195,6 +6566,11 @@ snapshots: '@typescript-eslint/types': 8.7.0 eslint-visitor-keys: 3.4.3 + '@typescript-eslint/visitor-keys@8.8.0': + dependencies: + '@typescript-eslint/types': 8.8.0 + eslint-visitor-keys: 3.4.3 + '@uiw/codemirror-extensions-basic-setup@4.23.0(@codemirror/autocomplete@6.18.0(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.32.0)(@lezer/common@1.2.1))(@codemirror/commands@6.6.0)(@codemirror/language@6.10.2)(@codemirror/lint@6.8.1)(@codemirror/search@6.5.6)(@codemirror/state@6.4.1)(@codemirror/view@6.32.0)': dependencies: '@codemirror/autocomplete': 6.18.0(@codemirror/language@6.10.2)(@codemirror/state@6.4.1)(@codemirror/view@6.32.0)(@lezer/common@1.2.1) @@ -6257,20 +6633,31 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.3.1(vite@5.4.0(@types/node@22.4.1)(terser@5.31.6))': + '@vitejs/plugin-react@4.3.1(vite@5.4.8(@types/node@20.14.15)(terser@5.31.6))': dependencies: '@babel/core': 7.25.2 '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.4.0(@types/node@22.4.1)(terser@5.31.6) + vite: 5.4.8(@types/node@20.14.15)(terser@5.31.6) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.1.2(vite@5.4.0(@types/node@22.4.1)(terser@5.31.6))(vue@3.4.37(typescript@5.5.4))': + '@vitejs/plugin-react@4.3.1(vite@5.4.8(@types/node@22.4.1)(terser@5.31.6))': dependencies: - vite: 5.4.0(@types/node@22.4.1)(terser@5.31.6) + '@babel/core': 7.25.2 + '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 5.4.8(@types/node@22.4.1)(terser@5.31.6) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@5.1.2(vite@5.4.8(@types/node@22.4.1)(terser@5.31.6))(vue@3.4.37(typescript@5.5.4))': + dependencies: + vite: 5.4.8(@types/node@22.4.1)(terser@5.31.6) vue: 3.4.37(typescript@5.5.4) '@vitest/browser@2.0.5(playwright@1.46.0)(typescript@5.5.4)(vitest@2.0.5)': @@ -6281,7 +6668,7 @@ snapshots: magic-string: 0.30.11 msw: 2.3.5(typescript@5.5.4) sirv: 2.0.4 - vitest: 2.0.5(@types/node@20.14.15)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(jsdom@24.1.1)(terser@5.31.6) + vitest: 2.0.5(@types/node@22.4.1)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(jsdom@24.1.1)(terser@5.31.6) ws: 8.18.0 optionalDependencies: playwright: 1.46.0 @@ -6305,14 +6692,14 @@ snapshots: chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(msw@2.3.5(typescript@5.5.4))(vite@5.4.0(@types/node@22.4.1)(terser@5.31.6))': + '@vitest/mocker@2.1.1(@vitest/spy@2.1.1)(msw@2.3.5(typescript@5.5.4))(vite@5.4.8(@types/node@22.4.1)(terser@5.31.6))': dependencies: '@vitest/spy': 2.1.1 estree-walker: 3.0.3 magic-string: 0.30.11 optionalDependencies: msw: 2.3.5(typescript@5.5.4) - vite: 5.4.0(@types/node@22.4.1)(terser@5.31.6) + vite: 5.4.8(@types/node@22.4.1)(terser@5.31.6) '@vitest/pretty-format@2.0.5': dependencies: @@ -6361,7 +6748,7 @@ snapshots: pathe: 1.1.2 sirv: 2.0.4 tinyrainbow: 1.2.0 - vitest: 2.0.5(@types/node@20.14.15)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(jsdom@24.1.1)(terser@5.31.6) + vitest: 2.0.5(@types/node@22.4.1)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(jsdom@24.1.1)(terser@5.31.6) optional: true '@vitest/utils@2.0.5': @@ -6842,6 +7229,8 @@ snapshots: chownr@1.1.4: {} + chownr@3.0.0: {} + ci-info@3.9.0: {} cli-boxes@3.0.0: {} @@ -7185,32 +7574,32 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-plugin-react-compiler@0.0.0-experimental-9ed098e-20240725(eslint@8.57.0): + eslint-plugin-react-compiler@0.0.0-experimental-9ed098e-20240725(eslint@9.11.1): dependencies: '@babel/core': 7.25.2 '@babel/parser': 7.25.3 '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.25.2) - eslint: 8.57.0 + eslint: 9.11.1 hermes-parser: 0.20.1 zod: 3.23.8 zod-validation-error: 3.3.1(zod@3.23.8) transitivePeerDependencies: - supports-color - eslint-plugin-react-debug@1.10.1(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-debug@1.10.1(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/type-utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 string-ts: 2.2.0 ts-pattern: 5.3.1 optionalDependencies: @@ -7218,20 +7607,20 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-react-debug@1.14.2(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-debug@1.14.2(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 - '@typescript-eslint/type-utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 string-ts: 2.2.0 ts-pattern: 5.3.1 optionalDependencies: @@ -7239,202 +7628,206 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-react-dom@1.10.1(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-dom@1.10.1(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.1.0 '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 ts-pattern: 5.3.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - eslint-plugin-react-dom@1.14.2(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-dom@1.14.2(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 ts-pattern: 5.3.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - eslint-plugin-react-hooks-extra@1.10.1(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-hooks-extra@1.10.1(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/type-utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 ts-pattern: 5.3.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - eslint-plugin-react-hooks-extra@1.14.2(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-hooks-extra@1.14.2(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 - '@typescript-eslint/type-utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 ts-pattern: 5.3.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - eslint-plugin-react-hooks@4.6.2(eslint@8.57.0): + eslint-plugin-react-hooks@4.6.2(eslint@9.11.1): dependencies: - eslint: 8.57.0 + eslint: 9.11.1 - eslint-plugin-react-naming-convention@1.10.1(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-hooks@5.1.0-rc-fb9a90fa48-20240614(eslint@9.11.1): dependencies: - '@eslint-react/ast': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + eslint: 9.11.1 + + eslint-plugin-react-naming-convention@1.10.1(eslint@9.11.1)(typescript@5.5.4): + dependencies: + '@eslint-react/ast': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/type-utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 ts-pattern: 5.3.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - eslint-plugin-react-naming-convention@1.14.2(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-naming-convention@1.14.2(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 - '@typescript-eslint/type-utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 ts-pattern: 5.3.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - eslint-plugin-react-refresh@0.4.9(eslint@8.57.0): + eslint-plugin-react-refresh@0.4.9(eslint@9.11.1): dependencies: - eslint: 8.57.0 + eslint: 9.11.1 - eslint-plugin-react-web-api@1.14.2(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-web-api@1.14.2(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) birecord: 0.1.1 - eslint: 8.57.0 + eslint: 9.11.1 ts-pattern: 5.3.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - eslint-plugin-react-x@1.10.1(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-x@1.10.1(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.10.1 - '@eslint-react/types': 1.10.1(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.10.1(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.10.1(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.10.1(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.1.0 - '@typescript-eslint/type-utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.1.0 - '@typescript-eslint/utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 - is-immutable-type: 5.0.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 + is-immutable-type: 5.0.0(eslint@9.11.1)(typescript@5.5.4) ts-pattern: 5.3.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - eslint-plugin-react-x@1.14.2(eslint@8.57.0)(typescript@5.5.4): + eslint-plugin-react-x@1.14.2(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@eslint-react/ast': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/core': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/jsx': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/shared': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/ast': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/core': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/jsx': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/shared': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@eslint-react/tools': 1.14.2 - '@eslint-react/types': 1.14.2(eslint@8.57.0)(typescript@5.5.4) - '@eslint-react/var': 1.14.2(eslint@8.57.0)(typescript@5.5.4) + '@eslint-react/types': 1.14.2(eslint@9.11.1)(typescript@5.5.4) + '@eslint-react/var': 1.14.2(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/scope-manager': 8.7.0 - '@typescript-eslint/type-utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/type-utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) '@typescript-eslint/types': 8.7.0 - '@typescript-eslint/utils': 8.7.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 - is-immutable-type: 5.0.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.7.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 + is-immutable-type: 5.0.0(eslint@9.11.1)(typescript@5.5.4) ts-pattern: 5.3.1 optionalDependencies: typescript: 5.5.4 transitivePeerDependencies: - supports-color - eslint-plugin-vue@9.27.0(eslint@8.57.0): + eslint-plugin-vue@9.27.0(eslint@9.11.1): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - eslint: 8.57.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.11.1) + eslint: 9.11.1 globals: 13.24.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 semver: 7.6.3 - vue-eslint-parser: 9.4.3(eslint@8.57.0) + vue-eslint-parser: 9.4.3(eslint@9.11.1) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color @@ -7444,6 +7837,11 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-scope@8.1.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-visitor-keys@3.4.3: {} eslint-visitor-keys@4.0.0: {} @@ -7491,6 +7889,48 @@ snapshots: transitivePeerDependencies: - supports-color + eslint@9.11.1: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.11.1) + '@eslint-community/regexpp': 4.11.0 + '@eslint/config-array': 0.18.0 + '@eslint/core': 0.6.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.11.1 + '@eslint/plugin-kit': 0.2.0 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.0 + '@nodelib/fs.walk': 1.2.8 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.6 + escape-string-regexp: 4.0.0 + eslint-scope: 8.1.0 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + espree@10.1.0: dependencies: acorn: 8.12.1 @@ -7588,6 +8028,10 @@ snapshots: dependencies: flat-cache: 3.2.0 + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + file-uri-to-path@1.0.0: {} fill-range@7.1.1: @@ -7615,6 +8059,11 @@ snapshots: keyv: 4.5.4 rimraf: 3.0.2 + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + flatted@3.3.1: {} focus-trap@7.5.4: @@ -7913,10 +8362,10 @@ snapshots: dependencies: is-extglob: 2.1.1 - is-immutable-type@5.0.0(eslint@8.57.0)(typescript@5.5.4): + is-immutable-type@5.0.0(eslint@9.11.1)(typescript@5.5.4): dependencies: - '@typescript-eslint/type-utils': 8.1.0(eslint@8.57.0)(typescript@5.5.4) - eslint: 8.57.0 + '@typescript-eslint/type-utils': 8.1.0(eslint@9.11.1)(typescript@5.5.4) + eslint: 9.11.1 ts-api-utils: 1.3.0(typescript@5.5.4) ts-declaration-location: 1.0.4(typescript@5.5.4) typescript: 5.5.4 @@ -8194,6 +8643,11 @@ snapshots: minisearch@7.1.0: {} + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + mitt@3.0.1: {} mkdirp-classic@0.5.3: {} @@ -8202,6 +8656,8 @@ snapshots: dependencies: minimist: 1.2.8 + mkdirp@3.0.1: {} + mlly@1.7.1: dependencies: acorn: 8.12.1 @@ -8441,6 +8897,8 @@ snapshots: picocolors@1.0.1: {} + picocolors@1.1.0: {} + picomatch@2.3.1: {} picomatch@4.0.2: {} @@ -8477,11 +8935,11 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-load-config@6.0.1(postcss@8.4.41)(tsx@4.17.0): + postcss-load-config@6.0.1(postcss@8.4.47)(tsx@4.17.0): dependencies: lilconfig: 3.1.2 optionalDependencies: - postcss: 8.4.41 + postcss: 8.4.47 tsx: 4.17.0 postcss-selector-parser@6.1.2: @@ -8495,6 +8953,12 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 + postcss@8.4.47: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.0 + source-map-js: 1.2.1 + postgres-array@2.0.0: {} postgres-bytea@1.0.0: {} @@ -8652,6 +9116,10 @@ snapshots: dependencies: glob: 7.2.3 + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + rollup@4.20.0: dependencies: '@types/estree': 1.0.5 @@ -8808,6 +9276,8 @@ snapshots: source-map-js@1.2.0: {} + source-map-js@1.2.1: {} + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -8933,6 +9403,15 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + term-size@2.2.1: {} terser@5.31.6: @@ -9009,7 +9488,7 @@ snapshots: tslib@2.6.3: {} - tsup@8.2.4(@microsoft/api-extractor@7.47.4(@types/node@22.4.1))(postcss@8.4.41)(tsx@4.17.0)(typescript@5.5.4): + tsup@8.2.4(@microsoft/api-extractor@7.47.4(@types/node@22.4.1))(postcss@8.4.47)(tsx@4.17.0)(typescript@5.5.4): dependencies: bundle-require: 5.0.0(esbuild@0.23.0) cac: 6.7.14 @@ -9021,7 +9500,7 @@ snapshots: globby: 11.1.0 joycon: 3.1.1 picocolors: 1.0.1 - postcss-load-config: 6.0.1(postcss@8.4.41)(tsx@4.17.0) + postcss-load-config: 6.0.1(postcss@8.4.47)(tsx@4.17.0) resolve-from: 5.0.0 rollup: 4.20.0 source-map: 0.8.0-beta.0 @@ -9029,7 +9508,7 @@ snapshots: tree-kill: 1.2.2 optionalDependencies: '@microsoft/api-extractor': 7.47.4(@types/node@22.4.1) - postcss: 8.4.41 + postcss: 8.4.47 typescript: 5.5.4 transitivePeerDependencies: - jiti @@ -9044,6 +9523,13 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tsx@4.19.1: + dependencies: + esbuild: 0.23.0 + get-tsconfig: 4.7.6 + optionalDependencies: + fsevents: 2.3.3 + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -9062,6 +9548,17 @@ snapshots: type-fest@4.25.0: optional: true + typescript-eslint@8.8.0(eslint@9.11.1)(typescript@5.5.4): + dependencies: + '@typescript-eslint/eslint-plugin': 8.8.0(@typescript-eslint/parser@8.8.0(eslint@9.11.1)(typescript@5.5.4))(eslint@9.11.1)(typescript@5.5.4) + '@typescript-eslint/parser': 8.8.0(eslint@9.11.1)(typescript@5.5.4) + '@typescript-eslint/utils': 8.8.0(eslint@9.11.1)(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - eslint + - supports-color + typescript@5.4.2: {} typescript@5.5.4: {} @@ -9113,7 +9610,7 @@ snapshots: debug: 4.3.6 pathe: 1.1.2 tinyrainbow: 1.2.0 - vite: 5.4.0(@types/node@20.14.15)(terser@5.31.6) + vite: 5.4.8(@types/node@20.14.15)(terser@5.31.6) transitivePeerDependencies: - '@types/node' - less @@ -9131,7 +9628,7 @@ snapshots: debug: 4.3.6 pathe: 1.1.2 tinyrainbow: 1.2.0 - vite: 5.4.0(@types/node@22.4.1)(terser@5.31.6) + vite: 5.4.8(@types/node@22.4.1)(terser@5.31.6) transitivePeerDependencies: - '@types/node' - less @@ -9148,7 +9645,7 @@ snapshots: cac: 6.7.14 debug: 4.3.6 pathe: 1.1.2 - vite: 5.4.0(@types/node@22.4.1)(terser@5.31.6) + vite: 5.4.8(@types/node@22.4.1)(terser@5.31.6) transitivePeerDependencies: - '@types/node' - less @@ -9195,24 +9692,34 @@ snapshots: fsevents: 2.3.3 terser: 5.31.6 - vite@5.4.0(@types/node@22.4.1)(terser@5.31.6): + vite@5.4.8(@types/node@20.14.15)(terser@5.31.6): dependencies: esbuild: 0.21.5 - postcss: 8.4.41 + postcss: 8.4.47 + rollup: 4.20.0 + optionalDependencies: + '@types/node': 20.14.15 + fsevents: 2.3.3 + terser: 5.31.6 + + vite@5.4.8(@types/node@22.4.1)(terser@5.31.6): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.47 rollup: 4.20.0 optionalDependencies: '@types/node': 22.4.1 fsevents: 2.3.3 terser: 5.31.6 - vitepress@1.3.2(@algolia/client-search@4.24.0)(@types/node@22.4.1)(@types/react@18.3.3)(@vue/composition-api@1.7.2(vue@3.4.37(typescript@5.5.4)))(postcss@8.4.41)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.16.3)(terser@5.31.6)(typescript@5.5.4): + vitepress@1.3.2(@algolia/client-search@4.24.0)(@types/node@22.4.1)(@types/react@18.3.3)(@vue/composition-api@1.7.2(vue@3.4.37(typescript@5.5.4)))(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.16.3)(terser@5.31.6)(typescript@5.5.4): dependencies: '@docsearch/css': 3.6.1 '@docsearch/js': 3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.16.3) '@shikijs/core': 1.12.1 '@shikijs/transformers': 1.12.1 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.1.2(vite@5.4.0(@types/node@22.4.1)(terser@5.31.6))(vue@3.4.37(typescript@5.5.4)) + '@vitejs/plugin-vue': 5.1.2(vite@5.4.8(@types/node@22.4.1)(terser@5.31.6))(vue@3.4.37(typescript@5.5.4)) '@vue/devtools-api': 7.3.8 '@vue/shared': 3.4.37 '@vueuse/core': 10.11.1(@vue/composition-api@1.7.2(vue@3.4.37(typescript@5.5.4)))(vue@3.4.37(typescript@5.5.4)) @@ -9221,10 +9728,10 @@ snapshots: mark.js: 8.11.1 minisearch: 7.1.0 shiki: 1.12.1 - vite: 5.4.0(@types/node@22.4.1)(terser@5.31.6) + vite: 5.4.8(@types/node@22.4.1)(terser@5.31.6) vue: 3.4.37(typescript@5.5.4) optionalDependencies: - postcss: 8.4.41 + postcss: 8.4.47 transitivePeerDependencies: - '@algolia/client-search' - '@types/node' @@ -9271,7 +9778,7 @@ snapshots: tinybench: 2.9.0 tinypool: 1.0.0 tinyrainbow: 1.2.0 - vite: 5.4.0(@types/node@20.14.15)(terser@5.31.6) + vite: 5.4.8(@types/node@20.14.15)(terser@5.31.6) vite-node: 2.0.5(@types/node@20.14.15)(terser@5.31.6) why-is-node-running: 2.3.0 optionalDependencies: @@ -9307,7 +9814,7 @@ snapshots: tinybench: 2.9.0 tinypool: 1.0.0 tinyrainbow: 1.2.0 - vite: 5.4.0(@types/node@22.4.1)(terser@5.31.6) + vite: 5.4.8(@types/node@22.4.1)(terser@5.31.6) vite-node: 2.0.5(@types/node@22.4.1)(terser@5.31.6) why-is-node-running: 2.3.0 optionalDependencies: @@ -9328,7 +9835,7 @@ snapshots: vitest@2.1.1(@types/node@22.4.1)(jsdom@24.1.1)(msw@2.3.5(typescript@5.5.4))(terser@5.31.6): dependencies: '@vitest/expect': 2.1.1 - '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(msw@2.3.5(typescript@5.5.4))(vite@5.4.0(@types/node@22.4.1)(terser@5.31.6)) + '@vitest/mocker': 2.1.1(@vitest/spy@2.1.1)(msw@2.3.5(typescript@5.5.4))(vite@5.4.8(@types/node@22.4.1)(terser@5.31.6)) '@vitest/pretty-format': 2.1.1 '@vitest/runner': 2.1.1 '@vitest/snapshot': 2.1.1 @@ -9343,7 +9850,7 @@ snapshots: tinyexec: 0.3.0 tinypool: 1.0.0 tinyrainbow: 1.2.0 - vite: 5.4.0(@types/node@22.4.1)(terser@5.31.6) + vite: 5.4.8(@types/node@22.4.1)(terser@5.31.6) vite-node: 2.1.1(@types/node@22.4.1)(terser@5.31.6) why-is-node-running: 2.3.0 optionalDependencies: @@ -9370,10 +9877,10 @@ snapshots: optionalDependencies: '@vue/composition-api': 1.7.2(vue@3.4.37(typescript@5.5.4)) - vue-eslint-parser@9.4.3(eslint@8.57.0): + vue-eslint-parser@9.4.3(eslint@9.11.1): dependencies: debug: 4.3.6 - eslint: 8.57.0 + eslint: 9.11.1 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 @@ -9526,6 +10033,8 @@ snapshots: yallist@4.0.0: {} + yallist@5.0.0: {} + yargs-parser@21.1.1: {} yargs@17.7.2: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 59a60bdc2..74faed713 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,4 @@ packages: - 'packages/*' + - 'demos/*' - 'docs' From b1c48277b6b1547045934f5797e18aef5aa64673 Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Tue, 8 Oct 2024 20:03:34 +0100 Subject: [PATCH 8/8] Fix types --- packages/pglite/src/fs/http/base.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/pglite/src/fs/http/base.ts b/packages/pglite/src/fs/http/base.ts index 3ada333e4..dd5cbd414 100644 --- a/packages/pglite/src/fs/http/base.ts +++ b/packages/pglite/src/fs/http/base.ts @@ -215,7 +215,7 @@ export abstract class HttpFsBase extends BaseFilesystem { read( fd: number, - buffer: Int8Array, // Buffer to read into + buffer: Uint8Array, // Buffer to read into offset: number, // Offset in buffer to start writing to length: number, // Number of bytes to read position: number, // Position in file to read from @@ -295,19 +295,19 @@ export abstract class HttpFsBase extends BaseFilesystem { writeFile( path: string, - data: string | Int8Array, + data: string | Uint8Array, options?: { encoding?: string; mode?: number; flag?: string }, ) { let node = this.getNode(path) if (!node) { node = this.createNode(path, options?.mode ?? 33184, 0) } - node.data = new Filelike(new Uint8Array(data as Int8Array)) + node.data = new Filelike(new Uint8Array(data as Uint8Array)) } write( fd: number, - buffer: Int8Array, // Buffer to read from + buffer: Uint8Array, // Buffer to read from offset: number, // Offset in buffer to start reading from length: number, // Number of bytes to write position: number, // Position in file to write to @@ -371,13 +371,13 @@ function buildTree(index: TarIndex): Node { interface FilelikeInterface { read( - buffer: Int8Array, + buffer: Uint8Array, offset: number, length: number, position: number, ): number write( - buffer: Int8Array, + buffer: Uint8Array, offset: number, length: number, position: number, @@ -397,7 +397,7 @@ class Filelike implements FilelikeInterface { } read( - buffer: Int8Array, + buffer: Uint8Array, offset: number, length: number, position: number, @@ -408,7 +408,7 @@ class Filelike implements FilelikeInterface { } write( - buffer: Int8Array, + buffer: Uint8Array, offset: number, length: number, position: number, @@ -475,7 +475,7 @@ class HttpFilelike implements FilelikeInterface { } read( - buffer: Int8Array, + buffer: Uint8Array, offset: number, length: number, position: number, @@ -527,7 +527,7 @@ class HttpFilelike implements FilelikeInterface { } write( - buffer: Int8Array, + buffer: Uint8Array, offset: number, length: number, position: number,