From d8b0996aecd15222921f5b9d874e5d49cf077881 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 12 Sep 2023 13:25:21 -0400 Subject: [PATCH 01/28] add test --- test-e2e/ipc-wrapper.js | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 test-e2e/ipc-wrapper.js diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js new file mode 100644 index 00000000..2f72ec67 --- /dev/null +++ b/test-e2e/ipc-wrapper.js @@ -0,0 +1,42 @@ +import { test } from 'brittle' +import { MessageChannel } from 'node:worker_threads' +import RAM from 'random-access-memory' +import { KeyManager } from '@mapeo/crypto' +import { createMapeoServer } from '../src/ipc-wrapper/server.js' +import { MapeoManager } from '../src/mapeo-manager.js' +import { createClient } from 'rpc-reflector' +import { createMapeoClient } from '../src/ipc-wrapper/client.js' + +test('IPC wrappers work', async (t) => { + const { port1, port2 } = new MessageChannel() + + const manager = new MapeoManager({ + rootKey: KeyManager.generateRootKey(), + dbFolder: ':memory:', + coreStorage: () => new RAM(), + }) + + const server = createMapeoServer(manager, port1) + const client = createMapeoClient(port2) + + port1.start() + port2.start() + + const projectId = await client.createProject({ name: 'mapeo' }) + + t.ok(projectId) + + const project = await client.getProject(projectId) + + t.ok(project) + + const projectSettings = await project.$getProjectSettings() + + t.alike(projectSettings, { name: 'mapeo' }) + + server.close() + createClient.close(client) + + port1.close() + port2.close() +}) From 7b129c0e76a693ce81f242863232638752cca869 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 12 Sep 2023 13:25:30 -0400 Subject: [PATCH 02/28] broken initial implementation --- package-lock.json | 137 +++++++++++++++++++++++++++++++++ package.json | 1 + src/ipc-wrapper/client.js | 49 ++++++++++++ src/ipc-wrapper/server.js | 39 ++++++++++ src/ipc-wrapper/sub-channel.js | 40 ++++++++++ 5 files changed, 266 insertions(+) create mode 100644 src/ipc-wrapper/client.js create mode 100644 src/ipc-wrapper/server.js create mode 100644 src/ipc-wrapper/sub-channel.js diff --git a/package-lock.json b/package-lock.json index 914cb81f..effcca7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,7 @@ "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", + "rpc-reflector": "^1.3.10", "sodium-universal": "^4.0.0", "sub-encoder": "^2.1.1", "tiny-typed-emitter": "^2.1.0" @@ -1739,6 +1740,14 @@ "better-sqlite3": "^8.4.0" } }, + "node_modules/@msgpack/msgpack": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-1.12.2.tgz", + "integrity": "sha512-Vwhc3ObxmDZmA5hY8mfsau2rJ4vGPvzbj20QSZ2/E1GDPF61QVyjLfNHak9xmel6pW4heRt3v1fHa6np9Ehfeg==", + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -2738,6 +2747,11 @@ "dev": true, "license": "MIT" }, + "node_modules/const-max-uint32": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/const-max-uint32/-/const-max-uint32-1.0.2.tgz", + "integrity": "sha512-T8/9bffg5RThuejasJWrwqxs3Q0fsJvyl7/33IB6svroD8JC93E7X60AuuOnDE8RlP6Jlb5FxmlrVDpl9KiU2Q==" + }, "node_modules/convert-source-map": { "version": "1.9.0", "dev": true, @@ -3357,6 +3371,17 @@ } } }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -3768,6 +3793,11 @@ "node": ">=6" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, "node_modules/events": { "version": "3.3.0", "license": "MIT", @@ -5226,6 +5256,16 @@ "node": ">=0.10.0" } }, + "node_modules/length-prefixed-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/length-prefixed-stream/-/length-prefixed-stream-2.0.0.tgz", + "integrity": "sha512-dvjTuWTKWe0oEznQcG6a9osfiYknCs7DEFJMP88n9Y581IFhYh1sZIgAFcuDOojKB0G7ftPreKhh4D0kh/VPjQ==", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "varint": "^5.0.0" + } + }, "node_modules/levn": { "version": "0.4.1", "dev": true, @@ -7163,6 +7203,43 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rpc-reflector": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/rpc-reflector/-/rpc-reflector-1.3.10.tgz", + "integrity": "sha512-/B40dEx0758gn+1wm0kSaECvivF3Qspg+0/N39/eKppScUglS1mypsHjkO6ZLUFZSH9T3YnH7JArQ4IO3UQVWA==", + "dependencies": { + "@msgpack/msgpack": "^1.12.1", + "@types/node": "^18.16.19", + "duplexify": "^4.1.2", + "eventemitter3": "^5.0.1", + "is-stream": "^2.0.1", + "length-prefixed-stream": "^2.0.0", + "p-timeout": "^4.1.0", + "pump": "^3.0.0", + "serialize-error": "^8.1.0", + "through2": "^4.0.2", + "validate.io-array-like": "^1.0.2" + } + }, + "node_modules/rpc-reflector/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rpc-reflector/node_modules/p-timeout": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", + "integrity": "sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==", + "engines": { + "node": ">=10" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "dev": true, @@ -7316,6 +7393,31 @@ "dev": true, "license": "MIT" }, + "node_modules/serialize-error": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/set-cookie-parser": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", @@ -7659,6 +7761,11 @@ "dev": true, "license": "MIT" }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "node_modules/streamx": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", @@ -7960,6 +8067,14 @@ "real-require": "^0.2.0" } }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dependencies": { + "readable-stream": "3" + } + }, "node_modules/time-ordered-set": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/time-ordered-set/-/time-ordered-set-1.0.2.tgz", @@ -8349,6 +8464,28 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/validate.io-array-like": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/validate.io-array-like/-/validate.io-array-like-1.0.2.tgz", + "integrity": "sha512-rGLiN0cvY9OWzQcWP+RtqZR/MK9RUz3gKDTCcRLtEQ/BvlanMF5PyqtVIN+CgrIBCv/ypfme9v7r4yMJPYpbNA==", + "dependencies": { + "const-max-uint32": "^1.0.2", + "validate.io-integer-primitive": "^1.0.0" + } + }, + "node_modules/validate.io-integer-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/validate.io-integer-primitive/-/validate.io-integer-primitive-1.0.0.tgz", + "integrity": "sha512-4ARGKA4FImVWJgrgttLYsYJmDGwxlhLfDCdq09gyVgohLKKRUfD3VAo1L2vTRCLt6hDhDtFKdZiuYUTWyBggwg==", + "dependencies": { + "validate.io-number-primitive": "^1.0.0" + } + }, + "node_modules/validate.io-number-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/validate.io-number-primitive/-/validate.io-number-primitive-1.0.0.tgz", + "integrity": "sha512-8rlCe7N0TRTd50dwk4WNoMXNbX/4+RdtqE3TO6Bk0GJvAgbQlfL5DGr/Pl9ZLbWR6CutMjE2cu+yOoCnFWk+Qw==" + }, "node_modules/varint": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz", diff --git a/package.json b/package.json index 7f12ea38..766de504 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,7 @@ "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", + "rpc-reflector": "^1.3.10", "sodium-universal": "^4.0.0", "sub-encoder": "^2.1.1", "tiny-typed-emitter": "^2.1.0" diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js new file mode 100644 index 00000000..c0313b1e --- /dev/null +++ b/src/ipc-wrapper/client.js @@ -0,0 +1,49 @@ +// @ts-check +import { createClient } from 'rpc-reflector' +import { SubChannel } from './sub-channel.js' + +/** + * @param {import('rpc-reflector/client.js').MessagePortLike} messagePort + * @returns {import('rpc-reflector/client.js').ClientApi} + */ +export function createMapeoClient(messagePort) { + // TODO: LRU cache? + /** @type {Map>} */ + const existingProjectClients = new Map() + + const managerChannel = new SubChannel(messagePort, '@@manager') + + /** @type {import('rpc-reflector').ClientApi} */ + const managerClient = createClient(managerChannel) + + const client = new Proxy(managerClient, { + get(target, prop, receiver) { + if (prop === 'getProject') { + return createProjectClient + } else { + return Reflect.get(target, prop, receiver) + } + + /** + * @param {import('../types.js').ProjectPublicId} projectPublicId + * @returns {import('rpc-reflector/client.js').ClientApi} + */ + function createProjectClient(projectPublicId) { + const existingClient = existingProjectClients.get(projectPublicId) + + if (existingClient) return existingClient + + const projectChannel = new SubChannel(messagePort, projectPublicId) + + /** @type {import('rpc-reflector').ClientApi} */ + const projectClient = createClient(projectChannel) + + existingProjectClients.set(projectPublicId, projectClient) + + return projectClient + } + }, + }) + + return client +} diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js new file mode 100644 index 00000000..6f8d6c6c --- /dev/null +++ b/src/ipc-wrapper/server.js @@ -0,0 +1,39 @@ +// @ts-check +import { createServer } from 'rpc-reflector' +import { SubChannel } from './sub-channel.js' + +/** + * @param {import('../mapeo-manager.js').MapeoManager} manager + * @param {import('rpc-reflector/server.js').MessagePortLike} messagePort + */ +export function createMapeoServer(manager, messagePort) { + // TODO: LRU? project.close() after time without use? + /** @type {Map void, project: import('../mapeo-project.js').MapeoProject }>}*/ + const existing = new Map() + + const managerChannel = new SubChannel(messagePort, '@@manager') + + const managerServer = createServer(manager, managerChannel) + + managerChannel.on('message', async (payload) => { + // TODO: figure out better way to know that this is the project public id + const projectPublicId = payload[payload.length - 1] + + if (typeof projectPublicId !== 'string') return + if (existing.has(projectPublicId)) return + + const projectChannel = new SubChannel(messagePort, projectPublicId) + + const project = await manager.getProject( + /** @type {import('../types.js').ProjectPublicId} */ (projectPublicId) + ) + + const { close } = createServer(project, projectChannel) + + projectChannel.emit('message', payload) + + existing.set(projectPublicId, { close, project }) + }) + + return managerServer +} diff --git a/src/ipc-wrapper/sub-channel.js b/src/ipc-wrapper/sub-channel.js new file mode 100644 index 00000000..97a1a432 --- /dev/null +++ b/src/ipc-wrapper/sub-channel.js @@ -0,0 +1,40 @@ +// @ts-check +import { TypedEmitter } from 'tiny-typed-emitter' + +/** + * @typedef {Object} Events + * @property {(message: any) => void} message + */ + +/** + * @extends {TypedEmitter} + */ +export class SubChannel extends TypedEmitter { + #id + #messagePort + + /** + * @param {import('rpc-reflector/server.js').MessagePortLike} messagePort Parent channel to add namespace to + * @param {string} id ID for the subchannel + */ + constructor(messagePort, id) { + super() + + this.#id = id + this.#messagePort = messagePort + + // Listen to all messages on the shared channel but only handle the relevant ones + this.#messagePort.on('message', ({ id, message }) => { + if (this.#id !== id) return + this.emit('message', message) + }) + } + + /** + * Send messages with the subchannel's ID + * @param {any} message + */ + postMessage(message) { + this.#messagePort.postMessage({ id: this.#id, message }) + } +} From 4be13037f243ee87ed8625a7dde5c10ea4ad1282 Mon Sep 17 00:00:00 2001 From: Gregor MacLennan Date: Tue, 12 Sep 2023 23:25:14 +0100 Subject: [PATCH 03/28] some fixes Co-authored-by: Andrew Chou --- src/ipc-wrapper/client.js | 15 +++++++++++---- src/ipc-wrapper/server.js | 16 ++++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index c0313b1e..dee35a61 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -26,21 +26,28 @@ export function createMapeoClient(messagePort) { /** * @param {import('../types.js').ProjectPublicId} projectPublicId - * @returns {import('rpc-reflector/client.js').ClientApi} + * @returns {Promise>} */ function createProjectClient(projectPublicId) { const existingClient = existingProjectClients.get(projectPublicId) - if (existingClient) return existingClient + if (existingClient) return Promise.resolve(existingClient) const projectChannel = new SubChannel(messagePort, projectPublicId) /** @type {import('rpc-reflector').ClientApi} */ - const projectClient = createClient(projectChannel) + const projectClient = new Proxy(createClient(projectChannel), { + get(target, prop, receiver) { + if (prop === 'then') { + return projectClient + } + return Reflect.get(target, prop, receiver) + }, + }) existingProjectClients.set(projectPublicId, projectClient) - return projectClient + return Promise.resolve(projectClient) } }, }) diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index 6f8d6c6c..bc47bd59 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -15,24 +15,24 @@ export function createMapeoServer(manager, messagePort) { const managerServer = createServer(manager, managerChannel) - managerChannel.on('message', async (payload) => { + messagePort.on('message', async (payload) => { // TODO: figure out better way to know that this is the project public id - const projectPublicId = payload[payload.length - 1] + const id = payload?.id + if (typeof id !== 'string' || id === '@@manager') return - if (typeof projectPublicId !== 'string') return - if (existing.has(projectPublicId)) return + if (existing.has(id)) return - const projectChannel = new SubChannel(messagePort, projectPublicId) + const projectChannel = new SubChannel(messagePort, id) const project = await manager.getProject( - /** @type {import('../types.js').ProjectPublicId} */ (projectPublicId) + /** @type {import('../types.js').ProjectPublicId} */ (id) ) const { close } = createServer(project, projectChannel) - projectChannel.emit('message', payload) + projectChannel.emit('message', payload.message) - existing.set(projectPublicId, { close, project }) + existing.set(id, { close, project }) }) return managerServer From 9313f48b49206c362ae2b93d6bef1f1a02da0d12 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Wed, 13 Sep 2023 10:40:30 -0400 Subject: [PATCH 04/28] fix test --- test-e2e/ipc-wrapper.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index 2f72ec67..cc9fdc45 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -2,9 +2,9 @@ import { test } from 'brittle' import { MessageChannel } from 'node:worker_threads' import RAM from 'random-access-memory' import { KeyManager } from '@mapeo/crypto' +import { createClient } from 'rpc-reflector' import { createMapeoServer } from '../src/ipc-wrapper/server.js' import { MapeoManager } from '../src/mapeo-manager.js' -import { createClient } from 'rpc-reflector' import { createMapeoClient } from '../src/ipc-wrapper/client.js' test('IPC wrappers work', async (t) => { @@ -32,7 +32,7 @@ test('IPC wrappers work', async (t) => { const projectSettings = await project.$getProjectSettings() - t.alike(projectSettings, { name: 'mapeo' }) + t.alike(projectSettings, { name: 'mapeo', defaultPresets: undefined }) server.close() createClient.close(client) From 077edbf3200afefa9728526cef5e482cb2feb916 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Wed, 13 Sep 2023 10:41:24 -0400 Subject: [PATCH 05/28] remove todo comment --- src/ipc-wrapper/server.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index bc47bd59..62dc9288 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -16,7 +16,6 @@ export function createMapeoServer(manager, messagePort) { const managerServer = createServer(manager, managerChannel) messagePort.on('message', async (payload) => { - // TODO: figure out better way to know that this is the project public id const id = payload?.id if (typeof id !== 'string' || id === '@@manager') return From 79252cbcb97460c3d9c5c99c9eef54590e078c14 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Wed, 13 Sep 2023 13:21:12 -0400 Subject: [PATCH 06/28] wip: handle server closing test for this is currently failing. case with client.getProject is not behaving as expected --- src/ipc-wrapper/server.js | 31 ++++++++++++++++++++++------- test-e2e/ipc-wrapper.js | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index 62dc9288..f475e5d3 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -9,17 +9,36 @@ import { SubChannel } from './sub-channel.js' export function createMapeoServer(manager, messagePort) { // TODO: LRU? project.close() after time without use? /** @type {Map void, project: import('../mapeo-project.js').MapeoProject }>}*/ - const existing = new Map() + const existingProjectServers = new Map() const managerChannel = new SubChannel(messagePort, '@@manager') const managerServer = createServer(manager, managerChannel) - messagePort.on('message', async (payload) => { + messagePort.on('message', handleMessage) + + return { + close() { + messagePort.off('message', handleMessage) + + for (const [id, server] of existingProjectServers.entries()) { + server.close() + existingProjectServers.delete(id) + } + + managerServer.close() + }, + } + + /** + * @param {any} payload + */ + async function handleMessage(payload) { const id = payload?.id + if (typeof id !== 'string' || id === '@@manager') return - if (existing.has(id)) return + if (existingProjectServers.has(id)) return const projectChannel = new SubChannel(messagePort, id) @@ -31,8 +50,6 @@ export function createMapeoServer(manager, messagePort) { projectChannel.emit('message', payload.message) - existing.set(id, { close, project }) - }) - - return managerServer + existingProjectServers.set(id, { close, project }) + } } diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index cc9fdc45..c5cad739 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -40,3 +40,44 @@ test('IPC wrappers work', async (t) => { port1.close() port2.close() }) + +test('Client calls fail after server closes', async (t) => { + const { port1, port2 } = new MessageChannel() + + const manager = new MapeoManager({ + rootKey: KeyManager.generateRootKey(), + dbFolder: ':memory:', + coreStorage: () => new RAM(), + }) + + const server = createMapeoServer(manager, port1) + const client = createMapeoClient(port2) + + port1.start() + port2.start() + + const projectId = await client.createProject({ name: 'mapeo' }) + const project = await client.getProject(projectId) + + await project.$getProjectSettings() + + server.close() + + // Doing it this way to speed up the test because each should wait for a timeout + const results = await Promise.allSettled([ + // Test client method that returns a normal value + client.listProjects(), + // Test client method that returns a proxied value (special case) + client.getProject(projectId), + // Test project method that returns a normal value + project.$getProjectSettings(), + ]) + + for (const result of results) { + // @ts-ignore + t.is(result.status, 'rejected', result.reason) + } + + port1.close() + port2.close() +}) From 9f6a7a5749f1b4c47ec4a1ffc44a18d29447bcc9 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Thu, 14 Sep 2023 11:17:26 -0400 Subject: [PATCH 07/28] fixes to SubChannel implementation --- src/ipc-wrapper/client.js | 12 +++-- src/ipc-wrapper/server.js | 30 +++++++----- src/ipc-wrapper/sub-channel.js | 90 +++++++++++++++++++++++++++++++--- src/ipc-wrapper/utils.js | 15 ++++++ test-e2e/ipc-wrapper.js | 27 +++++++--- 5 files changed, 145 insertions(+), 29 deletions(-) create mode 100644 src/ipc-wrapper/utils.js diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index dee35a61..5f338d2b 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -1,21 +1,23 @@ // @ts-check import { createClient } from 'rpc-reflector' -import { SubChannel } from './sub-channel.js' +import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' /** - * @param {import('rpc-reflector/client.js').MessagePortLike} messagePort + * @param {import('./sub-channel.js').MessagePortLike} messagePort * @returns {import('rpc-reflector/client.js').ClientApi} */ export function createMapeoClient(messagePort) { - // TODO: LRU cache? + // TODO: Use LRU cache? /** @type {Map>} */ const existingProjectClients = new Map() - const managerChannel = new SubChannel(messagePort, '@@manager') + const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) /** @type {import('rpc-reflector').ClientApi} */ const managerClient = createClient(managerChannel) + managerChannel.start() + const client = new Proxy(managerClient, { get(target, prop, receiver) { if (prop === 'getProject') { @@ -45,6 +47,8 @@ export function createMapeoClient(messagePort) { }, }) + projectChannel.start() + existingProjectClients.set(projectPublicId, projectClient) return Promise.resolve(projectClient) diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index f475e5d3..56dd9b6d 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -1,28 +1,32 @@ // @ts-check import { createServer } from 'rpc-reflector' -import { SubChannel } from './sub-channel.js' +import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' +import { extractMessageEventData } from './utils.js' /** * @param {import('../mapeo-manager.js').MapeoManager} manager - * @param {import('rpc-reflector/server.js').MessagePortLike} messagePort + * @param {import('./sub-channel.js').MessagePortLike} messagePort */ export function createMapeoServer(manager, messagePort) { - // TODO: LRU? project.close() after time without use? - /** @type {Map void, project: import('../mapeo-project.js').MapeoProject }>}*/ + // TODO: Use LRU cache and call project.close() after time without use? + /** @type {Map void, channel: SubChannel }>}*/ const existingProjectServers = new Map() - const managerChannel = new SubChannel(messagePort, '@@manager') + const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) const managerServer = createServer(manager, managerChannel) - messagePort.on('message', handleMessage) + managerChannel.start() + + messagePort.addEventListener('message', handleMessageEvent) return { close() { - messagePort.off('message', handleMessage) + messagePort.removeEventListener('message', handleMessageEvent) for (const [id, server] of existingProjectServers.entries()) { server.close() + server.channel.close() existingProjectServers.delete(id) } @@ -33,8 +37,10 @@ export function createMapeoServer(manager, messagePort) { /** * @param {any} payload */ - async function handleMessage(payload) { - const id = payload?.id + async function handleMessageEvent(payload) { + const data = extractMessageEventData(payload) + + const id = data?.id if (typeof id !== 'string' || id === '@@manager') return @@ -48,8 +54,10 @@ export function createMapeoServer(manager, messagePort) { const { close } = createServer(project, projectChannel) - projectChannel.emit('message', payload.message) + existingProjectServers.set(id, { close, channel: projectChannel }) + + projectChannel.emit('message', data.message) - existingProjectServers.set(id, { close, project }) + projectChannel.start() } } diff --git a/src/ipc-wrapper/sub-channel.js b/src/ipc-wrapper/sub-channel.js index 97a1a432..3ce7ac55 100644 --- a/src/ipc-wrapper/sub-channel.js +++ b/src/ipc-wrapper/sub-channel.js @@ -1,20 +1,34 @@ // @ts-check import { TypedEmitter } from 'tiny-typed-emitter' +import { extractMessageEventData } from './utils.js' + +export const MANAGER_CHANNEL_ID = '@@manager' /** * @typedef {Object} Events * @property {(message: any) => void} message */ +/** + * Node's built-in types for MessagePort are misleading so we opt for this limited type definition + * that fits our usage and works in both Node and browser contexts + * @typedef {EventTarget & { postMessage: (message: any) => void}} MessagePortLike + */ + /** * @extends {TypedEmitter} */ export class SubChannel extends TypedEmitter { #id #messagePort + /** @type {'idle' | 'active' | 'closed'} */ + #state + /** @type {Array<{id: string, message: any}>} */ + #queued + #handleMessageEvent /** - * @param {import('rpc-reflector/server.js').MessagePortLike} messagePort Parent channel to add namespace to + * @param {MessagePortLike} messagePort Parent channel to add namespace to * @param {string} id ID for the subchannel */ constructor(messagePort, id) { @@ -22,12 +36,42 @@ export class SubChannel extends TypedEmitter { this.#id = id this.#messagePort = messagePort + this.#state = 'idle' + this.#queued = [] + + /** + * @param {unknown} event + */ + this.#handleMessageEvent = (event) => { + const value = extractMessageEventData(event) + + if (!isRelevantEvent(value)) return - // Listen to all messages on the shared channel but only handle the relevant ones - this.#messagePort.on('message', ({ id, message }) => { - if (this.#id !== id) return - this.emit('message', message) - }) + switch (this.#state) { + case 'idle': { + this.#queued.push(value) + break + } + case 'active': { + const { id, message } = value + + if (this.#id !== id) return + this.emit('message', message) + + break + } + case 'closed': { + // no-op if closed (the event listener should be removed anyway) + break + } + } + } + + this.#messagePort.addEventListener('message', this.#handleMessageEvent) + } + + get id() { + return this.#id } /** @@ -37,4 +81,38 @@ export class SubChannel extends TypedEmitter { postMessage(message) { this.#messagePort.postMessage({ id: this.#id, message }) } + + start() { + if (this.#state !== 'idle') return + + this.#state = 'active' + + /** @type {{id: string, message: any} | undefined} */ + let event + while ((event = this.#queued.shift())) { + this.#handleMessageEvent(event) + } + } + + close() { + if (this.#state !== 'closed') return + + this.#state = 'closed' + this.#queued = [] + + // Node types are incorrect (as of v14, Node's MessagePort should also extend [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget)) + this.#messagePort.removeEventListener('message', this.#handleMessageEvent) + } +} + +/** + * @param {unknown} event + * @returns {event is { id: string, message: any }} + */ +function isRelevantEvent(event) { + if (!event || typeof event !== 'object') return false + if (!('id' in event && 'message' in event)) return false + if (typeof event.id !== 'string') return false + + return true } diff --git a/src/ipc-wrapper/utils.js b/src/ipc-wrapper/utils.js new file mode 100644 index 00000000..576bbb2f --- /dev/null +++ b/src/ipc-wrapper/utils.js @@ -0,0 +1,15 @@ +/** + * @template T + * @param {T} event + * @returns {T extends { data: infer D } ? D : T} + */ +export function extractMessageEventData(event) { + // In browser-like contexts, the actual payload will live in the `event.data` field + // https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/message_event#event_properties + if (event && typeof event === 'object' && 'data' in event) { + return /** @type {any} */ (event.data) + } + + // In Node the event is the actual data that was sent + return /** @type {any} */ (event) +} diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index c5cad739..2a5c43d9 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -1,5 +1,5 @@ import { test } from 'brittle' -import { MessageChannel } from 'node:worker_threads' +import { MessageChannel, MessagePort } from 'node:worker_threads' import RAM from 'random-access-memory' import { KeyManager } from '@mapeo/crypto' import { createClient } from 'rpc-reflector' @@ -16,7 +16,10 @@ test('IPC wrappers work', async (t) => { coreStorage: () => new RAM(), }) + // Since v14.7.0, Node's MessagePort extends EventTarget (https://nodejs.org/api/worker_threads.html#class-messageport) + // @ts-expect-error const server = createMapeoServer(manager, port1) + // @ts-expect-error const client = createMapeoClient(port2) port1.start() @@ -50,27 +53,35 @@ test('Client calls fail after server closes', async (t) => { coreStorage: () => new RAM(), }) + // Since v14.7.0, Node's MessagePort extends EventTarget (https://nodejs.org/api/worker_threads.html#class-messageport) + // @ts-expect-error const server = createMapeoServer(manager, port1) + // @ts-expect-error const client = createMapeoClient(port2) port1.start() port2.start() const projectId = await client.createProject({ name: 'mapeo' }) - const project = await client.getProject(projectId) + const projectBefore = await client.getProject(projectId) - await project.$getProjectSettings() + await projectBefore.$getProjectSettings() server.close() + createClient.close(client) + const projectAfter = await client.getProject(projectId) + + // Even after server closes we're still able to get the project ipc instance, which is okay + // because any field access should fail on that, rendering it unusable + // Adding this assertion to track changes in this behavior + t.ok(projectAfter) + // Doing it this way to speed up the test because each should wait for a timeout + // Attempting to access any fields on the ipc instances should fail (aside from client.getProject, which is tested above) const results = await Promise.allSettled([ - // Test client method that returns a normal value client.listProjects(), - // Test client method that returns a proxied value (special case) - client.getProject(projectId), - // Test project method that returns a normal value - project.$getProjectSettings(), + projectBefore.$getProjectSettings(), ]) for (const result of results) { From c3139c6f92ee64de84aded91dba4a57410e2143e Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Thu, 14 Sep 2023 12:50:25 -0400 Subject: [PATCH 08/28] remove unused import --- test-e2e/ipc-wrapper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index 2a5c43d9..ea6b84ef 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -1,5 +1,5 @@ import { test } from 'brittle' -import { MessageChannel, MessagePort } from 'node:worker_threads' +import { MessageChannel } from 'node:worker_threads' import RAM from 'random-access-memory' import { KeyManager } from '@mapeo/crypto' import { createClient } from 'rpc-reflector' From 32c5a01702c6e4a758f582a1828842e3f1a1f32e Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Thu, 14 Sep 2023 13:17:03 -0400 Subject: [PATCH 09/28] use LRU for project ipc instances --- package-lock.json | 34 +++++++++++++++++++++++++++++----- package.json | 1 + src/ipc-wrapper/client.js | 28 ++++++++++++++++++++-------- src/ipc-wrapper/server.js | 15 ++++++++++++--- 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8dac12b0..95e476b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,7 @@ "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", + "quick-lru": "^7.0.0", "quickbit-universal": "^2.2.0", "rpc-reflector": "^1.3.10", "sodium-universal": "^4.0.0", @@ -1840,6 +1841,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-keys/node_modules/quick-lru": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz", + "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/camelcase-keys/node_modules/type-fest": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", @@ -2299,6 +2312,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/decamelize-keys/node_modules/quick-lru": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz", + "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/decompress-response": { "version": "6.0.0", "license": "MIT", @@ -6177,12 +6202,11 @@ "dev": true }, "node_modules/quick-lru": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.1.tgz", - "integrity": "sha512-S27GBT+F0NTRiehtbrgaSE1idUAJ5bX8dPAQTdylEyNlrdcH5X4Lz7Edz3DYzecbsCluD5zO8ZNEe04z3D3u6Q==", - "dev": true, + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-7.0.0.tgz", + "integrity": "sha512-MX8gB7cVYTrYcFfAnfLlhRd0+Toyl8yX8uBx1MrX7K0jegiz9TumwOK27ldXrgDlHRdVi+MqU9Ssw6dr4BNreg==", "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/package.json b/package.json index dbdc3115..9b71b2e7 100644 --- a/package.json +++ b/package.json @@ -123,6 +123,7 @@ "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", + "quick-lru": "^7.0.0", "quickbit-universal": "^2.2.0", "rpc-reflector": "^1.3.10", "sodium-universal": "^4.0.0", diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index 5f338d2b..365bb5a4 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -1,15 +1,24 @@ // @ts-check import { createClient } from 'rpc-reflector' +import QuickLRU from 'quick-lru' import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' +const PROJECT_CLIENT_MAX_AGE = 1000 * 60 * 60 // 1 hour + /** * @param {import('./sub-channel.js').MessagePortLike} messagePort * @returns {import('rpc-reflector/client.js').ClientApi} */ export function createMapeoClient(messagePort) { - // TODO: Use LRU cache? - /** @type {Map>} */ - const existingProjectClients = new Map() + /** @type {QuickLRU, channel: SubChannel }>} */ + const existingProjectClients = new QuickLRU({ + maxSize: 3, + maxAge: PROJECT_CLIENT_MAX_AGE, + onEviction: (_id, { instance, channel }) => { + createClient.close(instance) + channel.close() + }, + }) const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) @@ -33,15 +42,15 @@ export function createMapeoClient(messagePort) { function createProjectClient(projectPublicId) { const existingClient = existingProjectClients.get(projectPublicId) - if (existingClient) return Promise.resolve(existingClient) + if (existingClient) return Promise.resolve(existingClient.instance) const projectChannel = new SubChannel(messagePort, projectPublicId) /** @type {import('rpc-reflector').ClientApi} */ - const projectClient = new Proxy(createClient(projectChannel), { + const projectClientProxy = new Proxy(createClient(projectChannel), { get(target, prop, receiver) { if (prop === 'then') { - return projectClient + return projectClientProxy } return Reflect.get(target, prop, receiver) }, @@ -49,9 +58,12 @@ export function createMapeoClient(messagePort) { projectChannel.start() - existingProjectClients.set(projectPublicId, projectClient) + existingProjectClients.set(projectPublicId, { + instance: projectClientProxy, + channel: projectChannel, + }) - return Promise.resolve(projectClient) + return Promise.resolve(projectClientProxy) } }, }) diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index 56dd9b6d..b2aad1b0 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -1,16 +1,25 @@ // @ts-check import { createServer } from 'rpc-reflector' +import QuickLRU from 'quick-lru' import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' import { extractMessageEventData } from './utils.js' +const PROJECT_SERVER_MAX_AGE = 1000 * 60 * 60 // 1 hour + /** * @param {import('../mapeo-manager.js').MapeoManager} manager * @param {import('./sub-channel.js').MessagePortLike} messagePort */ export function createMapeoServer(manager, messagePort) { - // TODO: Use LRU cache and call project.close() after time without use? - /** @type {Map void, channel: SubChannel }>}*/ - const existingProjectServers = new Map() + /** @type {QuickLRU void, channel: SubChannel }>} */ + const existingProjectServers = new QuickLRU({ + maxAge: PROJECT_SERVER_MAX_AGE, + maxSize: 3, + onEviction: (_id, server) => { + server.close() + server.channel.close() + }, + }) const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) From e9cdec4310f1dc840e7436086c5050865fc55e7c Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Thu, 14 Sep 2023 13:21:08 -0400 Subject: [PATCH 10/28] close server side manager channel --- src/ipc-wrapper/server.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index b2aad1b0..ca138014 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -40,6 +40,7 @@ export function createMapeoServer(manager, messagePort) { } managerServer.close() + managerChannel.close() }, } From c7fe50f72fabc9240ea392067443941414c8d33c Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Thu, 14 Sep 2023 14:13:14 -0400 Subject: [PATCH 11/28] whitespace fix --- src/ipc-wrapper/sub-channel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipc-wrapper/sub-channel.js b/src/ipc-wrapper/sub-channel.js index 3ce7ac55..b0d48e83 100644 --- a/src/ipc-wrapper/sub-channel.js +++ b/src/ipc-wrapper/sub-channel.js @@ -12,7 +12,7 @@ export const MANAGER_CHANNEL_ID = '@@manager' /** * Node's built-in types for MessagePort are misleading so we opt for this limited type definition * that fits our usage and works in both Node and browser contexts - * @typedef {EventTarget & { postMessage: (message: any) => void}} MessagePortLike + * @typedef {EventTarget & { postMessage: (message: any) => void }} MessagePortLike */ /** From e067dc37cf03f4b76671324edab73052cf4f5499 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Thu, 14 Sep 2023 14:16:27 -0400 Subject: [PATCH 12/28] use eventemitter3 for SubChannel implementation to work in browser --- package-lock.json | 1 + package.json | 1 + src/ipc-wrapper/sub-channel.js | 7 ++----- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 95e476b6..896e4873 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "compact-encoding": "^2.12.0", "corestore": "^6.8.4", "drizzle-orm": "0.28.2", + "eventemitter3": "^5.0.1", "fastify-plugin": "^4.5.0", "hypercore": "^10.9.0", "hypercore-crypto": "^3.3.1", diff --git a/package.json b/package.json index 9b71b2e7..80542806 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "compact-encoding": "^2.12.0", "corestore": "^6.8.4", "drizzle-orm": "0.28.2", + "eventemitter3": "^5.0.1", "fastify-plugin": "^4.5.0", "hypercore": "^10.9.0", "hypercore-crypto": "^3.3.1", diff --git a/src/ipc-wrapper/sub-channel.js b/src/ipc-wrapper/sub-channel.js index b0d48e83..0b17b105 100644 --- a/src/ipc-wrapper/sub-channel.js +++ b/src/ipc-wrapper/sub-channel.js @@ -1,5 +1,5 @@ // @ts-check -import { TypedEmitter } from 'tiny-typed-emitter' +import { EventEmitter } from 'eventemitter3' import { extractMessageEventData } from './utils.js' export const MANAGER_CHANNEL_ID = '@@manager' @@ -15,10 +15,7 @@ export const MANAGER_CHANNEL_ID = '@@manager' * @typedef {EventTarget & { postMessage: (message: any) => void }} MessagePortLike */ -/** - * @extends {TypedEmitter} - */ -export class SubChannel extends TypedEmitter { +export class SubChannel extends EventEmitter { #id #messagePort /** @type {'idle' | 'active' | 'closed'} */ From 892b6539e433ed0082fc5c0f62ec694d45be21fe Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Mon, 18 Sep 2023 11:40:43 -0400 Subject: [PATCH 13/28] remove usage of LRU cache --- package-lock.json | 12 ------------ package.json | 1 - src/ipc-wrapper/client.js | 14 ++------------ src/ipc-wrapper/server.js | 14 ++------------ 4 files changed, 4 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index a8bf9124..d25aa567 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,6 @@ "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", - "quick-lru": "^7.0.0", "quickbit-universal": "^2.2.0", "rpc-reflector": "^1.3.10", "sodium-universal": "^4.0.0", @@ -5990,17 +5989,6 @@ "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", "dev": true }, - "node_modules/quick-lru": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-7.0.0.tgz", - "integrity": "sha512-MX8gB7cVYTrYcFfAnfLlhRd0+Toyl8yX8uBx1MrX7K0jegiz9TumwOK27ldXrgDlHRdVi+MqU9Ssw6dr4BNreg==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/quickbit-native": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/quickbit-native/-/quickbit-native-2.2.0.tgz", diff --git a/package.json b/package.json index bc9ce6e3..ccd501df 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,6 @@ "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", - "quick-lru": "^7.0.0", "quickbit-universal": "^2.2.0", "rpc-reflector": "^1.3.10", "sodium-universal": "^4.0.0", diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index 365bb5a4..0ce2e684 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -1,24 +1,14 @@ // @ts-check import { createClient } from 'rpc-reflector' -import QuickLRU from 'quick-lru' import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' -const PROJECT_CLIENT_MAX_AGE = 1000 * 60 * 60 // 1 hour - /** * @param {import('./sub-channel.js').MessagePortLike} messagePort * @returns {import('rpc-reflector/client.js').ClientApi} */ export function createMapeoClient(messagePort) { - /** @type {QuickLRU, channel: SubChannel }>} */ - const existingProjectClients = new QuickLRU({ - maxSize: 3, - maxAge: PROJECT_CLIENT_MAX_AGE, - onEviction: (_id, { instance, channel }) => { - createClient.close(instance) - channel.close() - }, - }) + /** @type {Map, channel: SubChannel }>} */ + const existingProjectClients = new Map() const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index ca138014..a3845444 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -1,25 +1,15 @@ // @ts-check import { createServer } from 'rpc-reflector' -import QuickLRU from 'quick-lru' import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' import { extractMessageEventData } from './utils.js' -const PROJECT_SERVER_MAX_AGE = 1000 * 60 * 60 // 1 hour - /** * @param {import('../mapeo-manager.js').MapeoManager} manager * @param {import('./sub-channel.js').MessagePortLike} messagePort */ export function createMapeoServer(manager, messagePort) { - /** @type {QuickLRU void, channel: SubChannel }>} */ - const existingProjectServers = new QuickLRU({ - maxAge: PROJECT_SERVER_MAX_AGE, - maxSize: 3, - onEviction: (_id, server) => { - server.close() - server.channel.close() - }, - }) + /** @type {Map void, channel: SubChannel }>} */ + const existingProjectServers = new Map() const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) From 71a8398c522e298001b3de239ed2d81e92ebf8f1 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Mon, 18 Sep 2023 11:51:10 -0400 Subject: [PATCH 14/28] expose close function for client --- src/ipc-wrapper/client.js | 22 ++++++++++++++++++++-- test-e2e/ipc-wrapper.js | 10 ++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index 0ce2e684..5328bd92 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -2,6 +2,8 @@ import { createClient } from 'rpc-reflector' import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' +const CLOSE = Symbol('close') + /** * @param {import('./sub-channel.js').MessagePortLike} messagePort * @returns {import('rpc-reflector/client.js').ClientApi} @@ -19,12 +21,19 @@ export function createMapeoClient(messagePort) { const client = new Proxy(managerClient, { get(target, prop, receiver) { + if (prop === CLOSE) { + return () => { + managerChannel.close() + createClient.close(managerClient) + } + } + if (prop === 'getProject') { return createProjectClient - } else { - return Reflect.get(target, prop, receiver) } + return Reflect.get(target, prop, receiver) + /** * @param {import('../types.js').ProjectPublicId} projectPublicId * @returns {Promise>} @@ -60,3 +69,12 @@ export function createMapeoClient(messagePort) { return client } + +/** + * @param {import('rpc-reflector').ClientApi} client client created with `createMapeoClient` + * @returns {void} + */ +export function closeMapeoClient(client) { + // @ts-expect-error + return client[CLOSE]() +} diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index ea6b84ef..014a9850 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -2,10 +2,12 @@ import { test } from 'brittle' import { MessageChannel } from 'node:worker_threads' import RAM from 'random-access-memory' import { KeyManager } from '@mapeo/crypto' -import { createClient } from 'rpc-reflector' import { createMapeoServer } from '../src/ipc-wrapper/server.js' import { MapeoManager } from '../src/mapeo-manager.js' -import { createMapeoClient } from '../src/ipc-wrapper/client.js' +import { + createMapeoClient, + closeMapeoClient, +} from '../src/ipc-wrapper/client.js' test('IPC wrappers work', async (t) => { const { port1, port2 } = new MessageChannel() @@ -38,7 +40,7 @@ test('IPC wrappers work', async (t) => { t.alike(projectSettings, { name: 'mapeo', defaultPresets: undefined }) server.close() - createClient.close(client) + closeMapeoClient(client) port1.close() port2.close() @@ -69,7 +71,7 @@ test('Client calls fail after server closes', async (t) => { server.close() - createClient.close(client) + closeMapeoClient(client) const projectAfter = await client.getProject(projectId) // Even after server closes we're still able to get the project ipc instance, which is okay From fd58298a81bb2dae703bcd11ec76213b41d19863 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Mon, 18 Sep 2023 12:02:25 -0400 Subject: [PATCH 15/28] move createProjectClient function --- src/ipc-wrapper/client.js | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index 5328bd92..d27ba971 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -33,41 +33,41 @@ export function createMapeoClient(messagePort) { } return Reflect.get(target, prop, receiver) + }, + }) - /** - * @param {import('../types.js').ProjectPublicId} projectPublicId - * @returns {Promise>} - */ - function createProjectClient(projectPublicId) { - const existingClient = existingProjectClients.get(projectPublicId) + return client - if (existingClient) return Promise.resolve(existingClient.instance) + /** + * @param {import('../types.js').ProjectPublicId} projectPublicId + * @returns {Promise>} + */ + function createProjectClient(projectPublicId) { + const existingClient = existingProjectClients.get(projectPublicId) - const projectChannel = new SubChannel(messagePort, projectPublicId) + if (existingClient) return Promise.resolve(existingClient.instance) - /** @type {import('rpc-reflector').ClientApi} */ - const projectClientProxy = new Proxy(createClient(projectChannel), { - get(target, prop, receiver) { - if (prop === 'then') { - return projectClientProxy - } - return Reflect.get(target, prop, receiver) - }, - }) + const projectChannel = new SubChannel(messagePort, projectPublicId) - projectChannel.start() + /** @type {import('rpc-reflector').ClientApi} */ + const projectClientProxy = new Proxy(createClient(projectChannel), { + get(target, prop, receiver) { + if (prop === 'then') { + return projectClientProxy + } + return Reflect.get(target, prop, receiver) + }, + }) - existingProjectClients.set(projectPublicId, { - instance: projectClientProxy, - channel: projectChannel, - }) + projectChannel.start() - return Promise.resolve(projectClientProxy) - } - }, - }) + existingProjectClients.set(projectPublicId, { + instance: projectClientProxy, + channel: projectChannel, + }) - return client + return Promise.resolve(projectClientProxy) + } } /** From 612f06869c18049e1e34916cf9cf7e307e02549c Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Mon, 18 Sep 2023 15:04:36 -0400 Subject: [PATCH 16/28] small fix to SubChannel --- src/ipc-wrapper/sub-channel.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ipc-wrapper/sub-channel.js b/src/ipc-wrapper/sub-channel.js index 0b17b105..031f7c1b 100644 --- a/src/ipc-wrapper/sub-channel.js +++ b/src/ipc-wrapper/sub-channel.js @@ -44,17 +44,17 @@ export class SubChannel extends EventEmitter { if (!isRelevantEvent(value)) return + const { id, message } = value + + if (this.#id !== id) return + switch (this.#state) { case 'idle': { this.#queued.push(value) break } case 'active': { - const { id, message } = value - - if (this.#id !== id) return this.emit('message', message) - break } case 'closed': { From ada1aba341b0dfe68e4881830199663674bea157 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Mon, 18 Sep 2023 15:15:45 -0400 Subject: [PATCH 17/28] clean up tests --- test-e2e/ipc-wrapper.js | 77 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index 014a9850..d8a99c23 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -10,22 +10,7 @@ import { } from '../src/ipc-wrapper/client.js' test('IPC wrappers work', async (t) => { - const { port1, port2 } = new MessageChannel() - - const manager = new MapeoManager({ - rootKey: KeyManager.generateRootKey(), - dbFolder: ':memory:', - coreStorage: () => new RAM(), - }) - - // Since v14.7.0, Node's MessagePort extends EventTarget (https://nodejs.org/api/worker_threads.html#class-messageport) - // @ts-expect-error - const server = createMapeoServer(manager, port1) - // @ts-expect-error - const client = createMapeoClient(port2) - - port1.start() - port2.start() + const { client, cleanup } = setup() const projectId = await client.createProject({ name: 'mapeo' }) @@ -39,30 +24,11 @@ test('IPC wrappers work', async (t) => { t.alike(projectSettings, { name: 'mapeo', defaultPresets: undefined }) - server.close() - closeMapeoClient(client) - - port1.close() - port2.close() + return cleanup() }) test('Client calls fail after server closes', async (t) => { - const { port1, port2 } = new MessageChannel() - - const manager = new MapeoManager({ - rootKey: KeyManager.generateRootKey(), - dbFolder: ':memory:', - coreStorage: () => new RAM(), - }) - - // Since v14.7.0, Node's MessagePort extends EventTarget (https://nodejs.org/api/worker_threads.html#class-messageport) - // @ts-expect-error - const server = createMapeoServer(manager, port1) - // @ts-expect-error - const client = createMapeoClient(port2) - - port1.start() - port2.start() + const { client, server, cleanup } = setup() const projectId = await client.createProject({ name: 'mapeo' }) const projectBefore = await client.getProject(projectId) @@ -70,8 +36,8 @@ test('Client calls fail after server closes', async (t) => { await projectBefore.$getProjectSettings() server.close() - closeMapeoClient(client) + const projectAfter = await client.getProject(projectId) // Even after server closes we're still able to get the project ipc instance, which is okay @@ -91,6 +57,37 @@ test('Client calls fail after server closes', async (t) => { t.is(result.status, 'rejected', result.reason) } - port1.close() - port2.close() + return cleanup() }) + +function setup() { + const { port1, port2 } = new MessageChannel() + + const manager = new MapeoManager({ + rootKey: KeyManager.generateRootKey(), + dbFolder: ':memory:', + coreStorage: () => new RAM(), + }) + + // Since v14.7.0, Node's MessagePort extends EventTarget (https://nodejs.org/api/worker_threads.html#class-messageport) + // @ts-expect-error + const server = createMapeoServer(manager, port1) + // @ts-expect-error + const client = createMapeoClient(port2) + + port1.start() + port2.start() + + return { + port1, + port2, + server, + client, + cleanup: () => { + server.close() + closeMapeoClient(client) + port1.close() + port2.close() + }, + } +} From 77cdf54b05dcab3247c6c48eb178c4fc50070555 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Mon, 18 Sep 2023 16:11:36 -0400 Subject: [PATCH 18/28] use constant --- src/ipc-wrapper/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index a3845444..bfe074a9 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -42,7 +42,7 @@ export function createMapeoServer(manager, messagePort) { const id = data?.id - if (typeof id !== 'string' || id === '@@manager') return + if (typeof id !== 'string' || id === MANAGER_CHANNEL_ID) return if (existingProjectServers.has(id)) return From b7e98da58adab73cf23704734ea2cd7fa8891243 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Mon, 18 Sep 2023 17:14:08 -0400 Subject: [PATCH 19/28] handle getProject calls failing on server side --- package-lock.json | 22 +++++++++--- package.json | 1 + src/ipc-wrapper/client.js | 49 ++++++++++++++++++++----- src/ipc-wrapper/server.js | 65 +++++++++++++++++++++------------- src/ipc-wrapper/sub-channel.js | 4 ++- src/ipc-wrapper/utils.js | 10 ++++++ test-e2e/ipc-wrapper.js | 11 ++++++ 7 files changed, 123 insertions(+), 39 deletions(-) diff --git a/package-lock.json b/package-lock.json index d25aa567..858e8c1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "multi-core-indexer": "^1.0.0-alpha.7", "multicast-service-discovery": "^4.0.4", "p-defer": "^4.0.0", + "p-timeout": "^6.1.2", "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", @@ -5466,6 +5467,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-event/node_modules/p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-filter": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", @@ -5537,12 +5550,11 @@ } }, "node_modules/p-timeout": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", - "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", - "dev": true, + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", + "integrity": "sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==", "engines": { - "node": ">=12" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/package.json b/package.json index ccd501df..043e7d87 100644 --- a/package.json +++ b/package.json @@ -119,6 +119,7 @@ "multi-core-indexer": "^1.0.0-alpha.7", "multicast-service-discovery": "^4.0.4", "p-defer": "^4.0.0", + "p-timeout": "^6.1.2", "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index d27ba971..5f2ccb13 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -1,6 +1,7 @@ // @ts-check import { createClient } from 'rpc-reflector' -import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' +import pTimeout from 'p-timeout' +import { MANAGER_CHANNEL_ID, MAPEO_IPC_ID, SubChannel } from './sub-channel.js' const CLOSE = Symbol('close') @@ -12,17 +13,20 @@ export function createMapeoClient(messagePort) { /** @type {Map, channel: SubChannel }>} */ const existingProjectClients = new Map() + const mapeoIpcChannel = new SubChannel(messagePort, MAPEO_IPC_ID) + mapeoIpcChannel.start() + const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) + managerChannel.start() /** @type {import('rpc-reflector').ClientApi} */ const managerClient = createClient(managerChannel) - managerChannel.start() - const client = new Proxy(managerClient, { get(target, prop, receiver) { if (prop === CLOSE) { return () => { + mapeoIpcChannel.close() managerChannel.close() createClient.close(managerClient) } @@ -42,13 +46,44 @@ export function createMapeoClient(messagePort) { * @param {import('../types.js').ProjectPublicId} projectPublicId * @returns {Promise>} */ - function createProjectClient(projectPublicId) { + async function createProjectClient(projectPublicId) { const existingClient = existingProjectClients.get(projectPublicId) - if (existingClient) return Promise.resolve(existingClient.instance) + if (existingClient) return existingClient.instance + + // Wait for the server to confirm that it could retrieve the desired project + await pTimeout( + new Promise((res, rej) => { + mapeoIpcChannel.on( + 'message', + /** + * @param {import('./utils.js').MapeoIpcMessagePayload} payload + */ + function handleGetProjectResponse(payload) { + const { type, projectId, error } = payload + + if (type !== 'get_project') return + if (projectId !== projectPublicId) return + + mapeoIpcChannel.off('message', handleGetProjectResponse) + + if (error) rej(new Error(error)) + else res(null) + } + ) + + mapeoIpcChannel.postMessage({ + type: 'get_project', + projectId: projectPublicId, + }) + }), + { milliseconds: 3000 } + ) const projectChannel = new SubChannel(messagePort, projectPublicId) + projectChannel.start() + /** @type {import('rpc-reflector').ClientApi} */ const projectClientProxy = new Proxy(createClient(projectChannel), { get(target, prop, receiver) { @@ -59,14 +94,12 @@ export function createMapeoClient(messagePort) { }, }) - projectChannel.start() - existingProjectClients.set(projectPublicId, { instance: projectClientProxy, channel: projectChannel, }) - return Promise.resolve(projectClientProxy) + return projectClientProxy } } diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index bfe074a9..f67f8036 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -1,7 +1,6 @@ // @ts-check import { createServer } from 'rpc-reflector' -import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' -import { extractMessageEventData } from './utils.js' +import { MANAGER_CHANNEL_ID, MAPEO_IPC_ID, SubChannel } from './sub-channel.js' /** * @param {import('../mapeo-manager.js').MapeoManager} manager @@ -11,17 +10,19 @@ export function createMapeoServer(manager, messagePort) { /** @type {Map void, channel: SubChannel }>} */ const existingProjectServers = new Map() - const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) + const mapeoIpcChannel = new SubChannel(messagePort, MAPEO_IPC_ID) + mapeoIpcChannel.start() - const managerServer = createServer(manager, managerChannel) + mapeoIpcChannel.on('message', handleGetProject) + const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) managerChannel.start() - messagePort.addEventListener('message', handleMessageEvent) + const managerServer = createServer(manager, managerChannel) return { close() { - messagePort.removeEventListener('message', handleMessageEvent) + mapeoIpcChannel.off('message', handleGetProject) for (const [id, server] of existingProjectServers.entries()) { server.close() @@ -29,35 +30,49 @@ export function createMapeoServer(manager, messagePort) { existingProjectServers.delete(id) } + mapeoIpcChannel.close() managerServer.close() managerChannel.close() }, } /** - * @param {any} payload + * + * @param {import('./utils.js').MapeoIpcMessagePayload} payload */ - async function handleMessageEvent(payload) { - const data = extractMessageEventData(payload) - - const id = data?.id - - if (typeof id !== 'string' || id === MANAGER_CHANNEL_ID) return - - if (existingProjectServers.has(id)) return - - const projectChannel = new SubChannel(messagePort, id) - - const project = await manager.getProject( - /** @type {import('../types.js').ProjectPublicId} */ (id) - ) + async function handleGetProject(payload) { + const { type, projectId } = payload + + if (type !== 'get_project') return + if (existingProjectServers.has(projectId)) return + + let project + try { + project = await manager.getProject( + /** @type {import('../types.js').ProjectPublicId} */ (projectId) + ) + } catch (err) { + mapeoIpcChannel.postMessage({ + type: 'get_project', + projectId, + error: + err instanceof Error + ? err.message + : `Could not get project with ID ${projectId}`, + }) + return + } + + const projectChannel = new SubChannel(messagePort, projectId) + projectChannel.start() const { close } = createServer(project, projectChannel) - existingProjectServers.set(id, { close, channel: projectChannel }) - - projectChannel.emit('message', data.message) + existingProjectServers.set(projectId, { close, channel: projectChannel }) - projectChannel.start() + mapeoIpcChannel.postMessage({ + type: 'get_project', + projectId, + }) } } diff --git a/src/ipc-wrapper/sub-channel.js b/src/ipc-wrapper/sub-channel.js index 031f7c1b..b1c1adad 100644 --- a/src/ipc-wrapper/sub-channel.js +++ b/src/ipc-wrapper/sub-channel.js @@ -2,6 +2,9 @@ import { EventEmitter } from 'eventemitter3' import { extractMessageEventData } from './utils.js' +// Ideally unique ID used for identifying "global" Mapeo IPC messages +export const MAPEO_IPC_ID = '@@mapeo' +// Ideally unique ID used for identifying messages specific to a MapeoManager instance export const MANAGER_CHANNEL_ID = '@@manager' /** @@ -110,6 +113,5 @@ function isRelevantEvent(event) { if (!event || typeof event !== 'object') return false if (!('id' in event && 'message' in event)) return false if (typeof event.id !== 'string') return false - return true } diff --git a/src/ipc-wrapper/utils.js b/src/ipc-wrapper/utils.js index 576bbb2f..e50069fe 100644 --- a/src/ipc-wrapper/utils.js +++ b/src/ipc-wrapper/utils.js @@ -1,3 +1,13 @@ +/** + * @typedef {Object} MapeoGetProjectPayload + * @property {'get_project'} type + * @property {string} projectId + * @property {string} [error] + * + * @typedef {MapeoGetProjectPayload} MapeoIpcMessagePayload + * + */ + /** * @template T * @param {T} event diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index d8a99c23..7ca04f7b 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -27,6 +27,17 @@ test('IPC wrappers work', async (t) => { return cleanup() }) +test('Attempting to get non-existent project fails', async (t) => { + const { client, cleanup } = setup() + + await t.exception(async () => { + // @ts-expect-error + await client.getProject('mapeo') + }) + + return cleanup() +}) + test('Client calls fail after server closes', async (t) => { const { client, server, cleanup } = setup() From 687c2bcb2097d28f0b51501ad31554d0502e8655 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Mon, 18 Sep 2023 17:27:57 -0400 Subject: [PATCH 20/28] add stressish test --- test-e2e/ipc-wrapper.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index 7ca04f7b..99f5c64b 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -27,6 +27,37 @@ test('IPC wrappers work', async (t) => { return cleanup() }) +test('Multiple projects and several calls in same tick', async (t) => { + const { client, cleanup } = setup() + + const sample = Array(10).fill(null) + + const projectIds = await Promise.all( + sample.map((_, index) => + client.createProject({ + name: `Mapeo ${index}`, + }) + ) + ) + + const projects = await Promise.all( + projectIds.map((id) => client.getProject(id)) + ) + + const settings = await Promise.all( + projects.map((project) => project.$getProjectSettings()) + ) + + const listedProjects = await client.listProjects() + + t.is(projectIds.length, sample.length) + t.is(projects.length, sample.length) + t.is(settings.length, sample.length) + t.is(listedProjects.length, sample.length) + + return cleanup() +}) + test('Attempting to get non-existent project fails', async (t) => { const { client, cleanup } = setup() From d8ebfc2de4d29daaa39514055e8a48c9375587e8 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 19 Sep 2023 07:29:29 -0400 Subject: [PATCH 21/28] Revert "handle getProject calls failing on server side" This reverts commit b7e98da58adab73cf23704734ea2cd7fa8891243. --- package-lock.json | 22 +++--------- package.json | 1 - src/ipc-wrapper/client.js | 49 +++++-------------------- src/ipc-wrapper/server.js | 65 +++++++++++++--------------------- src/ipc-wrapper/sub-channel.js | 4 +-- src/ipc-wrapper/utils.js | 10 ------ 6 files changed, 39 insertions(+), 112 deletions(-) diff --git a/package-lock.json b/package-lock.json index 858e8c1b..d25aa567 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,6 @@ "multi-core-indexer": "^1.0.0-alpha.7", "multicast-service-discovery": "^4.0.4", "p-defer": "^4.0.0", - "p-timeout": "^6.1.2", "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", @@ -5467,18 +5466,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-event/node_modules/p-timeout": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", - "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-filter": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", @@ -5550,11 +5537,12 @@ } }, "node_modules/p-timeout": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", - "integrity": "sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true, "engines": { - "node": ">=14.16" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/package.json b/package.json index 043e7d87..ccd501df 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,6 @@ "multi-core-indexer": "^1.0.0-alpha.7", "multicast-service-discovery": "^4.0.4", "p-defer": "^4.0.0", - "p-timeout": "^6.1.2", "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index 5f2ccb13..d27ba971 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -1,7 +1,6 @@ // @ts-check import { createClient } from 'rpc-reflector' -import pTimeout from 'p-timeout' -import { MANAGER_CHANNEL_ID, MAPEO_IPC_ID, SubChannel } from './sub-channel.js' +import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' const CLOSE = Symbol('close') @@ -13,20 +12,17 @@ export function createMapeoClient(messagePort) { /** @type {Map, channel: SubChannel }>} */ const existingProjectClients = new Map() - const mapeoIpcChannel = new SubChannel(messagePort, MAPEO_IPC_ID) - mapeoIpcChannel.start() - const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) - managerChannel.start() /** @type {import('rpc-reflector').ClientApi} */ const managerClient = createClient(managerChannel) + managerChannel.start() + const client = new Proxy(managerClient, { get(target, prop, receiver) { if (prop === CLOSE) { return () => { - mapeoIpcChannel.close() managerChannel.close() createClient.close(managerClient) } @@ -46,44 +42,13 @@ export function createMapeoClient(messagePort) { * @param {import('../types.js').ProjectPublicId} projectPublicId * @returns {Promise>} */ - async function createProjectClient(projectPublicId) { + function createProjectClient(projectPublicId) { const existingClient = existingProjectClients.get(projectPublicId) - if (existingClient) return existingClient.instance - - // Wait for the server to confirm that it could retrieve the desired project - await pTimeout( - new Promise((res, rej) => { - mapeoIpcChannel.on( - 'message', - /** - * @param {import('./utils.js').MapeoIpcMessagePayload} payload - */ - function handleGetProjectResponse(payload) { - const { type, projectId, error } = payload - - if (type !== 'get_project') return - if (projectId !== projectPublicId) return - - mapeoIpcChannel.off('message', handleGetProjectResponse) - - if (error) rej(new Error(error)) - else res(null) - } - ) - - mapeoIpcChannel.postMessage({ - type: 'get_project', - projectId: projectPublicId, - }) - }), - { milliseconds: 3000 } - ) + if (existingClient) return Promise.resolve(existingClient.instance) const projectChannel = new SubChannel(messagePort, projectPublicId) - projectChannel.start() - /** @type {import('rpc-reflector').ClientApi} */ const projectClientProxy = new Proxy(createClient(projectChannel), { get(target, prop, receiver) { @@ -94,12 +59,14 @@ export function createMapeoClient(messagePort) { }, }) + projectChannel.start() + existingProjectClients.set(projectPublicId, { instance: projectClientProxy, channel: projectChannel, }) - return projectClientProxy + return Promise.resolve(projectClientProxy) } } diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index f67f8036..bfe074a9 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -1,6 +1,7 @@ // @ts-check import { createServer } from 'rpc-reflector' -import { MANAGER_CHANNEL_ID, MAPEO_IPC_ID, SubChannel } from './sub-channel.js' +import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' +import { extractMessageEventData } from './utils.js' /** * @param {import('../mapeo-manager.js').MapeoManager} manager @@ -10,19 +11,17 @@ export function createMapeoServer(manager, messagePort) { /** @type {Map void, channel: SubChannel }>} */ const existingProjectServers = new Map() - const mapeoIpcChannel = new SubChannel(messagePort, MAPEO_IPC_ID) - mapeoIpcChannel.start() + const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) - mapeoIpcChannel.on('message', handleGetProject) + const managerServer = createServer(manager, managerChannel) - const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) managerChannel.start() - const managerServer = createServer(manager, managerChannel) + messagePort.addEventListener('message', handleMessageEvent) return { close() { - mapeoIpcChannel.off('message', handleGetProject) + messagePort.removeEventListener('message', handleMessageEvent) for (const [id, server] of existingProjectServers.entries()) { server.close() @@ -30,49 +29,35 @@ export function createMapeoServer(manager, messagePort) { existingProjectServers.delete(id) } - mapeoIpcChannel.close() managerServer.close() managerChannel.close() }, } /** - * - * @param {import('./utils.js').MapeoIpcMessagePayload} payload + * @param {any} payload */ - async function handleGetProject(payload) { - const { type, projectId } = payload - - if (type !== 'get_project') return - if (existingProjectServers.has(projectId)) return - - let project - try { - project = await manager.getProject( - /** @type {import('../types.js').ProjectPublicId} */ (projectId) - ) - } catch (err) { - mapeoIpcChannel.postMessage({ - type: 'get_project', - projectId, - error: - err instanceof Error - ? err.message - : `Could not get project with ID ${projectId}`, - }) - return - } - - const projectChannel = new SubChannel(messagePort, projectId) - projectChannel.start() + async function handleMessageEvent(payload) { + const data = extractMessageEventData(payload) + + const id = data?.id + + if (typeof id !== 'string' || id === MANAGER_CHANNEL_ID) return + + if (existingProjectServers.has(id)) return + + const projectChannel = new SubChannel(messagePort, id) + + const project = await manager.getProject( + /** @type {import('../types.js').ProjectPublicId} */ (id) + ) const { close } = createServer(project, projectChannel) - existingProjectServers.set(projectId, { close, channel: projectChannel }) + existingProjectServers.set(id, { close, channel: projectChannel }) + + projectChannel.emit('message', data.message) - mapeoIpcChannel.postMessage({ - type: 'get_project', - projectId, - }) + projectChannel.start() } } diff --git a/src/ipc-wrapper/sub-channel.js b/src/ipc-wrapper/sub-channel.js index b1c1adad..031f7c1b 100644 --- a/src/ipc-wrapper/sub-channel.js +++ b/src/ipc-wrapper/sub-channel.js @@ -2,9 +2,6 @@ import { EventEmitter } from 'eventemitter3' import { extractMessageEventData } from './utils.js' -// Ideally unique ID used for identifying "global" Mapeo IPC messages -export const MAPEO_IPC_ID = '@@mapeo' -// Ideally unique ID used for identifying messages specific to a MapeoManager instance export const MANAGER_CHANNEL_ID = '@@manager' /** @@ -113,5 +110,6 @@ function isRelevantEvent(event) { if (!event || typeof event !== 'object') return false if (!('id' in event && 'message' in event)) return false if (typeof event.id !== 'string') return false + return true } diff --git a/src/ipc-wrapper/utils.js b/src/ipc-wrapper/utils.js index e50069fe..576bbb2f 100644 --- a/src/ipc-wrapper/utils.js +++ b/src/ipc-wrapper/utils.js @@ -1,13 +1,3 @@ -/** - * @typedef {Object} MapeoGetProjectPayload - * @property {'get_project'} type - * @property {string} projectId - * @property {string} [error] - * - * @typedef {MapeoGetProjectPayload} MapeoIpcMessagePayload - * - */ - /** * @template T * @param {T} event From be7cb48ee546f42027db6f948588243586a2ffce Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 19 Sep 2023 07:30:05 -0400 Subject: [PATCH 22/28] fix SubChannel.close --- src/ipc-wrapper/sub-channel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipc-wrapper/sub-channel.js b/src/ipc-wrapper/sub-channel.js index 031f7c1b..4744ee9c 100644 --- a/src/ipc-wrapper/sub-channel.js +++ b/src/ipc-wrapper/sub-channel.js @@ -92,7 +92,7 @@ export class SubChannel extends EventEmitter { } close() { - if (this.#state !== 'closed') return + if (this.#state === 'closed') return this.#state = 'closed' this.#queued = [] From d976081296ba1d3de23cfaa3afd31e1815e72909 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 19 Sep 2023 07:46:37 -0400 Subject: [PATCH 23/28] update rpc-reflector --- package-lock.json | 8 ++++---- package.json | 2 +- src/ipc-wrapper/client.js | 14 +++----------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index d25aa567..195982ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "protobufjs": "^7.2.3", "protomux": "^3.4.1", "quickbit-universal": "^2.2.0", - "rpc-reflector": "^1.3.10", + "rpc-reflector": "^1.3.11", "sodium-universal": "^4.0.0", "sub-encoder": "^2.1.1", "tiny-typed-emitter": "^2.1.0", @@ -6502,9 +6502,9 @@ } }, "node_modules/rpc-reflector": { - "version": "1.3.10", - "resolved": "https://registry.npmjs.org/rpc-reflector/-/rpc-reflector-1.3.10.tgz", - "integrity": "sha512-/B40dEx0758gn+1wm0kSaECvivF3Qspg+0/N39/eKppScUglS1mypsHjkO6ZLUFZSH9T3YnH7JArQ4IO3UQVWA==", + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/rpc-reflector/-/rpc-reflector-1.3.11.tgz", + "integrity": "sha512-TIf/RHJy11q/xmNBj0Xj2Z4GVPP1aLeaZXSRtthcMnXNuK+tv7SpZldB5Jk6RFHzA9TgxhcWvLHdHrdlEDKH0w==", "dependencies": { "@msgpack/msgpack": "^1.12.1", "@types/node": "^18.16.19", diff --git a/package.json b/package.json index ccd501df..c39a17a5 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "protobufjs": "^7.2.3", "protomux": "^3.4.1", "quickbit-universal": "^2.2.0", - "rpc-reflector": "^1.3.10", + "rpc-reflector": "^1.3.11", "sodium-universal": "^4.0.0", "sub-encoder": "^2.1.1", "tiny-typed-emitter": "^2.1.0", diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index d27ba971..4ac09ad5 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -50,23 +50,15 @@ export function createMapeoClient(messagePort) { const projectChannel = new SubChannel(messagePort, projectPublicId) /** @type {import('rpc-reflector').ClientApi} */ - const projectClientProxy = new Proxy(createClient(projectChannel), { - get(target, prop, receiver) { - if (prop === 'then') { - return projectClientProxy - } - return Reflect.get(target, prop, receiver) - }, - }) - + const projectClient = createClient(projectChannel) projectChannel.start() existingProjectClients.set(projectPublicId, { - instance: projectClientProxy, + instance: projectClient, channel: projectChannel, }) - return Promise.resolve(projectClientProxy) + return Promise.resolve(projectClient) } } From 1fa204afbcf7d56557c273a9dd0e076ddcb634e1 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 19 Sep 2023 08:24:20 -0400 Subject: [PATCH 24/28] revised implementation for handling getProject failure --- package-lock.json | 22 +++++++++++++---- package.json | 1 + src/ipc-wrapper/client.js | 42 +++++++++++++++++++++++++++++---- src/ipc-wrapper/server.js | 43 +++++++++++++++++++++++++--------- src/ipc-wrapper/sub-channel.js | 2 ++ src/ipc-wrapper/utils.js | 10 ++++++++ test-e2e/ipc-wrapper.js | 32 ++++++++++++++++++++----- 7 files changed, 125 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 195982ef..dc0c439d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "multi-core-indexer": "^1.0.0-alpha.7", "multicast-service-discovery": "^4.0.4", "p-defer": "^4.0.0", + "p-timeout": "^6.1.2", "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", @@ -5466,6 +5467,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-event/node_modules/p-timeout": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", + "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-filter": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", @@ -5537,12 +5550,11 @@ } }, "node_modules/p-timeout": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", - "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", - "dev": true, + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", + "integrity": "sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==", "engines": { - "node": ">=12" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" diff --git a/package.json b/package.json index c39a17a5..ddec6bdf 100644 --- a/package.json +++ b/package.json @@ -119,6 +119,7 @@ "multi-core-indexer": "^1.0.0-alpha.7", "multicast-service-discovery": "^4.0.4", "p-defer": "^4.0.0", + "p-timeout": "^6.1.2", "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index 4ac09ad5..fa8f865e 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -1,6 +1,8 @@ // @ts-check import { createClient } from 'rpc-reflector' -import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' +import pTimeout from 'p-timeout' +import { MANAGER_CHANNEL_ID, MAPEO_RPC_ID, SubChannel } from './sub-channel.js' +import { extractMessageEventData } from './utils.js' const CLOSE = Symbol('close') @@ -42,11 +44,41 @@ export function createMapeoClient(messagePort) { * @param {import('../types.js').ProjectPublicId} projectPublicId * @returns {Promise>} */ - function createProjectClient(projectPublicId) { + async function createProjectClient(projectPublicId) { const existingClient = existingProjectClients.get(projectPublicId) - if (existingClient) return Promise.resolve(existingClient.instance) - + if (existingClient) return existingClient.instance + + await pTimeout( + new Promise((res, rej) => { + messagePort.addEventListener( + 'message', + /** + * @param {unknown} event + */ + function handleMapeoRpcEvent(event) { + const data = extractMessageEventData(event) + + if (!data || typeof data !== 'object') return + if (!('id' in data && 'projectId' in data)) return + + if (data.id !== MAPEO_RPC_ID) return + if (data.projectId !== projectPublicId) return + + messagePort.removeEventListener('message', handleMapeoRpcEvent) + + if ('error' in data && typeof data.error === 'string') + rej(new Error(data.error)) + else res(null) + } + ) + + messagePort.postMessage({ + id: projectPublicId, + }) + }), + { milliseconds: 3000 } + ) const projectChannel = new SubChannel(messagePort, projectPublicId) /** @type {import('rpc-reflector').ClientApi} */ @@ -58,7 +90,7 @@ export function createMapeoClient(messagePort) { channel: projectChannel, }) - return Promise.resolve(projectClient) + return projectClient } } diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index bfe074a9..f1026cef 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -1,6 +1,6 @@ // @ts-check import { createServer } from 'rpc-reflector' -import { MANAGER_CHANNEL_ID, SubChannel } from './sub-channel.js' +import { MANAGER_CHANNEL_ID, MAPEO_RPC_ID, SubChannel } from './sub-channel.js' import { extractMessageEventData } from './utils.js' /** @@ -17,11 +17,11 @@ export function createMapeoServer(manager, messagePort) { managerChannel.start() - messagePort.addEventListener('message', handleMessageEvent) + messagePort.addEventListener('message', createProjectServer) return { close() { - messagePort.removeEventListener('message', handleMessageEvent) + messagePort.removeEventListener('message', createProjectServer) for (const [id, server] of existingProjectServers.entries()) { server.close() @@ -35,28 +35,49 @@ export function createMapeoServer(manager, messagePort) { } /** - * @param {any} payload + * @param {unknown} payload */ - async function handleMessageEvent(payload) { + async function createProjectServer(payload) { const data = extractMessageEventData(payload) - const id = data?.id + if (!data || typeof data !== 'object') return - if (typeof id !== 'string' || id === MANAGER_CHANNEL_ID) return + const id = 'id' in data && typeof data.id === 'string' ? data.id : null + + if (!id || id === MANAGER_CHANNEL_ID || id === MAPEO_RPC_ID) return if (existingProjectServers.has(id)) return const projectChannel = new SubChannel(messagePort, id) - const project = await manager.getProject( - /** @type {import('../types.js').ProjectPublicId} */ (id) - ) + let project + try { + project = await manager.getProject( + /** @type {import('../types.js').ProjectPublicId} */ (id) + ) + messagePort.postMessage({ + id: MAPEO_RPC_ID, + projectId: id, + }) + } catch (err) { + messagePort.postMessage({ + id: MAPEO_RPC_ID, + projectId: id, + error: + err instanceof Error + ? err.message + : `Could not get project with ID ${id}`, + }) + return + } const { close } = createServer(project, projectChannel) existingProjectServers.set(id, { close, channel: projectChannel }) - projectChannel.emit('message', data.message) + if ('message' in data) { + projectChannel.emit('message', data.message) + } projectChannel.start() } diff --git a/src/ipc-wrapper/sub-channel.js b/src/ipc-wrapper/sub-channel.js index 4744ee9c..fc1845b5 100644 --- a/src/ipc-wrapper/sub-channel.js +++ b/src/ipc-wrapper/sub-channel.js @@ -2,6 +2,8 @@ import { EventEmitter } from 'eventemitter3' import { extractMessageEventData } from './utils.js' +// Ideally unique ID used for identifying "global" Mapeo IPC messages +export const MAPEO_RPC_ID = '@@mapeo-rpc' export const MANAGER_CHANNEL_ID = '@@manager' /** diff --git a/src/ipc-wrapper/utils.js b/src/ipc-wrapper/utils.js index 576bbb2f..e50069fe 100644 --- a/src/ipc-wrapper/utils.js +++ b/src/ipc-wrapper/utils.js @@ -1,3 +1,13 @@ +/** + * @typedef {Object} MapeoGetProjectPayload + * @property {'get_project'} type + * @property {string} projectId + * @property {string} [error] + * + * @typedef {MapeoGetProjectPayload} MapeoIpcMessagePayload + * + */ + /** * @template T * @param {T} event diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index 99f5c64b..14e7c07c 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -30,14 +30,17 @@ test('IPC wrappers work', async (t) => { test('Multiple projects and several calls in same tick', async (t) => { const { client, cleanup } = setup() - const sample = Array(10).fill(null) + const sample = Array(10) + .fill(null) + .map((_, index) => { + return { + name: `Mapeo ${index}`, + defaultPresets: undefined, + } + }) const projectIds = await Promise.all( - sample.map((_, index) => - client.createProject({ - name: `Mapeo ${index}`, - }) - ) + sample.map(async (s) => client.createProject(s)) ) const projects = await Promise.all( @@ -55,6 +58,11 @@ test('Multiple projects and several calls in same tick', async (t) => { t.is(settings.length, sample.length) t.is(listedProjects.length, sample.length) + settings.forEach((s, index) => { + const expectedSettings = sample[index] + t.alike(s, expectedSettings) + }) + return cleanup() }) @@ -66,6 +74,18 @@ test('Attempting to get non-existent project fails', async (t) => { await client.getProject('mapeo') }) + const results = await Promise.allSettled([ + // @ts-expect-error + client.getProject('mapeo'), + // @ts-expect-error + client.getProject('mapeo'), + ]) + + t.alike( + results.map(({ status }) => status), + ['rejected', 'rejected'] + ) + return cleanup() }) From 57456b7d200fd5de2c28f18d7ce50a69efd02dcc Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 19 Sep 2023 10:11:09 -0400 Subject: [PATCH 25/28] improve areas with potential race conditions --- package-lock.json | 12 ------- package.json | 1 - src/ipc-wrapper/client.js | 72 +++++++++++++++++-------------------- src/ipc-wrapper/server.js | 75 +++++++++++++++++++++++++++------------ test-e2e/ipc-wrapper.js | 21 +++++++++-- 5 files changed, 102 insertions(+), 79 deletions(-) diff --git a/package-lock.json b/package-lock.json index dc0c439d..b65bc880 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,6 @@ "multi-core-indexer": "^1.0.0-alpha.7", "multicast-service-discovery": "^4.0.4", "p-defer": "^4.0.0", - "p-timeout": "^6.1.2", "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", @@ -5549,17 +5548,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-timeout": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.2.tgz", - "integrity": "sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parent-module": { "version": "1.0.1", "dev": true, diff --git a/package.json b/package.json index ddec6bdf..c39a17a5 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,6 @@ "multi-core-indexer": "^1.0.0-alpha.7", "multicast-service-discovery": "^4.0.4", "p-defer": "^4.0.0", - "p-timeout": "^6.1.2", "private-ip": "^3.0.0", "protobufjs": "^7.2.3", "protomux": "^3.4.1", diff --git a/src/ipc-wrapper/client.js b/src/ipc-wrapper/client.js index fa8f865e..321ec21b 100644 --- a/src/ipc-wrapper/client.js +++ b/src/ipc-wrapper/client.js @@ -1,8 +1,7 @@ // @ts-check import { createClient } from 'rpc-reflector' -import pTimeout from 'p-timeout' +import pDefer from 'p-defer' import { MANAGER_CHANNEL_ID, MAPEO_RPC_ID, SubChannel } from './sub-channel.js' -import { extractMessageEventData } from './utils.js' const CLOSE = Symbol('close') @@ -11,22 +10,36 @@ const CLOSE = Symbol('close') * @returns {import('rpc-reflector/client.js').ClientApi} */ export function createMapeoClient(messagePort) { - /** @type {Map, channel: SubChannel }>} */ - const existingProjectClients = new Map() + /** @type {Map>>} */ + const projectClientPromises = new Map() const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) + const mapeoRpcChannel = new SubChannel(messagePort, MAPEO_RPC_ID) /** @type {import('rpc-reflector').ClientApi} */ const managerClient = createClient(managerChannel) + /** @type {import('rpc-reflector').ClientApi} */ + const mapeoRpcClient = createClient(mapeoRpcChannel) + mapeoRpcChannel.start() managerChannel.start() const client = new Proxy(managerClient, { get(target, prop, receiver) { if (prop === CLOSE) { - return () => { + return async () => { managerChannel.close() createClient.close(managerClient) + + const projectClientResults = await Promise.allSettled( + projectClientPromises.values() + ) + + for (const result of projectClientResults) { + if (result.status === 'fulfilled') { + createClient.close(result.value) + } + } } } @@ -45,50 +58,29 @@ export function createMapeoClient(messagePort) { * @returns {Promise>} */ async function createProjectClient(projectPublicId) { - const existingClient = existingProjectClients.get(projectPublicId) + const existingClientPromise = projectClientPromises.get(projectPublicId) - if (existingClient) return existingClient.instance + if (existingClientPromise) return existingClientPromise - await pTimeout( - new Promise((res, rej) => { - messagePort.addEventListener( - 'message', - /** - * @param {unknown} event - */ - function handleMapeoRpcEvent(event) { - const data = extractMessageEventData(event) + /** @type {import('p-defer').DeferredPromise>}*/ + const deferred = pDefer() - if (!data || typeof data !== 'object') return - if (!('id' in data && 'projectId' in data)) return + projectClientPromises.set(projectPublicId, deferred.promise) - if (data.id !== MAPEO_RPC_ID) return - if (data.projectId !== projectPublicId) return + try { + await mapeoRpcClient.assertProjectExists(projectPublicId) + } catch (err) { + deferred.reject(err) + throw err + } - messagePort.removeEventListener('message', handleMapeoRpcEvent) - - if ('error' in data && typeof data.error === 'string') - rej(new Error(data.error)) - else res(null) - } - ) - - messagePort.postMessage({ - id: projectPublicId, - }) - }), - { milliseconds: 3000 } - ) const projectChannel = new SubChannel(messagePort, projectPublicId) /** @type {import('rpc-reflector').ClientApi} */ const projectClient = createClient(projectChannel) projectChannel.start() - existingProjectClients.set(projectPublicId, { - instance: projectClient, - channel: projectChannel, - }) + deferred.resolve(projectClient) return projectClient } @@ -96,9 +88,9 @@ export function createMapeoClient(messagePort) { /** * @param {import('rpc-reflector').ClientApi} client client created with `createMapeoClient` - * @returns {void} + * @returns {Promise} */ -export function closeMapeoClient(client) { +export async function closeMapeoClient(client) { // @ts-expect-error return client[CLOSE]() } diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index f1026cef..4ef41eaf 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -8,77 +8,106 @@ import { extractMessageEventData } from './utils.js' * @param {import('./sub-channel.js').MessagePortLike} messagePort */ export function createMapeoServer(manager, messagePort) { - /** @type {Map void, channel: SubChannel }>} */ + /** @type {Map void }>} */ const existingProjectServers = new Map() + /** @type {Map} */ + const existingProjectChannels = new Map() + + const mapeoRpcApi = new MapeoRpcApi(manager) + const managerChannel = new SubChannel(messagePort, MANAGER_CHANNEL_ID) + const mapeoRpcChannel = new SubChannel(messagePort, MAPEO_RPC_ID) const managerServer = createServer(manager, managerChannel) + const mapeoRpcServer = createServer(mapeoRpcApi, mapeoRpcChannel) managerChannel.start() + mapeoRpcChannel.start() - messagePort.addEventListener('message', createProjectServer) + messagePort.addEventListener('message', handleMessage) return { close() { - messagePort.removeEventListener('message', createProjectServer) + messagePort.removeEventListener('message', handleMessage) for (const [id, server] of existingProjectServers.entries()) { server.close() - server.channel.close() + + const channel = existingProjectChannels.get(id) + + if (channel) { + channel.close() + existingProjectChannels.delete(id) + } + existingProjectServers.delete(id) } managerServer.close() managerChannel.close() + mapeoRpcServer.close() }, } /** * @param {unknown} payload */ - async function createProjectServer(payload) { + async function handleMessage(payload) { const data = extractMessageEventData(payload) - if (!data || typeof data !== 'object') return + if (!data || typeof data !== 'object' || !('message' in data)) return const id = 'id' in data && typeof data.id === 'string' ? data.id : null if (!id || id === MANAGER_CHANNEL_ID || id === MAPEO_RPC_ID) return - if (existingProjectServers.has(id)) return + if (existingProjectChannels.has(id)) return const projectChannel = new SubChannel(messagePort, id) + existingProjectChannels.set(id, projectChannel) let project try { project = await manager.getProject( /** @type {import('../types.js').ProjectPublicId} */ (id) ) - messagePort.postMessage({ - id: MAPEO_RPC_ID, - projectId: id, - }) } catch (err) { - messagePort.postMessage({ - id: MAPEO_RPC_ID, - projectId: id, - error: - err instanceof Error - ? err.message - : `Could not get project with ID ${id}`, - }) + // TODO: how to respond to client so that method errors? + projectChannel.close() + existingProjectChannels.delete(id) + existingProjectServers.delete(id) return } const { close } = createServer(project, projectChannel) - existingProjectServers.set(id, { close, channel: projectChannel }) + existingProjectServers.set(id, { close }) - if ('message' in data) { - projectChannel.emit('message', data.message) - } + projectChannel.emit('message', data.message) projectChannel.start() } } + +export class MapeoRpcApi { + #manager + + /** + * @param {import('../mapeo-manager.js').MapeoManager} manager + */ + constructor(manager) { + this.#manager = manager + } + + /** + * @param {string} projectId + * @returns {Promise} + */ + async assertProjectExists(projectId) { + const project = await this.#manager.getProject( + /** @type {import('../types.js').ProjectPublicId} */ (projectId) + ) + return !!project + } +} diff --git a/test-e2e/ipc-wrapper.js b/test-e2e/ipc-wrapper.js index 14e7c07c..72ae1cc1 100644 --- a/test-e2e/ipc-wrapper.js +++ b/test-e2e/ipc-wrapper.js @@ -89,6 +89,21 @@ test('Attempting to get non-existent project fails', async (t) => { return cleanup() }) +test('Concurrent calls that succeed', async (t) => { + const { client, cleanup } = setup() + + const projectId = await client.createProject() + + const [project1, project2] = await Promise.all([ + client.getProject(projectId), + client.getProject(projectId), + ]) + + t.is(project1, project2) + + return cleanup() +}) + test('Client calls fail after server closes', async (t) => { const { client, server, cleanup } = setup() @@ -98,7 +113,7 @@ test('Client calls fail after server closes', async (t) => { await projectBefore.$getProjectSettings() server.close() - closeMapeoClient(client) + await closeMapeoClient(client) const projectAfter = await client.getProject(projectId) @@ -145,9 +160,9 @@ function setup() { port2, server, client, - cleanup: () => { + cleanup: async () => { server.close() - closeMapeoClient(client) + await closeMapeoClient(client) port1.close() port2.close() }, From fc86445dfb5442b51c53499b51bf1202cb645804 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 19 Sep 2023 11:48:11 -0400 Subject: [PATCH 26/28] remove unused type --- src/ipc-wrapper/utils.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/ipc-wrapper/utils.js b/src/ipc-wrapper/utils.js index e50069fe..576bbb2f 100644 --- a/src/ipc-wrapper/utils.js +++ b/src/ipc-wrapper/utils.js @@ -1,13 +1,3 @@ -/** - * @typedef {Object} MapeoGetProjectPayload - * @property {'get_project'} type - * @property {string} projectId - * @property {string} [error] - * - * @typedef {MapeoGetProjectPayload} MapeoIpcMessagePayload - * - */ - /** * @template T * @param {T} event From 368d11c3be394be4461b104510908b6318494ac4 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Tue, 19 Sep 2023 11:57:29 -0400 Subject: [PATCH 27/28] package file updates --- package-lock.json | 1371 ++++++++++++++++----------------------------- package.json | 2 +- 2 files changed, 470 insertions(+), 903 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1be0d5dc..65d3111c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -362,12 +362,12 @@ "@bufbuild/buf-win32-x64": "1.26.1" } }, - "node_modules/@bufbuild/buf-darwin-x64": { + "node_modules/@bufbuild/buf-darwin-arm64": { "version": "1.26.1", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.26.1.tgz", - "integrity": "sha512-jl5WmUv30OW8JiRLid9+mVx1XVH0XttpUfkQfmqDFdUHGfdy4XWYK8kr84YyWu0SiMTIt1mPXkqG5UM3x+tdIQ==", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.26.1.tgz", + "integrity": "sha512-nmyWiT/59RFja0ZuXFxjNGoAMDPTApU66CZUUevkFVWbNB9nzeQDjx2vsJyACY64k5fTgZiaelSiyppwObQknw==", "cpu": [ - "x64" + "arm64" ], "dev": true, "optional": true, @@ -390,28 +390,24 @@ }, "node_modules/@drizzle-team/studio": { "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@drizzle-team/studio/-/studio-0.0.5.tgz", - "integrity": "sha512-ps5qF0tMxWRVu+V5gvCRrQNqlY92aTnIKdq27gm9LZMSdaKYZt6AVvSK1dlUMzs6Rt0Jm80b+eWct6xShBKhIw==", "dev": true }, "node_modules/@esbuild-kit/core-utils": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.1.0.tgz", - "integrity": "sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "~0.17.6", "source-map-support": "^0.5.21" } }, - "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64": { + "node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64": { "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", - "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", "cpu": [ - "x64" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -422,10 +418,9 @@ }, "node_modules/@esbuild-kit/core-utils/node_modules/esbuild": { "version": "0.17.19", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", - "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -459,22 +454,20 @@ }, "node_modules/@esbuild-kit/esm-loader": { "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.5.5.tgz", - "integrity": "sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==", "dev": true, + "license": "MIT", "dependencies": { "@esbuild-kit/core-utils": "^3.0.0", "get-tsconfig": "^4.4.0" } }, - "node_modules/@esbuild/darwin-x64": { + "node_modules/@esbuild/darwin-arm64": { "version": "0.18.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.17.tgz", - "integrity": "sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==", "cpu": [ - "x64" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -485,9 +478,8 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -500,18 +492,16 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -532,18 +522,16 @@ }, "node_modules/@eslint/js": { "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", - "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@fastify/ajv-compiler": { "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.5.0.tgz", - "integrity": "sha512-ebbEtlI7dxXF5ziNdr05mOY8NnDiPB1XvAlLHctRt/Rc+C3LCOVW5imUVX+mhvUhnNzmPBHewUkOFgGlCxgdAA==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^8.11.0", "ajv-formats": "^2.1.1", @@ -552,9 +540,8 @@ }, "node_modules/@fastify/ajv-compiler/node_modules/ajv": { "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -568,44 +555,38 @@ }, "node_modules/@fastify/ajv-compiler/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@fastify/deepmerge": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-1.3.0.tgz", - "integrity": "sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@fastify/error": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.3.0.tgz", - "integrity": "sha512-dj7vjIn1Ar8sVXj2yAXiMNCJDmS9MQ9XMlIecX2dIzzhjSHCyKo4DdXjXMs7wKW2kj6yvVRSpuQjOZ3YLrh56w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@fastify/fast-json-stringify-compiler": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", - "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", "dev": true, + "license": "MIT", "dependencies": { "fast-json-stringify": "^5.7.0" } }, "node_modules/@fastify/type-provider-typebox": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@fastify/type-provider-typebox/-/type-provider-typebox-3.3.0.tgz", - "integrity": "sha512-CJ4bhrx2FurljP7zIR1pIGlSzf3ChSm65p5MyKUR74CT4Ft5gcqrZg6FNq4mOCtMegmgUL7Z0Ly762aIHp5ZWw==", + "license": "MIT", "peerDependencies": { "@sinclair/typebox": ">=0.26 <=0.29" } }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", @@ -629,14 +610,12 @@ }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@hyperswarm/secret-stream": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@hyperswarm/secret-stream/-/secret-stream-6.1.2.tgz", - "integrity": "sha512-oem+ZEG+wOU1K47qGi51pKyqG1N3F+zz42xmReHeGZVR84y+K+6VQIXCON4EozYad8HEGCixpupt8yH8W4sMxg==", + "license": "MIT", "dependencies": { "b4a": "^1.1.0", "hypercore-crypto": "^3.3.1", @@ -650,9 +629,8 @@ }, "node_modules/@hyperswarm/testnet": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@hyperswarm/testnet/-/testnet-3.1.2.tgz", - "integrity": "sha512-V/Q4o4NmzCtD9t1zkrEhv8s+QiC9SukXQLbAKS4qlxJ6kFHwf5UC/04Hk3kKFofU2PJzEqQbh2NEWgBU6KAb8Q==", "dev": true, + "license": "MIT", "dependencies": { "hyperdht": "^6.5.2" }, @@ -662,8 +640,7 @@ }, "node_modules/@isaacs/cliui": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -678,8 +655,7 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -689,8 +665,7 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -700,13 +675,11 @@ }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -721,8 +694,7 @@ }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -735,8 +707,7 @@ }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -802,13 +773,11 @@ }, "node_modules/@json-schema-spec/json-pointer": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@json-schema-spec/json-pointer/-/json-pointer-0.1.2.tgz", - "integrity": "sha512-BYY7IavBjwsWWSmVcMz2A9mKiDD9RvacnsItgmy1xV8cmgbtxFfKmKMtkVpD7pYtkx4mIW4800yZBXueVFIWPw==" + "license": "MIT" }, "node_modules/@json-schema-tools/dereferencer": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@json-schema-tools/dereferencer/-/dereferencer-1.6.1.tgz", - "integrity": "sha512-+h+K/H3pWoJVztTuz1ycTUc0ai/xH5eLZLurE4jQpqYwPcPvsXtFfbRxDhvxrrpjjg4PV3HmEjjORIEQPO4Dmw==", + "license": "Apache-2.0", "dependencies": { "@json-schema-tools/reference-resolver": "^1.2.5", "@json-schema-tools/traverse": "^1.10.0", @@ -817,8 +786,7 @@ }, "node_modules/@json-schema-tools/reference-resolver": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@json-schema-tools/reference-resolver/-/reference-resolver-1.2.5.tgz", - "integrity": "sha512-xNQgX/ABnwvbIeexL5Czv08lXjHAL80HEUogza7E19eIL/EXD8HM4FvxG1JuTGyi5fA+sSP64C9pabELizcBBw==", + "license": "Apache-2.0", "dependencies": { "@json-schema-spec/json-pointer": "^0.1.2", "isomorphic-fetch": "^3.0.0" @@ -826,8 +794,7 @@ }, "node_modules/@json-schema-tools/traverse": { "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@json-schema-tools/traverse/-/traverse-1.10.1.tgz", - "integrity": "sha512-vYY5EIxCPzEXEWL/vTjdHy4g92tv1ApUQCjPJsj9gEoXLNNVwJlwwgRZisuvgFBZ3zeLzQygrbehERSpYdmFZA==" + "license": "Apache-2.0" }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", @@ -855,8 +822,7 @@ }, "node_modules/@mapeo/crypto/node_modules/sodium-universal": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-3.1.0.tgz", - "integrity": "sha512-N2gxk68Kg2qZLSJ4h0NffEhp4BjgWHCHXVlDi1aG1hA3y+ZeWEmHqnpml8Hy47QzfL1xLy5nwr9LcsWAg2Ep0A==", + "license": "MIT", "dependencies": { "blake2b": "^2.1.1", "chacha20-universal": "^1.0.4", @@ -872,8 +838,7 @@ }, "node_modules/@mapeo/schema": { "version": "3.0.0-next.8", - "resolved": "https://registry.npmjs.org/@mapeo/schema/-/schema-3.0.0-next.8.tgz", - "integrity": "sha512-GtN04HUasXAaWUcRQ/FlmS6P9eXdnz7zDr0mhb8QO4q6bxdgD7H74VPL48o8sOGc7vpz26widpyCA4HJhcQ+QA==", + "license": "MIT", "dependencies": { "@json-schema-tools/dereferencer": "^1.6.1", "ajv": "^8.12.0", @@ -887,8 +852,7 @@ }, "node_modules/@mapeo/schema/node_modules/ajv": { "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -902,16 +866,14 @@ }, "node_modules/@mapeo/schema/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@mapeo/schema/node_modules/foreground-child": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -925,8 +887,7 @@ }, "node_modules/@mapeo/schema/node_modules/glob": { "version": "10.3.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", - "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.0.3", @@ -946,13 +907,11 @@ }, "node_modules/@mapeo/schema/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "license": "MIT" }, "node_modules/@mapeo/schema/node_modules/minimatch": { "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -965,8 +924,7 @@ }, "node_modules/@mapeo/schema/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", "engines": { "node": ">=14" }, @@ -976,8 +934,7 @@ }, "node_modules/@mapeo/schema/node_modules/type-fest": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.2.0.tgz", - "integrity": "sha512-5zknd7Dss75pMSED270A1RQS3KloqRJA9XbXLe0eCxyw7xXFb3rd+9B0UQ/0E+LQT6lnrLviEolYORlRWamn4w==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" }, @@ -987,8 +944,7 @@ }, "node_modules/@mapeo/sqlite-indexer": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@mapeo/sqlite-indexer/-/sqlite-indexer-1.0.0-alpha.6.tgz", - "integrity": "sha512-iLUePxr2kHgsWfFTuJAKjTSZCRuVsIVNbQVyLEkN0pX/2dWzljCxCRvO+9rc1x+bThUas96ZAzCedqeeqC0zRw==", + "license": "MIT", "dependencies": { "@types/better-sqlite3": "^7.6.4", "better-sqlite3": "^8.4.0" @@ -1036,8 +992,7 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", "optional": true, "engines": { "node": ">=14" @@ -1045,28 +1000,23 @@ }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -1074,73 +1024,62 @@ }, "node_modules/@protobufjs/float": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + "license": "BSD-3-Clause" }, "node_modules/@sinclair/typebox": { "version": "0.29.6", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.29.6.tgz", - "integrity": "sha512-aX5IFYWlMa7tQ8xZr3b2gtVReCvg7f3LEhjir/JAjX2bJCMVJA5tIPv30wTD4KDfcwMd7DDYY3hFDeGmOgtrZQ==" + "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^2.0.0" } }, "node_modules/@types/b4a": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@types/b4a/-/b4a-1.6.0.tgz", - "integrity": "sha512-rYU2r5nSUPyKyufWijxgTjsFp2kLCwydj2TmKU4StJeGPHS/Fs5KHgP89DNF0jddyeAbN5mdjNDqIrjIHca60g==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/better-sqlite3": { "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.4.tgz", - "integrity": "sha512-dzrRZCYPXIXfSR1/surNbJ/grU3scTaygS0OMzjlGf71i9sc2fGyHPXXiXmEvNIoE0cGwsanEFMVJxPXmco9Eg==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/debug": { "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", - "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/ms": "*" } @@ -1157,26 +1096,22 @@ }, "node_modules/@types/minimist": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/ms": { "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "18.16.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.19.tgz", - "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==" + "license": "MIT" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -1185,9 +1120,8 @@ }, "node_modules/@types/sinonjs__fake-timers": { "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", - "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/streamx": { "version": "2.9.1", @@ -1275,9 +1209,8 @@ }, "node_modules/abort-controller": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "dev": true, + "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" }, @@ -1287,15 +1220,13 @@ }, "node_modules/abstract-logging": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", - "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/acorn": { "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1305,18 +1236,16 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/aggregate-error": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", "dev": true, + "license": "MIT", "dependencies": { "clean-stack": "^4.0.0", "indent-string": "^5.0.0" @@ -1330,9 +1259,8 @@ }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1386,8 +1314,7 @@ }, "node_modules/ansi-sequence-parser": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz", - "integrity": "sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==" + "license": "MIT" }, "node_modules/ansi-styles": { "version": "4.3.0", @@ -1416,21 +1343,18 @@ }, "node_modules/archy": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/array-buffer-byte-length": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "is-array-buffer": "^3.0.1" @@ -1462,9 +1386,8 @@ }, "node_modules/arraybuffer.prototype.slice": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", - "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", @@ -1498,18 +1421,16 @@ }, "node_modules/atomic-sleep": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } }, "node_modules/available-typed-arrays": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -1519,9 +1440,8 @@ }, "node_modules/avvio": { "version": "8.2.1", - "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.2.1.tgz", - "integrity": "sha512-TAlMYvOuwGyLK3PfBb5WKBXZmXz2fVCgv23d6zZFdle/q3gPjmxBaeuC0pY0Dzs5PWMSgfqqEZkrye19GlDTgw==", "dev": true, + "license": "MIT", "dependencies": { "archy": "^1.0.0", "debug": "^4.0.0", @@ -1530,8 +1450,7 @@ }, "node_modules/b4a": { "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + "license": "ISC" }, "node_modules/balanced-match": { "version": "1.0.2", @@ -1571,9 +1490,8 @@ }, "node_modules/better-sqlite3": { "version": "8.5.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-8.5.0.tgz", - "integrity": "sha512-vbPcv/Hx5WYdyNg/NbcfyaBZyv9s/NVbxb7yCeC5Bq1pVocNxeL2tZmSu3Rlm4IEOTjYdGyzWQgyx0OSdORBzw==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.0" @@ -1581,8 +1499,7 @@ }, "node_modules/big-sparse-array": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/big-sparse-array/-/big-sparse-array-1.0.3.tgz", - "integrity": "sha512-6RjV/3mSZORlMdpUaQ6rUSpG637cZm0//E54YYGtQg1c1O+AbZP8UTdJ/TchsDZcTVLmyWZcseBfp2HBeXUXOQ==" + "license": "MIT" }, "node_modules/binary-extensions": { "version": "2.2.0", @@ -1594,8 +1511,7 @@ }, "node_modules/binary-stream-equals": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/binary-stream-equals/-/binary-stream-equals-1.0.0.tgz", - "integrity": "sha512-xiUT5LGfD8JiLhbXiG+ByOnbgb9f2ssRLfZDQMl3nZdf89EotQZGZuMkDN8J3n46emabE7RnJ1q0r7Hv3INExw==", + "license": "MIT", "dependencies": { "b4a": "^1.3.1" } @@ -1692,9 +1608,8 @@ }, "node_modules/brittle": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/brittle/-/brittle-3.2.1.tgz", - "integrity": "sha512-j96VOgFnDcIFGtJp2tZLXlGEFIURjdbJ+I1mvig8qNd9MVL4zHa8fOK8AqXPFy4iHD7fCKC06MTX8RF8mlt76g==", "dev": true, + "license": "MIT", "dependencies": { "b4a": "^1.6.0", "c8": "^7.11.3", @@ -1732,9 +1647,8 @@ }, "node_modules/buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/c8": { "version": "7.12.0", @@ -1763,9 +1677,8 @@ }, "node_modules/c8/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1783,9 +1696,8 @@ }, "node_modules/c8/node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -1798,9 +1710,8 @@ }, "node_modules/call-bind": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -1830,9 +1741,8 @@ }, "node_modules/camelcase-keys": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-8.0.2.tgz", - "integrity": "sha512-qMKdlOfsjlezMqxkUGGMaWWs17i2HoL15tM+wtx8ld4nLrUwU58TFdvyGOz/piNP842KeO8yXvggVQSdQ828NA==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "^7.0.0", "map-obj": "^4.3.0", @@ -1848,9 +1758,8 @@ }, "node_modules/camelcase-keys/node_modules/camelcase": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -1860,9 +1769,8 @@ }, "node_modules/camelcase-keys/node_modules/map-obj": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -1870,23 +1778,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/camelcase-keys/node_modules/quick-lru": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz", - "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/camelcase-keys/node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -1896,9 +1791,8 @@ }, "node_modules/case-anything": { "version": "2.1.13", - "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.13.tgz", - "integrity": "sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.13" }, @@ -1984,9 +1878,8 @@ }, "node_modules/clean-stack": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", - "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "5.0.0" }, @@ -1999,9 +1892,8 @@ }, "node_modules/clean-stack/node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2011,9 +1903,8 @@ }, "node_modules/cli-color": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", - "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", "dev": true, + "license": "ISC", "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.61", @@ -2037,8 +1928,7 @@ }, "node_modules/codecs": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/codecs/-/codecs-3.1.0.tgz", - "integrity": "sha512-Dqx8NwvBvnMeuPQdVKy/XEF71igjR5apxBvCGeV0pP1tXadOiaLvDTXt7xh+/5wI1ASB195mXQGJbw3Ml4YDWQ==", + "license": "MIT", "dependencies": { "b4a": "^1.6.3" } @@ -2059,17 +1949,15 @@ }, "node_modules/commander": { "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || >=14" } }, "node_modules/compact-encoding": { "version": "2.12.0", - "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-2.12.0.tgz", - "integrity": "sha512-8eCZLmyBT4LtC90F/ekIqWos8Y7NaFxY75qa/SlSDVa95NVgMcibQb8z8MTeKb9zctemOJczSXMf5pwMqKjYEQ==", + "license": "Apache-2.0", "dependencies": { "b4a": "^1.3.0" } @@ -2101,17 +1989,15 @@ }, "node_modules/cookie": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/corestore": { "version": "6.8.4", - "resolved": "https://registry.npmjs.org/corestore/-/corestore-6.8.4.tgz", - "integrity": "sha512-rJUn1bK2Id18mxZSb64fKGCSsbbBAvPUkSZVzsLB4Nnwhf3pkwxt/JjBvKHtsrvRyPAu9xtxUdUk1cSQ1JnOPw==", + "license": "MIT", "dependencies": { "b4a": "^1.3.1", "hypercore": "^10.12.0", @@ -2140,9 +2026,8 @@ }, "node_modules/cp-file": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-10.0.0.tgz", - "integrity": "sha512-vy2Vi1r2epK5WqxOLnskeKeZkdZvTKfFZQCplE3XWsP+SUJyd5XAUFC9lFgTjjXJF2GMne/UML14iEmkAaDfFg==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.10", "nested-error-stacks": "^2.1.1", @@ -2157,9 +2042,8 @@ }, "node_modules/cpy": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/cpy/-/cpy-10.1.0.tgz", - "integrity": "sha512-VC2Gs20JcTyeQob6UViBLnyP0bYHkBh6EiKzot9vi2DmeGlFT9Wd7VG3NBrkNx/jYvFBeyDOMMHdHQhbtKLgHQ==", "dev": true, + "license": "MIT", "dependencies": { "arrify": "^3.0.0", "cp-file": "^10.0.0", @@ -2179,9 +2063,8 @@ }, "node_modules/cpy-cli": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cpy-cli/-/cpy-cli-5.0.0.tgz", - "integrity": "sha512-fb+DZYbL9KHc0BC4NYqGRrDIJZPXUmjjtqdw4XRRg8iV8dIfghUX/WiL+q4/B/KFTy3sK6jsbUhBaz0/Hxg7IQ==", "dev": true, + "license": "MIT", "dependencies": { "cpy": "^10.1.0", "meow": "^12.0.1" @@ -2198,9 +2081,8 @@ }, "node_modules/cpy/node_modules/arrify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", - "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2236,9 +2118,8 @@ }, "node_modules/crypto-random-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^1.0.1" }, @@ -2251,9 +2132,8 @@ }, "node_modules/crypto-random-string/node_modules/type-fest": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -2263,9 +2143,8 @@ }, "node_modules/d": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "dev": true, + "license": "ISC", "dependencies": { "es5-ext": "^0.10.50", "type": "^1.0.1" @@ -2273,8 +2152,7 @@ }, "node_modules/debounceify": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/debounceify/-/debounceify-1.0.0.tgz", - "integrity": "sha512-7BeSMAPUohdDJ7sU6Tq2M8HkJR05IqQCeVm/qNemrpOgP5SGZD5WeNOXNfsgbESinz6OjMooWPTGZiKUX91XJQ==" + "license": "MIT" }, "node_modules/debug": { "version": "4.3.4", @@ -2293,17 +2171,15 @@ }, "node_modules/debugging-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/debugging-stream/-/debugging-stream-2.0.0.tgz", - "integrity": "sha512-xwfl6wB/3xc553uwtGnSa94jFxnGOc02C0WU2Nmzwr80gzeqn1FX4VcbvoKIhe8L/lPq4BTQttAbrTN94uN8rA==", + "license": "MIT", "dependencies": { "streamx": "^2.12.4" } }, "node_modules/decamelize": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -2313,9 +2189,8 @@ }, "node_modules/decamelize-keys": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-2.0.1.tgz", - "integrity": "sha512-nrNeSCtU2gV3Apcmn/EZ+aR20zKDuNDStV67jPiupokD3sOAFeMzslLMCFdKv1sPqzwoe5ZUhsSW9IAVgKSL/Q==", "dev": true, + "license": "MIT", "dependencies": { "decamelize": "^6.0.0", "map-obj": "^4.3.0", @@ -2331,9 +2206,8 @@ }, "node_modules/decamelize-keys/node_modules/map-obj": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -2341,18 +2215,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decamelize-keys/node_modules/quick-lru": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz", - "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/decompress-response": { "version": "6.0.0", "license": "MIT", @@ -2380,9 +2242,8 @@ }, "node_modules/define-properties": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dev": true, + "license": "MIT", "dependencies": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" @@ -2485,8 +2346,7 @@ }, "node_modules/dht-rpc": { "version": "6.7.0", - "resolved": "https://registry.npmjs.org/dht-rpc/-/dht-rpc-6.7.0.tgz", - "integrity": "sha512-owzv0fEPFD+5xkkm5fpD9i1tRcpxY8SbAhM+JHnDlcICuNMaPWvzUI+2fg4su6YteKXlShshsAEGy//vfT7pHg==", + "license": "MIT", "dependencies": { "b4a": "^1.6.1", "compact-encoding": "^2.11.0", @@ -2503,21 +2363,15 @@ }, "node_modules/difflib": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", "dev": true, "dependencies": { "heap": ">= 0.2.0" - }, - "engines": { - "node": "*" } }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -2554,18 +2408,16 @@ }, "node_modules/dprint-node": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/dprint-node/-/dprint-node-1.0.7.tgz", - "integrity": "sha512-NTZOW9A7ipb0n7z7nC3wftvsbceircwVHSgzobJsEQa+7RnOMbhrfX5IflA6CtC4GA63DSAiHYXa4JKEy9F7cA==", "dev": true, + "license": "MIT", "dependencies": { "detect-libc": "^1.0.3" } }, "node_modules/dprint-node/node_modules/detect-libc": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, + "license": "Apache-2.0", "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -2575,8 +2427,6 @@ }, "node_modules/dreamopt": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/dreamopt/-/dreamopt-0.8.0.tgz", - "integrity": "sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==", "dev": true, "dependencies": { "wordwrap": ">=0.0.2" @@ -2587,9 +2437,8 @@ }, "node_modules/drizzle-kit": { "version": "0.19.12", - "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.19.12.tgz", - "integrity": "sha512-rcsmh5gUIkvuD0WrbEc+aLpqY2q2J8ltynRcJiJo2l01hhsYvPnX0sgxWlFXlfAIa5ZXNw2nJZhYlslI6tG3MA==", "dev": true, + "license": "MIT", "dependencies": { "@drizzle-team/studio": "^0.0.5", "@esbuild-kit/esm-loader": "^2.5.5", @@ -2610,18 +2459,16 @@ }, "node_modules/drizzle-kit/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/drizzle-kit/node_modules/camelcase": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -2631,9 +2478,8 @@ }, "node_modules/drizzle-kit/node_modules/chalk": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -2643,9 +2489,8 @@ }, "node_modules/drizzle-kit/node_modules/minimatch": { "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -2658,8 +2503,7 @@ }, "node_modules/drizzle-orm": { "version": "0.28.2", - "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.28.2.tgz", - "integrity": "sha512-QRyuzvpJr7GE6LpvZ/sg2nAKNg2if1uGGkgFTiXn4auuYId//vVJe6HBsDTktfKfcaDGzIYos+/f+PS5EkBmrg==", + "license": "Apache-2.0", "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=3", @@ -2754,8 +2598,7 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "license": "MIT" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -2786,9 +2629,8 @@ }, "node_modules/es-abstract": { "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", "dev": true, + "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.1", @@ -2839,9 +2681,8 @@ }, "node_modules/es-set-tostringtag": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3", "has": "^1.0.3", @@ -2853,9 +2694,8 @@ }, "node_modules/es-to-primitive": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -2870,10 +2710,9 @@ }, "node_modules/es5-ext": { "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", "dev": true, "hasInstallScript": true, + "license": "ISC", "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", @@ -2885,9 +2724,8 @@ }, "node_modules/es6-iterator": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "dev": true, + "license": "MIT", "dependencies": { "d": "1", "es5-ext": "^0.10.35", @@ -2896,9 +2734,8 @@ }, "node_modules/es6-symbol": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dev": true, + "license": "ISC", "dependencies": { "d": "^1.0.1", "ext": "^1.1.2" @@ -2906,9 +2743,8 @@ }, "node_modules/es6-weak-map": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "dev": true, + "license": "ISC", "dependencies": { "d": "1", "es5-ext": "^0.10.46", @@ -2918,10 +2754,9 @@ }, "node_modules/esbuild": { "version": "0.18.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.17.tgz", - "integrity": "sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -2955,9 +2790,8 @@ }, "node_modules/esbuild-register": { "version": "3.4.2", - "resolved": "https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.4.2.tgz", - "integrity": "sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -2986,9 +2820,8 @@ }, "node_modules/eslint": { "version": "8.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", - "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", @@ -3043,9 +2876,8 @@ }, "node_modules/eslint-scope": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -3059,9 +2891,8 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -3071,9 +2902,8 @@ }, "node_modules/espree": { "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", @@ -3100,9 +2930,8 @@ }, "node_modules/esquery": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -3112,9 +2941,8 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -3124,9 +2952,8 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -3146,9 +2973,8 @@ }, "node_modules/event-emitter": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "dev": true, + "license": "MIT", "dependencies": { "d": "1", "es5-ext": "~0.10.14" @@ -3156,9 +2982,8 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3184,30 +3009,26 @@ }, "node_modules/ext": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", "dev": true, + "license": "ISC", "dependencies": { "type": "^2.7.2" } }, "node_modules/ext/node_modules/type": { "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fast-content-type-parse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.0.0.tgz", - "integrity": "sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", - "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -3219,9 +3040,8 @@ }, "node_modules/fast-glob": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3235,9 +3055,8 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -3247,15 +3066,13 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-json-stringify": { "version": "5.7.0", - "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.7.0.tgz", - "integrity": "sha512-sBVPTgnAZseLu1Qgj6lUbQ0HfjFhZWXAmpZ5AaSGkyLh5gAXBga/uPJjQPHpDFjC9adWIpdOcCLSDTgrZ7snoQ==", "dev": true, + "license": "MIT", "dependencies": { "@fastify/deepmerge": "^1.0.0", "ajv": "^8.10.0", @@ -3267,9 +3084,8 @@ }, "node_modules/fast-json-stringify/node_modules/ajv": { "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -3283,9 +3099,8 @@ }, "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -3294,38 +3109,33 @@ }, "node_modules/fast-querystring": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", - "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", "dev": true, + "license": "MIT", "dependencies": { "fast-decode-uri-component": "^1.0.1" } }, "node_modules/fast-redact": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.2.0.tgz", - "integrity": "sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/fast-safe-stringify": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + "license": "MIT" }, "node_modules/fast-uri": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.2.0.tgz", - "integrity": "sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastify": { "version": "4.20.0", - "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.20.0.tgz", - "integrity": "sha512-zWWi5KGAb1YZ6fyrnFnA1CA1EZHkGM6YuELgB3QpS3l4lLRy14W1cc16b4KGPH/zQ98WCSdS+T41JkHY3eq1oA==", "dev": true, + "license": "MIT", "dependencies": { "@fastify/ajv-compiler": "^3.5.0", "@fastify/error": "^3.2.0", @@ -3347,14 +3157,12 @@ }, "node_modules/fastify-plugin": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.0.tgz", - "integrity": "sha512-79ak0JxddO0utAXAQ5ccKhvs6vX2MGyHHMMsmZkBANrq3hXc1CHzvNPHOcvTsVMEPl5I+NT+RO4YKMGehOfSIg==" + "license": "MIT" }, "node_modules/fastify/node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -3400,9 +3208,8 @@ }, "node_modules/find-my-way": { "version": "7.6.2", - "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-7.6.2.tgz", - "integrity": "sha512-0OjHn1b1nCX3eVbm9ByeEHiscPYiHLfhei1wOUU9qffQkk98wE0Lo8VrVYfSGMgnSnDh86DxedduAnBf4nwUEw==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-querystring": "^1.0.0", @@ -3449,9 +3256,8 @@ }, "node_modules/flat-cache/node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3469,9 +3275,8 @@ }, "node_modules/flat-cache/node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -3493,9 +3298,8 @@ }, "node_modules/for-each": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "license": "MIT", "dependencies": { "is-callable": "^1.1.3" } @@ -3514,9 +3318,8 @@ }, "node_modules/forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3571,9 +3374,8 @@ }, "node_modules/function.prototype.name": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -3589,9 +3391,8 @@ }, "node_modules/functions-have-names": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3606,9 +3407,8 @@ }, "node_modules/get-intrinsic": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -3621,9 +3421,8 @@ }, "node_modules/get-symbol-description": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -3637,9 +3436,8 @@ }, "node_modules/get-tsconfig": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.2.tgz", - "integrity": "sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -3653,9 +3451,8 @@ }, "node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3702,9 +3499,8 @@ }, "node_modules/globals": { "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -3717,9 +3513,8 @@ }, "node_modules/globals/node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -3729,9 +3524,8 @@ }, "node_modules/globalthis": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, + "license": "MIT", "dependencies": { "define-properties": "^1.1.3" }, @@ -3744,9 +3538,8 @@ }, "node_modules/globby": { "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "dev": true, + "license": "MIT", "dependencies": { "dir-glob": "^3.0.1", "fast-glob": "^3.3.0", @@ -3763,9 +3556,8 @@ }, "node_modules/gopd": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -3775,8 +3567,7 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "license": "ISC" }, "node_modules/grapheme-splitter": { "version": "1.0.4", @@ -3804,9 +3595,8 @@ }, "node_modules/hanji": { "version": "0.0.5", - "resolved": "https://registry.npmjs.org/hanji/-/hanji-0.0.5.tgz", - "integrity": "sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==", "dev": true, + "license": "ISC", "dependencies": { "lodash.throttle": "^4.1.1", "sisteransi": "^1.0.5" @@ -3814,9 +3604,8 @@ }, "node_modules/hard-rejection": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3833,9 +3622,8 @@ }, "node_modules/has-bigints": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3849,9 +3637,8 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.1" }, @@ -3861,9 +3648,8 @@ }, "node_modules/has-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3873,9 +3659,8 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3885,9 +3670,8 @@ }, "node_modules/has-tostringtag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -3900,15 +3684,13 @@ }, "node_modules/heap": { "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/hosted-git-info": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^7.5.1" }, @@ -3918,9 +3700,8 @@ }, "node_modules/hosted-git-info/node_modules/lru-cache": { "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -3932,8 +3713,7 @@ }, "node_modules/hyperbee": { "version": "2.13.5", - "resolved": "https://registry.npmjs.org/hyperbee/-/hyperbee-2.13.5.tgz", - "integrity": "sha512-hh7njHKT3W4TDFmQTkKCWypzefuXDk2dGyd87KUYw0vtrJeLKxe1pARH/qJ8psCJG9LsuQL2UQR+1dFAqclATA==", + "license": "MIT", "dependencies": { "b4a": "^1.6.0", "codecs": "^3.0.0", @@ -3947,8 +3727,7 @@ }, "node_modules/hyperblobs": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hyperblobs/-/hyperblobs-2.3.0.tgz", - "integrity": "sha512-iBCLVEo6FK+Xd7cpLM3DQ6cTfuMmKPfDZNj5/JqKEgziBEuI0ZGGyMM5dqaVvtRX4s71y8BhrgsDi2p0pWdSmg==", + "license": "MIT", "dependencies": { "b4a": "^1.6.1", "mutexify": "^1.4.0", @@ -3957,8 +3736,7 @@ }, "node_modules/hypercore": { "version": "10.17.0", - "resolved": "https://registry.npmjs.org/hypercore/-/hypercore-10.17.0.tgz", - "integrity": "sha512-Yp9lyfUjp81Gy1nPHemNFtYQtngliCGZ6prH+qxvjr2FPVG1QFtNqtOh+ZxFu4hXZ1dAOLYkQOA7Qq2vjFe64A==", + "license": "MIT", "dependencies": { "@hyperswarm/secret-stream": "^6.0.0", "b4a": "^1.1.0", @@ -3982,8 +3760,7 @@ }, "node_modules/hypercore-crypto": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/hypercore-crypto/-/hypercore-crypto-3.4.0.tgz", - "integrity": "sha512-0cZA1B58p1J84TDbTh8DMMIj7Qr7Rzz8NyGIo+ykUhdwD21gtjiiLWoME92QvN+lgbfu0Zfr9vwxT8sRmyg+AA==", + "license": "MIT", "dependencies": { "b4a": "^1.1.0", "compact-encoding": "^2.5.1", @@ -3992,13 +3769,11 @@ }, "node_modules/hypercore-errors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hypercore-errors/-/hypercore-errors-1.0.0.tgz", - "integrity": "sha512-lYGykNANCfQdvsDNfbAV2RJCu4ITXxFrq3Gf0nDRZEwH0po/rjZdjTLYhzH1mJZNc6toNaD5URBpwqeD/Ug4JA==" + "license": "Apache-2.0" }, "node_modules/hyperdht": { "version": "6.5.3", - "resolved": "https://registry.npmjs.org/hyperdht/-/hyperdht-6.5.3.tgz", - "integrity": "sha512-Zsot2GMOXR3eG2ifg2CKqAlfGa4MP306kpAyWuTrWRjRRynXZq+kRB6RPkZ+AV9+fqMigL3r/AFnKQ1Gwpo+iw==", + "license": "MIT", "dependencies": { "@hyperswarm/secret-stream": "^6.0.0", "b4a": "^1.3.1", @@ -4022,8 +3797,7 @@ }, "node_modules/hyperdrive": { "version": "11.5.3", - "resolved": "https://registry.npmjs.org/hyperdrive/-/hyperdrive-11.5.3.tgz", - "integrity": "sha512-0542G6n9eAXK/+fl6bs+9rvxCrL/dQo9mZsbY+BFSCD3S6ymBlaVnjOCuQdNflYBOHFVNnbBYdDvZ9meInv+tw==", + "license": "Apache-2.0", "dependencies": { "hyperbee": "^2.11.1", "hyperblobs": "^2.3.0", @@ -4039,8 +3813,7 @@ }, "node_modules/hyperswarm": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/hyperswarm/-/hyperswarm-4.4.1.tgz", - "integrity": "sha512-8VLR/DLx6BnZATdCoECwFWasz7tIVdxkwlALT25sV6GEERf2fwttkJrb+5BS9vht/fyXJ4l41x6YgDWCabIoiw==", + "license": "MIT", "dependencies": { "b4a": "^1.3.1", "events": "^3.3.0", @@ -4069,9 +3842,8 @@ }, "node_modules/ignore": { "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -4106,9 +3878,8 @@ }, "node_modules/indent-string": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4134,9 +3905,8 @@ }, "node_modules/internal-slot": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.0", "has": "^1.0.3", @@ -4156,9 +3926,8 @@ }, "node_modules/is-array-buffer": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.0", @@ -4175,9 +3944,8 @@ }, "node_modules/is-bigint": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, + "license": "MIT", "dependencies": { "has-bigints": "^1.0.1" }, @@ -4198,9 +3966,8 @@ }, "node_modules/is-boolean-object": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -4214,9 +3981,8 @@ }, "node_modules/is-callable": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4236,9 +4002,8 @@ }, "node_modules/is-date-object": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -4291,9 +4056,8 @@ }, "node_modules/is-negative-zero": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4310,9 +4074,8 @@ }, "node_modules/is-number-object": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -4340,24 +4103,21 @@ }, "node_modules/is-plain-obj": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-promise": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/is-regex": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -4371,9 +4131,8 @@ }, "node_modules/is-shared-array-buffer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -4383,9 +4142,8 @@ }, "node_modules/is-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -4395,9 +4153,8 @@ }, "node_modules/is-string": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -4410,9 +4167,8 @@ }, "node_modules/is-symbol": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, + "license": "MIT", "dependencies": { "has-symbols": "^1.0.2" }, @@ -4425,9 +4181,8 @@ }, "node_modules/is-typed-array": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, + "license": "MIT", "dependencies": { "which-typed-array": "^1.1.11" }, @@ -4440,9 +4195,8 @@ }, "node_modules/is-weakref": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2" }, @@ -4463,9 +4217,8 @@ }, "node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", @@ -4473,8 +4226,7 @@ }, "node_modules/isomorphic-fetch": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "license": "MIT", "dependencies": { "node-fetch": "^2.6.1", "whatwg-fetch": "^3.4.1" @@ -4515,8 +4267,7 @@ }, "node_modules/jackspeak": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.0.tgz", - "integrity": "sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==", + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -4546,9 +4297,8 @@ }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -4569,9 +4319,8 @@ }, "node_modules/json-diff": { "version": "0.9.0", - "resolved": "https://registry.npmjs.org/json-diff/-/json-diff-0.9.0.tgz", - "integrity": "sha512-cVnggDrVkAAA3OvFfHpFEhOnmcsUpleEKq4d4O8sQWWSH40MBrWstKigVB1kGrgLWzuom+7rRdaCsnBD6VyObQ==", "dev": true, + "license": "MIT", "dependencies": { "cli-color": "^2.0.0", "difflib": "~0.2.1", @@ -4586,9 +4335,8 @@ }, "node_modules/json-parse-better-errors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -4597,9 +4345,8 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify": { "version": "1.0.2", @@ -4630,8 +4377,7 @@ }, "node_modules/jsonc-parser": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" + "license": "MIT" }, "node_modules/jsonfile": { "version": "6.1.0", @@ -4654,9 +4400,8 @@ }, "node_modules/junk": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz", - "integrity": "sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.20" }, @@ -4666,14 +4411,12 @@ }, "node_modules/kademlia-routing-table": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/kademlia-routing-table/-/kademlia-routing-table-1.0.1.tgz", - "integrity": "sha512-dKk19sC3/+kWhBIvOKCthxVV+JH0NrswSBq4sA4eOkkPMqQM1rRuOWte1WSKXeP8r9Nx4NuiH2gny3lMddJTpw==" + "license": "MIT" }, "node_modules/kind-of": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4715,9 +4458,8 @@ }, "node_modules/light-my-request": { "version": "5.10.0", - "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.10.0.tgz", - "integrity": "sha512-ZU2D9GmAcOUculTTdH9/zryej6n8TzT+fNGdNtm6SDp5MMMpHrJJkvAdE3c6d8d2chE9i+a//dS9CWZtisknqA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "cookie": "^0.5.0", "process-warning": "^2.0.0", @@ -4731,9 +4473,8 @@ }, "node_modules/load-json-file": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -4746,9 +4487,8 @@ }, "node_modules/load-json-file/node_modules/parse-json": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, + "license": "MIT", "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -4782,14 +4522,12 @@ }, "node_modules/lodash.throttle": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/long": { "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + "license": "Apache-2.0" }, "node_modules/loose-envify": { "version": "1.4.0", @@ -4814,9 +4552,8 @@ }, "node_modules/lru-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", "dev": true, + "license": "MIT", "dependencies": { "es5-ext": "~0.10.2" } @@ -4827,8 +4564,7 @@ }, "node_modules/magic-bytes.js": { "version": "1.0.14", - "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.0.14.tgz", - "integrity": "sha512-Xz644ideT892A7l9JtYLlVp3KjQc8gHJP9rN6H2Mq8OOld6BMU7xiS9rFGYAXeY7Z/yHOYtFSLyFzL8/NaodPw==" + "license": "MIT" }, "node_modules/magic-string": { "version": "0.25.9", @@ -4865,8 +4601,7 @@ }, "node_modules/marked": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -4876,9 +4611,8 @@ }, "node_modules/memoizee": { "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", "dev": true, + "license": "ISC", "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.53", @@ -4892,8 +4626,6 @@ }, "node_modules/memorystream": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true, "engines": { "node": ">= 0.10.0" @@ -4901,9 +4633,8 @@ }, "node_modules/meow": { "version": "12.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.0.1.tgz", - "integrity": "sha512-/QOqMALNoKQcJAOOdIXjNLtfcCdLXbMFyB1fOOPdm6RzfBTlsuodOCTBDjVbeUSmgDQb8UI2oONqYGtq1PKKKA==", "dev": true, + "license": "MIT", "dependencies": { "@types/minimist": "^1.2.2", "camelcase-keys": "^8.0.2", @@ -4927,26 +4658,23 @@ }, "node_modules/meow/node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -4967,9 +4695,8 @@ }, "node_modules/min-indent": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -4993,9 +4720,8 @@ }, "node_modules/minimist-options": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, + "license": "MIT", "dependencies": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", @@ -5007,25 +4733,22 @@ }, "node_modules/minimist-options/node_modules/arrify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/minipass": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "license": "ISC", "engines": { "node": ">=8" } }, "node_modules/mirror-drive": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/mirror-drive/-/mirror-drive-1.2.1.tgz", - "integrity": "sha512-1Y6vj25cVXIxzkiN9HRPOLunk/KnWAFG+EDHtjMBt/ydaD9UKUsqb0p/ly1ht/vFtDTvWEW5lPoIll6hzvMu3g==", + "license": "MIT", "dependencies": { "binary-stream-equals": "^1.0.0", "same-data": "^1.0.0" @@ -5041,8 +4764,7 @@ }, "node_modules/multi-core-indexer": { "version": "1.0.0-alpha.7", - "resolved": "https://registry.npmjs.org/multi-core-indexer/-/multi-core-indexer-1.0.0-alpha.7.tgz", - "integrity": "sha512-+QR4YTwg1j+t2fN7O4mOYN373pOLb6YhxlPsblb1ENFU99LPQ3PdfRM/FSYUTOf3kMi8C69BRGivIPNCNxmZOw==", + "license": "MIT", "dependencies": { "@types/node": "^18.16.19", "@types/streamx": "^2.9.1", @@ -5092,8 +4814,7 @@ }, "node_modules/mutexify": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/mutexify/-/mutexify-1.4.0.tgz", - "integrity": "sha512-pbYSsOrSB/AKN5h/WzzLRMFgZhClWccf2XIB4RSMC8JbquiB0e0/SH5AIfdQMdyHmYtv4seU7yV/TvAwPLJ1Yg==", + "license": "MIT", "dependencies": { "queue-tick": "^1.0.0" } @@ -5104,9 +4825,8 @@ }, "node_modules/nanobench": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/nanobench/-/nanobench-3.0.0.tgz", - "integrity": "sha512-PaNQpZVmB/hFDQSBExgEJ5/1nzdqaIMUXzwWxFCYRl6j8lFt6kdNAUy1ieyPeMYWQk3AAmRg6UQn4g96J1SgLA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^5.0.1", "mutexify": "^1.4.0", @@ -5119,9 +4839,8 @@ }, "node_modules/nanobench/node_modules/chalk": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", - "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -5150,8 +4869,7 @@ }, "node_modules/nat-sampler": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nat-sampler/-/nat-sampler-1.0.1.tgz", - "integrity": "sha512-yQvyNN7xbqR8crTKk3U8gRgpcV1Az+vfCEijiHu9oHHsnIl8n3x+yXNHl42M6L3czGynAVoOT9TqBfS87gDdcw==" + "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", @@ -5164,21 +4882,18 @@ }, "node_modules/nested-error-stacks": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", - "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/next-tick": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/nice-try": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-abi": { "version": "3.30.0", @@ -5205,8 +4920,7 @@ }, "node_modules/node-fetch": { "version": "2.6.13", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz", - "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==", + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -5233,8 +4947,7 @@ }, "node_modules/noise-curve-ed": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/noise-curve-ed/-/noise-curve-ed-2.0.1.tgz", - "integrity": "sha512-8HMZ40Wmarg8RQjVemLrjB49JSL6eGeOD+tlzaQW5/p+hNPfHFEMC3UZZ57zUqUprMuz6GN+gsPExpz2DWL+iA==", + "license": "ISC", "dependencies": { "b4a": "^1.1.0", "nanoassert": "^2.0.0", @@ -5243,8 +4956,7 @@ }, "node_modules/noise-handshake": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/noise-handshake/-/noise-handshake-3.0.2.tgz", - "integrity": "sha512-4RQ9/6R/GLKA3DPcLDeo954ZBZezHBNpc4YnhyisZ9DPiTRnc81aGdCbH3J9pHllDfj82/f9wKHRRsU7C6pNEg==", + "license": "ISC", "dependencies": { "b4a": "^1.1.0", "nanoassert": "^2.0.0", @@ -5253,9 +4965,8 @@ }, "node_modules/normalize-package-data": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", - "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^6.0.0", "is-core-module": "^2.8.1", @@ -5268,9 +4979,8 @@ }, "node_modules/normalize-package-data/node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -5291,9 +5001,8 @@ }, "node_modules/npm-run-all": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "chalk": "^2.4.1", @@ -5316,9 +5025,8 @@ }, "node_modules/npm-run-all/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -5328,9 +5036,8 @@ }, "node_modules/npm-run-all/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -5342,24 +5049,21 @@ }, "node_modules/npm-run-all/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/npm-run-all/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/npm-run-all/node_modules/cross-spawn": { "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, + "license": "MIT", "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -5373,33 +5077,29 @@ }, "node_modules/npm-run-all/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/npm-run-all/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/npm-run-all/node_modules/hosted-git-info": { "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/npm-run-all/node_modules/normalize-package-data": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -5409,18 +5109,16 @@ }, "node_modules/npm-run-all/node_modules/path-key": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/npm-run-all/node_modules/path-type": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^3.0.0" }, @@ -5430,9 +5128,8 @@ }, "node_modules/npm-run-all/node_modules/read-pkg": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, + "license": "MIT", "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -5444,18 +5141,16 @@ }, "node_modules/npm-run-all/node_modules/semver": { "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/npm-run-all/node_modules/shebang-command": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^1.0.0" }, @@ -5465,18 +5160,16 @@ }, "node_modules/npm-run-all/node_modules/shebang-regex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/npm-run-all/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -5486,9 +5179,8 @@ }, "node_modules/npm-run-all/node_modules/which": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5498,27 +5190,24 @@ }, "node_modules/object-inspect": { "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -5534,9 +5223,8 @@ }, "node_modules/on-exit-leak-free": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", - "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/once": { "version": "1.4.0", @@ -5586,8 +5274,7 @@ }, "node_modules/p-defer": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.0.tgz", - "integrity": "sha512-Vb3QRvQ0Y5XnF40ZUWW7JfLogicVh/EnA5gBIvKDJoYpeI82+1E3AlB9yOcKFS0AhHrWVnAQO39fbR0G99IVEQ==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -5597,9 +5284,8 @@ }, "node_modules/p-event": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", - "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", "dev": true, + "license": "MIT", "dependencies": { "p-timeout": "^5.0.2" }, @@ -5612,9 +5298,8 @@ }, "node_modules/p-event/node_modules/p-timeout": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", - "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -5624,9 +5309,8 @@ }, "node_modules/p-filter": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", - "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", "dev": true, + "license": "MIT", "dependencies": { "p-map": "^5.1.0" }, @@ -5639,9 +5323,8 @@ }, "node_modules/p-filter/node_modules/p-map": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", - "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", "dev": true, + "license": "MIT", "dependencies": { "aggregate-error": "^4.0.0" }, @@ -5682,9 +5365,8 @@ }, "node_modules/p-map": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-6.0.0.tgz", - "integrity": "sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -5848,8 +5530,7 @@ }, "node_modules/path-scurry": { "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -5863,8 +5544,7 @@ }, "node_modules/path-scurry/node_modules/lru-cache": { "version": "9.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.1.tgz", - "integrity": "sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==", + "license": "ISC", "engines": { "node": "14 || >=16.14" } @@ -5894,9 +5574,8 @@ }, "node_modules/pidtree": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", "dev": true, + "license": "MIT", "bin": { "pidtree": "bin/pidtree.js" }, @@ -5906,18 +5585,16 @@ }, "node_modules/pify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/pino": { "version": "8.14.1", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.14.1.tgz", - "integrity": "sha512-8LYNv7BKWXSfS+k6oEc6occy5La+q2sPwU3q2ljTX5AZk7v+5kND2o5W794FyRaqha6DJajmkNRsWtPpFyMUdw==", "dev": true, + "license": "MIT", "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", @@ -5937,9 +5614,8 @@ }, "node_modules/pino-abstract-transport": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", - "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", "dev": true, + "license": "MIT", "dependencies": { "readable-stream": "^4.0.0", "split2": "^4.0.0" @@ -5947,8 +5623,6 @@ }, "node_modules/pino-abstract-transport/node_modules/buffer": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, "funding": [ { @@ -5964,6 +5638,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -5971,9 +5646,8 @@ }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", - "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", "dev": true, + "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -5987,9 +5661,8 @@ }, "node_modules/pino-std-serializers": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", - "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/please-upgrade-node": { "version": "3.2.0", @@ -6056,9 +5729,8 @@ }, "node_modules/prettier": { "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -6071,33 +5743,29 @@ }, "node_modules/pretty-hrtime": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/process-warning": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", - "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/protobufjs": { "version": "7.2.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", - "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", "hasInstallScript": true, + "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -6118,8 +5786,7 @@ }, "node_modules/protocol-buffers-encodings": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/protocol-buffers-encodings/-/protocol-buffers-encodings-1.2.0.tgz", - "integrity": "sha512-daeNPuKh1NlLD1uDfbLpD+xyUTc07nEtfHwmBZmt/vH0B7VOM+JOCOpDcx9ZRpqHjAiIkGqyTDi+wfGSl17R9w==", + "license": "MIT", "dependencies": { "b4a": "^1.6.0", "signed-varint": "^2.0.1", @@ -6133,8 +5800,7 @@ }, "node_modules/protomux": { "version": "3.4.1", - "resolved": "https://registry.npmjs.org/protomux/-/protomux-3.4.1.tgz", - "integrity": "sha512-V8MDCiDGqxM4/hGOewmezbCX7HZfcYGtpdO0MK6pEhBLSknENuqqE98OEWyQuwDalfHULVO8ml7LSwTB5g5Z6g==", + "license": "MIT", "dependencies": { "b4a": "^1.3.1", "compact-encoding": "^2.5.1", @@ -6144,9 +5810,8 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -6157,9 +5822,8 @@ }, "node_modules/proxy-addr/node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -6213,9 +5877,19 @@ }, "node_modules/quick-format-unescaped": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", - "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "6.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/quickbit-native": { "version": "2.2.0", @@ -6243,8 +5917,7 @@ }, "node_modules/random-access-file": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-4.0.4.tgz", - "integrity": "sha512-1W21gZ8ne3RgPyTNpq8INr7feTY0+hPpV4X59yL9Miv5QiZV7U1QpRb/zEG2IuaojW9qVTeWBC19Ty0m0uqFBg==", + "license": "MIT", "dependencies": { "random-access-storage": "^3.0.0" }, @@ -6254,9 +5927,8 @@ }, "node_modules/random-access-memory": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/random-access-memory/-/random-access-memory-6.2.0.tgz", - "integrity": "sha512-5gRsd32lQd87tHM1ODkrBsvTnQ00GMw5KjeiSFWjEeTkv6E4zSTewUaHRxDbfk+lroRaunAEECGo/gNnq1T/HQ==", "dev": true, + "license": "MIT", "dependencies": { "b4a": "^1.6.0", "is-options": "^1.0.2", @@ -6297,9 +5969,8 @@ }, "node_modules/read-pkg": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-7.1.0.tgz", - "integrity": "sha512-5iOehe+WF75IccPc30bWTbpdDQLOCc3Uu8bi3Dte3Eueij81yx1Mrufk8qBx/YAbR4uL1FdUr+7BKXDwEtisXg==", "dev": true, + "license": "MIT", "dependencies": { "@types/normalize-package-data": "^2.4.1", "normalize-package-data": "^3.0.2", @@ -6315,9 +5986,8 @@ }, "node_modules/read-pkg-up": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-9.1.0.tgz", - "integrity": "sha512-vaMRR1AC1nrd5CQM0PhlRsO5oc2AAigqr7cCrZ/MW/Rsaflz4RlgzkpL4qoU/z1F6wrbd85iFv1OQj/y5RdGvg==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^6.3.0", "read-pkg": "^7.1.0", @@ -6332,9 +6002,8 @@ }, "node_modules/read-pkg-up/node_modules/find-up": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^7.1.0", "path-exists": "^5.0.0" @@ -6348,9 +6017,8 @@ }, "node_modules/read-pkg-up/node_modules/locate-path": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^6.0.0" }, @@ -6363,9 +6031,8 @@ }, "node_modules/read-pkg-up/node_modules/p-limit": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^1.0.0" }, @@ -6378,9 +6045,8 @@ }, "node_modules/read-pkg-up/node_modules/p-locate": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^4.0.0" }, @@ -6393,18 +6059,16 @@ }, "node_modules/read-pkg-up/node_modules/path-exists": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/read-pkg-up/node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -6414,9 +6078,8 @@ }, "node_modules/read-pkg-up/node_modules/yocto-queue": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.20" }, @@ -6426,9 +6089,8 @@ }, "node_modules/read-pkg/node_modules/hosted-git-info": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -6438,9 +6100,8 @@ }, "node_modules/read-pkg/node_modules/normalize-package-data": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", @@ -6453,9 +6114,8 @@ }, "node_modules/read-pkg/node_modules/semver": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -6468,9 +6128,8 @@ }, "node_modules/read-pkg/node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -6480,8 +6139,7 @@ }, "node_modules/read-write-mutexify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/read-write-mutexify/-/read-write-mutexify-2.1.0.tgz", - "integrity": "sha512-fDw/p5/acI1ytVY1UbxEDma/ej1yJH/n9NcjS9YNzcE6sPBPWdlru3ydRa/UBowUg4zqOvNMD5SOGYJrlQ6MzQ==" + "license": "MIT" }, "node_modules/readable-stream": { "version": "3.6.0", @@ -6508,31 +6166,27 @@ }, "node_modules/ready-resource": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ready-resource/-/ready-resource-1.0.0.tgz", - "integrity": "sha512-9/Oj3DXv+QxWinvVcxVVRXn9Jj4b9wssv0PvQh5bO+N/vzqo6kmScUNl+faWWMEu0rYMPa6Tvp50+rP5ujZvqg==" + "license": "MIT" }, "node_modules/real-require": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", - "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12.13.0" } }, "node_modules/record-cache": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/record-cache/-/record-cache-1.2.0.tgz", - "integrity": "sha512-kyy3HWCez2WrotaL3O4fTn0rsIdfRKOdQQcEJ9KpvmKmbffKVvwsloX063EgRUlpJIXHiDQFhJcTbZequ2uTZw==", + "license": "MIT", "dependencies": { "b4a": "^1.3.1" } }, "node_modules/redent": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", - "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", "dev": true, + "license": "MIT", "dependencies": { "indent-string": "^5.0.0", "strip-indent": "^4.0.0" @@ -6546,9 +6200,8 @@ }, "node_modules/regexp.prototype.flags": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -6606,18 +6259,16 @@ }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, "node_modules/ret": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", - "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -6633,15 +6284,13 @@ }, "node_modules/rfdc": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/rimraf": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^10.2.5" }, @@ -6657,18 +6306,16 @@ }, "node_modules/rimraf/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/rimraf/node_modules/foreground-child": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -6682,9 +6329,8 @@ }, "node_modules/rimraf/node_modules/glob": { "version": "10.3.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", - "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.0.3", @@ -6704,9 +6350,8 @@ }, "node_modules/rimraf/node_modules/minimatch": { "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6719,9 +6364,8 @@ }, "node_modules/rimraf/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -6790,9 +6434,8 @@ }, "node_modules/safe-array-concat": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.0", @@ -6826,9 +6469,8 @@ }, "node_modules/safe-regex-test": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -6840,37 +6482,32 @@ }, "node_modules/safe-regex2": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz", - "integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==", "dev": true, + "license": "MIT", "dependencies": { "ret": "~0.2.0" } }, "node_modules/safe-stable-stringify": { "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/safety-catch": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/safety-catch/-/safety-catch-1.0.2.tgz", - "integrity": "sha512-C1UYVZ4dtbBxEtvOcpjBaaD27nP8MlvyAQEp2fOTOEe6pfUpk1cDUxij6BR1jZup6rSyUTaBBplK7LanskrULA==" + "license": "MIT" }, "node_modules/same-data": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/same-data/-/same-data-1.0.0.tgz", - "integrity": "sha512-Eqn7N2yV+aKMlUHTRqUwYG1Iv0cJqjlvLKj/GoP5PozJn361QaOYX14+v87r7NqQUZC22noP/LfLrSQiPwAygw==" + "license": "MIT" }, "node_modules/same-object": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/same-object/-/same-object-1.0.2.tgz", - "integrity": "sha512-csHWhvUsLbIOHDM/nP+KHWM+BLPsIzWkFa8HbzaI0G7BqKXgx+7FJpKTGgLXyz5amfdY2OVBcmXTqYOMEk04og==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/sass": { "version": "1.56.2", @@ -6902,9 +6539,8 @@ }, "node_modules/secure-json-parse": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/semver": { "version": "6.3.0", @@ -6946,9 +6582,8 @@ }, "node_modules/set-cookie-parser": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", - "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/sha256-universal": { "version": "1.2.1", @@ -7001,17 +6636,15 @@ }, "node_modules/shell-quote": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/shiki": { "version": "0.14.2", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.2.tgz", - "integrity": "sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==", + "license": "MIT", "dependencies": { "ansi-sequence-parser": "^1.1.0", "jsonc-parser": "^3.2.0", @@ -7028,9 +6661,8 @@ }, "node_modules/side-channel": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -7047,8 +6679,7 @@ }, "node_modules/signed-varint": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/signed-varint/-/signed-varint-2.0.1.tgz", - "integrity": "sha512-abgDPg1106vuZZOvw7cFwdCABddfJRz5akcCcchzTbhyhYnsG31y4AlZEgp315T7W3nQq5P4xeOm186ZiPVFzw==", + "license": "MIT", "dependencies": { "varint": "~5.0.0" } @@ -7060,9 +6691,8 @@ }, "node_modules/simdle-native": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/simdle-native/-/simdle-native-1.1.3.tgz", - "integrity": "sha512-KuD5YD9kyZ7kOEhPWNyQnL+NIGSmYnykjvQ6Yc4RBpJVYcl7bx4z9Jx3bODwVqNhOgbwXbZUOoFXol9/VG74EA==", "hasInstallScript": true, + "license": "Apache-2.0", "optional": true, "dependencies": { "b4a": "^1.6.0", @@ -7072,8 +6702,7 @@ }, "node_modules/simdle-universal": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/simdle-universal/-/simdle-universal-1.1.2.tgz", - "integrity": "sha512-3n3w1bs+uwgHKQjt6arez83EywNlhZzYvNOhvAASTl/8KqNIcqr6aHyGt3JRlfuUC7iB0tomJRPlJ2cRGIpBzA==", + "license": "ISC", "dependencies": { "b4a": "^1.6.0" }, @@ -7131,15 +6760,13 @@ }, "node_modules/sisteransi": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -7170,8 +6797,7 @@ }, "node_modules/sodium-secretstream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/sodium-secretstream/-/sodium-secretstream-1.1.0.tgz", - "integrity": "sha512-Qg7D2xomELDjDCWAmE4izk1aecG/il8pQIGmSWFaKgah/V58BVWG/PuSZF6vseTpcqnetIFGaOWzmPNzyTD50A==", + "license": "MIT", "dependencies": { "b4a": "^1.1.1", "sodium-universal": "^4.0.0" @@ -7179,8 +6805,7 @@ }, "node_modules/sodium-universal": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.0.tgz", - "integrity": "sha512-iKHl8XnBV96k1c75gwwzANFdephw/MDWSjQAjPmBE+du0y3P23Q8uf7AcdcfFsYAMwLg7WVBfSAIBtV/JvRsjA==", + "license": "MIT", "dependencies": { "blake2b": "^2.1.1", "chacha20-universal": "^1.0.4", @@ -7195,18 +6820,16 @@ }, "node_modules/sodium-universal/node_modules/sodium-native": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.0.1.tgz", - "integrity": "sha512-OQTaxrVLtMvrnfcwZVsOTHe58MfDApJiHJNoOwcmmrhwvlYkfaUt2WuzRio8PgEMOd96R5aDHY49DCtock1zsA==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "node-gyp-build": "^4.3.0" } }, "node_modules/sonic-boom": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", - "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", "dev": true, + "license": "MIT", "dependencies": { "atomic-sleep": "^1.0.0" } @@ -7228,9 +6851,8 @@ }, "node_modules/source-map-support": { "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -7243,9 +6865,8 @@ }, "node_modules/spdx-correct": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -7253,15 +6874,13 @@ }, "node_modules/spdx-exceptions": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true + "dev": true, + "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, + "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -7269,15 +6888,13 @@ }, "node_modules/spdx-license-ids": { "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", - "dev": true + "dev": true, + "license": "CC0-1.0" }, "node_modules/split2": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, + "license": "ISC", "engines": { "node": ">= 10.x" } @@ -7307,8 +6924,7 @@ }, "node_modules/streamx": { "version": "2.15.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", - "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", + "license": "MIT", "dependencies": { "fast-fifo": "^1.1.0", "queue-tick": "^1.0.1" @@ -7336,8 +6952,7 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7349,9 +6964,8 @@ }, "node_modules/string.prototype.padend": { "version": "3.1.4", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz", - "integrity": "sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -7366,9 +6980,8 @@ }, "node_modules/string.prototype.trim": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -7383,9 +6996,8 @@ }, "node_modules/string.prototype.trimend": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -7397,9 +7009,8 @@ }, "node_modules/string.prototype.trimstart": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -7422,8 +7033,7 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -7433,18 +7043,16 @@ }, "node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/strip-indent": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", - "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", "dev": true, + "license": "MIT", "dependencies": { "min-indent": "^1.0.1" }, @@ -7457,9 +7065,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -7469,8 +7076,7 @@ }, "node_modules/sub-encoder": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/sub-encoder/-/sub-encoder-2.1.1.tgz", - "integrity": "sha512-Xfza05u5b26tYB0uiTZLPvKis0gSf8VaX8IZNgtRSHzXiYW7SWHJe6vfRVP+wuK8GAqwhGJQwQ03E5HX7W5+YA==", + "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.0", "codecs": "^3.1.0" @@ -7522,18 +7128,16 @@ }, "node_modules/temp-dir": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", - "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" } }, "node_modules/tempy": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", - "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", "dev": true, + "license": "MIT", "dependencies": { "is-stream": "^3.0.0", "temp-dir": "^3.0.0", @@ -7549,9 +7153,8 @@ }, "node_modules/tempy/node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -7598,9 +7201,8 @@ }, "node_modules/thread-stream": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", - "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", "dev": true, + "license": "MIT", "dependencies": { "real-require": "^0.2.0" } @@ -7620,8 +7222,7 @@ }, "node_modules/time-ordered-set": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/time-ordered-set/-/time-ordered-set-1.0.2.tgz", - "integrity": "sha512-vGO99JkxvgX+u+LtOKQEpYf31Kj3i/GNwVstfnh4dyINakMgeZCpew1e3Aj+06hEslhtHEd52g7m5IV+o1K8Mw==" + "license": "MIT" }, "node_modules/timeout-refresh": { "version": "2.0.1", @@ -7629,9 +7230,8 @@ }, "node_modules/timers-ext": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", "dev": true, + "license": "ISC", "dependencies": { "es5-ext": "~0.10.46", "next-tick": "1" @@ -7639,17 +7239,15 @@ }, "node_modules/tiny-lru": { "version": "11.0.1", - "resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-11.0.1.tgz", - "integrity": "sha512-iNgFugVuQgBKrqeO/mpiTTgmBsTP0WL6yeuLfLs/Ctf0pI/ixGqIRm8sDCwMcXGe9WWvt2sGXI5mNqZbValmJg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=12" } }, "node_modules/tiny-typed-emitter": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", - "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==" + "license": "MIT" }, "node_modules/tmatch": { "version": "5.0.0", @@ -7690,14 +7288,12 @@ }, "node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "license": "MIT" }, "node_modules/trim-newlines": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-5.0.0.tgz", - "integrity": "sha512-kstfs+hgwmdsOadN3KgA+C68wPJwnZq4DN6WMDCvZapDWEF34W2TyPKN2v2+BJnZgIz5QOfxFeldLyYvdgRAwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -7707,18 +7303,16 @@ }, "node_modules/ts-poet": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-6.5.0.tgz", - "integrity": "sha512-44jURLT1HG6+NsDcadM826V6Ekux+wk07Go+MX5Gfx+8zcPKfUiFEtnjL9imuRVGSCRtloRLqw4bDGZVJYGZMQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "dprint-node": "^1.0.7" } }, "node_modules/ts-proto": { "version": "1.156.7", - "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.156.7.tgz", - "integrity": "sha512-vuSby+Mx0CniXscbHx9ieKCEErGBuie12RmduPA67p27Io5C0gkzlMnyN/j3vKWAJrP/h6+mbAoo6WrlalOt7w==", "dev": true, + "license": "ISC", "dependencies": { "case-anything": "^2.1.13", "protobufjs": "^7.2.4", @@ -7731,9 +7325,8 @@ }, "node_modules/ts-proto-descriptors": { "version": "1.15.0", - "resolved": "https://registry.npmjs.org/ts-proto-descriptors/-/ts-proto-descriptors-1.15.0.tgz", - "integrity": "sha512-TYyJ7+H+7Jsqawdv+mfsEpZPTIj9siDHS6EMCzG/z3b/PZiphsX+mWtqFfFVe5/N0Th6V3elK9lQqjnrgTOfrg==", "dev": true, + "license": "ISC", "dependencies": { "long": "^5.2.3", "protobufjs": "^7.2.4" @@ -7751,9 +7344,8 @@ }, "node_modules/type": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/type-check": { "version": "0.4.0", @@ -7768,18 +7360,16 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "3.10.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.10.0.tgz", - "integrity": "sha512-hmAPf1datm+gt3c2mvu0sJyhFy6lTkIGf0GzyaZWxRLnabQfPUqg6tF95RPg6sLxKI7nFLGdFxBcf2/7+GXI+A==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=14.16" }, @@ -7792,9 +7382,8 @@ }, "node_modules/typed-array-buffer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -7806,9 +7395,8 @@ }, "node_modules/typed-array-byte-length": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -7824,9 +7412,8 @@ }, "node_modules/typed-array-byte-offset": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -7843,9 +7430,8 @@ }, "node_modules/typed-array-length": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -7857,8 +7443,7 @@ }, "node_modules/typedoc": { "version": "0.24.8", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.24.8.tgz", - "integrity": "sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==", + "license": "Apache-2.0", "dependencies": { "lunr": "^2.3.9", "marked": "^4.3.0", @@ -7877,8 +7462,7 @@ }, "node_modules/typedoc-plugin-markdown": { "version": "3.15.4", - "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.15.4.tgz", - "integrity": "sha512-KpjFL/NDrQAbY147oIoOgob2vAdEchsMcTVd6+e6H2lC1l5xhi48bhP/fMJI7qYQ8th5nubervgqw51z7gY66A==", + "license": "MIT", "dependencies": { "handlebars": "^4.7.7" }, @@ -7888,16 +7472,14 @@ }, "node_modules/typedoc/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/typedoc/node_modules/minimatch": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz", - "integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -7910,8 +7492,7 @@ }, "node_modules/typescript": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7922,9 +7503,8 @@ }, "node_modules/udx-native": { "version": "1.5.5", - "resolved": "https://registry.npmjs.org/udx-native/-/udx-native-1.5.5.tgz", - "integrity": "sha512-jBDQvkX5DkgX0vxRzhe8COv6P9lIZnqTUSfdD0j578fLZINBAtab7DfUXg8bUodOm140h5s94FK+/zCXNLWJvw==", "hasInstallScript": true, + "license": "MIT", "dependencies": { "b4a": "^1.5.0", "events": "^3.3.0", @@ -7946,9 +7526,8 @@ }, "node_modules/unbox-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, + "license": "MIT", "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -7961,9 +7540,8 @@ }, "node_modules/unique-string": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", "dev": true, + "license": "MIT", "dependencies": { "crypto-random-string": "^4.0.0" }, @@ -7984,8 +7562,7 @@ }, "node_modules/unix-path-resolve": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unix-path-resolve/-/unix-path-resolve-1.0.2.tgz", - "integrity": "sha512-kG4g5nobBBaMnH2XbrS4sLUXEpx4nY2J3C6KAlAUcnahG2HChxSPVKWYrqEq76iTo+cyMkLUjqxGaQR2tz097Q==" + "license": "MIT" }, "node_modules/unordered-set": { "version": "2.0.1", @@ -8017,9 +7594,8 @@ }, "node_modules/validate-npm-package-license": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, + "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -8054,28 +7630,23 @@ }, "node_modules/vscode-oniguruma": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" + "license": "MIT" }, "node_modules/vscode-textmate": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" + "license": "MIT" }, "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "license": "BSD-2-Clause" }, "node_modules/whatwg-fetch": { "version": "3.6.17", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.17.tgz", - "integrity": "sha512-c4ghIvG6th0eudYwKZY5keb81wtFz9/WeAHAoy8+r18kcWlitUIrmGFQ2rWEl4UCKUilD3zCLHOIPheHx5ypRQ==" + "license": "MIT" }, "node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -8096,9 +7667,8 @@ }, "node_modules/which-boxed-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, + "license": "MIT", "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -8112,9 +7682,8 @@ }, "node_modules/which-typed-array": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", "dev": true, + "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -8160,8 +7729,7 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -8252,9 +7820,8 @@ }, "node_modules/zod": { "version": "3.21.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", - "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 79e7470f..15665a99 100644 --- a/package.json +++ b/package.json @@ -106,9 +106,9 @@ "b4a": "^1.6.3", "base32.js": "^0.1.0", "better-sqlite3": "^8.3.0", + "big-sparse-array": "^1.0.3", "bogon": "^1.1.0", "bonjour-service": "^1.1.1", - "big-sparse-array": "^1.0.3", "compact-encoding": "^2.12.0", "corestore": "^6.8.4", "debug": "^4.3.4", From 08ae6a8464136c7590daaad4e9eb6a9742357084 Mon Sep 17 00:00:00 2001 From: Andrew Chou Date: Thu, 21 Sep 2023 10:09:23 -0400 Subject: [PATCH 28/28] close mapeo rpc channel on close Co-authored-by: Gregor MacLennan --- src/ipc-wrapper/server.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ipc-wrapper/server.js b/src/ipc-wrapper/server.js index 4ef41eaf..f8181744 100644 --- a/src/ipc-wrapper/server.js +++ b/src/ipc-wrapper/server.js @@ -47,6 +47,7 @@ export function createMapeoServer(manager, messagePort) { managerServer.close() managerChannel.close() mapeoRpcServer.close() + mapeoRpcChannel.close() }, }