diff --git a/packages/core/package.json b/packages/core/package.json index 01cf53f..42e434f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -39,7 +39,6 @@ "@blocksuite/lit": "0.0.0-20231101080734-aa27dc89-nightly", "@blocksuite/store": "0.0.0-20231101080734-aa27dc89-nightly", "@toeverything/theme": "0.7.24", - "@toeverything/y-indexeddb": "0.10.0-canary.9", "foxact": "^0.2.26", "idb": "^7.1.1", "jotai": "^2.5.1", @@ -49,6 +48,7 @@ "react": "18.3.0-canary-8039e6d0b-20231026", "react-dom": "18.3.0-canary-8039e6d0b-20231026", "uuid": "^9.0.1", + "y-idb": "workspace:*", "y-utility": "^0.1.3", "y-utils": "workspace:*", "yjs": "^13.6.10" diff --git a/packages/core/src/store/index.ts b/packages/core/src/store/index.ts index e7678c2..7da81de 100644 --- a/packages/core/src/store/index.ts +++ b/packages/core/src/store/index.ts @@ -215,7 +215,7 @@ export class WorkspaceManager { const { createIndexedDBProvider, downloadBinary - } = await import('@toeverything/y-indexeddb') + } = await import('y-idb/browser') this.#preloads.push(async (workspace) => { const binary = await downloadBinary(workspace.doc.guid, 'refine-indexeddb') @@ -225,8 +225,7 @@ export class WorkspaceManager { } }) this.#providers.push((workspace) => { - const provider = createIndexedDBProvider(workspace.doc, - 'refine-indexeddb') + const provider = createIndexedDBProvider('refine-indexeddb', workspace.doc) return { connect: () => { provider.connect() diff --git a/packages/core/tsconfig.src.json b/packages/core/tsconfig.src.json index 43e3d91..33b038e 100644 --- a/packages/core/tsconfig.src.json +++ b/packages/core/tsconfig.src.json @@ -19,6 +19,9 @@ "references": [ { "path": "../jotai-inject" + }, + { + "path": "../y-idb" } ] } diff --git a/packages/core/vite.config.ts b/packages/core/vite.config.ts index 817f5d7..952cb2a 100644 --- a/packages/core/vite.config.ts +++ b/packages/core/vite.config.ts @@ -28,7 +28,8 @@ export default defineConfig({ /^y-utility/, 'uuid', /^foxact/, - 'idb' + 'idb', + 'y-idb/browser' ] } }, diff --git a/packages/y-idb/package.json b/packages/y-idb/package.json new file mode 100644 index 0000000..7f7b3e1 --- /dev/null +++ b/packages/y-idb/package.json @@ -0,0 +1,44 @@ +{ + "name": "y-idb", + "description": "yjs persistence", + "version": "0.0.1", + "type": "module", + "author": "himself65 ", + "files": [ + "dist" + ], + "keywords": [ + "yjs", + "provider", + "database", + "persistence" + ], + "exports": { + "./browser": { + "types": "./dist/src/browser.d.ts", + "import": "./dist/browser.js", + "require": "./dist/browser.cjs" + } + }, + "scripts": { + "build": "vite build", + "dev": "vite build --watch" + }, + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "vite": "^4.5.0", + "vite-plugin-dts": "^3.6.3", + "vite-plugin-istanbul": "^5.0.0", + "vitest": "^0.34.6", + "yjs": "^13.6.10" + + }, + "dependencies": { + "idb": "^8.0.0" + }, + "peerDependencies": { + "yjs": "^13" + } +} diff --git a/packages/y-idb/src/browser.ts b/packages/y-idb/src/browser.ts new file mode 100644 index 0000000..ca78aaf --- /dev/null +++ b/packages/y-idb/src/browser.ts @@ -0,0 +1,134 @@ +import { + openDB, + type DBSchema, + type IDBPDatabase +} from 'idb' +import type { + Workspace, + ProviderAdapter, + StatusAdapter +} from './shared/type.js' +import { createLazyProvider } from './shared/lazy-provider.js' +import { + applyUpdate, + diffUpdate, + Doc, + encodeStateAsUpdate, + encodeStateVectorFromUpdate +} from 'yjs' + +const mergeCount = 200 + +function mergeUpdates (updates: Uint8Array[]): Uint8Array { + const doc = new Doc() + for (const update of updates) { + applyUpdate(doc, update) + } + return encodeStateAsUpdate(doc) +} + +interface YDB extends DBSchema { + workspace: { + key: string + value: Workspace, + indexes: { + guid: string + } + } +} + +function createLazyDB (name: string): () => Promise> { + let lazyDBPromise: Promise> | null = null + return async () => { + if (lazyDBPromise !== null) { + return lazyDBPromise + } + lazyDBPromise = openDB(name, 1, { + upgrade (db) { + { + db.createObjectStore('workspace', { + keyPath: 'guid' + }) + } + } + }) + return lazyDBPromise + } +} + +export function createIndexedDBProvider ( + name: string, rootDoc: Doc): ProviderAdapter & StatusAdapter { + const getDB = createLazyDB(name) + return createLazyProvider(rootDoc, { + queryDocState: async (guid, query) => { + const db = await getDB() + const tx = db.transaction('workspace', 'readonly') + const os = tx.objectStore('workspace') + const workspace = await os.get(guid) + if (workspace === undefined || workspace.updates.length === 0) { + return { + missingUpdate: new Uint8Array() + } + } + + const { updates } = workspace + + const update = mergeUpdates(updates.map(({ update }) => update)) + + const missingUpdate = query?.stateVector + ? diffUpdate(update, query?.stateVector) + : update + + return { missingUpdate, stateVector: encodeStateVectorFromUpdate(update) } + }, + sendDocUpdate: async (guid, update) => { + const db = await getDB() + const tx = db.transaction('workspace', 'readwrite') + const os = tx.objectStore('workspace') + const data = await os.get(guid) + if (data === undefined) { + await os.add({ + guid, + updates: [], + author: name + }) + } else { + if (data.updates.length > mergeCount) { + data.updates = [ + { + update: mergeUpdates(data.updates.map(({ update }) => update)), + date: Date.now() + } + ] + } + await os.put({ + guid, + updates: [ + ...data.updates, { + date: Date.now(), + update + } + ], + author: name + }) + } + } + }, { + author: 'ydb' + }) +} + +export async function downloadBinary( + guid: string, + name: string +): Promise { + const getDB = createLazyDB(name) + const db = await getDB() + const tx = db.transaction('workspace', 'readonly') + const os = tx.objectStore('workspace') + const workspace = await os.get(guid) + if (!workspace) { + return false; + } + return workspace.updates.map(({ update }) => update).reduce((a, b) => mergeUpdates([a, b])) +} diff --git a/packages/y-idb/src/shared/lazy-provider.ts b/packages/y-idb/src/shared/lazy-provider.ts new file mode 100644 index 0000000..20d4b8f --- /dev/null +++ b/packages/y-idb/src/shared/lazy-provider.ts @@ -0,0 +1,329 @@ +/// Credit: https://github.com/toeverything/AFFiNE/tree/559ec3956f643d00d47fead8728e9b587f68b625/packages/common/y-provider +import { + applyUpdate, + type Doc, + encodeStateAsUpdate, + encodeStateVector +} from 'yjs' +import type { + DataSourceAdapter, + ProviderAdapter, + Status, + StatusAdapter +} from './type.js' +import { assertExists } from './utils.js' + +// perf: need memorization here +function queryDoc (doc: Doc, guid: string): Doc | undefined { + if (doc.guid === guid) { + return doc + } + for (const subdoc of doc.subdocs) { + const found = queryDoc(subdoc, guid) + if (found) { + return found + } + } + return undefined +} + +interface LazyProviderOptions { + author?: string; +} + +/** + * Creates a lazy provider that connects to a datasource and synchronizes a root document. + */ +export const createLazyProvider = ( + rootDoc: Doc, + datasource: DataSourceAdapter, + options: LazyProviderOptions = {} +): ProviderAdapter & StatusAdapter => { + let connected = false + const pendingMap = new Map() // guid -> pending-updates + const disposableMap = new Map void>>() + const connectedDocs = new Set() + let abortController: AbortController | null = null + + const { author = 'unknown-provider' } = options + + let currentStatus: Status = { + type: 'idle' + } + let syncingStack = 0 + const callbackSet = new Set<() => void>() + const changeStatus = (newStatus: Status) => { + // simulate a stack, each syncing and synced should be paired + if (newStatus.type === 'syncing') { + syncingStack++ + } else if (newStatus.type === 'synced' || newStatus.type === 'error') { + syncingStack-- + } + + if (syncingStack < 0) { + console.error( + 'syncingStatus < 0, this should not happen', + author + ) + } + + if (syncingStack === 0) { + currentStatus = newStatus + } + if (newStatus.type !== 'synced') { + currentStatus = newStatus + } + if (syncingStack === 0) { + if (!connected) { + currentStatus = { + type: 'idle' + } + } else { + currentStatus = { + type: 'synced' + } + } + } + callbackSet.forEach(cb => cb()) + } + + async function syncDoc (doc: Doc) { + const guid = doc.guid + if (!connected) { + return + } + + changeStatus({ + type: 'syncing' + }) + const remoteUpdate = await datasource.queryDocState(guid, { + stateVector: encodeStateVector(doc), + author + }).then(remoteUpdate => { + changeStatus({ + type: 'synced' + }) + return remoteUpdate + }).catch(error => { + changeStatus({ + type: 'error', + error + }) + throw error + }) + + pendingMap.set(guid, []) + + if (remoteUpdate.missingUpdate.length > 0) { + applyUpdate(doc, remoteUpdate.missingUpdate, author) + } + + if (!connected) { + return + } + + // perf: optimize me + // it is possible the doc is only in memory but not yet in the datasource + // we need to send the whole update to the datasource + await datasource.sendDocUpdate( + guid, + encodeStateAsUpdate(doc, + remoteUpdate ? remoteUpdate.stateVector : undefined), + author + ) + + doc.emit('sync', []) + } + + function setupDocListener (rootDoc: Doc) { + const disposables = new Set<() => void>() + disposableMap.set(rootDoc.guid, disposables) + const updateHandler = async (update: Uint8Array, updateOrigin: unknown) => { + if (author === updateOrigin) { + return + } + changeStatus({ + type: 'syncing' + }) + datasource.sendDocUpdate(rootDoc.guid, update, + typeof updateOrigin === 'string' ? updateOrigin : 'unknown-origin'). + then(() => { + changeStatus({ + type: 'synced' + }) + }). + catch(error => { + changeStatus({ + type: 'error', + error + }) + console.error(error) + }) + } + + const subdocsHandler = (event: { + loaded: Set; + removed: Set; + added: Set; + }) => { + event.loaded.forEach(subdoc => { + connectDoc(subdoc).catch(console.error) + }) + event.removed.forEach(subdoc => { + disposeDoc(subdoc) + }) + } + + const destroyHandler = () => { + disposeDoc(rootDoc) + } + + rootDoc.on('update', updateHandler) + rootDoc.on('subdocs', subdocsHandler) + rootDoc.once('destroy', destroyHandler) + disposables.add(() => { + rootDoc.off('update', updateHandler) + rootDoc.off('subdocs', subdocsHandler) + rootDoc.off('destroy', destroyHandler) + }) + } + + function setupDatasourceListeners () { + assertExists(abortController, 'abortController should be defined') + const unsubscribe = datasource.onDocUpdate?.((guid, update) => { + changeStatus({ + type: 'syncing' + }) + const doc = queryDoc(rootDoc, guid) + if (doc) { + applyUpdate(doc, update, author) + if (pendingMap.has(guid)) { + pendingMap.get(guid)?. + forEach(update => applyUpdate(doc, update, author)) + pendingMap.delete(guid) + } + } else { + // This case happens when the father doc is not yet updated, + // so that the child doc is not yet created. + // We need to put it into cache so that it can be applied later. + console.warn('doc not found', guid) + pendingMap.set(guid, (pendingMap.get(guid) ?? []).concat(update)) + } + changeStatus({ + type: 'synced' + }) + }) + abortController.signal.addEventListener('abort', () => { + unsubscribe?.() + }) + } + + // when a subdoc is loaded, we need to sync it with the datasource and setup listeners + async function connectDoc (doc: Doc) { + // skip if already connected + if (connectedDocs.has(doc.guid)) { + return + } + connectedDocs.add(doc.guid) + setupDocListener(doc) + await syncDoc(doc) + + await Promise.all( + [...doc.subdocs].filter(subdoc => subdoc.shouldLoad). + map(subdoc => connectDoc(subdoc)) + ) + } + + function disposeDoc (doc: Doc) { + connectedDocs.delete(doc.guid) + const disposables = disposableMap.get(doc.guid) + if (disposables) { + disposables.forEach(dispose => dispose()) + disposableMap.delete(doc.guid) + } + // also dispose all subdocs + doc.subdocs.forEach(disposeDoc) + } + + function disposeAll () { + disposableMap.forEach(disposables => { + disposables.forEach(dispose => dispose()) + }) + disposableMap.clear() + connectedDocs.clear() + } + + /** + * Connects to the datasource and sets up event listeners for document updates. + */ + function connect () { + connected = true + abortController = new AbortController() + + changeStatus({ + type: 'syncing' + }) + // root doc should be already loaded, + // but we want to populate the cache for later update events + connectDoc(rootDoc).then(() => { + changeStatus({ + type: 'synced' + }) + }).catch(error => { + changeStatus({ + type: 'error', + error + }) + console.error(error) + }) + setupDatasourceListeners() + } + + async function disconnect () { + connected = false + disposeAll() + assertExists(abortController, 'abortController should be defined') + abortController.abort() + abortController = null + } + + const syncDocRecursive = async (doc: Doc) => { + await syncDoc(doc) + await Promise.all( + [...doc.subdocs.values()].map(subdoc => syncDocRecursive(subdoc)) + ) + } + + return { + //#region status adapter + getStatus () { + return currentStatus + }, + onStatusChange (cb: () => void) { + callbackSet.add(cb) + return () => { + callbackSet.delete(cb) + } + }, + //#endregion + //#region provider adapter + sync: async onlyRootDoc => { + connected = true + try { + if (onlyRootDoc) { + await syncDoc(rootDoc) + } else { + await syncDocRecursive(rootDoc) + } + } finally { + connected = false + } + }, + getConnected (): boolean { + return connected + }, + connect, + disconnect + //#endregion + } +} diff --git a/packages/y-idb/src/shared/type.ts b/packages/y-idb/src/shared/type.ts new file mode 100644 index 0000000..8e715b5 --- /dev/null +++ b/packages/y-idb/src/shared/type.ts @@ -0,0 +1,56 @@ +type Chunk = { + update: Uint8Array + date: number +} + +export type Workspace = { + guid: string + updates: Chunk[] + author: string +} + +export type QueryOptions = { + stateVector: Uint8Array + author: string +} + +export interface DocStateResponse { + missingUpdate: Uint8Array; + stateVector?: Uint8Array; +} + +export type Dispose = () => void + +export type Status = { + type: 'idle' +} | { + type: 'syncing' +} | { + type: 'error' + error: unknown +} | { + type: 'synced' +} + +export type DataSourceAdapter = { + queryDocState: ( + guid: string, + query?: Partial + ) => Promise + sendDocUpdate: ( + guid: string, update: Uint8Array, origin: string) => Promise + onDocUpdate?: (callback: ( + guid: string, update: Uint8Array) => void) => Dispose +} + +export type ProviderAdapter = { + sync (onlyRootDoc?: boolean): Promise; + getConnected (): boolean; + connect (): void; + disconnect (): void; +}; + +export type StatusAdapter = { + getStatus (): Status + onStatusChange (callback: () => void): Dispose +} diff --git a/packages/y-idb/src/shared/utils.ts b/packages/y-idb/src/shared/utils.ts new file mode 100644 index 0000000..8f5f111 --- /dev/null +++ b/packages/y-idb/src/shared/utils.ts @@ -0,0 +1,5 @@ +export function assertExists (value: T | null | undefined, message?: string): asserts value is T { + if (value === null || value === undefined) { + throw new Error(message || 'value is null or undefined') + } +} diff --git a/packages/y-idb/tsconfig.json b/packages/y-idb/tsconfig.json new file mode 100644 index 0000000..ad6678b --- /dev/null +++ b/packages/y-idb/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "ESNext", + "target": "ES2020", + "moduleResolution": "bundler", + "outDir": "./dist", + "lib": ["ESNext", "DOM"] + }, + "include": [ + "./src" + ] +} diff --git a/packages/y-idb/vite.config.ts b/packages/y-idb/vite.config.ts new file mode 100644 index 0000000..e4f0ee6 --- /dev/null +++ b/packages/y-idb/vite.config.ts @@ -0,0 +1,30 @@ +import { defineConfig } from 'vite' +import dts from 'vite-plugin-dts' +import istanbul from 'vite-plugin-istanbul'; + +export default defineConfig({ + build: { + sourcemap: true, + lib: { + entry: { + 'browser': './src/browser.ts', + }, + formats: ['es', 'cjs'] + }, + outDir: './dist', + rollupOptions: { + external: [ + /^idb/, + /^yjs/ + ] + } + }, + plugins: [ + istanbul({ + forceBuildInstrument: process.env.COVERAGE === 'true' + }), + dts({ + include: ["src"], + }) + ] +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1536d27..0ebc2f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -122,7 +122,7 @@ importers: version: link:../../packages/jotai-inject next: specifier: 14.0.2 - version: 14.0.2(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) + version: 14.0.2(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) next-themes: specifier: ^0.2.1 version: 0.2.1(next@14.0.2)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) @@ -235,7 +235,7 @@ importers: version: 0.0.35 next: specifier: 14.0.3 - version: 14.0.3(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) + version: 14.0.3(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) next-themes: specifier: ^0.2.1 version: 0.2.1(next@14.0.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) @@ -291,9 +291,6 @@ importers: '@toeverything/theme': specifier: 0.7.24 version: 0.7.24 - '@toeverything/y-indexeddb': - specifier: 0.10.0-canary.9 - version: 0.10.0-canary.9(yjs@13.6.10) foxact: specifier: ^0.2.26 version: 0.2.26(react@18.3.0-canary-8039e6d0b-20231026) @@ -321,6 +318,9 @@ importers: uuid: specifier: ^9.0.1 version: 9.0.1 + y-idb: + specifier: workspace:* + version: link:../y-idb y-utility: specifier: ^0.1.3 version: 0.1.3(yjs@13.6.10) @@ -408,6 +408,28 @@ importers: specifier: ^0.34.6 version: 0.34.6(@vitest/ui@0.34.6)(happy-dom@12.10.3) + packages/y-idb: + dependencies: + idb: + specifier: ^8.0.0 + version: 8.0.0 + devDependencies: + vite: + specifier: ^4.5.0 + version: 4.5.0(@types/node@20.9.5) + vite-plugin-dts: + specifier: ^3.6.3 + version: 3.6.3(@types/node@20.9.5)(typescript@5.3.2)(vite@4.5.0) + vite-plugin-istanbul: + specifier: ^5.0.0 + version: 5.0.0(vite@4.5.0) + vitest: + specifier: ^0.34.6 + version: 0.34.6(@vitest/ui@0.34.6) + yjs: + specifier: ^13.6.10 + version: 13.6.10 + packages/y-io: dependencies: y-utils: @@ -437,7 +459,7 @@ importers: version: 5.0.0(vite@4.5.0) vitest: specifier: ^0.34.6 - version: 0.34.6(@vitest/ui@0.34.6)(happy-dom@12.10.3) + version: 0.34.6(@vitest/ui@0.34.6) yjs: specifier: ^13.6.10 version: 13.6.10 @@ -461,7 +483,7 @@ importers: version: 5.0.0(vite@4.5.0) vitest: specifier: ^0.34.6 - version: 0.34.6(@vitest/ui@0.34.6)(happy-dom@12.10.3) + version: 0.34.6(@vitest/ui@0.34.6) yjs: specifier: ^13.6.10 version: 13.6.10 @@ -509,23 +531,23 @@ packages: - encoding dev: false - /@babel/code-frame@7.22.13: - resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} + /@babel/code-frame@7.23.4: + resolution: {integrity: sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.22.20 + '@babel/highlight': 7.23.4 chalk: 2.4.2 dev: true - /@babel/code-frame@7.23.4: - resolution: {integrity: sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==} + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.23.4 chalk: 2.4.2 - /@babel/compat-data@7.23.3: - resolution: {integrity: sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==} + /@babel/compat-data@7.23.5: + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} engines: {node: '>=6.9.0'} /@babel/core@7.23.3: @@ -549,6 +571,29 @@ packages: semver: 6.3.1 transitivePeerDependencies: - supports-color + dev: true + + /@babel/core@7.23.5: + resolution: {integrity: sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) + '@babel/helpers': 7.23.5 + '@babel/parser': 7.23.5 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.5 + '@babel/types': 7.23.5 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color /@babel/generator@7.23.4: resolution: {integrity: sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==} @@ -558,13 +603,23 @@ packages: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.20 jsesc: 2.5.2 + dev: true + + /@babel/generator@7.23.5: + resolution: {integrity: sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.20 + jsesc: 2.5.2 /@babel/helper-compilation-targets@7.22.15: resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.23.3 - '@babel/helper-validator-option': 7.22.15 + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 browserslist: 4.22.1 lru-cache: 5.1.1 semver: 6.3.1 @@ -604,6 +659,20 @@ packages: '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 /@babel/helper-plugin-utils@7.22.5: resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} @@ -630,8 +699,8 @@ packages: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - /@babel/helper-validator-option@7.22.15: - resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==} + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} /@babel/helpers@7.23.4: @@ -643,15 +712,17 @@ packages: '@babel/types': 7.23.4 transitivePeerDependencies: - supports-color + dev: true - /@babel/highlight@7.22.20: - resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} + /@babel/helpers@7.23.5: + resolution: {integrity: sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.5 + '@babel/types': 7.23.5 + transitivePeerDependencies: + - supports-color /@babel/highlight@7.23.4: resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} @@ -675,6 +746,14 @@ packages: hasBin: true dependencies: '@babel/types': 7.23.4 + dev: true + + /@babel/parser@7.23.5: + resolution: {integrity: sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.5 /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.3): resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} @@ -706,9 +785,9 @@ packages: resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.23.4 - '@babel/parser': 7.23.4 - '@babel/types': 7.23.4 + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.23.5 + '@babel/types': 7.23.5 /@babel/traverse@7.23.4: resolution: {integrity: sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg==} @@ -726,6 +805,24 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color + dev: true + + /@babel/traverse@7.23.5: + resolution: {integrity: sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.5 + '@babel/types': 7.23.5 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color /@babel/types@7.23.4: resolution: {integrity: sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==} @@ -735,6 +832,14 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + /@babel/types@7.23.5: + resolution: {integrity: sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -1355,7 +1460,7 @@ packages: react: '>=16' dependencies: '@types/mdx': 2.0.9 - '@types/react': 18.2.38 + '@types/react': 18.2.41 react: 18.3.0-canary-8039e6d0b-20231026 dev: false @@ -2182,7 +2287,7 @@ packages: resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} engines: {node: '>=14'} dependencies: - '@babel/code-frame': 7.22.13 + '@babel/code-frame': 7.23.4 '@babel/runtime': 7.23.2 '@types/aria-query': 5.0.3 aria-query: 5.1.3 @@ -2252,17 +2357,6 @@ packages: resolution: {integrity: sha512-DbQv2/I5MvdES0EaATmP1aU5llX8PfEJEamzKN3Ahiu2FoYOXiE99xkfKPD0c7x/XTiLYQsIv1EsOqwzXR6gPA==} dev: false - /@toeverything/y-indexeddb@0.10.0-canary.9(yjs@13.6.10): - resolution: {integrity: sha512-3hzktNuOaXut/RgRjKNeqQura1zeYF+tSLSlWDc0rDBOrEpwD/1EOpKVCbgtl8ke7f4oinLfgBNk4HcwqaQUYQ==} - peerDependencies: - yjs: ^13 - dependencies: - idb: 7.1.1 - nanoid: 5.0.1 - y-provider: 0.10.0-canary.9(yjs@13.6.10) - yjs: 13.6.10 - dev: false - /@tokenizer/token@0.3.0: resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} dev: false @@ -2518,6 +2612,14 @@ packages: '@types/scheduler': 0.16.5 csstype: 3.1.2 + /@types/react@18.2.41: + resolution: {integrity: sha512-CwOGr/PiLiNBxEBqpJ7fO3kocP/2SSuC9fpH5K7tusrg4xPSRT/193rzolYwQnTN02We/ATXKnb6GqA5w4fRxw==} + dependencies: + '@types/prop-types': 15.7.9 + '@types/scheduler': 0.16.5 + csstype: 3.1.2 + dev: false + /@types/responselike@1.0.2: resolution: {integrity: sha512-/4YQT5Kp6HxUDb4yhRkm0bJ7TbjvTddqX7PZ5hz6qV3pxSo72f/6YPRo+Mu2DU307tm9IioO69l7uAwn5XNcFA==} dependencies: @@ -2828,7 +2930,7 @@ packages: /@vue/compiler-core@3.3.8: resolution: {integrity: sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==} dependencies: - '@babel/parser': 7.23.4 + '@babel/parser': 7.23.5 '@vue/shared': 3.3.8 estree-walker: 2.0.2 source-map-js: 1.0.2 @@ -2851,7 +2953,7 @@ packages: /@vue/compiler-sfc@3.3.8: resolution: {integrity: sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==} dependencies: - '@babel/parser': 7.23.4 + '@babel/parser': 7.23.5 '@vue/compiler-core': 3.3.8 '@vue/compiler-dom': 3.3.8 '@vue/compiler-ssr': 3.3.8 @@ -2892,7 +2994,7 @@ packages: /@vue/reactivity-transform@3.3.8: resolution: {integrity: sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==} dependencies: - '@babel/parser': 7.23.4 + '@babel/parser': 7.23.5 '@vue/compiler-core': 3.3.8 '@vue/shared': 3.3.8 estree-walker: 2.0.2 @@ -6345,6 +6447,10 @@ packages: resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} dev: false + /idb@8.0.0: + resolution: {integrity: sha512-l//qvlAKGmQO31Qn7xdzagVPPaHTxXx199MhrAFuVBTPqydcPYBWjkrbv4Y0ktB+GmWOiwHl237UUOrLmQxLvw==} + dev: false + /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} requiresBuild: true @@ -6757,7 +6863,7 @@ packages: resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.23.3 + '@babel/core': 7.23.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 semver: 6.3.1 @@ -6769,7 +6875,7 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.23.3 + '@babel/core': 7.23.5 '@babel/parser': 7.23.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 @@ -8440,12 +8546,6 @@ packages: engines: {node: ^14 || ^16 || >=18} hasBin: true - /nanoid@5.0.1: - resolution: {integrity: sha512-vWeVtV5Cw68aML/QaZvqN/3QQXc6fBfIieAlu05m7FZW2Dgb+3f0xc0TTxuJW+7u30t7iSDTV/j3kVI0oJqIfQ==} - engines: {node: ^18 || >=20} - hasBin: true - dev: false - /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} dev: true @@ -8478,7 +8578,7 @@ packages: react: '>=16.0.0' react-dom: '>=16.0.0' dependencies: - next: 14.0.2(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) + next: 14.0.2(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) react: 18.3.0-canary-8039e6d0b-20231026 react-dom: 18.3.0-canary-8039e6d0b-20231026(react@18.3.0-canary-8039e6d0b-20231026) dev: false @@ -8490,7 +8590,7 @@ packages: react: '*' react-dom: '*' dependencies: - next: 14.0.2(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) + next: 14.0.2(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) react: 18.3.0-canary-8039e6d0b-20231026 react-dom: 18.3.0-canary-8039e6d0b-20231026(react@18.3.0-canary-8039e6d0b-20231026) dev: false @@ -8502,12 +8602,12 @@ packages: react: '*' react-dom: '*' dependencies: - next: 14.0.3(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) + next: 14.0.3(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) react: 18.3.0-canary-8039e6d0b-20231026 react-dom: 18.3.0-canary-8039e6d0b-20231026(react@18.3.0-canary-8039e6d0b-20231026) dev: false - /next@14.0.2(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026): + /next@14.0.2(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026): resolution: {integrity: sha512-jsAU2CkYS40GaQYOiLl9m93RTv2DA/tTJ0NRlmZIBIL87YwQ/xR8k796z7IqgM3jydI8G25dXvyYMC9VDIevIg==} engines: {node: '>=18.17.0'} hasBin: true @@ -8529,7 +8629,7 @@ packages: postcss: 8.4.31 react: 18.3.0-canary-8039e6d0b-20231026 react-dom: 18.3.0-canary-8039e6d0b-20231026(react@18.3.0-canary-8039e6d0b-20231026) - styled-jsx: 5.1.1(@babel/core@7.23.3)(react@18.3.0-canary-8039e6d0b-20231026) + styled-jsx: 5.1.1(@babel/core@7.23.5)(react@18.3.0-canary-8039e6d0b-20231026) watchpack: 2.4.0 optionalDependencies: '@next/swc-darwin-arm64': 14.0.2 @@ -8546,7 +8646,7 @@ packages: - babel-plugin-macros dev: false - /next@14.0.3(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026): + /next@14.0.3(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026): resolution: {integrity: sha512-AbYdRNfImBr3XGtvnwOxq8ekVCwbFTv/UJoLwmaX89nk9i051AEY4/HAWzU0YpaTDw8IofUpmuIlvzWF13jxIw==} engines: {node: '>=18.17.0'} hasBin: true @@ -8568,7 +8668,7 @@ packages: postcss: 8.4.31 react: 18.3.0-canary-8039e6d0b-20231026 react-dom: 18.3.0-canary-8039e6d0b-20231026(react@18.3.0-canary-8039e6d0b-20231026) - styled-jsx: 5.1.1(@babel/core@7.23.3)(react@18.3.0-canary-8039e6d0b-20231026) + styled-jsx: 5.1.1(@babel/core@7.23.5)(react@18.3.0-canary-8039e6d0b-20231026) watchpack: 2.4.0 optionalDependencies: '@next/swc-darwin-arm64': 14.0.3 @@ -8597,7 +8697,7 @@ packages: react-cusdis: optional: true dependencies: - next: 14.0.2(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) + next: 14.0.2(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) next-themes: 0.2.1(next@14.0.2)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) nextra: 2.13.2(next@14.0.2)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) react: 18.3.0-canary-8039e6d0b-20231026 @@ -8621,7 +8721,7 @@ packages: git-url-parse: 13.1.1 intersection-observer: 0.12.2 match-sorter: 6.3.1 - next: 14.0.2(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) + next: 14.0.2(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) next-seo: 6.4.0(next@14.0.2)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) next-themes: 0.2.1(next@14.0.2)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) nextra: 2.13.2(next@14.0.2)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) @@ -8651,7 +8751,7 @@ packages: gray-matter: 4.0.3 katex: 0.16.9 lodash.get: 4.4.2 - next: 14.0.2(@babel/core@7.23.3)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) + next: 14.0.2(@babel/core@7.23.5)(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) next-mdx-remote: 4.4.1(react-dom@18.3.0-canary-8039e6d0b-20231026)(react@18.3.0-canary-8039e6d0b-20231026) p-limit: 3.1.0 react: 18.3.0-canary-8039e6d0b-20231026 @@ -10380,7 +10480,7 @@ packages: inline-style-parser: 0.1.1 dev: false - /styled-jsx@5.1.1(@babel/core@7.23.3)(react@18.3.0-canary-8039e6d0b-20231026): + /styled-jsx@5.1.1(@babel/core@7.23.5)(react@18.3.0-canary-8039e6d0b-20231026): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} peerDependencies: @@ -10393,7 +10493,7 @@ packages: babel-plugin-macros: optional: true dependencies: - '@babel/core': 7.23.3 + '@babel/core': 7.23.5 client-only: 0.0.1 react: 18.3.0-canary-8039e6d0b-20231026 dev: false @@ -11280,6 +11380,72 @@ packages: fsevents: 2.3.3 dev: true + /vitest@0.34.6(@vitest/ui@0.34.6): + resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.9 + '@types/chai-subset': 1.3.4 + '@types/node': 20.9.5 + '@vitest/expect': 0.34.6 + '@vitest/runner': 0.34.6 + '@vitest/snapshot': 0.34.6 + '@vitest/spy': 0.34.6 + '@vitest/ui': 0.34.6(vitest@0.34.6) + '@vitest/utils': 0.34.6 + acorn: 8.11.2 + acorn-walk: 8.3.0 + cac: 6.7.14 + chai: 4.3.10 + debug: 4.3.4 + local-pkg: 0.4.3 + magic-string: 0.30.5 + pathe: 1.1.1 + picocolors: 1.0.0 + std-env: 3.4.3 + strip-literal: 1.3.0 + tinybench: 2.5.1 + tinypool: 0.7.0 + vite: 4.5.0(@types/node@20.9.5) + vite-node: 0.34.6(@types/node@20.9.5) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vitest@0.34.6(@vitest/ui@0.34.6)(happy-dom@12.10.3): resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==} engines: {node: '>=v14.18.0'} @@ -11619,14 +11785,6 @@ packages: lib0: 0.2.87 yjs: 13.6.10 - /y-provider@0.10.0-canary.9(yjs@13.6.10): - resolution: {integrity: sha512-ImkLqCpxHK0lkxD12s7BE4p14NiAnQQSJGN5GONl4W4CyLBx6+tRop3yg66abg64N3JYX9EwXxnIVDziq6b8Dw==} - peerDependencies: - yjs: ^13 - dependencies: - yjs: 13.6.10 - dev: false - /y-utility@0.1.3(yjs@13.6.10): resolution: {integrity: sha512-o9aXG5ZG4c/QgiK1Bt9UDXGVCNwn0dLti/rZSPTsjtuvwH6sshslU2SfoW65pfZqjLJYEHclM/JtUPPjv05lLw==} engines: {node: '>=16'} diff --git a/tsconfig.json b/tsconfig.json index e99b88c..f7ca5e5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -56,6 +56,8 @@ "paths": { "@refine/core/*": ["./packages/core/src/*"], "@refine/server/*": ["./apps/server/src/*"], + "y-idb": ["./packages/y-idb/src/index"], + "y-idb/*": ["./packages/y-idb/src/*"], "jotai-inject": ["./packages/jotai-inject/src/index"], "jotai-inject/*": ["./packages/jotai-inject/src/*"], } @@ -84,6 +86,9 @@ }, { "path": "./packages/y-utils/tsconfig.json" + }, + { + "path": "./packages/y-idb/tsconfig.json" } ], "include": [],