From 4b1f1a55f3c39fc664480382363005d22060bb01 Mon Sep 17 00:00:00 2001
From: benya7
Date: Mon, 28 Jul 2025 18:42:33 +0200
Subject: [PATCH 01/11] refactor: Standardize core types and remove static data
---
.../components/admin/categoriesManagement.vue | 9 +-
.../components/admin/contentManagement.vue | 7 +-
.../components/admin/featuredManagement.vue | 9 +-
.../admin/maintenanceManagement.vue | 14 +-
.../admin/subscriptionManagement.vue | 34 +--
.../src/components/misc/contentCard.vue | 3 +-
.../components/misc/infiniteReleaseList.vue | 4 +-
.../src/components/releases/albumViewer.vue | 3 +-
.../releases/contentCategoryForm.vue | 18 +-
.../components/releases/metadataFieldForm.vue | 8 +-
.../src/components/releases/releaseForm.vue | 30 +-
.../renderer/src/composables/staticData.ts | 276 ------------------
.../src/constants/contentCategories.ts | 0
.../renderer/src/plugins/lensService/hooks.ts | 212 ++++----------
packages/renderer/src/types.ts | 17 +-
packages/renderer/src/views/categoryPage.vue | 4 +-
packages/renderer/src/views/homePage.vue | 5 +-
packages/renderer/src/views/releasePage.vue | 4 +-
18 files changed, 135 insertions(+), 522 deletions(-)
delete mode 100644 packages/renderer/src/composables/staticData.ts
delete mode 100644 packages/renderer/src/constants/contentCategories.ts
diff --git a/packages/renderer/src/components/admin/categoriesManagement.vue b/packages/renderer/src/components/admin/categoriesManagement.vue
index 24498e17..a3b8351f 100644
--- a/packages/renderer/src/components/admin/categoriesManagement.vue
+++ b/packages/renderer/src/components/admin/categoriesManagement.vue
@@ -133,8 +133,8 @@ import { useSnackbarMessage } from '/@/composables/snackbarMessage';
import ContentCategoryForm from '/@/components/releases/contentCategoryForm.vue';
import confirmationDialog from '/@/components/misc/confimationDialog.vue';
-import type { ContentCategoryData, ContentCategoryMetadata } from '@riffcc/lens-sdk';
import { useContentCategoriesQuery } from '../../plugins/lensService/hooks';
+import type { ContentCategoryItem } from '/@/types';
const { data: contentCategories } = useContentCategoriesQuery();
@@ -143,12 +143,7 @@ const createCategoryDialog = ref(false);
const editCategoryDialog = ref(false);
const confirmDeleteCategoryDialog = ref(false);
-const editedContentCategory = ref, 'siteAddress'>>({
- id: '',
- displayName: '',
- featured: false,
- metadataSchema: {},
-});
+const editedContentCategory = ref>({});
const { snackbarMessage, showSnackbar, openSnackbar, closeSnackbar } = useSnackbarMessage();
diff --git a/packages/renderer/src/components/admin/contentManagement.vue b/packages/renderer/src/components/admin/contentManagement.vue
index 297f6d52..18ebfa34 100644
--- a/packages/renderer/src/components/admin/contentManagement.vue
+++ b/packages/renderer/src/components/admin/contentManagement.vue
@@ -179,7 +179,6 @@ import {
parseUrlOrCid,
// getStatusColor,
} from '/@/utils';
-import type { AnyObject } from '@riffcc/lens-sdk';
import { useDeleteReleaseMutation, useGetReleasesQuery } from '/@/plugins/lensService/hooks';
@@ -226,8 +225,8 @@ const tableHeaders: Header[] = [
{ title: 'Actions', key: 'actions', sortable: false },
];
-const targetReleaseToEdit = ref | null>(null);
-const targetReleaseToDelete = ref | null>(null);
+const targetReleaseToEdit = ref(null);
+const targetReleaseToDelete = ref(null);
const { snackbarMessage, showSnackbar, openSnackbar, closeSnackbar } = useSnackbarMessage();
@@ -243,7 +242,7 @@ function handleError(message: string) {
async function confirmDeleteBlockRelease() {
if (!targetReleaseToDelete.value) return;
- deleteReleaseMutation.mutate({ id: targetReleaseToDelete.value.id });
+ deleteReleaseMutation.mutate(targetReleaseToDelete.value.id);
}
function requestFeatureRelease(releaseId: string | undefined) {
diff --git a/packages/renderer/src/components/admin/featuredManagement.vue b/packages/renderer/src/components/admin/featuredManagement.vue
index 33a9b210..e360f208 100644
--- a/packages/renderer/src/components/admin/featuredManagement.vue
+++ b/packages/renderer/src/components/admin/featuredManagement.vue
@@ -160,12 +160,11 @@ import { computed, onMounted, ref, watch, type Ref } from 'vue';
import { useSnackbarMessage } from '/@/composables/snackbarMessage';
import confirmationDialog from '/@/components/misc/confimationDialog.vue';
import { filterActivedFeatured, filterPromotedFeatured } from '/@/utils';
-import type { FeaturedReleaseItem, PartialFeaturedReleaseItem } from '/@/types';
+import type { FeaturedReleaseItem } from '/@/types';
import { useAddFeaturedReleaseMutation, useEditFeaturedReleaseMutation, useGetFeaturedReleasesQuery } from '/@/plugins/lensService/hooks';
-import { FEATURED_END_TIME_PROPERTY } from '@riffcc/lens-sdk';
const props = defineProps<{
- initialFeatureData: PartialFeaturedReleaseItem | null;
+ initialFeatureData: Partial | null;
}>();
const emit = defineEmits<{
@@ -196,7 +195,7 @@ const editFeaturedReleaseMutation = useEditFeaturedReleaseMutation({
},
});
-const newFeaturedRelease: Ref = ref({});
+const newFeaturedRelease: Ref> = ref({});
const formRef = ref();
const isLoading = computed(() => addFeaturedReleaseMutation.isPending.value || editFeaturedReleaseMutation.isPending.value);
@@ -300,7 +299,7 @@ const confirmEndFeaturedRelease = async () => {
if (!featuredItemIdToEnd.value) return;
editFeaturedReleaseMutation.mutate({
...featuredItemIdToEnd.value,
- [FEATURED_END_TIME_PROPERTY]: (new Date()).toISOString(),
+ endTime: (new Date()).toISOString(),
});
featuredItemIdToEnd.value = null;
};
diff --git a/packages/renderer/src/components/admin/maintenanceManagement.vue b/packages/renderer/src/components/admin/maintenanceManagement.vue
index 17189b8b..1992d886 100644
--- a/packages/renderer/src/components/admin/maintenanceManagement.vue
+++ b/packages/renderer/src/components/admin/maintenanceManagement.vue
@@ -116,7 +116,6 @@ import { ref } from 'vue';
import { useGetReleasesQuery, useGetFeaturedReleasesQuery, useAddReleaseMutation, useEditReleaseMutation, useDeleteReleaseMutation, useAddFeaturedReleaseMutation, useEditFeaturedReleaseMutation, useDeleteFeaturedReleaseMutation } from '/@/plugins/lensService/hooks';
import { useSnackbarMessage } from '/@/composables/snackbarMessage';
import type { ReleaseItem } from '/@/types';
-import type { AnyObject } from '@riffcc/lens-sdk';
const isExporting = ref(false);
const isImporting = ref(false);
@@ -236,7 +235,7 @@ const deleteAllData = async () => {
console.log(`Deleting ${featuredReleases.value.length} featured releases...`);
for (const featured of featuredReleases.value) {
try {
- const result = await deleteFeaturedReleaseMutation.mutateAsync({ id: featured.id });
+ const result = await deleteFeaturedReleaseMutation.mutateAsync(featured.id);
if (result.success) {
featuredDeleted++;
} else {
@@ -253,7 +252,7 @@ const deleteAllData = async () => {
console.log(`Deleting ${releases.value.length} releases...`);
for (const release of releases.value) {
try {
- const result = await deleteReleaseMutation.mutateAsync({ id: release.id });
+ const result = await deleteReleaseMutation.mutateAsync(release.id);
if (result.success) {
releasesDeleted++;
} else {
@@ -295,13 +294,15 @@ const performImport = async () => {
for (const release of importData.releases) {
try {
// Extract the data without the __context
- const releaseData: Omit, 'siteAddress'> = {
+ const releaseData: ReleaseItem = {
id: release.id,
name: release.name,
categoryId: release.categoryId,
contentCID: release.contentCID,
thumbnailCID: release.thumbnailCID,
metadata: release.metadata,
+ siteAddress: release.siteAddress,
+ postedBy: release.postedBy,
};
if (importMode.value === 'upsert') {
@@ -333,6 +334,9 @@ const performImport = async () => {
for (const featured of importData.featuredReleases) {
try {
const featuredData = {
+ id: featured.id,
+ siteAddress: featured.siteAddress,
+ postedBy: featured.postedBy,
releaseId: featured.releaseId,
startTime: featured.startTime,
endTime: featured.endTime,
@@ -346,8 +350,6 @@ const performImport = async () => {
// Update existing
await editFeaturedReleaseMutation.mutateAsync({
...featuredData,
- id: featured.id,
- siteAddress: existing.siteAddress,
});
featuredImported++;
} else {
diff --git a/packages/renderer/src/components/admin/subscriptionManagement.vue b/packages/renderer/src/components/admin/subscriptionManagement.vue
index 16593bbd..452b92de 100644
--- a/packages/renderer/src/components/admin/subscriptionManagement.vue
+++ b/packages/renderer/src/components/admin/subscriptionManagement.vue
@@ -18,15 +18,11 @@
@submit.prevent="handleOnSubmit"
>
-
+
@@ -83,7 +78,7 @@
icon="$delete"
density="comfortable"
size="small"
- @click="() => unsubscribe({id: s.id})"
+ @click="() => unsubscribe({ id: s.id })"
>
@@ -106,9 +101,9 @@
diff --git a/packages/renderer/src/composables/lensInitialization.ts b/packages/renderer/src/composables/lensInitialization.ts
new file mode 100644
index 00000000..fd32a21a
--- /dev/null
+++ b/packages/renderer/src/composables/lensInitialization.ts
@@ -0,0 +1,74 @@
+import { ref } from 'vue';
+import { useLensService } from '/@/plugins/lensService/hooks';
+import { RIFFCC_PEERBIT_BOOTSTRAPPERS } from '../constants/config';
+
+// This state will be shared across the entire application
+const isLensReady = ref(false);
+
+const initLensService = async () => {
+ // Prevent re-initialization
+ if (isLensReady.value) return;
+
+ const { lensService } = useLensService();
+ const siteAddress = import.meta.env.VITE_SITE_ADDRESS;
+ const lensNode = import.meta.env.VITE_LENS_NODE;
+
+ // --- Environment Variable Checks (Good, no changes needed) ---
+ if (!siteAddress) {
+ throw new Error('VITE_SITE_ADDRESS env var missing...', { cause: 'MISSING_CONFIG' });
+ }
+ if (!lensNode) {
+ throw new Error('VITE_LENS_NODE env var missing...', { cause: 'MISSING_CONFIG' });
+ }
+
+ try {
+ console.log('Starting background Lens Service initialization...');
+ await lensService.init('.lens-node');
+
+ // --- REFINED DIALING LOGIC ---
+
+ // 1. Construct a clean, unified list of all addresses to dial.
+ // - `lensNode` is treated as a single string (no spread).
+ // - `RIFFCC_PEERBIT_BOOTSTRAPPERS` is correctly spread if it's an array.
+ const allAddressesToDial = [
+ lensNode,
+ ...RIFFCC_PEERBIT_BOOTSTRAPPERS,
+ ].filter(Boolean); // .filter(Boolean) removes any empty or null strings.
+
+ console.log('Attempting to dial bootstrap peers:', allAddressesToDial);
+
+ // 2. Dial all peers in parallel.
+ const dialResults = await Promise.allSettled(
+ allAddressesToDial.map(b => lensService.peerbit?.dial(b.trim())),
+ );
+
+ // 3. (IMPROVEMENT) Log the results of the dialing attempts for easy debugging.
+ let successfulDials = 0;
+ dialResults.forEach((result, index) => {
+ const address = allAddressesToDial[index];
+ if (result.status === 'fulfilled') {
+ successfulDials++;
+ console.log(`ā
Successfully dialed: ${address}`);
+ } else {
+ console.warn(`ā Failed to dial: ${address}`, result.reason.message || result.reason);
+ }
+ });
+ console.log(`Finished dialing: ${successfulDials}/${allAddressesToDial.length} peers connected.`);
+
+
+ // --- Continue with initialization ---
+ await lensService.openSite(siteAddress, { federate: false });
+ isLensReady.value = true;
+ console.log('ā
Lens Service is ready in the background.');
+
+ } catch (error) {
+ console.error('ā Lens Service background initialization failed:', error);
+ }
+};
+
+export function useLensInitialization() {
+ return {
+ isLensReady,
+ initLensService,
+ };
+}
diff --git a/packages/renderer/src/constants/config.ts b/packages/renderer/src/constants/config.ts
new file mode 100644
index 00000000..8401e22b
--- /dev/null
+++ b/packages/renderer/src/constants/config.ts
@@ -0,0 +1,5 @@
+export const RIFFCC_IPFS_GATEWAY = 'cdn.riff.cc';
+export const RIFFCC_PEERBIT_BOOTSTRAPPERS = [
+ '/dns4/4032881a26640025f9a4253104b7aaf6d4b55599.peerchecker.com/tcp/4003/wss/p2p/12D3KooWPYWLY5E7w1SyPJ18y77Wsyfo1fEJcwRonKNPxPam3teJ',
+ '/dns4/65da3760cb3fd2926532310b0650ddca4f88ebd5.peerchecker.com/tcp/4003/wss/p2p/12D3KooWMQTwyWnvKyFPjs72bbrDMUDM7pmtF328X7iTfWws3A18',
+];
diff --git a/packages/renderer/src/constants/ipfs.ts b/packages/renderer/src/constants/ipfs.ts
deleted file mode 100644
index 6f2cfd30..00000000
--- a/packages/renderer/src/constants/ipfs.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const IPFS_GATEWAY = 'cdn.riff.cc';
diff --git a/packages/renderer/src/plugins/index.ts b/packages/renderer/src/plugins/index.ts
index 4a6796a5..4636ed93 100644
--- a/packages/renderer/src/plugins/index.ts
+++ b/packages/renderer/src/plugins/index.ts
@@ -5,36 +5,8 @@ import type { App } from 'vue';
import vuetify from './vuetify';
import router from './router';
import lensServicePlugin from './lensService';
-import { VueQueryPlugin, QueryClient } from '@tanstack/vue-query';
-
-// Configure QueryClient with optimized defaults for P2P network
-const queryClient = new QueryClient({
- defaultOptions: {
- queries: {
- // Network timeout for queries - PeerBit needs time to find nodes
- networkMode: 'online',
- // Retry configuration
- retry: (failureCount, error) => {
- // Handle PeerBit-specific errors
- if (error?.message?.includes('delivery acknowledges from all nodes')) {
- return failureCount < 2; // Limited retries for connectivity
- }
- if (error?.message?.includes('Failed to get message')) {
- return failureCount < 3; // More retries for message delivery
- }
- return failureCount < 2; // Default retry
- },
- retryDelay: attemptIndex => Math.min(500 * Math.pow(2, attemptIndex), 2000),
- // Cache configuration
- staleTime: 1000 * 60, // 1 minute default
- gcTime: 1000 * 60 * 15, // 15 minutes
- },
- mutations: {
- retry: 1,
- retryDelay: 1000,
- },
- },
-});
+import { VueQueryPlugin } from '@tanstack/vue-query';
+import { queryClient } from './tanstackQuery';
export function registerPlugins (app: App) {
app
diff --git a/packages/renderer/src/plugins/router.ts b/packages/renderer/src/plugins/router.ts
index e11bceb8..b43f5858 100644
--- a/packages/renderer/src/plugins/router.ts
+++ b/packages/renderer/src/plugins/router.ts
@@ -1,7 +1,10 @@
-import {createRouter, createWebHashHistory, type RouteRecordRaw} from 'vue-router';
-
+import type { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
+import { createRouter, createWebHashHistory, type RouteRecordRaw } from 'vue-router';
+import { multiaddr } from '@multiformats/multiaddr';
// Keep HomePage as direct import since it's the landing page
import HomePage from '/@/views/homePage.vue';
+import { queryClient } from './tanstackQuery';
+import type { AccountStatusResponse } from '@riffcc/lens-sdk';
// Lazy load all other routes
const AdminPage = () => import('../views/adminPage.vue');
@@ -13,6 +16,104 @@ const TermsPage = () => import('/@/views/termsPage.vue');
const UploadPage = () => import('/@/views/uploadPage.vue');
const CategoryPage = () => import('../views/categoryPage.vue');
+/**
+ * Parses the VITE_LENS_NODE environment variable to build the base API URL.
+ * This provides a single, reliable source of truth for the API endpoint.
+ *
+ * @returns {string} The constructed base API URL.
+ */
+function getApiUrl(): string {
+ const lensNodeMaStr = import.meta.env.VITE_LENS_NODE;
+
+ if (!lensNodeMaStr) {
+ console.error('VITE_LENS_NODE environment variable is not set. API calls will fail.');
+ // Fallback to a default or return an empty string, depending on desired behavior.
+ return 'http://localhost:5002/api/v1';
+ }
+
+ try {
+ const ma = multiaddr(lensNodeMaStr);
+ const nodeOptions = ma.nodeAddress(); // Gets { family, address, port }
+
+ // Determine the protocol based on the presence of 'wss' or 'ws'
+ // 'wss' implies 'https' and 'ws' implies 'http'
+ const protocol = ma.getComponents().map(c => c.name).includes('wss') ? 'https' : 'http';
+
+ // Determine the API port. Conventionally, it might be different from the P2P port.
+ // Let's assume a convention: P2P port 8002 -> API port 5002, P2P 4003 -> API 9002
+ let apiPort;
+ switch (nodeOptions.port) {
+ case 8002: // Local P2P port
+ apiPort = 5002;
+ break;
+ case 4003: // Production P2P port
+ apiPort = 9002;
+ break;
+ default:
+ // Default fallback if the P2P port is something unexpected
+ console.warn(`Unexpected P2P port ${nodeOptions.port}, defaulting API port to 9002.`);
+ apiPort = 9002;
+ }
+
+ return `${protocol}://${nodeOptions.address}:${apiPort}/api/v1`;
+
+ } catch (error) {
+ console.error('Failed to parse VITE_LENS_NODE multiaddr:', error);
+ // Fallback if parsing fails
+ return 'http://localhost:5002/api/v1';
+ }
+}
+
+export const API_URL = getApiUrl();
+const PREFETCH_CONFIG = {
+ initialReleases: {
+ url: `${API_URL}/releases`,
+ queryKey: ['releases'],
+ },
+ initialFeaturedReleases: {
+ url: `${API_URL}/featured-releases`,
+ queryKey: ['featuredReleases'],
+ },
+ initialContentCategories: {
+ url: `${API_URL}/content-categories`,
+ queryKey: ['contentCategories'],
+ },
+};
+
+type PrefetchKey = keyof typeof PREFETCH_CONFIG;
+
+/**
+ * Checks if the user is authenticated and has the required permissions.
+ * Redirects to the homepage if checks fail.
+ *
+ * @param to - The route being navigated to.
+ * @param from - The route being navigated from.
+ * @param next - The navigation guard's next function.
+ * @param requiredPermission - The specific permission string to check for (e.g., 'release:create').
+ */
+export function requirePermission(
+ to: RouteLocationNormalized,
+ from: RouteLocationNormalized,
+ next: NavigationGuardNext,
+ requiredPermission: string,
+) {
+ // 1. Synchronously get the account status from the cache.
+ const accountStatus = queryClient.getQueryData(['accountStatus']);
+
+ // 2. Check for the permission.
+ // We use `?.` (optional chaining) to safely access `permissions` in case accountStatus is undefined.
+ const hasPermission = accountStatus?.permissions.includes(requiredPermission) ?? false;
+
+ if (hasPermission) {
+ // 3. If the user has permission, allow them to proceed.
+ next();
+ } else {
+ // 4. If the user does not have permission, redirect to the homepage.
+ console.warn(`Redirecting: User lacks required permission ('${requiredPermission}') for route '${to.path}'.`);
+ next({ path: '/' });
+ }
+}
+
const routes: Array = [
{
path: '/',
@@ -22,16 +123,31 @@ const routes: Array = [
path: '/account',
name: 'Account',
component: AccountPage,
+
},
{
path: '/upload',
name: 'Upload',
component: UploadPage,
+ beforeEnter: (to, from, next) => {
+ // We pass the specific permission required for this route
+ requirePermission(to, from, next, 'release:create');
+ },
},
{
path: '/admin',
name: 'Admin Website',
component: AdminPage,
+ beforeEnter: (to, from, next) => {
+ // Example for a more complex check. You would create a dedicated helper for this.
+ const accountStatus = queryClient.getQueryData(['accountStatus']);
+ const isAdmin = accountStatus?.isAdmin || accountStatus?.roles.includes('moderator') || false;
+ if (isAdmin) {
+ next();
+ } else {
+ next({ path: '/' });
+ }
+ },
},
{
path: '/about',
@@ -50,25 +166,129 @@ const routes: Array = [
name: 'Release',
component: ReleasePage,
props: true,
+ beforeEnter: async (to, from, next) => {
+ // 1. Get the release ID from the route params.
+ const id = to.params.id as string;
+
+ // Ensure we have an ID to work with.
+ if (!id) {
+ console.error('Release page navigation attempted without an ID.');
+ // Optionally, redirect to a 404 page or the homepage.
+ next({ path: '/' });
+ return;
+ }
+
+ console.log(`Release Guard: Pre-fetching data for release ID: ${id}`);
+
+ // 2. Define the specific query key for this release.
+ const queryKey = ['release', id];
+
+ // 3. Check if data for this specific release is already in the cache.
+ // This is a crucial optimization. If the user clicks a release, then navigates
+ // away and clicks the same release again, we don't need to re-fetch.
+ if (queryClient.getQueryData(queryKey)) {
+ console.log(`Cache hit for release ${id}. Skipping fetch.`);
+ next();
+ return;
+ }
+
+ try {
+ // 4. Fetch the data from your fast API.
+ const response = await fetch(`${API_URL}/releases/${id}`);
+
+ if (response.ok) {
+ const releaseData = await response.json();
+
+ // 5. Seed the cache with the fetched data.
+ queryClient.setQueryData(queryKey, releaseData);
+ console.log(`ā
Cache seeded for release ${id}.`);
+ } else {
+ // Handle cases where the release is not found (404) or other server errors.
+ console.error(`API Error fetching release ${id}: Status ${response.status}`);
+ // You might want to clear any stale data if it exists and redirect.
+ queryClient.setQueryData(queryKey, undefined);
+ // Optionally redirect to a 'not-found' page.
+ // For now, we'll just proceed and let the component handle the empty state.
+ }
+ } catch (error) {
+ console.error(`Fetch failed for release ${id}:`, error);
+ } finally {
+ // 6. Always call next() to allow navigation to proceed.
+ next();
+ }
+ },
},
{
path: '/featured/:category',
component: CategoryPage,
- props: true,
- },
- {
- path: '/:category',
- component: CategoryPage,
props: route => ({ ...route.params, showAll: true }),
},
];
-const routeur = createRouter({
+const router = createRouter({
history: createWebHashHistory(),
routes,
scrollBehavior() {
- return {top: 0};
+ return { top: 0 };
},
});
-export default routeur;
+let hasAttemptedPrefetch = false;
+
+router.beforeEach(async (to, from, next) => {
+ if (hasAttemptedPrefetch) {
+ next();
+ return;
+ }
+
+ console.log('Global Guard: First-time app entry. Checking API health for pre-fetching...');
+ hasAttemptedPrefetch = true; // Set this immediately to ensure this entire block runs only once.
+
+ try {
+ // 1. Perform a quick health check with a short timeout.
+ // We use AbortController to enforce a timeout on the fetch call.
+ const controller = new AbortController();
+ const timeoutId = setTimeout(() => controller.abort(), 1500); // 1.5-second timeout
+
+ const healthResponse = await fetch(`${API_URL}/health`, { signal: controller.signal });
+ clearTimeout(timeoutId); // Clear the timeout if the fetch completes in time
+
+ if (!healthResponse.ok) {
+ throw new Error(`API health check failed with status: ${healthResponse.status}`);
+ }
+
+ // 2. If health check passes, proceed with pre-fetching.
+ console.log('API is healthy. Proceeding with pre-fetching and cache seeding...');
+ const prefetchKeys = Object.keys(PREFETCH_CONFIG) as PrefetchKey[];
+ const promises = prefetchKeys.map(key => fetch(PREFETCH_CONFIG[key].url));
+ const results = await Promise.allSettled(promises);
+
+ console.groupCollapsed('API Pre-fetch Responses & Cache Seeding');
+ // Process each result
+ results.forEach(async (result, index) => {
+ const key = prefetchKeys[index];
+ const config = PREFETCH_CONFIG[key];
+
+ if (result.status === 'fulfilled' && result.value.ok) {
+ const data = await result.value.json();
+ queryClient.setQueryData(config.queryKey, data);
+ console.log(`ā
[SUCCESS & CACHE SEEDED] ${key}:`, data);
+ } else if (result.status === 'fulfilled' && !result.value.ok) {
+ console.error(`ā [API ERROR] for ${key} at ${result.value.url}: Server responded with status ${result.value.status}`);
+ } else if (result.status === 'rejected') {
+ console.error(`ā [FETCH FAILED] for ${key}:`, result.reason.message);
+ }
+ });
+
+ console.groupEnd();
+
+ } catch (error) {
+ console.error('An unexpected error occurred during global data pre-fetching:', error);
+ } finally {
+ // ALWAYS call next() to allow the initial navigation to complete.
+ next();
+ }
+});
+
+
+export default router;
diff --git a/packages/renderer/src/plugins/tanstackQuery.ts b/packages/renderer/src/plugins/tanstackQuery.ts
new file mode 100644
index 00000000..4a048e93
--- /dev/null
+++ b/packages/renderer/src/plugins/tanstackQuery.ts
@@ -0,0 +1,30 @@
+import { QueryClient } from '@tanstack/vue-query';
+
+// Configure QueryClient with optimized defaults for P2P network
+export const queryClient = new QueryClient({
+ defaultOptions: {
+ queries: {
+ // Network timeout for queries - PeerBit needs time to find nodes
+ networkMode: 'online',
+ // Retry configuration
+ retry: (failureCount, error) => {
+ // Handle PeerBit-specific errors
+ if (error?.message?.includes('delivery acknowledges from all nodes')) {
+ return failureCount < 2; // Limited retries for connectivity
+ }
+ if (error?.message?.includes('Failed to get message')) {
+ return failureCount < 3; // More retries for message delivery
+ }
+ return failureCount < 2; // Default retry
+ },
+ retryDelay: attemptIndex => Math.min(500 * Math.pow(2, attemptIndex), 2000),
+ // Cache configuration
+ staleTime: 1000 * 60, // 1 minute default
+ gcTime: 1000 * 60 * 15, // 15 minutes
+ },
+ mutations: {
+ retry: 1,
+ retryDelay: 1000,
+ },
+ },
+});
diff --git a/packages/renderer/src/utils.ts b/packages/renderer/src/utils.ts
index 12fb3b2f..e352f46c 100644
--- a/packages/renderer/src/utils.ts
+++ b/packages/renderer/src/utils.ts
@@ -1,7 +1,7 @@
import {base16} from 'multiformats/bases/base16';
import {CID} from 'multiformats/cid';
import {cid as isCID} from 'is-ipfs';
-import { IPFS_GATEWAY } from './constants/ipfs';
+import { RIFFCC_IPFS_GATEWAY } from './constants/config';
import type { FeaturedReleaseItem } from './types';
import {Duration} from 'luxon';
@@ -82,7 +82,7 @@ export function parseUrlOrCid(urlOrCid?: string): string | undefined {
// Load optional gateway override from environment variable
const gatewayOverride = import.meta.env.VITE_IPFS_GATEWAY as string | undefined;
- const selectedGateway = gatewayOverride || IPFS_GATEWAY;
+ const selectedGateway = gatewayOverride || RIFFCC_IPFS_GATEWAY;
// Use HTTPS for gateways, unless the override specifies a protocol
const gatewayBase = selectedGateway.startsWith('http://') || selectedGateway.startsWith('https://')
@@ -94,7 +94,7 @@ export function parseUrlOrCid(urlOrCid?: string): string | undefined {
// For now, let's assume the override is a domain or IP:port.
const codexGatewayBase = gatewayOverride
? (gatewayOverride.startsWith('http://') || gatewayOverride.startsWith('https://') ? gatewayOverride.replace(/^(https?:\/\/)/, '$1codex-') : `https://codex-${gatewayOverride}`)
- : `https://codex-${IPFS_GATEWAY}`;
+ : `https://codex-${RIFFCC_IPFS_GATEWAY}`;
if (urlOrCid.startsWith('zD')) {
diff --git a/packages/renderer/src/views/homePage.vue b/packages/renderer/src/views/homePage.vue
index 76666619..e5c6389c 100644
--- a/packages/renderer/src/views/homePage.vue
+++ b/packages/renderer/src/views/homePage.vue
@@ -83,24 +83,17 @@ import { filterActivedFeatured, filterPromotedFeatured } from '../utils';
const router = useRouter();
-// Optimize loading: Reduce stale time for faster fallback and eager loading
const {
data: releases,
isLoading: isReleasesLoading,
isFetched: isReleasesFetched,
-} = useGetReleasesQuery({
- staleTime: 1000 * 30, // 30s stale time for faster refresh
-});
+} = useGetReleasesQuery();
const {
data: featuredReleases,
isLoading: isFeaturedReleasesLoading,
isFetched: isFeaturedReleasesFetched,
-} = useGetFeaturedReleasesQuery({
- staleTime: 1000 * 30, // 30s stale time for faster refresh
-});
-
-
+} = useGetFeaturedReleasesQuery();
const { data: contentCategories } = useContentCategoriesQuery();
@@ -122,90 +115,47 @@ const promotedFeaturedReleases = computed(() => {
});
+const activeSections = computed(() => {
+ const limitPerCategory = 8;
+ if (!contentCategories.value || !activedFeaturedReleases.value) return [];
-function categorizeReleasesByFeaturedCategories(
- rels?: ReleaseItem[],
- featuredCats?: Omit, 'siteAddress'>[],
- limitPerCategory: number = 8,
-): Record[]> {
- const result: Record[]> = {};
- if (!rels || !featuredCats) {
- return result;
- }
- const addedReleaseIds = new Set();
-
- featuredCats.forEach(fc => {
- result[fc.id] = [];
- });
-
- for (const rel of rels) {
- if (!rel.id || addedReleaseIds.has(rel.id)) {
- continue;
- }
-
- for (const fc of featuredCats) {
- const currentCategoryId = fc.id;
- if (rel.categoryId === currentCategoryId) {
- if (result[currentCategoryId].length < limitPerCategory) {
- result[currentCategoryId].push(rel);
- addedReleaseIds.add(rel.id);
- }
- // A release is categorized, move to the next release.
- // It won't be added to multiple sections by this logic as release.category is singular.
- break;
- }
+ const releasesByCategory = new Map();
+ for (const release of activedFeaturedReleases.value) {
+ if (!release.categoryId) continue;
+ if (!releasesByCategory.has(release.categoryId)) {
+ releasesByCategory.set(release.categoryId, []);
}
+ releasesByCategory.get(release.categoryId)!.push(release);
}
- return result;
-}
-
-const categorizedReleases = computed(() => {
- return categorizeReleasesByFeaturedCategories(activedFeaturedReleases.value, contentCategories.value);
-});
-
-const activeSections = computed<{
- id: string;
- title: string;
- items: ReleaseItem[];
- navigationPath: string;
-}[]>(() => {
- if (!contentCategories.value) return [];
return contentCategories.value
- .filter(c => c.featured)
- .map(fc => {
- const categoryId = fc.id;
- const items = categorizedReleases.value[categoryId] || [];
+ .filter(category => category.featured)
+ .map(featuredCategory => {
+ const items = releasesByCategory.get(featuredCategory.categoryId) || [];
return {
- id: fc.id,
- title: categoryId === 'tvShow' ? fc.displayName : `Featured ${fc.displayName}`,
- items: items,
- navigationPath: `/featured/${categoryId}`,
+ id: featuredCategory.categoryId,
+ title: featuredCategory.categoryId === 'tv-shows' ? featuredCategory.displayName : `Featured ${featuredCategory.displayName}`,
+ items: items.slice(0, limitPerCategory),
+ navigationPath: `/featured/${featuredCategory.categoryId}`,
};
})
.filter(section => section.items.length > 0);
});
-
-// Progressive loading - show content as each query completes
const isLoading = computed(() => {
- // Show loading if BOTH queries are still loading
- // This prevents showing "no featured content" before releases are loaded
return isReleasesLoading.value || isFeaturedReleasesLoading.value;
});
const noFeaturedContent = computed(() => {
- // Only show "no featured content" if BOTH queries are done and there's no featured content
if (!isReleasesFetched.value || !isFeaturedReleasesFetched.value) {
- return false; // Still loading, don't show "no featured content" yet
+ return false;
}
return promotedFeaturedReleases.value.length === 0 && activeSections.value.length === 0;
});
const noContent = computed(() => {
- // Only show "no content" if BOTH queries are done and there's truly no content anywhere
if (!isReleasesFetched.value || !isFeaturedReleasesFetched.value) {
- return false; // Still loading something, don't show "no content" yet
+ return false;
}
return releases.value?.length === 0 && featuredReleases.value?.length === 0;
});
diff --git a/types/env.d.ts b/types/env.d.ts
index 05fc3dc5..a76b4eb2 100644
--- a/types/env.d.ts
+++ b/types/env.d.ts
@@ -20,7 +20,7 @@ interface ImportMetaEnv {
readonly VITE_APP_VERSION: string;
readonly VITE_SITE_ADDRESS: string | undefined;
- readonly VITE_BOOTSTRAPPERS: string | undefined;
+ readonly VITE_LENS_NODE: string | undefined;
}
From 8e9f7a99a3a0e30ce203b77254f03485e151aaae Mon Sep 17 00:00:00 2001
From: benya7
Date: Tue, 29 Jul 2025 22:30:11 +0200
Subject: [PATCH 03/11] feat: Refactor UI components for new auth model and
data flow
---
.../renderer/src/components/layout/appBar.vue | 47 ++++--
.../src/components/layout/appFooter.vue | 4 +-
.../renderer/src/plugins/lensService/hooks.ts | 1 -
packages/renderer/src/views/accountPage.vue | 156 ++++++++++++------
packages/renderer/src/views/categoryPage.vue | 13 +-
5 files changed, 148 insertions(+), 73 deletions(-)
diff --git a/packages/renderer/src/components/layout/appBar.vue b/packages/renderer/src/components/layout/appBar.vue
index 5f8f220c..5cfd163d 100644
--- a/packages/renderer/src/components/layout/appBar.vue
+++ b/packages/renderer/src/components/layout/appBar.vue
@@ -36,20 +36,20 @@
:key="item.id"
:title="item.displayName"
active-class="text-primary-lighten-1"
- :active="route.path === item.id"
- @click="router.push(`/${item.id}`)"
+ :active="route.path === item.categoryId"
+ @click="router.push(`/featured/${item.categoryId}`)"
>
{{ item.displayName }}
-
+
@@ -134,11 +134,34 @@ const { data: contentCategories } = useContentCategoriesQuery();
const featuredContentCategories = computed(() => contentCategories.value?.filter(c => c.featured));
const { data: accountStatus } = useAccountStatusQuery();
-const isMember = computed(() => accountStatus.value === 1);
-const isAdmin = computed(() => accountStatus.value === 2);
+
+const canUpload = computed(() =>
+ accountStatus.value?.permissions.includes('release:create') ?? false,
+);
+
+const canAccessAdminPanel = computed(() => {
+ // Always guard against the initial undefined state.
+ if (!accountStatus.value) {
+ return false;
+ }
+
+ // Check for the direct isAdmin flag first.
+ if (accountStatus.value.isAdmin) {
+ return true;
+ }
+
+ // FIX: Use .includes() or .some() to check for the presence of a role.
+ // .includes() is cleaner if you only need to check for one role.
+ if (accountStatus.value.roles.includes('moderator')) {
+ return true;
+ }
+
+ // If none of the above, deny access.
+ return false;
+});
const { userData } = useUserSession();
-function handleOnDisconnect(){
+function handleOnDisconnect() {
userData.value = null;
};
diff --git a/packages/renderer/src/components/layout/appFooter.vue b/packages/renderer/src/components/layout/appFooter.vue
index 82338b3e..8042deb8 100644
--- a/packages/renderer/src/components/layout/appFooter.vue
+++ b/packages/renderer/src/components/layout/appFooter.vue
@@ -62,12 +62,12 @@
diff --git a/packages/renderer/src/plugins/lensService/hooks.ts b/packages/renderer/src/plugins/lensService/hooks.ts
index c52af208..09610e5b 100644
--- a/packages/renderer/src/plugins/lensService/hooks.ts
+++ b/packages/renderer/src/plugins/lensService/hooks.ts
@@ -13,7 +13,6 @@ import type {
EditInput,
} from '@riffcc/lens-sdk';
import type { ContentCategoryItem, FeaturedReleaseItem, ReleaseItem } from '/@/types';
-import { useLensInitialization } from '/@/composables/lensInitialization';
export function useLensService() {
const lensService = inject('lensService');
diff --git a/packages/renderer/src/views/accountPage.vue b/packages/renderer/src/views/accountPage.vue
index 9dc10e82..1794204f 100644
--- a/packages/renderer/src/views/accountPage.vue
+++ b/packages/renderer/src/views/accountPage.vue
@@ -13,14 +13,21 @@
-
+
-
- Account info
-
+ Account info
-
+
+
+
+
+ ADMINISTRATOR
+
+
+ {{ role }}
+
+
-
-
-
-
-
- Connectivity
-
-
-
-
-
- Not implemented ā ļø
+
+
+ {{ formattedPermissions }}
+
-
diff --git a/packages/renderer/src/views/categoryPage.vue b/packages/renderer/src/views/categoryPage.vue
index 2a127ad2..7abffaf7 100644
--- a/packages/renderer/src/views/categoryPage.vue
+++ b/packages/renderer/src/views/categoryPage.vue
@@ -5,7 +5,7 @@
>
- {{ pageTitle }}
+ {{ pageCategory?.displayName }}
router.push(`/release/${release.id}`)"
@@ -25,8 +25,8 @@
>
-
-
+
+
isReleasesLoading.value || isFeaturedLoading.va
const pageCategory = computed(() => {
const categoryId = props.category;
- const category = contentCategories.value?.find((cat) => cat.id === categoryId);
+ const category = contentCategories.value?.find((cat) => cat.categoryId === categoryId);
return category;
});
-const pageTitle = computed(() => {
- const displayName = pageCategory.value?.displayName ?? props.category;
- return props.showAll ? displayName : `Featured ${displayName}`;
-});
-
// Get featured releases that are active and in this category
const featuredReleasesInCategory = computed(() => {
if (!releases.value || !featuredReleases.value) return [];
From e34999c5d6729aeb27237bd85dc73ade61972de9 Mon Sep 17 00:00:00 2001
From: benya7
Date: Thu, 31 Jul 2025 17:57:09 +0200
Subject: [PATCH 04/11] update: nginx template
---
docs/{lens_ngixn.conf => lens_nginx.conf} | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
rename docs/{lens_ngixn.conf => lens_nginx.conf} (99%)
diff --git a/docs/lens_ngixn.conf b/docs/lens_nginx.conf
similarity index 99%
rename from docs/lens_ngixn.conf
rename to docs/lens_nginx.conf
index 61f2ab66..030251f7 100644
--- a/docs/lens_ngixn.conf
+++ b/docs/lens_nginx.conf
@@ -120,7 +120,7 @@ server {
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
- proxy_pass http://127.0.0.1:8082;
+ proxy_pass http://127.0.0.1:5002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
From e908fb758659ffb928539802e97d6e8d2d7a163b Mon Sep 17 00:00:00 2001
From: benya7
Date: Thu, 31 Jul 2025 19:34:06 +0200
Subject: [PATCH 05/11] fix: path error on icons
---
packages/renderer/src/plugins/vuetify.ts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/packages/renderer/src/plugins/vuetify.ts b/packages/renderer/src/plugins/vuetify.ts
index 9d36eabd..58111226 100644
--- a/packages/renderer/src/plugins/vuetify.ts
+++ b/packages/renderer/src/plugins/vuetify.ts
@@ -39,6 +39,8 @@ import {
mdiFullscreen,
mdiMenu,
mdiChevronUp,
+ mdiChevronLeft,
+ mdiChevronRight,
mdiCircle,
mdiCheck,
mdiAccountSupervisor,
@@ -77,6 +79,8 @@ const iconsAliasesMapping = {
'fullscreen': mdiFullscreen,
'menu': mdiMenu,
'chevron-up': mdiChevronUp,
+ prev: mdiChevronLeft,
+ next: mdiChevronRight,
'circle': mdiCircle,
'check': mdiCheck,
'account-supervisor': mdiAccountSupervisor,
From 1b532e9bc82cc70b8d9dea5afefc63898a297f2e Mon Sep 17 00:00:00 2001
From: benya7
Date: Thu, 31 Jul 2025 20:00:40 +0200
Subject: [PATCH 06/11] update: scripts
---
package.json | 45 +++++++++++++++++----------------------------
1 file changed, 17 insertions(+), 28 deletions(-)
diff --git a/package.json b/package.json
index 35e7c7ba..5d905d5b 100644
--- a/package.json
+++ b/package.json
@@ -13,34 +13,23 @@
"packages/*"
],
"scripts": {
- "build": "pnpm run build:main && pnpm run build:preload && pnpm run build:renderer",
- "build:main": "cd ./packages/main && vite build",
- "build:preload": "cd ./packages/preload && vite build",
- "build:renderer": "cd ./packages/renderer && vite build",
- "preview:renderer": "cd ./packages/renderer && vite preview --outDir ./dist/web",
- "compile": "cross-env MODE=production pnpm run build && electron-builder build --config .electron-builder.config.cjs --dir --config.asar=false",
- "compile:web": "cd ./packages/renderer && cross-env MODE=production WEB=true NODE_OPTIONS='--max-old-space-size=8192' vite build",
- "test": "pnpm run test:lib && pnpm run test:main && pnpm run test:preload && pnpm run test:renderer && pnpm run test:e2e",
- "test:e2e": "pnpm run build && vitest run",
- "test:main": "vitest run -r packages/main --passWithNoTests",
- "test:preload": "vitest run -r packages/preload --passWithNoTests",
- "test:renderer": "vitest run -r packages/renderer --passWithNoTests",
- "test:firefox": "pnpm run compile:web && ENVIRONNEMENT_TESTS=firefox vitest run",
- "test:webkit": "pnpm run compile:web && ENVIRONNEMENT_TESTS=webkit vitest run",
- "test:chrome": "pnpm run compile:web && ENVIRONNEMENT_TESTS=chromium vitest run",
- "watch": "node scripts/watch.mjs",
- "watch:web": "cd packages/renderer && cross-env WEB=true vite --port 5175",
- "watch:web:stub": "cross-env VITE_STUB_DATA=true pnpm watch:web",
- "preview:web": "pnpm compile:web && cross-env WEB=true vite preview packages/renderer",
- "lint": "eslint .",
- "typecheck:main": "tsc --noEmit -p packages/main/tsconfig.json",
- "typecheck:preload": "tsc --noEmit -p packages/preload/tsconfig.json",
- "typecheck:renderer": "vue-tsc --noEmit -p packages/renderer/tsconfig.json",
- "typecheck": "pnpm run typecheck:main && pnpm run typecheck:preload && pnpm run typecheck:renderer",
- "postinstall": "cross-env ELECTRON_RUN_AS_NODE=1 electron scripts/update-electron-vendors.mjs",
- "format": "npx prettier --write \"**/*.{js,mjs,cjs,ts,mts,cts,vue,json}\"",
- "benchmark": "node benchmark.js",
- "benchmark:baseline": "pnpm vitest run tests/dev-server-benchmark.spec.ts --reporter=verbose"
+ "dev": "cd packages/renderer && cross-env WEB=true vite --port 5175",
+ "dev:stub": "cross-env VITE_STUB_DATA=true pnpm dev",
+ "build": "cd packages/renderer && cross-env MODE=production WEB=true NODE_OPTIONS='--max-old-space-size=8192' vite build",
+ "preview": "pnpm build && cd packages/renderer && vite preview --outDir ./dist/web",
+ "lint": "eslint . --fix",
+ "format": "prettier --write \"**/*.{js,mjs,cjs,ts,mts,cts,vue,json}\"",
+ "typecheck": "vue-tsc --noEmit -p packages/renderer/tsconfig.json",
+ "test": "vitest run",
+ "test:unit": "vitest run --dir tests/unit",
+ "test:e2e": "playwright test",
+ "test:e2e:ui": "playwright test --ui",
+ "dev:electron": "node scripts/watch.mjs",
+ "build:electron": "pnpm run build:electron:main && pnpm run build:electron:preload && pnpm run build:electron:renderer",
+ "build:electron:main": "cd ./packages/main && vite build",
+ "build:electron:preload": "cd ./packages/preload && vite build",
+ "build:electron:renderer": "cd ./packages/renderer && vite build",
+ "compile:electron": "cross-env MODE=production pnpm run build:electron && electron-builder build --config .electron-builder.config.cjs --dir --config.asar=false"
},
"devDependencies": {
"@eslint/js": "^9.29.0",
From 8d7b2fcbcc1702d2b84fb6e279610ea63c5ca582 Mon Sep 17 00:00:00 2001
From: benya7
Date: Thu, 31 Jul 2025 20:01:28 +0200
Subject: [PATCH 07/11] update: dependencies
---
package.json | 4 +-
pnpm-lock.yaml | 1213 ++++++++++++++++++++++++++++--------------------
2 files changed, 722 insertions(+), 495 deletions(-)
diff --git a/package.json b/package.json
index 5d905d5b..b20bf654 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"devDependencies": {
"@eslint/js": "^9.29.0",
"@mdi/js": "^7.4.47",
+ "@playwright/test": "^1.54.1",
"@rollup/plugin-node-resolve": "^16.0.1",
"@types/luxon": "^3.6.2",
"@types/node": "^22.15.33",
@@ -49,7 +50,6 @@
"eslint-plugin-vue": "^9.33.0",
"happy-dom": "^14.12.3",
"nano-staged": "^0.8.0",
- "playwright": "^1.53.1",
"prettier-plugin-organize-imports": "^4.1.0",
"rollup-plugin-node-builtins": "^2.1.2",
"rollup-plugin-node-globals": "^1.4.0",
@@ -71,7 +71,7 @@
},
"dependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
- "@riffcc/lens-sdk": "^0.1.25",
+ "@riffcc/lens-sdk": "^0.1.32",
"@tanstack/vue-query": "^5.81.2",
"@vueuse/core": "^12.8.2",
"core-js": "^3.43.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0fa06d25..c4d83fcb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,8 +15,8 @@ importers:
specifier: ^0.2.3
version: 0.2.3(esbuild@0.25.5)
'@riffcc/lens-sdk':
- specifier: ^0.1.25
- version: 0.1.25(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ specifier: ^0.1.32
+ version: 0.1.32(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
'@tanstack/vue-query':
specifier: ^5.81.2
version: 5.81.2(vue@3.5.17(typescript@5.8.3))
@@ -57,6 +57,9 @@ importers:
'@mdi/js':
specifier: ^7.4.47
version: 7.4.47
+ '@playwright/test':
+ specifier: ^1.54.1
+ version: 1.54.1
'@rollup/plugin-node-resolve':
specifier: ^16.0.1
version: 16.0.1(rollup@4.44.1)
@@ -102,9 +105,6 @@ importers:
nano-staged:
specifier: ^0.8.0
version: 0.8.0
- playwright:
- specifier: ^1.53.1
- version: 1.53.1
prettier-plugin-organize-imports:
specifier: ^4.1.0
version: 4.1.0(prettier@3.5.3)(typescript@5.8.3)(vue-tsc@2.2.10(typescript@5.8.3))
@@ -165,6 +165,9 @@ packages:
7zip-bin@5.2.0:
resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==}
+ '@adraffy/ens-normalize@1.10.1':
+ resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==}
+
'@ampproject/remapping@2.3.0':
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
@@ -173,22 +176,26 @@ packages:
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
- '@babel/compat-data@7.27.7':
- resolution: {integrity: sha512-xgu/ySj2mTiUFmdE9yCMfBxLp4DHd5DwmbbD05YAuICfodYT3VvRxbrh81LGQ/8UpSdtMdfKMn3KouYDX59DGQ==}
+ '@babel/compat-data@7.28.0':
+ resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==}
engines: {node: '>=6.9.0'}
- '@babel/core@7.27.7':
- resolution: {integrity: sha512-BU2f9tlKQ5CAthiMIgpzAh4eDTLWo1mqi9jqE2OxMG0E/OM199VJt2q8BztTxpnSW0i1ymdwLXRJnYzvDM5r2w==}
+ '@babel/core@7.28.0':
+ resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==}
engines: {node: '>=6.9.0'}
- '@babel/generator@7.27.5':
- resolution: {integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==}
+ '@babel/generator@7.28.0':
+ resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==}
engines: {node: '>=6.9.0'}
'@babel/helper-compilation-targets@7.27.2':
resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==}
engines: {node: '>=6.9.0'}
+ '@babel/helper-globals@7.28.0':
+ resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
+ engines: {node: '>=6.9.0'}
+
'@babel/helper-module-imports@7.27.1':
resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==}
engines: {node: '>=6.9.0'}
@@ -215,8 +222,8 @@ packages:
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
engines: {node: '>=6.9.0'}
- '@babel/helpers@7.27.6':
- resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==}
+ '@babel/helpers@7.28.2':
+ resolution: {integrity: sha512-/V9771t+EgXz62aCcyofnQhGM8DQACbRhvzKFsXKC9QM+5MadF8ZmIm0crDMaz3+o0h0zXfJnd4EhbYbxsrcFw==}
engines: {node: '>=6.9.0'}
'@babel/parser@7.27.7':
@@ -224,6 +231,11 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
+ '@babel/parser@7.28.0':
+ resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
'@babel/plugin-syntax-async-generators@7.8.4':
resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
peerDependencies:
@@ -303,22 +315,26 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/runtime@7.27.6':
- resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==}
+ '@babel/runtime@7.28.2':
+ resolution: {integrity: sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==}
engines: {node: '>=6.9.0'}
'@babel/template@7.27.2':
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
engines: {node: '>=6.9.0'}
- '@babel/traverse@7.27.7':
- resolution: {integrity: sha512-X6ZlfR/O/s5EQ/SnUSLzr+6kGnkg8HXGMzpgsMsrJVcfDtH1vIp6ctCN4eZ1LS5c0+te5Cb6Y514fASjMRJ1nw==}
+ '@babel/traverse@7.28.0':
+ resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==}
engines: {node: '>=6.9.0'}
'@babel/types@7.27.7':
resolution: {integrity: sha512-8OLQgDScAOHXnAz2cV+RfzzNMipuLVBz2biuAJFMV9bfkNf393je3VM8CLkjQodW5+iWsSJdSgSWT6rsZoXHPw==}
engines: {node: '>=6.9.0'}
+ '@babel/types@7.28.2':
+ resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==}
+ engines: {node: '>=6.9.0'}
+
'@chainsafe/as-chacha20poly1305@0.1.0':
resolution: {integrity: sha512-BpNcL8/lji/GM3+vZ/bgRWqJ1q5kwvTFmGPk7pxm/QQZDbaMI98waOHjEymTjq2JmdD/INdNBFOVSyJofXg7ew==}
@@ -745,38 +761,33 @@ packages:
resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- '@jridgewell/gen-mapping@0.3.8':
- resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
- engines: {node: '>=6.0.0'}
+ '@jridgewell/gen-mapping@0.3.12':
+ resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==}
'@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
- '@jridgewell/set-array@1.2.1':
- resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
- engines: {node: '>=6.0.0'}
-
'@jridgewell/source-map@0.3.6':
resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==}
'@jridgewell/sourcemap-codec@1.5.0':
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
- '@jridgewell/trace-mapping@0.3.25':
- resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+ '@jridgewell/trace-mapping@0.3.29':
+ resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==}
'@leichtgewicht/ip-codec@2.0.5':
resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==}
- '@libp2p/circuit-relay-v2@3.2.20':
- resolution: {integrity: sha512-RkMWdTm926hTEVq0mC94sjnHLodr3sf1E7mP5honSF+SSCkAhUxAKBtH1ze0Fy7s1q28mtVgp5voXvawqt2ghw==}
+ '@libp2p/circuit-relay-v2@3.2.23':
+ resolution: {integrity: sha512-i6t3h5IaydcPCDXk2hNPCH2k6rY0JTRduqRmmVw3FbVpgM/DVonJV/XZa735K/a4jT8QRo6psI6UYSt+3ceqdg==}
'@libp2p/crypto@5.1.7':
resolution: {integrity: sha512-7DO0piidLEKfCuNfS420BlHG0e2tH7W/zugdsPSiC/1Apa/s1B1dBkaIEgfDkGjrRP4S/8Or86Rtq7zXeEu67g==}
- '@libp2p/identify@3.0.37':
- resolution: {integrity: sha512-oDdNZaP6a0eH3UIXBee4gOeOT4U4krfOAbqfqe/pM6exQqTyvzv21lOuFvC5EKgOYw63NoNPw1Iwnk36hDBpTg==}
+ '@libp2p/identify@3.0.38':
+ resolution: {integrity: sha512-2eCZU5CSTvyt78jtMLQ88m6Rlrcrt7BVccGHsdjx8hguvFYWqBjq19RQ5Zm47bbHlNzjLwrAUi6vfKx2r7fKIg==}
'@libp2p/interface-internal@2.3.18':
resolution: {integrity: sha512-tnZ20IFASXLbDc2JxeUPZNIXDuN5Ge7be6BU458WLvmquf93NlSqZkWs6xFdi+0yXUrw7GGTgzIP5v+1LnDUmA==}
@@ -805,17 +816,17 @@ packages:
'@libp2p/peer-store@11.2.6':
resolution: {integrity: sha512-3Lc982/7drqlXa51s9l1/DFHD48zzIjMMYajxFM2KbobyStH+lztYnFc3kNGB9sZijULaW1480PvbTMm9WaJ0g==}
- '@libp2p/tcp@10.1.17':
- resolution: {integrity: sha512-/y8UdorOCG3bnV9q6qGCANWY/UA8P22x4rs971zCSsCcRntvESl/EysatIhKf0AwBqJLJPyiVz0axvGn5gv4sQ==}
+ '@libp2p/tcp@10.1.18':
+ resolution: {integrity: sha512-tB7rjETju5UMiYpyzAEOsX7qGVahJwaoBlsMAfpb35a8lH+KU0AaxBMMK8P4cFbKZZQSuDN86Is0mb5EG7npVA==}
'@libp2p/utils@6.7.1':
resolution: {integrity: sha512-x3WImvw4unmx1ZeAedj8AkRe4UImUlkw0ZItYAiKiekElMNUXwv+Yt48dI/LmB38JIof8sng29XvUeCVU3F6OA==}
- '@libp2p/webrtc@5.2.20':
- resolution: {integrity: sha512-xh6Y69PtLnb1BYUdVYfrC3gAVBVwzFiiIWg6A1fsTf4/URbArbX9kgc9Yb763+pnZdQcvy3uL6lfFIPVqLkNWg==}
+ '@libp2p/webrtc@5.2.23':
+ resolution: {integrity: sha512-2iNEkiqNBlRXbdpIyP96tp+dvpXEnVJJk91WUPryS9ULrsyceTraKjEnlQUmSyKcxZRChfdLXax7LtpPJqjZAA==}
- '@libp2p/websockets@9.2.17':
- resolution: {integrity: sha512-PNhLFZA+DyV8xynCphrl4H4a1mVRIe6ZPKqLt9UwWr9Ye0ecjgVcL38uDo0XAZkx+NO3S+YspCx8yquJnDyi2A==}
+ '@libp2p/websockets@9.2.18':
+ resolution: {integrity: sha512-P27ZMv5TuKZDr8nfvVOExaDxBMCwvGLaPxbK3qMC8WiaFBuR5Z38X/HpnTFI5wog8LcKCRD+gFzRZWd/9nEVZw==}
'@malept/cross-spawn-promise@2.0.0':
resolution: {integrity: sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==}
@@ -834,11 +845,11 @@ packages:
'@multiformats/mafmt@12.1.6':
resolution: {integrity: sha512-tlJRfL21X+AKn9b5i5VnaTD6bNttpSpcqwKVmDmSHLwxoz97fAHaepqFOk/l1fIu94nImIXneNbhsJx/RQNIww==}
- '@multiformats/multiaddr-matcher@1.7.2':
- resolution: {integrity: sha512-BJzHOBAAxGZKw+FY/MzeIKGKERAW/1XOrpj61wgzZVvR/iksyGTQhliyTgmuakpBJPSsCxlrk3eLemVhZuJIFQ==}
+ '@multiformats/multiaddr-matcher@2.0.2':
+ resolution: {integrity: sha512-si7EZCI93mfBJKKRkh+u2bB9W6W5APVN3XfdwuseEJ0OS7ysg0Jno9SuAi0bRzsl5OEFESoF71SjsRqgp8PXAA==}
- '@multiformats/multiaddr-to-uri@11.0.0':
- resolution: {integrity: sha512-9RNmlIGwZbBLsHekT50dbt4o4u8Iciw9kGjv+WHiGxQdsJ6xKKjU1+C0Vbas6RilMbaVOAOnEyfNcXbUmTkLxQ==}
+ '@multiformats/multiaddr-to-uri@11.0.2':
+ resolution: {integrity: sha512-SiLFD54zeOJ0qMgo9xv1Tl9O5YktDKAVDP4q4hL16mSq4O4sfFNagNADz8eAofxd6TfQUzGQ3TkRRG9IY2uHRg==}
'@multiformats/multiaddr@12.5.1':
resolution: {integrity: sha512-+DDlr9LIRUS8KncI1TX/FfUn8F2dl6BIxJgshS/yFQCNB5IAF0OGzcwB39g5NLE22s4qqDePv0Qof6HdpJ/4aQ==}
@@ -847,10 +858,17 @@ packages:
resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==}
engines: {node: ^14.21.3 || >=16}
- '@noble/curves@1.9.2':
- resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==}
+ '@noble/curves@1.2.0':
+ resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==}
+
+ '@noble/curves@1.9.6':
+ resolution: {integrity: sha512-GIKz/j99FRthB8icyJQA51E8Uk5hXmdyThjgQXRKiv9h0zeRlzSCLIzFw6K1LotZ3XuB7yzlf76qk7uBmTdFqA==}
engines: {node: ^14.21.3 || >=16}
+ '@noble/hashes@1.3.2':
+ resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
+ engines: {node: '>= 16'}
+
'@noble/hashes@1.8.0':
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
engines: {node: ^14.21.3 || >=16}
@@ -961,35 +979,35 @@ packages:
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
engines: {node: '>= 10.0.0'}
- '@peculiar/asn1-cms@2.3.15':
- resolution: {integrity: sha512-B+DoudF+TCrxoJSTjjcY8Mmu+lbv8e7pXGWrhNp2/EGJp9EEcpzjBCar7puU57sGifyzaRVM03oD5L7t7PghQg==}
+ '@peculiar/asn1-cms@2.4.0':
+ resolution: {integrity: sha512-TJvw5Tna/txvzzwnKUlCFd6zIz4R7qysHCaU6M2oe/MUT6EkvJDOzGGNY0hdjJYpuuHoqanQbIqEBhSLSWe1Tg==}
- '@peculiar/asn1-csr@2.3.15':
- resolution: {integrity: sha512-caxAOrvw2hUZpxzhz8Kp8iBYKsHbGXZPl2KYRMIPvAfFateRebS3136+orUpcVwHRmpXWX2kzpb6COlIrqCumA==}
+ '@peculiar/asn1-csr@2.4.0':
+ resolution: {integrity: sha512-9yQz0hQ9ynGr/I1X1v64QQGfRMbviHXyqY07cy69UzXa8s4ayCKx/TncU6lDWcTKs7P/X/AEcuJcG7Xbw0cl1A==}
- '@peculiar/asn1-ecc@2.3.15':
- resolution: {integrity: sha512-/HtR91dvgog7z/WhCVdxZJ/jitJuIu8iTqiyWVgRE9Ac5imt2sT/E4obqIVGKQw7PIy+X6i8lVBoT6wC73XUgA==}
+ '@peculiar/asn1-ecc@2.4.0':
+ resolution: {integrity: sha512-fJiYUBCJBDkjh347zZe5H81BdJ0+OGIg0X9z06v8xXUoql3MFeENUX0JsjCaVaU9A0L85PefLPGYkIoGpTnXLQ==}
- '@peculiar/asn1-pfx@2.3.15':
- resolution: {integrity: sha512-E3kzQe3J2xV9DP6SJS4X6/N1e4cYa2xOAK46VtvpaRk8jlheNri8v0rBezKFVPB1rz/jW8npO+u1xOvpATFMWg==}
+ '@peculiar/asn1-pfx@2.4.0':
+ resolution: {integrity: sha512-fhpeoJ6T4nCLWT5tt3Un+BbyM1lLFnGXcRC2Ioe5ra2I0yptdjw05j20rV8BlUVzPIvUYpatq6joMQKe3ibh0w==}
- '@peculiar/asn1-pkcs8@2.3.15':
- resolution: {integrity: sha512-/PuQj2BIAw1/v76DV1LUOA6YOqh/UvptKLJHtec/DQwruXOCFlUo7k6llegn8N5BTeZTWMwz5EXruBw0Q10TMg==}
+ '@peculiar/asn1-pkcs8@2.4.0':
+ resolution: {integrity: sha512-4r2LtsAM0HWXLxetGTYKyBumky7W6C1EuiOctqhl7zFK5MHjiZ+9WOeaoeTPR1g3OEoeG7KEWIkaUOyRH4ojTw==}
- '@peculiar/asn1-pkcs9@2.3.15':
- resolution: {integrity: sha512-yiZo/1EGvU1KiQUrbcnaPGWc0C7ElMMskWn7+kHsCFm+/9fU0+V1D/3a5oG0Jpy96iaXggQpA9tzdhnYDgjyFg==}
+ '@peculiar/asn1-pkcs9@2.4.0':
+ resolution: {integrity: sha512-D7paqEVpu9wuWuClMN+vR5cqJWJITNPaMoa9R+FmkJ8ywF9UaS2JFI0RYclKILNoLdLg1N4eUCoJvM+ubsIIZQ==}
- '@peculiar/asn1-rsa@2.3.15':
- resolution: {integrity: sha512-p6hsanvPhexRtYSOHihLvUUgrJ8y0FtOM97N5UEpC+VifFYyZa0iZ5cXjTkZoDwxJ/TTJ1IJo3HVTB2JJTpXvg==}
+ '@peculiar/asn1-rsa@2.4.0':
+ resolution: {integrity: sha512-6PP75voaEnOSlWR9sD25iCQyLgFZHXbmxvUfnnDcfL6Zh5h2iHW38+bve4LfH7a60x7fkhZZNmiYqAlAff9Img==}
- '@peculiar/asn1-schema@2.3.15':
- resolution: {integrity: sha512-QPeD8UA8axQREpgR5UTAfu2mqQmm97oUqahDtNdBcfj3qAnoXzFdQW+aNf/tD2WVXF8Fhmftxoj0eMIT++gX2w==}
+ '@peculiar/asn1-schema@2.4.0':
+ resolution: {integrity: sha512-umbembjIWOrPSOzEGG5vxFLkeM8kzIhLkgigtsOrfLKnuzxWxejAcUX+q/SoZCdemlODOcr5WiYa7+dIEzBXZQ==}
- '@peculiar/asn1-x509-attr@2.3.15':
- resolution: {integrity: sha512-TWJVJhqc+IS4MTEML3l6W1b0sMowVqdsnI4dnojg96LvTuP8dga9f76fjP07MUuss60uSyT2ckoti/2qHXA10A==}
+ '@peculiar/asn1-x509-attr@2.4.0':
+ resolution: {integrity: sha512-Tr5Zi+wcE2sfR0gKRvsPwXoA1U8CuDnwiFbxCS+5Z1Nck9zlHj86+4/EZhwucjKXwPEHk1ekhqb3iwISY/+E/w==}
- '@peculiar/asn1-x509@2.3.15':
- resolution: {integrity: sha512-0dK5xqTqSLaxv1FHXIcd4Q/BZNuopg+u1l23hT9rOmQ1g4dNtw0g/RnEi+TboB0gOwGtrWn269v27cMgchFIIg==}
+ '@peculiar/asn1-x509@2.4.0':
+ resolution: {integrity: sha512-F7mIZY2Eao2TaoVqigGMLv+NDdpwuBKU1fucHPONfzaBS4JXXCNCmfO0Z3dsy7JzKGqtDcYC1mr9JjaZQZNiuw==}
'@peculiar/json-schema@1.1.12':
resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==}
@@ -999,8 +1017,8 @@ packages:
resolution: {integrity: sha512-BRs5XUAwiyCDQMsVA9IDvDa7UBR9gAvPHgugOeGng3YN6vJ9JYonyDc0lNczErgtCWtucjR5N7VtaonboD/ezg==}
engines: {node: '>=10.12.0'}
- '@peculiar/x509@1.12.4':
- resolution: {integrity: sha512-4bWU48fN53nt3W683CrEVcUIus7WQlBq/EMVFx7K+FvQTOWJ5RmfJvTLVOfwDjAyxs7jVPbgUGBdqEDlLy1t9Q==}
+ '@peculiar/x509@1.13.0':
+ resolution: {integrity: sha512-r9BOb1GZ3gx58Pog7u9x70spnHlCQPFm7u/ZNlFv+uBsU7kTDY9QkUD+l+X0awopDuCK1fkH3nEIZeMDSG/jlw==}
'@peerbit/any-store-interface@1.0.0':
resolution: {integrity: sha512-Hlqzy0oFoynmpaxnaVzPByyagXorCZVWVAm+E179uXZRHwfa9KUZ9uGevAAIQFBh6WgiM5Vne6Whjg+9EJBxGA==}
@@ -1098,24 +1116,29 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
+ '@playwright/test@1.54.1':
+ resolution: {integrity: sha512-FS8hQ12acieG2dYSksmLOF7BNxnVf2afRJdCuM1eMSxj6QTSE6G4InGF7oApGgDb65MX7AwMVlIkpru0yZA4Xw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
'@protobufjs/float@1.0.2':
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
'@protobufjs/utf8@1.1.0':
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
- '@react-native/assets-registry@0.79.2':
- resolution: {integrity: sha512-5h2Z7/+/HL/0h88s0JHOdRCW4CXMCJoROxqzHqxdrjGL6EBD1DdaB4ZqkCOEVSW4Vjhir5Qb97C8i/MPWEYPtg==}
+ '@react-native/assets-registry@0.80.2':
+ resolution: {integrity: sha512-+sI2zIM22amhkZqW+RpD3qDoopeRiezrTtZMP+Y3HI+6/2JbEq7DdyV/2YS1lrSSdyy3STW2V37Lt4dKqP0lEQ==}
engines: {node: '>=18'}
- '@react-native/codegen@0.79.2':
- resolution: {integrity: sha512-8JTlGLuLi1p8Jx2N/enwwEd7/2CfrqJpv90Cp77QLRX3VHF2hdyavRIxAmXMwN95k+Me7CUuPtqn2X3IBXOWYg==}
+ '@react-native/codegen@0.80.2':
+ resolution: {integrity: sha512-eYad9ex9/RS6oFbbpu6LxsczktbhfJbJlTvtRlcWLJjJbFTeNr5Q7CgBT2/m5VtpxnJ/0YdmZ9vdazsJ2yp9kw==}
engines: {node: '>=18'}
peerDependencies:
'@babel/core': '*'
- '@react-native/community-cli-plugin@0.79.2':
- resolution: {integrity: sha512-E+YEY2dL+68HyR2iahsZdyBKBUi9QyPyaN9vsnda1jNgCjNpSPk2yAF5cXsho+zKK5ZQna3JSeE1Kbi2IfGJbw==}
+ '@react-native/community-cli-plugin@0.80.2':
+ resolution: {integrity: sha512-UBjsE+lv1YtThs56mgFaUdWv0jNE1oO58Lkbf3dn47F0e7YiTubIcvP6AnlaMhZF2Pmt9ky8J1jTpgItO9tGeg==}
engines: {node: '>=18'}
peerDependencies:
'@react-native-community/cli': '*'
@@ -1123,27 +1146,27 @@ packages:
'@react-native-community/cli':
optional: true
- '@react-native/debugger-frontend@0.79.2':
- resolution: {integrity: sha512-cGmC7X6kju76DopSBNc+PRAEetbd7TWF9J9o84hOp/xL3ahxR2kuxJy0oJX8Eg8oehhGGEXTuMKHzNa3rDBeSg==}
+ '@react-native/debugger-frontend@0.80.2':
+ resolution: {integrity: sha512-n3D88bqNk0bY+YjNxbM6giqva06xj+rgEfu91Pg+nJ0szSL2eLl7ULERJqI3hxFt0XGuTpTOxZgw/Po5maXa4g==}
engines: {node: '>=18'}
- '@react-native/dev-middleware@0.79.2':
- resolution: {integrity: sha512-9q4CpkklsAs1L0Bw8XYCoqqyBSrfRALGEw4/r0EkR38Y/6fVfNfdsjSns0pTLO6h0VpxswK34L/hm4uK3MoLHw==}
+ '@react-native/dev-middleware@0.80.2':
+ resolution: {integrity: sha512-8OeBEZNiApdbZaqTrrzeyFwXn/JwgJox7jdtjVAH56DggTVJXdbnyUjQ4ts6XAacEQgpFOAskoO730eyafOkAA==}
engines: {node: '>=18'}
- '@react-native/gradle-plugin@0.79.2':
- resolution: {integrity: sha512-6MJFemrwR0bOT0QM+2BxX9k3/pvZQNmJ3Js5pF/6owsA0cUDiCO57otiEU8Fz+UywWEzn1FoQfOfQ8vt2GYmoA==}
+ '@react-native/gradle-plugin@0.80.2':
+ resolution: {integrity: sha512-C5/FYbIfCXPFjF/hIcWFKC9rEadDDhPMbxE7tarGR9tmYKyb9o7fYvfNe8fFgbCRKelMHP0ShATz3T73pHHDfA==}
engines: {node: '>=18'}
- '@react-native/js-polyfills@0.79.2':
- resolution: {integrity: sha512-IaY87Ckd4GTPMkO1/Fe8fC1IgIx3vc3q9Tyt/6qS3Mtk9nC0x9q4kSR5t+HHq0/MuvGtu8HpdxXGy5wLaM+zUw==}
+ '@react-native/js-polyfills@0.80.2':
+ resolution: {integrity: sha512-f63M3paxHK92p6L9o+AY7hV/YojCZAhb+fdDpSfOtDtCngWbBhd6foJrO6IybzDFERxlwErupUg3pqr5w3KJWw==}
engines: {node: '>=18'}
- '@react-native/normalize-colors@0.79.2':
- resolution: {integrity: sha512-+b+GNrupWrWw1okHnEENz63j7NSMqhKeFMOyzYLBwKcprG8fqJQhDIGXfizKdxeIa5NnGSAevKL1Ev1zJ56X8w==}
+ '@react-native/normalize-colors@0.80.2':
+ resolution: {integrity: sha512-08Ax7554Z31NXi5SQ6h1GsiSrlZEOYHQNSC7u+x91Tdiq87IXldW8Ib1N3ThXoDcD8bjr+I+MdlabEJw36/fFg==}
- '@react-native/virtualized-lists@0.79.2':
- resolution: {integrity: sha512-9G6ROJeP+rdw9Bvr5ruOlag11ET7j1z/En1riFFNo6W3xZvJY+alCuH1ttm12y9+zBm4n8jwCk4lGhjYaV4dKw==}
+ '@react-native/virtualized-lists@0.80.2':
+ resolution: {integrity: sha512-kXsIV2eB73QClbbH/z/lRhZkyj3Dke4tarM5w2yXSNwJthMPMfj4KqLZ6Lnf0nmPPjz7qo/voKtlrGqlM822Rg==}
engines: {node: '>=18'}
peerDependencies:
'@types/react': ^19.0.0
@@ -1153,8 +1176,8 @@ packages:
'@types/react':
optional: true
- '@riffcc/lens-sdk@0.1.25':
- resolution: {integrity: sha512-OEvXBKdhsjhbkwzoDct3NR8I8HxCVpRlIT+iqScUcWbTz1BugNV3wEMYYlmAEXr9f0e55Jx/+iTT1ToEHLn5Xg==}
+ '@riffcc/lens-sdk@0.1.32':
+ resolution: {integrity: sha512-J1wd8/qnmn3iXyZa9EwoeYKla07l5tbMasUyTlQwQbIJFiG0MubUGK2vD/avvjeISANxxP4RM5MLwAiuVOUfsA==}
'@rollup/plugin-inject@5.0.5':
resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==}
@@ -1493,6 +1516,9 @@ packages:
'@types/node@22.15.33':
resolution: {integrity: sha512-wzoocdnnpSxZ+6CjW4ADCK1jVmd1S/J3ArNWfn8FDDQtRm8dkDg7TA+mvek2wNrfCgwuZxqEOiB9B1XCJ6+dbw==}
+ '@types/node@22.7.5':
+ resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==}
+
'@types/plist@3.0.5':
resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==}
@@ -1748,6 +1774,9 @@ packages:
aes-js@3.0.0:
resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==}
+ aes-js@4.0.0-beta.5:
+ resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==}
+
agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
@@ -1772,6 +1801,9 @@ packages:
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ ajv@8.17.1:
+ resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
+
alien-signals@1.0.13:
resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==}
@@ -1894,13 +1926,13 @@ packages:
resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- babel-plugin-syntax-hermes-parser@0.25.1:
- resolution: {integrity: sha512-IVNpGzboFLfXZUAwkLFcI/bnqVbwky0jP3eBno4HKtqvQJAHBLdgxiG6lQ4to0+Q/YCN3PO0od5NZwIKyY4REQ==}
+ babel-plugin-syntax-hermes-parser@0.28.1:
+ resolution: {integrity: sha512-meT17DOuUElMNsL5LZN56d+KBp22hb0EfxWfuPUeoSi54e40v1W4C2V36P75FpsH9fVEfDKpw5Nnkahc8haSsQ==}
- babel-preset-current-node-syntax@1.1.0:
- resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==}
+ babel-preset-current-node-syntax@1.2.0:
+ resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==}
peerDependencies:
- '@babel/core': ^7.0.0
+ '@babel/core': ^7.0.0 || ^8.0.0-0
babel-preset-jest@29.6.3:
resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==}
@@ -1920,6 +1952,9 @@ packages:
bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
+ bip39@3.1.0:
+ resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==}
+
bl@0.8.2:
resolution: {integrity: sha512-pfqikmByp+lifZCS0p6j6KreV6kNU6Apzpm2nKOk+94cZb/jvle55+JxWiByUQ0Wo/+XnDXEy5MxxKMb6r0VIw==}
@@ -2069,8 +2104,8 @@ packages:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'}
- caniuse-lite@1.0.30001726:
- resolution: {integrity: sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==}
+ caniuse-lite@1.0.30001731:
+ resolution: {integrity: sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==}
cborg@4.2.12:
resolution: {integrity: sha512-z126yLoavS75cdTuiKu61RC3Y3trqtDAgQRa5Q0dpHn1RmqhIedptWXKnk0lQ5yo/GmcV9myvIkzFgZ8GnqSog==}
@@ -2141,6 +2176,9 @@ packages:
resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==}
engines: {node: '>=8'}
+ cliui@6.0.0:
+ resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
+
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -2309,6 +2347,10 @@ packages:
supports-color:
optional: true
+ decamelize@1.2.0:
+ resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
+ engines: {node: '>=0.10.0'}
+
decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'}
@@ -2387,6 +2429,9 @@ packages:
diffie-hellman@5.0.3:
resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
+ dijkstrajs@1.0.3:
+ resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
+
dir-compare@4.2.0:
resolution: {integrity: sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==}
@@ -2452,8 +2497,8 @@ packages:
deprecated: Please use @electron/rebuild moving forward. There is no API change, just a package name change
hasBin: true
- electron-to-chromium@1.5.176:
- resolution: {integrity: sha512-2nDK9orkm7M9ZZkjO3PjbEd3VUulQLyg5T9O3enJdFvUg46Hzd4DUvTvAuEgbdHYXyFsiG4A5sO9IzToMH1cDg==}
+ electron-to-chromium@1.5.193:
+ resolution: {integrity: sha512-eePuBZXM9OVCwfYUhd2OzESeNGnWmLyeu0XAEjf7xjijNjHFdeJSzuRUGN4ueT2tEYo5YqjHramKEFxz67p3XA==}
electron-updater@6.6.2:
resolution: {integrity: sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw==}
@@ -2630,6 +2675,10 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
+ ethers@6.15.0:
+ resolution: {integrity: sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==}
+ engines: {node: '>=14.0.0'}
+
event-iterator@2.0.0:
resolution: {integrity: sha512-KGft0ldl31BZVV//jj+IAIGCxkvvUkkON+ScH6zfoX+l+omX6001ggyRSpI0Io2Hlro0ThXotswCtfzS8UkIiQ==}
@@ -2691,6 +2740,9 @@ packages:
resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==}
engines: {node: '>=6'}
+ fast-uri@3.0.6:
+ resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==}
+
fastq@1.19.1:
resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
@@ -2879,10 +2931,6 @@ packages:
resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==}
engines: {node: '>=10.0'}
- globals@11.12.0:
- resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
- engines: {node: '>=4'}
-
globals@13.24.0:
resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
engines: {node: '>=8'}
@@ -2952,18 +3000,18 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
- hermes-estree@0.25.1:
- resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==}
-
hermes-estree@0.28.1:
resolution: {integrity: sha512-w3nxl/RGM7LBae0v8LH2o36+8VqwOZGv9rX1wyoWT6YaKZLqpJZ0YQ5P0LVr3tuRpf7vCx0iIG4i/VmBJejxTQ==}
- hermes-parser@0.25.1:
- resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==}
+ hermes-estree@0.29.1:
+ resolution: {integrity: sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==}
hermes-parser@0.28.1:
resolution: {integrity: sha512-nf8o+hE8g7UJWParnccljHumE9Vlq8F7MqIdeahl+4x0tvCUJYRrT0L7h0MMg/X9YJmkNwsfbaNNrzPtFXOscg==}
+ hermes-parser@0.29.1:
+ resolution: {integrity: sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==}
+
hmac-drbg@1.0.1:
resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==}
@@ -3013,6 +3061,9 @@ packages:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
+ idb-keyval@6.2.2:
+ resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==}
+
idb-wrapper@1.7.2:
resolution: {integrity: sha512-zfNREywMuf0NzDo9mVsL0yegjsirJxHpKHvWcyRozIqQy89g0a3U+oBPOCN4cc0oCiOuYgZHimzaW/R46G1Mpg==}
@@ -3386,6 +3437,9 @@ packages:
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@@ -3458,8 +3512,8 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
- libp2p@2.8.12:
- resolution: {integrity: sha512-wWknf2YsfHwnNK0XyFxCkVVNrckCrY+lwCdp4bpHScb5ALcWmzpgWP8+h/b66sEJ3IUJjhgjMkN1W9sS53KTPQ==}
+ libp2p@2.9.0:
+ resolution: {integrity: sha512-gzRnhLY+k9KjYifWQCYbdEfmWqCFdM0TZ5Q7qqdY13sAUKXixK0MF5+Z9LMrm5ELGDPWX7pRVLGK8BOSv5/v3Q==}
libsodium-wrappers@0.7.15:
resolution: {integrity: sha512-E4anqJQwcfiC6+Yrl01C1m8p99wEhLmJSs0VQqST66SbQXXBoaJY0pF4BNjRYa/sOQAxx6lXAaAFIlx+15tXJQ==}
@@ -3580,61 +3634,61 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
- metro-babel-transformer@0.82.4:
- resolution: {integrity: sha512-4juJahGRb1gmNbQq48lNinB6WFNfb6m0BQqi/RQibEltNiqTCxew/dBspI2EWA4xVCd3mQWGfw0TML4KurQZnQ==}
+ metro-babel-transformer@0.82.5:
+ resolution: {integrity: sha512-W/scFDnwJXSccJYnOFdGiYr9srhbHPdxX9TvvACOFsIXdLilh3XuxQl/wXW6jEJfgIb0jTvoTlwwrqvuwymr6Q==}
engines: {node: '>=18.18'}
- metro-cache-key@0.82.4:
- resolution: {integrity: sha512-2JCTqcpF+f2OghOpe/+x+JywfzDkrHdAqinPFWmK2ezNAU/qX0jBFaTETogPibFivxZJil37w9Yp6syX8rFUng==}
+ metro-cache-key@0.82.5:
+ resolution: {integrity: sha512-qpVmPbDJuRLrT4kcGlUouyqLGssJnbTllVtvIgXfR7ZuzMKf0mGS+8WzcqzNK8+kCyakombQWR0uDd8qhWGJcA==}
engines: {node: '>=18.18'}
- metro-cache@0.82.4:
- resolution: {integrity: sha512-vX0ylSMGtORKiZ4G8uP6fgfPdDiCWvLZUGZ5zIblSGylOX6JYhvExl0Zg4UA9pix/SSQu5Pnp9vdODMFsNIxhw==}
+ metro-cache@0.82.5:
+ resolution: {integrity: sha512-AwHV9607xZpedu1NQcjUkua8v7HfOTKfftl6Vc9OGr/jbpiJX6Gpy8E/V9jo/U9UuVYX2PqSUcVNZmu+LTm71Q==}
engines: {node: '>=18.18'}
- metro-config@0.82.4:
- resolution: {integrity: sha512-Ki3Wumr3hKHGDS7RrHsygmmRNc/PCJrvkLn0+BWWxmbOmOcMMJDSmSI+WRlT8jd5VPZFxIi4wg+sAt5yBXAK0g==}
+ metro-config@0.82.5:
+ resolution: {integrity: sha512-/r83VqE55l0WsBf8IhNmc/3z71y2zIPe5kRSuqA5tY/SL/ULzlHUJEMd1szztd0G45JozLwjvrhAzhDPJ/Qo/g==}
engines: {node: '>=18.18'}
- metro-core@0.82.4:
- resolution: {integrity: sha512-Xo4ozbxPg2vfgJGCgXZ8sVhC2M0lhTqD+tsKO2q9aelq/dCjnnSb26xZKcQO80CQOQUL7e3QWB7pLFGPjZm31A==}
+ metro-core@0.82.5:
+ resolution: {integrity: sha512-OJL18VbSw2RgtBm1f2P3J5kb892LCVJqMvslXxuxjAPex8OH7Eb8RBfgEo7VZSjgb/LOf4jhC4UFk5l5tAOHHA==}
engines: {node: '>=18.18'}
- metro-file-map@0.82.4:
- resolution: {integrity: sha512-eO7HD1O3aeNsbEe6NBZvx1lLJUrxgyATjnDmb7bm4eyF6yWOQot9XVtxTDLNifECuvsZ4jzRiTInrbmIHkTdGA==}
+ metro-file-map@0.82.5:
+ resolution: {integrity: sha512-vpMDxkGIB+MTN8Af5hvSAanc6zXQipsAUO+XUx3PCQieKUfLwdoa8qaZ1WAQYRpaU+CJ8vhBcxtzzo3d9IsCIQ==}
engines: {node: '>=18.18'}
- metro-minify-terser@0.82.4:
- resolution: {integrity: sha512-W79Mi6BUwWVaM8Mc5XepcqkG+TSsCyyo//dmTsgYfJcsmReQorRFodil3bbJInETvjzdnS1mCsUo9pllNjT1Hg==}
+ metro-minify-terser@0.82.5:
+ resolution: {integrity: sha512-v6Nx7A4We6PqPu/ta1oGTqJ4Usz0P7c+3XNeBxW9kp8zayS3lHUKR0sY0wsCHInxZlNAEICx791x+uXytFUuwg==}
engines: {node: '>=18.18'}
- metro-resolver@0.82.4:
- resolution: {integrity: sha512-uWoHzOBGQTPT5PjippB8rRT3iI9CTgFA9tRiLMzrseA5o7YAlgvfTdY9vFk2qyk3lW3aQfFKWkmqENryPRpu+Q==}
+ metro-resolver@0.82.5:
+ resolution: {integrity: sha512-kFowLnWACt3bEsuVsaRNgwplT8U7kETnaFHaZePlARz4Fg8tZtmRDUmjaD68CGAwc0rwdwNCkWizLYpnyVcs2g==}
engines: {node: '>=18.18'}
- metro-runtime@0.82.4:
- resolution: {integrity: sha512-vVyFO7H+eLXRV2E7YAUYA7aMGBECGagqxmFvC2hmErS7oq90BbPVENfAHbUWq1vWH+MRiivoRxdxlN8gBoF/dw==}
+ metro-runtime@0.82.5:
+ resolution: {integrity: sha512-rQZDoCUf7k4Broyw3Ixxlq5ieIPiR1ULONdpcYpbJQ6yQ5GGEyYjtkztGD+OhHlw81LCR2SUAoPvtTus2WDK5g==}
engines: {node: '>=18.18'}
- metro-source-map@0.82.4:
- resolution: {integrity: sha512-9jzDQJ0FPas1FuQFtwmBHsez2BfhFNufMowbOMeG3ZaFvzeziE8A0aJwILDS3U+V5039ssCQFiQeqDgENWvquA==}
+ metro-source-map@0.82.5:
+ resolution: {integrity: sha512-wH+awTOQJVkbhn2SKyaw+0cd+RVSCZ3sHVgyqJFQXIee/yLs3dZqKjjeKKhhVeudgjXo7aE/vSu/zVfcQEcUfw==}
engines: {node: '>=18.18'}
- metro-symbolicate@0.82.4:
- resolution: {integrity: sha512-LwEwAtdsx7z8rYjxjpLWxuFa2U0J6TS6ljlQM4WAATKa4uzV8unmnRuN2iNBWTmRqgNR77mzmI2vhwD4QSCo+w==}
+ metro-symbolicate@0.82.5:
+ resolution: {integrity: sha512-1u+07gzrvYDJ/oNXuOG1EXSvXZka/0JSW1q2EYBWerVKMOhvv9JzDGyzmuV7hHbF2Hg3T3S2uiM36sLz1qKsiw==}
engines: {node: '>=18.18'}
hasBin: true
- metro-transform-plugins@0.82.4:
- resolution: {integrity: sha512-NoWQRPHupVpnDgYguiEcm7YwDhnqW02iWWQjO2O8NsNP09rEMSq99nPjARWfukN7+KDh6YjLvTIN20mj3dk9kw==}
+ metro-transform-plugins@0.82.5:
+ resolution: {integrity: sha512-57Bqf3rgq9nPqLrT2d9kf/2WVieTFqsQ6qWHpEng5naIUtc/Iiw9+0bfLLWSAw0GH40iJ4yMjFcFJDtNSYynMA==}
engines: {node: '>=18.18'}
- metro-transform-worker@0.82.4:
- resolution: {integrity: sha512-kPI7Ad/tdAnI9PY4T+2H0cdgGeSWWdiPRKuytI806UcN4VhFL6OmYa19/4abYVYF+Cd2jo57CDuwbaxRfmXDhw==}
+ metro-transform-worker@0.82.5:
+ resolution: {integrity: sha512-mx0grhAX7xe+XUQH6qoHHlWedI8fhSpDGsfga7CpkO9Lk9W+aPitNtJWNGrW8PfjKEWbT9Uz9O50dkI8bJqigw==}
engines: {node: '>=18.18'}
- metro@0.82.4:
- resolution: {integrity: sha512-/gFmw3ux9CPG5WUmygY35hpyno28zi/7OUn6+OFfbweA8l0B+PPqXXLr0/T6cf5nclCcH0d22o+02fICaShVxw==}
+ metro@0.82.5:
+ resolution: {integrity: sha512-8oAXxL7do8QckID/WZEKaIFuQJFUTLzfVcC48ghkHhNK2RGuQq8Xvf4AVd+TUA0SZtX0q8TGNXZ/eba1ckeGCg==}
engines: {node: '>=18.18'}
hasBin: true
@@ -3884,8 +3938,8 @@ packages:
nullthrows@1.1.1:
resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==}
- ob1@0.82.4:
- resolution: {integrity: sha512-n9S8e4l5TvkrequEAMDidl4yXesruWTNTzVkeaHSGywoTOIwTzZzKw7Z670H3eaXDZui5MJXjWGNzYowVZIxCA==}
+ ob1@0.82.5:
+ resolution: {integrity: sha512-QyQQ6e66f+Ut/qUVjEce0E/wux5nAGLXYZDn1jr15JWstHsCH3l6VVrg8NKDptW9NEiBXKOJeGF/ydxeSDF3IQ==}
engines: {node: '>=18.18'}
object-inspect@1.13.4:
@@ -4095,13 +4149,13 @@ packages:
resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==}
engines: {node: '>=10'}
- playwright-core@1.53.1:
- resolution: {integrity: sha512-Z46Oq7tLAyT0lGoFx4DOuB1IA9D1TPj0QkYxpPVUnGDqHHvDpCftu1J2hM2PiWsNMoZh8+LQaarAWcDfPBc6zg==}
+ playwright-core@1.54.1:
+ resolution: {integrity: sha512-Nbjs2zjj0htNhzgiy5wu+3w09YetDx5pkrpI/kZotDlDUaYk0HVA5xrBVPdow4SAUIlhgKcJeJg4GRKW6xHusA==}
engines: {node: '>=18'}
hasBin: true
- playwright@1.53.1:
- resolution: {integrity: sha512-LJ13YLr/ocweuwxyGf1XNFWIU4M2zUSo149Qbp+A4cpwDjsxRPj7k6H25LBrEHiEwxvRbD8HdwvQmRMSvquhYw==}
+ playwright@1.54.1:
+ resolution: {integrity: sha512-peWpSwIBmSLi6aW2auvrUtf2DqY16YYcCMO8rTVx486jKmDTJg7UAhyrraP98GB8BoPURZP8+nxO7TSd4cPr5g==}
engines: {node: '>=18'}
hasBin: true
@@ -4109,6 +4163,10 @@ packages:
resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==}
engines: {node: '>=10.4.0'}
+ pngjs@5.0.0:
+ resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
+ engines: {node: '>=10.13.0'}
+
possible-typed-array-names@1.1.0:
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
engines: {node: '>= 0.4'}
@@ -4225,6 +4283,11 @@ packages:
resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==}
engines: {node: '>=6.0.0'}
+ qrcode@1.5.4:
+ resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+
qs@6.14.0:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
engines: {node: '>=0.6'}
@@ -4246,8 +4309,8 @@ packages:
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
engines: {node: '>=10'}
- race-event@1.3.0:
- resolution: {integrity: sha512-kaLm7axfOnahIqD3jQ4l1e471FIFcEGebXEnhxyLscuUzV8C94xVHtWEqDDXxll7+yu/6lW0w1Ff4HbtvHvOHg==}
+ race-event@1.6.1:
+ resolution: {integrity: sha512-vi7WH5g5KoTFpu2mme/HqZiWH14XSOtg5rfp6raBskBHl7wnmy3F/biAIyY5MsK+BHWhoPhxtZ1Y2R7OHHaWyQ==}
race-signal@1.1.3:
resolution: {integrity: sha512-Mt2NznMgepLfORijhQMncE26IhkmjEphig+/1fKC0OtaKwys/gpvpmswSjoN01SS+VO951mj0L4VIDXdXsjnfA==}
@@ -4266,24 +4329,24 @@ packages:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
hasBin: true
- react-devtools-core@6.1.2:
- resolution: {integrity: sha512-ldFwzufLletzCikNJVYaxlxMLu7swJ3T2VrGfzXlMsVhZhPDKXA38DEROidaYZVgMAmQnIjymrmqto5pyfrwPA==}
+ react-devtools-core@6.1.5:
+ resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==}
react-is@18.3.1:
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
- react-native-webrtc@124.0.5:
- resolution: {integrity: sha512-LIQJKst+t53bJOcQef9VXuz3pVheSBUA4olQGkxosbF4pHW1gsWoXYmf6wmI2zrqOA+aZsjjB6aT9AKLyr6a0Q==}
+ react-native-webrtc@124.0.6:
+ resolution: {integrity: sha512-5GviOGK19vujT7sGvSYdZE+bBlh0KC9g1JLharzajpCDVrNdCSpYxveOJUINSRevLsmL12FgNJJgnTjFKn7Aqw==}
peerDependencies:
react-native: '>=0.60.0'
- react-native@0.79.2:
- resolution: {integrity: sha512-AnGzb56JvU5YCL7cAwg10+ewDquzvmgrMddiBM0GAWLwQM/6DJfGd2ZKrMuKKehHerpDDZgG+EY64gk3x3dEkw==}
+ react-native@0.80.2:
+ resolution: {integrity: sha512-6ySV4qTJo/To3lgpG/9Mcg/ZtvExqOVZuT7JVGcO5rS2Bjvl/yUAkQF0hTnbRb2Ch6T5MlKghrM4OeHX+KA9Pg==}
engines: {node: '>=18'}
hasBin: true
peerDependencies:
- '@types/react': ^19.0.0
- react: ^19.0.0
+ '@types/react': ^19.1.0
+ react: ^19.1.0
peerDependenciesMeta:
'@types/react':
optional: true
@@ -4292,8 +4355,8 @@ packages:
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
engines: {node: '>=0.10.0'}
- react@19.1.0:
- resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==}
+ react@19.1.1:
+ resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==}
engines: {node: '>=0.10.0'}
read-binary-file-arch@1.0.6:
@@ -4338,6 +4401,13 @@ packages:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ require-main-filename@2.0.0:
+ resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
+
resedit@1.7.2:
resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==}
engines: {node: '>=12', npm: '>=6'}
@@ -4480,8 +4550,8 @@ packages:
sax@1.4.1:
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
- scheduler@0.25.0:
- resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
+ scheduler@0.26.0:
+ resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==}
scrypt-js@3.0.1:
resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==}
@@ -4839,6 +4909,9 @@ packages:
tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
+ tslib@2.7.0:
+ resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
+
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
@@ -4911,6 +4984,9 @@ packages:
uint8arrays@5.1.0:
resolution: {integrity: sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==}
+ undici-types@6.19.8:
+ resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
+
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
@@ -5179,6 +5255,9 @@ packages:
resolution: {integrity: sha512-XUguZbDxCA2wBn2LoFtcEhXL6AXo+hVjGonwhSTTTU9SzbWG8Xu3onNIpzf9j/mYUcJQ0f+m37SzG77G851uFw==}
engines: {node: '>=16.0.0', npm: '>=7.0.0'}
+ which-module@2.0.1:
+ resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
+
which-typed-array@1.1.19:
resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
engines: {node: '>= 0.4'}
@@ -5200,6 +5279,10 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
+ wrap-ansi@6.2.0:
+ resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
+ engines: {node: '>=8'}
+
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
@@ -5238,8 +5321,20 @@ packages:
utf-8-validate:
optional: true
- ws@8.18.2:
- resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==}
+ ws@8.17.1:
+ resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ ws@8.18.3:
+ resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
@@ -5278,6 +5373,9 @@ packages:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
+ y18n@4.0.3:
+ resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
+
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@@ -5288,10 +5386,18 @@ packages:
yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+ yargs-parser@18.1.3:
+ resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
+ engines: {node: '>=6'}
+
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
+ yargs@15.4.1:
+ resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
+ engines: {node: '>=8'}
+
yargs@17.7.2:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
@@ -5307,10 +5413,12 @@ snapshots:
7zip-bin@5.2.0: {}
+ '@adraffy/ens-normalize@1.10.1': {}
+
'@ampproject/remapping@2.3.0':
dependencies:
- '@jridgewell/gen-mapping': 0.3.8
- '@jridgewell/trace-mapping': 0.3.25
+ '@jridgewell/gen-mapping': 0.3.12
+ '@jridgewell/trace-mapping': 0.3.29
'@babel/code-frame@7.27.1':
dependencies:
@@ -5318,20 +5426,20 @@ snapshots:
js-tokens: 4.0.0
picocolors: 1.1.1
- '@babel/compat-data@7.27.7': {}
+ '@babel/compat-data@7.28.0': {}
- '@babel/core@7.27.7':
+ '@babel/core@7.28.0':
dependencies:
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.27.1
- '@babel/generator': 7.27.5
+ '@babel/generator': 7.28.0
'@babel/helper-compilation-targets': 7.27.2
- '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.7)
- '@babel/helpers': 7.27.6
- '@babel/parser': 7.27.7
+ '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0)
+ '@babel/helpers': 7.28.2
+ '@babel/parser': 7.28.0
'@babel/template': 7.27.2
- '@babel/traverse': 7.27.7
- '@babel/types': 7.27.7
+ '@babel/traverse': 7.28.0
+ '@babel/types': 7.28.2
convert-source-map: 2.0.0
debug: 4.4.1
gensync: 1.0.0-beta.2
@@ -5340,35 +5448,37 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/generator@7.27.5':
+ '@babel/generator@7.28.0':
dependencies:
- '@babel/parser': 7.27.7
- '@babel/types': 7.27.7
- '@jridgewell/gen-mapping': 0.3.8
- '@jridgewell/trace-mapping': 0.3.25
+ '@babel/parser': 7.28.0
+ '@babel/types': 7.28.2
+ '@jridgewell/gen-mapping': 0.3.12
+ '@jridgewell/trace-mapping': 0.3.29
jsesc: 3.1.0
'@babel/helper-compilation-targets@7.27.2':
dependencies:
- '@babel/compat-data': 7.27.7
+ '@babel/compat-data': 7.28.0
'@babel/helper-validator-option': 7.27.1
browserslist: 4.25.1
lru-cache: 5.1.1
semver: 6.3.1
+ '@babel/helper-globals@7.28.0': {}
+
'@babel/helper-module-imports@7.27.1':
dependencies:
- '@babel/traverse': 7.27.7
- '@babel/types': 7.27.7
+ '@babel/traverse': 7.28.0
+ '@babel/types': 7.28.2
transitivePeerDependencies:
- supports-color
- '@babel/helper-module-transforms@7.27.3(@babel/core@7.27.7)':
+ '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-module-imports': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
- '@babel/traverse': 7.27.7
+ '@babel/traverse': 7.28.0
transitivePeerDependencies:
- supports-color
@@ -5380,107 +5490,111 @@ snapshots:
'@babel/helper-validator-option@7.27.1': {}
- '@babel/helpers@7.27.6':
+ '@babel/helpers@7.28.2':
dependencies:
'@babel/template': 7.27.2
- '@babel/types': 7.27.7
+ '@babel/types': 7.28.2
'@babel/parser@7.27.7':
dependencies:
'@babel/types': 7.27.7
- '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.7)':
+ '@babel/parser@7.28.0':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/types': 7.28.2
+
+ '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.0)':
+ dependencies:
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.7)':
+ '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@babel/helper-plugin-utils': 7.27.1
- '@babel/runtime@7.27.6': {}
+ '@babel/runtime@7.28.2': {}
'@babel/template@7.27.2':
dependencies:
'@babel/code-frame': 7.27.1
- '@babel/parser': 7.27.7
- '@babel/types': 7.27.7
+ '@babel/parser': 7.28.0
+ '@babel/types': 7.28.2
- '@babel/traverse@7.27.7':
+ '@babel/traverse@7.28.0':
dependencies:
'@babel/code-frame': 7.27.1
- '@babel/generator': 7.27.5
- '@babel/parser': 7.27.7
+ '@babel/generator': 7.28.0
+ '@babel/helper-globals': 7.28.0
+ '@babel/parser': 7.28.0
'@babel/template': 7.27.2
- '@babel/types': 7.27.7
+ '@babel/types': 7.28.2
debug: 4.4.1
- globals: 11.12.0
transitivePeerDependencies:
- supports-color
@@ -5489,6 +5603,11 @@ snapshots:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
+ '@babel/types@7.28.2':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.27.1
+
'@chainsafe/as-chacha20poly1305@0.1.0': {}
'@chainsafe/as-sha256@1.2.0': {}
@@ -5503,7 +5622,7 @@ snapshots:
'@libp2p/interface': 2.10.5
'@libp2p/peer-id': 5.1.8
'@noble/ciphers': 1.3.0
- '@noble/curves': 1.9.2
+ '@noble/curves': 1.9.6
'@noble/hashes': 1.8.0
it-length-prefixed: 10.0.1
it-length-prefixed-stream: 2.0.3
@@ -6054,9 +6173,9 @@ snapshots:
'@jest/transform@29.7.0':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@jest/types': 29.6.3
- '@jridgewell/trace-mapping': 0.3.25
+ '@jridgewell/trace-mapping': 0.3.29
babel-plugin-istanbul: 6.1.1
chalk: 4.1.2
convert-source-map: 2.0.0
@@ -6081,31 +6200,28 @@ snapshots:
'@types/yargs': 17.0.33
chalk: 4.1.2
- '@jridgewell/gen-mapping@0.3.8':
+ '@jridgewell/gen-mapping@0.3.12':
dependencies:
- '@jridgewell/set-array': 1.2.1
'@jridgewell/sourcemap-codec': 1.5.0
- '@jridgewell/trace-mapping': 0.3.25
+ '@jridgewell/trace-mapping': 0.3.29
'@jridgewell/resolve-uri@3.1.2': {}
- '@jridgewell/set-array@1.2.1': {}
-
'@jridgewell/source-map@0.3.6':
dependencies:
- '@jridgewell/gen-mapping': 0.3.8
- '@jridgewell/trace-mapping': 0.3.25
+ '@jridgewell/gen-mapping': 0.3.12
+ '@jridgewell/trace-mapping': 0.3.29
'@jridgewell/sourcemap-codec@1.5.0': {}
- '@jridgewell/trace-mapping@0.3.25':
+ '@jridgewell/trace-mapping@0.3.29':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
'@leichtgewicht/ip-codec@2.0.5': {}
- '@libp2p/circuit-relay-v2@3.2.20':
+ '@libp2p/circuit-relay-v2@3.2.23':
dependencies:
'@libp2p/crypto': 5.1.7
'@libp2p/interface': 2.10.5
@@ -6115,7 +6231,7 @@ snapshots:
'@libp2p/peer-record': 8.0.34
'@libp2p/utils': 6.7.1
'@multiformats/multiaddr': 12.5.1
- '@multiformats/multiaddr-matcher': 1.7.2
+ '@multiformats/multiaddr-matcher': 2.0.2
any-signal: 4.1.1
it-protobuf-stream: 2.0.3
it-stream-types: 2.0.2
@@ -6131,14 +6247,14 @@ snapshots:
'@libp2p/crypto@5.1.7':
dependencies:
'@libp2p/interface': 2.10.5
- '@noble/curves': 1.9.2
+ '@noble/curves': 1.9.6
'@noble/hashes': 1.8.0
multiformats: 13.3.7
protons-runtime: 5.6.0
uint8arraylist: 2.4.8
uint8arrays: 5.1.0
- '@libp2p/identify@3.0.37':
+ '@libp2p/identify@3.0.38':
dependencies:
'@libp2p/crypto': 5.1.7
'@libp2p/interface': 2.10.5
@@ -6147,7 +6263,7 @@ snapshots:
'@libp2p/peer-record': 8.0.34
'@libp2p/utils': 6.7.1
'@multiformats/multiaddr': 12.5.1
- '@multiformats/multiaddr-matcher': 1.7.2
+ '@multiformats/multiaddr-matcher': 2.0.2
it-drain: 3.0.10
it-parallel: 3.0.13
it-protobuf-stream: 2.0.3
@@ -6250,18 +6366,18 @@ snapshots:
uint8arraylist: 2.4.8
uint8arrays: 5.1.0
- '@libp2p/tcp@10.1.17':
+ '@libp2p/tcp@10.1.18':
dependencies:
'@libp2p/interface': 2.10.5
'@libp2p/utils': 6.7.1
'@multiformats/multiaddr': 12.5.1
- '@multiformats/multiaddr-matcher': 1.7.2
+ '@multiformats/multiaddr-matcher': 2.0.2
'@types/sinon': 17.0.4
main-event: 1.0.1
p-defer: 4.0.1
p-event: 6.0.1
progress-events: 1.0.1
- race-event: 1.3.0
+ race-event: 1.6.1
stream-to-it: 1.0.1
'@libp2p/utils@6.7.1':
@@ -6285,12 +6401,12 @@ snapshots:
main-event: 1.0.1
netmask: 2.0.2
p-defer: 4.0.1
- race-event: 1.3.0
+ race-event: 1.6.1
race-signal: 1.1.3
uint8arraylist: 2.4.8
uint8arrays: 5.1.0
- '@libp2p/webrtc@5.2.20(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))':
+ '@libp2p/webrtc@5.2.23(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))':
dependencies:
'@chainsafe/is-ip': 2.1.0
'@chainsafe/libp2p-noise': 16.1.4
@@ -6302,9 +6418,9 @@ snapshots:
'@libp2p/peer-id': 5.1.8
'@libp2p/utils': 6.7.1
'@multiformats/multiaddr': 12.5.1
- '@multiformats/multiaddr-matcher': 1.7.2
+ '@multiformats/multiaddr-matcher': 2.0.2
'@peculiar/webcrypto': 1.5.0
- '@peculiar/x509': 1.12.4
+ '@peculiar/x509': 1.13.0
any-signal: 4.1.1
detect-browser: 5.3.0
get-port: 7.1.0
@@ -6320,9 +6436,9 @@ snapshots:
p-wait-for: 5.0.2
progress-events: 1.0.1
protons-runtime: 5.6.0
- race-event: 1.3.0
+ race-event: 1.6.1
race-signal: 1.1.3
- react-native-webrtc: 124.0.5(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ react-native-webrtc: 124.0.6(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
uint8-varint: 2.0.4
uint8arraylist: 2.4.8
uint8arrays: 5.1.0
@@ -6330,13 +6446,13 @@ snapshots:
- react-native
- supports-color
- '@libp2p/websockets@9.2.17':
+ '@libp2p/websockets@9.2.18':
dependencies:
'@libp2p/interface': 2.10.5
'@libp2p/utils': 6.7.1
'@multiformats/multiaddr': 12.5.1
- '@multiformats/multiaddr-matcher': 1.7.2
- '@multiformats/multiaddr-to-uri': 11.0.0
+ '@multiformats/multiaddr-matcher': 2.0.2
+ '@multiformats/multiaddr-to-uri': 11.0.2
'@types/ws': 8.18.1
it-ws: 6.1.5
main-event: 1.0.1
@@ -6344,7 +6460,7 @@ snapshots:
p-event: 6.0.1
progress-events: 1.0.1
race-signal: 1.1.3
- ws: 8.18.2
+ ws: 8.18.3
transitivePeerDependencies:
- bufferutil
- utf-8-validate
@@ -6378,13 +6494,11 @@ snapshots:
dependencies:
'@multiformats/multiaddr': 12.5.1
- '@multiformats/multiaddr-matcher@1.7.2':
+ '@multiformats/multiaddr-matcher@2.0.2':
dependencies:
- '@chainsafe/is-ip': 2.1.0
'@multiformats/multiaddr': 12.5.1
- multiformats: 13.3.7
- '@multiformats/multiaddr-to-uri@11.0.0':
+ '@multiformats/multiaddr-to-uri@11.0.2':
dependencies:
'@multiformats/multiaddr': 12.5.1
@@ -6400,10 +6514,16 @@ snapshots:
'@noble/ciphers@1.3.0': {}
- '@noble/curves@1.9.2':
+ '@noble/curves@1.2.0':
+ dependencies:
+ '@noble/hashes': 1.3.2
+
+ '@noble/curves@1.9.6':
dependencies:
'@noble/hashes': 1.8.0
+ '@noble/hashes@1.3.2': {}
+
'@noble/hashes@1.8.0': {}
'@nodelib/fs.scandir@2.1.5':
@@ -6491,78 +6611,78 @@ snapshots:
'@parcel/watcher-win32-x64': 2.5.1
optional: true
- '@peculiar/asn1-cms@2.3.15':
+ '@peculiar/asn1-cms@2.4.0':
dependencies:
- '@peculiar/asn1-schema': 2.3.15
- '@peculiar/asn1-x509': 2.3.15
- '@peculiar/asn1-x509-attr': 2.3.15
+ '@peculiar/asn1-schema': 2.4.0
+ '@peculiar/asn1-x509': 2.4.0
+ '@peculiar/asn1-x509-attr': 2.4.0
asn1js: 3.0.6
tslib: 2.8.1
- '@peculiar/asn1-csr@2.3.15':
+ '@peculiar/asn1-csr@2.4.0':
dependencies:
- '@peculiar/asn1-schema': 2.3.15
- '@peculiar/asn1-x509': 2.3.15
+ '@peculiar/asn1-schema': 2.4.0
+ '@peculiar/asn1-x509': 2.4.0
asn1js: 3.0.6
tslib: 2.8.1
- '@peculiar/asn1-ecc@2.3.15':
+ '@peculiar/asn1-ecc@2.4.0':
dependencies:
- '@peculiar/asn1-schema': 2.3.15
- '@peculiar/asn1-x509': 2.3.15
+ '@peculiar/asn1-schema': 2.4.0
+ '@peculiar/asn1-x509': 2.4.0
asn1js: 3.0.6
tslib: 2.8.1
- '@peculiar/asn1-pfx@2.3.15':
+ '@peculiar/asn1-pfx@2.4.0':
dependencies:
- '@peculiar/asn1-cms': 2.3.15
- '@peculiar/asn1-pkcs8': 2.3.15
- '@peculiar/asn1-rsa': 2.3.15
- '@peculiar/asn1-schema': 2.3.15
+ '@peculiar/asn1-cms': 2.4.0
+ '@peculiar/asn1-pkcs8': 2.4.0
+ '@peculiar/asn1-rsa': 2.4.0
+ '@peculiar/asn1-schema': 2.4.0
asn1js: 3.0.6
tslib: 2.8.1
- '@peculiar/asn1-pkcs8@2.3.15':
+ '@peculiar/asn1-pkcs8@2.4.0':
dependencies:
- '@peculiar/asn1-schema': 2.3.15
- '@peculiar/asn1-x509': 2.3.15
+ '@peculiar/asn1-schema': 2.4.0
+ '@peculiar/asn1-x509': 2.4.0
asn1js: 3.0.6
tslib: 2.8.1
- '@peculiar/asn1-pkcs9@2.3.15':
+ '@peculiar/asn1-pkcs9@2.4.0':
dependencies:
- '@peculiar/asn1-cms': 2.3.15
- '@peculiar/asn1-pfx': 2.3.15
- '@peculiar/asn1-pkcs8': 2.3.15
- '@peculiar/asn1-schema': 2.3.15
- '@peculiar/asn1-x509': 2.3.15
- '@peculiar/asn1-x509-attr': 2.3.15
+ '@peculiar/asn1-cms': 2.4.0
+ '@peculiar/asn1-pfx': 2.4.0
+ '@peculiar/asn1-pkcs8': 2.4.0
+ '@peculiar/asn1-schema': 2.4.0
+ '@peculiar/asn1-x509': 2.4.0
+ '@peculiar/asn1-x509-attr': 2.4.0
asn1js: 3.0.6
tslib: 2.8.1
- '@peculiar/asn1-rsa@2.3.15':
+ '@peculiar/asn1-rsa@2.4.0':
dependencies:
- '@peculiar/asn1-schema': 2.3.15
- '@peculiar/asn1-x509': 2.3.15
+ '@peculiar/asn1-schema': 2.4.0
+ '@peculiar/asn1-x509': 2.4.0
asn1js: 3.0.6
tslib: 2.8.1
- '@peculiar/asn1-schema@2.3.15':
+ '@peculiar/asn1-schema@2.4.0':
dependencies:
asn1js: 3.0.6
pvtsutils: 1.3.6
tslib: 2.8.1
- '@peculiar/asn1-x509-attr@2.3.15':
+ '@peculiar/asn1-x509-attr@2.4.0':
dependencies:
- '@peculiar/asn1-schema': 2.3.15
- '@peculiar/asn1-x509': 2.3.15
+ '@peculiar/asn1-schema': 2.4.0
+ '@peculiar/asn1-x509': 2.4.0
asn1js: 3.0.6
tslib: 2.8.1
- '@peculiar/asn1-x509@2.3.15':
+ '@peculiar/asn1-x509@2.4.0':
dependencies:
- '@peculiar/asn1-schema': 2.3.15
+ '@peculiar/asn1-schema': 2.4.0
asn1js: 3.0.6
pvtsutils: 1.3.6
tslib: 2.8.1
@@ -6573,21 +6693,21 @@ snapshots:
'@peculiar/webcrypto@1.5.0':
dependencies:
- '@peculiar/asn1-schema': 2.3.15
+ '@peculiar/asn1-schema': 2.4.0
'@peculiar/json-schema': 1.1.12
pvtsutils: 1.3.6
tslib: 2.8.1
webcrypto-core: 1.8.1
- '@peculiar/x509@1.12.4':
+ '@peculiar/x509@1.13.0':
dependencies:
- '@peculiar/asn1-cms': 2.3.15
- '@peculiar/asn1-csr': 2.3.15
- '@peculiar/asn1-ecc': 2.3.15
- '@peculiar/asn1-pkcs9': 2.3.15
- '@peculiar/asn1-rsa': 2.3.15
- '@peculiar/asn1-schema': 2.3.15
- '@peculiar/asn1-x509': 2.3.15
+ '@peculiar/asn1-cms': 2.4.0
+ '@peculiar/asn1-csr': 2.4.0
+ '@peculiar/asn1-ecc': 2.4.0
+ '@peculiar/asn1-pkcs9': 2.4.0
+ '@peculiar/asn1-rsa': 2.4.0
+ '@peculiar/asn1-schema': 2.4.0
+ '@peculiar/asn1-x509': 2.4.0
pvtsutils: 1.3.6
reflect-metadata: 0.2.2
tslib: 2.8.1
@@ -6650,7 +6770,7 @@ snapshots:
'@peerbit/indexer-interface': 2.0.10
'@peerbit/log': 4.0.63
- '@peerbit/document@9.11.6(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))':
+ '@peerbit/document@9.11.6(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))':
dependencies:
'@dao-xyz/borsh': 5.2.3
'@peerbit/document-interface': 2.2.5
@@ -6658,20 +6778,20 @@ snapshots:
'@peerbit/indexer-interface': 2.0.10
'@peerbit/indexer-simple': 1.1.15
'@peerbit/indexer-sqlite3': 1.2.22
- '@peerbit/program': 5.2.13(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
- '@peerbit/rpc': 5.3.8(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
- '@peerbit/shared-log': 11.2.8(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/program': 5.2.13(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ '@peerbit/rpc': 5.3.8(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ '@peerbit/shared-log': 11.2.8(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
transitivePeerDependencies:
- bufferutil
- react-native
- supports-color
- utf-8-validate
- '@peerbit/identity-access-controller@5.0.93(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))':
+ '@peerbit/identity-access-controller@5.0.93(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))':
dependencies:
'@dao-xyz/borsh': 5.2.3
- '@peerbit/document': 9.11.6(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
- '@peerbit/trusted-network': 4.1.110(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/document': 9.11.6(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ '@peerbit/trusted-network': 4.1.110(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
transitivePeerDependencies:
- bufferutil
- react-native
@@ -6705,14 +6825,14 @@ snapshots:
'@peerbit/any-store': 2.1.11
'@peerbit/crypto': 2.3.9
- '@peerbit/libp2p-test-utils@2.1.18(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))':
+ '@peerbit/libp2p-test-utils@2.1.18(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))':
dependencies:
- '@libp2p/circuit-relay-v2': 3.2.20
- '@libp2p/identify': 3.0.37
- '@libp2p/tcp': 10.1.17
- '@libp2p/webrtc': 5.2.20(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
- '@libp2p/websockets': 9.2.17
- libp2p: 2.8.12
+ '@libp2p/circuit-relay-v2': 3.2.23
+ '@libp2p/identify': 3.0.38
+ '@libp2p/tcp': 10.1.18
+ '@libp2p/webrtc': 5.2.23(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ '@libp2p/websockets': 9.2.18
+ libp2p: 2.9.0
transitivePeerDependencies:
- bufferutil
- react-native
@@ -6729,7 +6849,7 @@ snapshots:
'@peerbit/indexer-simple': 1.1.15
'@peerbit/logger': 1.0.3
'@peerbit/time': 2.1.0
- libp2p: 2.8.12
+ libp2p: 2.9.0
p-queue: 8.1.0
path-browserify: 1.0.1
uuid: 10.0.0
@@ -6738,14 +6858,14 @@ snapshots:
dependencies:
pino: 8.21.0
- '@peerbit/program@5.2.13(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))':
+ '@peerbit/program@5.2.13(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))':
dependencies:
'@dao-xyz/borsh': 5.2.3
'@peerbit/any-store-interface': 1.0.0
'@peerbit/blocks-interface': 1.4.6
'@peerbit/crypto': 2.3.9
'@peerbit/keychain': 1.0.29
- '@peerbit/libp2p-test-utils': 2.1.18(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/libp2p-test-utils': 2.1.18(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
'@peerbit/pubsub-interface': 4.0.2
transitivePeerDependencies:
- bufferutil
@@ -6767,12 +6887,12 @@ snapshots:
'@peerbit/riblt@1.0.6': {}
- '@peerbit/rpc@5.3.8(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))':
+ '@peerbit/rpc@5.3.8(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))':
dependencies:
'@dao-xyz/borsh': 5.2.3
'@peerbit/crypto': 2.3.9
'@peerbit/logger': 1.0.3
- '@peerbit/program': 5.2.13(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/program': 5.2.13(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
'@peerbit/time': 2.1.0
transitivePeerDependencies:
- bufferutil
@@ -6780,14 +6900,14 @@ snapshots:
- supports-color
- utf-8-validate
- '@peerbit/shared-log@11.2.8(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))':
+ '@peerbit/shared-log@11.2.8(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))':
dependencies:
'@dao-xyz/borsh': 5.2.3
'@peerbit/log': 4.0.63
'@peerbit/logger': 1.0.3
- '@peerbit/program': 5.2.13(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/program': 5.2.13(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
'@peerbit/riblt': 1.0.6
- '@peerbit/rpc': 5.3.8(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/rpc': 5.3.8(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
'@peerbit/time': 2.1.0
transitivePeerDependencies:
- bufferutil
@@ -6810,17 +6930,17 @@ snapshots:
'@peerbit/time': 2.1.0
abortable-iterator: 5.1.0
fast-fifo: 1.3.2
- libp2p: 2.8.12
+ libp2p: 2.9.0
p-queue: 8.1.0
yallist: 4.0.0
'@peerbit/time@2.1.0': {}
- '@peerbit/trusted-network@4.1.110(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))':
+ '@peerbit/trusted-network@4.1.110(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))':
dependencies:
'@dao-xyz/borsh': 5.2.3
'@peerbit/crypto': 2.3.9
- '@peerbit/document': 9.11.6(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/document': 9.11.6(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
transitivePeerDependencies:
- bufferutil
- react-native
@@ -6830,46 +6950,50 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
+ '@playwright/test@1.54.1':
+ dependencies:
+ playwright: 1.54.1
+
'@protobufjs/float@1.0.2': {}
'@protobufjs/utf8@1.1.0': {}
- '@react-native/assets-registry@0.79.2': {}
+ '@react-native/assets-registry@0.80.2': {}
- '@react-native/codegen@0.79.2(@babel/core@7.27.7)':
+ '@react-native/codegen@0.80.2(@babel/core@7.28.0)':
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
glob: 7.2.3
- hermes-parser: 0.25.1
+ hermes-parser: 0.28.1
invariant: 2.2.4
nullthrows: 1.1.1
yargs: 17.7.2
- '@react-native/community-cli-plugin@0.79.2':
+ '@react-native/community-cli-plugin@0.80.2':
dependencies:
- '@react-native/dev-middleware': 0.79.2
+ '@react-native/dev-middleware': 0.80.2
chalk: 4.1.2
- debug: 2.6.9
+ debug: 4.4.1
invariant: 2.2.4
- metro: 0.82.4
- metro-config: 0.82.4
- metro-core: 0.82.4
+ metro: 0.82.5
+ metro-config: 0.82.5
+ metro-core: 0.82.5
semver: 7.7.2
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
- '@react-native/debugger-frontend@0.79.2': {}
+ '@react-native/debugger-frontend@0.80.2': {}
- '@react-native/dev-middleware@0.79.2':
+ '@react-native/dev-middleware@0.80.2':
dependencies:
'@isaacs/ttlcache': 1.4.1
- '@react-native/debugger-frontend': 0.79.2
+ '@react-native/debugger-frontend': 0.80.2
chrome-launcher: 0.15.2
chromium-edge-launcher: 0.2.0
connect: 3.7.0
- debug: 2.6.9
+ debug: 4.4.1
invariant: 2.2.4
nullthrows: 1.1.1
open: 7.4.2
@@ -6880,33 +7004,44 @@ snapshots:
- supports-color
- utf-8-validate
- '@react-native/gradle-plugin@0.79.2': {}
+ '@react-native/gradle-plugin@0.80.2': {}
- '@react-native/js-polyfills@0.79.2': {}
+ '@react-native/js-polyfills@0.80.2': {}
- '@react-native/normalize-colors@0.79.2': {}
+ '@react-native/normalize-colors@0.80.2': {}
- '@react-native/virtualized-lists@0.79.2(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))(react@19.1.0)':
+ '@react-native/virtualized-lists@0.80.2(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))(react@19.1.1)':
dependencies:
invariant: 2.2.4
nullthrows: 1.1.1
- react: 19.1.0
- react-native: 0.79.2(@babel/core@7.27.7)(react@19.1.0)
+ react: 19.1.1
+ react-native: 0.80.2(@babel/core@7.28.0)(react@19.1.1)
- '@riffcc/lens-sdk@0.1.25(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))':
+ '@riffcc/lens-sdk@0.1.32(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))':
dependencies:
'@dao-xyz/borsh': 5.2.3
+ '@libp2p/crypto': 5.1.7
'@peerbit/crypto': 2.3.9
- '@peerbit/document': 9.11.6(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
- '@peerbit/identity-access-controller': 5.0.93(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/document': 9.11.6(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ '@peerbit/identity-access-controller': 5.0.93(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ '@peerbit/indexer-interface': 2.0.10
'@peerbit/log': 4.0.63
- '@peerbit/program': 5.2.13(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/program': 5.2.13(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
'@peerbit/pubsub-interface': 4.0.2
- '@peerbit/rpc': 5.3.8(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
- '@peerbit/shared-log': 11.2.8(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/rpc': 5.3.8(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ '@peerbit/shared-log': 11.2.8(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
'@peerbit/stream-interface': 5.2.3
'@peerbit/time': 2.1.0
- peerbit: 4.1.40(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/trusted-network': 4.1.110(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ ajv: 8.17.1
+ bip39: 3.1.0
+ ethers: 6.15.0
+ idb-keyval: 6.2.2
+ libsodium-wrappers: 0.7.15
+ p-defer: 4.0.1
+ peerbit: 4.1.40(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ qrcode: 1.5.4
+ uint8arrays: 5.1.0
uuid: 11.1.0
transitivePeerDependencies:
- bufferutil
@@ -7110,24 +7245,24 @@ snapshots:
'@types/babel__core@7.20.5':
dependencies:
- '@babel/parser': 7.27.7
- '@babel/types': 7.27.7
+ '@babel/parser': 7.28.0
+ '@babel/types': 7.28.2
'@types/babel__generator': 7.27.0
'@types/babel__template': 7.4.4
'@types/babel__traverse': 7.20.7
'@types/babel__generator@7.27.0':
dependencies:
- '@babel/types': 7.27.7
+ '@babel/types': 7.28.2
'@types/babel__template@7.4.4':
dependencies:
- '@babel/parser': 7.27.7
- '@babel/types': 7.27.7
+ '@babel/parser': 7.28.0
+ '@babel/types': 7.28.2
'@types/babel__traverse@7.20.7':
dependencies:
- '@babel/types': 7.27.7
+ '@babel/types': 7.28.2
'@types/cacheable-request@6.0.3':
dependencies:
@@ -7190,6 +7325,10 @@ snapshots:
dependencies:
undici-types: 6.21.0
+ '@types/node@22.7.5':
+ dependencies:
+ undici-types: 6.19.8
+
'@types/plist@3.0.5':
dependencies:
'@types/node': 22.15.33
@@ -7530,6 +7669,8 @@ snapshots:
aes-js@3.0.0: {}
+ aes-js@4.0.0-beta.5: {}
+
agent-base@6.0.2:
dependencies:
debug: 4.4.1
@@ -7558,6 +7699,13 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
+ ajv@8.17.1:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.0.6
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
alien-signals@1.0.13: {}
anser@1.4.10: {}
@@ -7683,13 +7831,13 @@ snapshots:
dependencies:
possible-typed-array-names: 1.1.0
- babel-jest@29.7.0(@babel/core@7.27.7):
+ babel-jest@29.7.0(@babel/core@7.28.0):
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
'@jest/transform': 29.7.0
'@types/babel__core': 7.20.5
babel-plugin-istanbul: 6.1.1
- babel-preset-jest: 29.6.3(@babel/core@7.27.7)
+ babel-preset-jest: 29.6.3(@babel/core@7.28.0)
chalk: 4.1.2
graceful-fs: 4.2.11
slash: 3.0.0
@@ -7709,38 +7857,38 @@ snapshots:
babel-plugin-jest-hoist@29.6.3:
dependencies:
'@babel/template': 7.27.2
- '@babel/types': 7.27.7
+ '@babel/types': 7.28.2
'@types/babel__core': 7.20.5
'@types/babel__traverse': 7.20.7
- babel-plugin-syntax-hermes-parser@0.25.1:
+ babel-plugin-syntax-hermes-parser@0.28.1:
dependencies:
- hermes-parser: 0.25.1
-
- babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.7):
- dependencies:
- '@babel/core': 7.27.7
- '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.7)
- '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.7)
- '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.7)
- '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.7)
- '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.7)
- '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.7)
- '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.7)
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.7)
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.7)
- '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.7)
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.7)
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.7)
- '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.7)
- '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.7)
- '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.7)
+ hermes-parser: 0.28.1
- babel-preset-jest@29.6.3(@babel/core@7.27.7):
- dependencies:
- '@babel/core': 7.27.7
+ babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.0):
+ dependencies:
+ '@babel/core': 7.28.0
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.0)
+ '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.0)
+ '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.0)
+ '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.0)
+ '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.0)
+ '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.0)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.0)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.0)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.0)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.0)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.0)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.0)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.0)
+ '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.0)
+ '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.0)
+
+ babel-preset-jest@29.6.3(@babel/core@7.28.0):
+ dependencies:
+ '@babel/core': 7.28.0
babel-plugin-jest-hoist: 29.6.3
- babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.7)
+ babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.0)
balanced-match@1.0.2: {}
@@ -7755,6 +7903,10 @@ snapshots:
dependencies:
file-uri-to-path: 1.0.0
+ bip39@3.1.0:
+ dependencies:
+ '@noble/hashes': 1.8.0
+
bl@0.8.2:
dependencies:
readable-stream: 1.0.34
@@ -7850,8 +8002,8 @@ snapshots:
browserslist@4.25.1:
dependencies:
- caniuse-lite: 1.0.30001726
- electron-to-chromium: 1.5.176
+ caniuse-lite: 1.0.30001731
+ electron-to-chromium: 1.5.193
node-releases: 2.0.19
update-browserslist-db: 1.1.3(browserslist@4.25.1)
@@ -7978,7 +8130,7 @@ snapshots:
camelcase@6.3.0: {}
- caniuse-lite@1.0.30001726: {}
+ caniuse-lite@1.0.30001731: {}
cborg@4.2.12: {}
@@ -8057,6 +8209,12 @@ snapshots:
string-width: 4.2.3
optional: true
+ cliui@6.0.0:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 6.2.0
+
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@@ -8241,6 +8399,8 @@ snapshots:
dependencies:
ms: 2.1.3
+ decamelize@1.2.0: {}
+
decompress-response@6.0.0:
dependencies:
mimic-response: 3.1.0
@@ -8306,6 +8466,8 @@ snapshots:
miller-rabin: 4.0.1
randombytes: 2.1.0
+ dijkstrajs@1.0.3: {}
+
dir-compare@4.2.0:
dependencies:
minimatch: 3.1.2
@@ -8431,7 +8593,7 @@ snapshots:
- bluebird
- supports-color
- electron-to-chromium@1.5.176: {}
+ electron-to-chromium@1.5.193: {}
electron-updater@6.6.2:
dependencies:
@@ -8673,6 +8835,19 @@ snapshots:
etag@1.8.1: {}
+ ethers@6.15.0:
+ dependencies:
+ '@adraffy/ens-normalize': 1.10.1
+ '@noble/curves': 1.2.0
+ '@noble/hashes': 1.3.2
+ '@types/node': 22.7.5
+ aes-js: 4.0.0-beta.5
+ tslib: 2.7.0
+ ws: 8.17.1
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+
event-iterator@2.0.0: {}
event-target-shim@5.0.1: {}
@@ -8725,6 +8900,8 @@ snapshots:
fast-redact@3.5.0: {}
+ fast-uri@3.0.6: {}
+
fastq@1.19.1:
dependencies:
reusify: 1.1.0
@@ -8954,8 +9131,6 @@ snapshots:
serialize-error: 7.0.1
optional: true
- globals@11.12.0: {}
-
globals@13.24.0:
dependencies:
type-fest: 0.20.2
@@ -9030,18 +9205,18 @@ snapshots:
he@1.2.0: {}
- hermes-estree@0.25.1: {}
-
hermes-estree@0.28.1: {}
- hermes-parser@0.25.1:
- dependencies:
- hermes-estree: 0.25.1
+ hermes-estree@0.29.1: {}
hermes-parser@0.28.1:
dependencies:
hermes-estree: 0.28.1
+ hermes-parser@0.29.1:
+ dependencies:
+ hermes-estree: 0.29.1
+
hmac-drbg@1.0.1:
dependencies:
hash.js: 1.1.7
@@ -9112,6 +9287,8 @@ snapshots:
dependencies:
safer-buffer: 2.1.2
+ idb-keyval@6.2.2: {}
+
idb-wrapper@1.7.2: {}
ieee754@1.2.1: {}
@@ -9279,8 +9456,8 @@ snapshots:
istanbul-lib-instrument@5.2.1:
dependencies:
- '@babel/core': 7.27.7
- '@babel/parser': 7.27.7
+ '@babel/core': 7.28.0
+ '@babel/parser': 7.28.0
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.2
semver: 6.3.1
@@ -9364,7 +9541,7 @@ snapshots:
abort-error: 1.0.1
it-pushable: 3.2.3
main-event: 1.0.1
- race-event: 1.3.0
+ race-event: 1.6.1
race-signal: 1.1.3
it-queueless-pushable@2.0.2:
@@ -9392,7 +9569,7 @@ snapshots:
event-iterator: 2.0.0
it-stream-types: 2.0.2
uint8arrays: 5.1.0
- ws: 8.18.2
+ ws: 8.18.3
transitivePeerDependencies:
- bufferutil
- utf-8-validate
@@ -9519,6 +9696,8 @@ snapshots:
json-schema-traverse@0.4.1: {}
+ json-schema-traverse@1.0.0: {}
+
json-stable-stringify-without-jsonify@1.0.1: {}
json-stringify-safe@5.0.1:
@@ -9620,7 +9799,7 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
- libp2p@2.8.12:
+ libp2p@2.9.0:
dependencies:
'@chainsafe/is-ip': 2.1.0
'@chainsafe/netmask': 2.0.0
@@ -9635,7 +9814,7 @@ snapshots:
'@libp2p/utils': 6.7.1
'@multiformats/dns': 1.0.6
'@multiformats/multiaddr': 12.5.1
- '@multiformats/multiaddr-matcher': 1.7.2
+ '@multiformats/multiaddr-matcher': 2.0.2
any-signal: 4.1.1
datastore-core: 10.0.4
interface-datastore: 8.3.2
@@ -9647,7 +9826,7 @@ snapshots:
p-defer: 4.0.1
p-retry: 6.2.1
progress-events: 1.0.1
- race-event: 1.3.0
+ race-event: 1.6.1
race-signal: 1.1.3
uint8arrays: 5.1.0
@@ -9778,50 +9957,50 @@ snapshots:
merge2@1.4.1: {}
- metro-babel-transformer@0.82.4:
+ metro-babel-transformer@0.82.5:
dependencies:
- '@babel/core': 7.27.7
+ '@babel/core': 7.28.0
flow-enums-runtime: 0.0.6
- hermes-parser: 0.28.1
+ hermes-parser: 0.29.1
nullthrows: 1.1.1
transitivePeerDependencies:
- supports-color
- metro-cache-key@0.82.4:
+ metro-cache-key@0.82.5:
dependencies:
flow-enums-runtime: 0.0.6
- metro-cache@0.82.4:
+ metro-cache@0.82.5:
dependencies:
exponential-backoff: 3.1.2
flow-enums-runtime: 0.0.6
https-proxy-agent: 7.0.6
- metro-core: 0.82.4
+ metro-core: 0.82.5
transitivePeerDependencies:
- supports-color
- metro-config@0.82.4:
+ metro-config@0.82.5:
dependencies:
connect: 3.7.0
cosmiconfig: 5.2.1
flow-enums-runtime: 0.0.6
jest-validate: 29.7.0
- metro: 0.82.4
- metro-cache: 0.82.4
- metro-core: 0.82.4
- metro-runtime: 0.82.4
+ metro: 0.82.5
+ metro-cache: 0.82.5
+ metro-core: 0.82.5
+ metro-runtime: 0.82.5
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
- metro-core@0.82.4:
+ metro-core@0.82.5:
dependencies:
flow-enums-runtime: 0.0.6
lodash.throttle: 4.1.1
- metro-resolver: 0.82.4
+ metro-resolver: 0.82.5
- metro-file-map@0.82.4:
+ metro-file-map@0.82.5:
dependencies:
debug: 4.4.1
fb-watchman: 2.0.2
@@ -9835,86 +10014,86 @@ snapshots:
transitivePeerDependencies:
- supports-color
- metro-minify-terser@0.82.4:
+ metro-minify-terser@0.82.5:
dependencies:
flow-enums-runtime: 0.0.6
terser: 5.43.1
- metro-resolver@0.82.4:
+ metro-resolver@0.82.5:
dependencies:
flow-enums-runtime: 0.0.6
- metro-runtime@0.82.4:
+ metro-runtime@0.82.5:
dependencies:
- '@babel/runtime': 7.27.6
+ '@babel/runtime': 7.28.2
flow-enums-runtime: 0.0.6
- metro-source-map@0.82.4:
+ metro-source-map@0.82.5:
dependencies:
- '@babel/traverse': 7.27.7
- '@babel/traverse--for-generate-function-map': '@babel/traverse@7.27.7'
- '@babel/types': 7.27.7
+ '@babel/traverse': 7.28.0
+ '@babel/traverse--for-generate-function-map': '@babel/traverse@7.28.0'
+ '@babel/types': 7.28.2
flow-enums-runtime: 0.0.6
invariant: 2.2.4
- metro-symbolicate: 0.82.4
+ metro-symbolicate: 0.82.5
nullthrows: 1.1.1
- ob1: 0.82.4
+ ob1: 0.82.5
source-map: 0.5.7
vlq: 1.0.1
transitivePeerDependencies:
- supports-color
- metro-symbolicate@0.82.4:
+ metro-symbolicate@0.82.5:
dependencies:
flow-enums-runtime: 0.0.6
invariant: 2.2.4
- metro-source-map: 0.82.4
+ metro-source-map: 0.82.5
nullthrows: 1.1.1
source-map: 0.5.7
vlq: 1.0.1
transitivePeerDependencies:
- supports-color
- metro-transform-plugins@0.82.4:
+ metro-transform-plugins@0.82.5:
dependencies:
- '@babel/core': 7.27.7
- '@babel/generator': 7.27.5
+ '@babel/core': 7.28.0
+ '@babel/generator': 7.28.0
'@babel/template': 7.27.2
- '@babel/traverse': 7.27.7
+ '@babel/traverse': 7.28.0
flow-enums-runtime: 0.0.6
nullthrows: 1.1.1
transitivePeerDependencies:
- supports-color
- metro-transform-worker@0.82.4:
+ metro-transform-worker@0.82.5:
dependencies:
- '@babel/core': 7.27.7
- '@babel/generator': 7.27.5
- '@babel/parser': 7.27.7
- '@babel/types': 7.27.7
+ '@babel/core': 7.28.0
+ '@babel/generator': 7.28.0
+ '@babel/parser': 7.28.0
+ '@babel/types': 7.28.2
flow-enums-runtime: 0.0.6
- metro: 0.82.4
- metro-babel-transformer: 0.82.4
- metro-cache: 0.82.4
- metro-cache-key: 0.82.4
- metro-minify-terser: 0.82.4
- metro-source-map: 0.82.4
- metro-transform-plugins: 0.82.4
+ metro: 0.82.5
+ metro-babel-transformer: 0.82.5
+ metro-cache: 0.82.5
+ metro-cache-key: 0.82.5
+ metro-minify-terser: 0.82.5
+ metro-source-map: 0.82.5
+ metro-transform-plugins: 0.82.5
nullthrows: 1.1.1
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
- metro@0.82.4:
+ metro@0.82.5:
dependencies:
'@babel/code-frame': 7.27.1
- '@babel/core': 7.27.7
- '@babel/generator': 7.27.5
- '@babel/parser': 7.27.7
+ '@babel/core': 7.28.0
+ '@babel/generator': 7.28.0
+ '@babel/parser': 7.28.0
'@babel/template': 7.27.2
- '@babel/traverse': 7.27.7
- '@babel/types': 7.27.7
+ '@babel/traverse': 7.28.0
+ '@babel/types': 7.28.2
accepts: 1.3.8
chalk: 4.1.2
ci-info: 2.0.0
@@ -9923,24 +10102,24 @@ snapshots:
error-stack-parser: 2.1.4
flow-enums-runtime: 0.0.6
graceful-fs: 4.2.11
- hermes-parser: 0.28.1
+ hermes-parser: 0.29.1
image-size: 1.2.1
invariant: 2.2.4
jest-worker: 29.7.0
jsc-safe-url: 0.2.4
lodash.throttle: 4.1.1
- metro-babel-transformer: 0.82.4
- metro-cache: 0.82.4
- metro-cache-key: 0.82.4
- metro-config: 0.82.4
- metro-core: 0.82.4
- metro-file-map: 0.82.4
- metro-resolver: 0.82.4
- metro-runtime: 0.82.4
- metro-source-map: 0.82.4
- metro-symbolicate: 0.82.4
- metro-transform-plugins: 0.82.4
- metro-transform-worker: 0.82.4
+ metro-babel-transformer: 0.82.5
+ metro-cache: 0.82.5
+ metro-cache-key: 0.82.5
+ metro-config: 0.82.5
+ metro-core: 0.82.5
+ metro-file-map: 0.82.5
+ metro-resolver: 0.82.5
+ metro-runtime: 0.82.5
+ metro-source-map: 0.82.5
+ metro-symbolicate: 0.82.5
+ metro-transform-plugins: 0.82.5
+ metro-transform-worker: 0.82.5
mime-types: 2.1.35
nullthrows: 1.1.1
serialize-error: 2.1.0
@@ -10190,7 +10369,7 @@ snapshots:
nullthrows@1.1.1: {}
- ob1@0.82.4:
+ ob1@0.82.5:
dependencies:
flow-enums-runtime: 0.0.6
@@ -10369,23 +10548,23 @@ snapshots:
pe-library@0.4.1: {}
- peerbit@4.1.40(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0)):
+ peerbit@4.1.40(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1)):
dependencies:
'@chainsafe/libp2p-yamux': 7.0.4
'@dao-xyz/borsh': 5.2.3
'@dao-xyz/datastore-level': 11.1.0
- '@libp2p/circuit-relay-v2': 3.2.20
- '@libp2p/identify': 3.0.37
- '@libp2p/tcp': 10.1.17
- '@libp2p/webrtc': 5.2.20(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
- '@libp2p/websockets': 9.2.17
+ '@libp2p/circuit-relay-v2': 3.2.23
+ '@libp2p/identify': 3.0.38
+ '@libp2p/tcp': 10.1.18
+ '@libp2p/webrtc': 5.2.23(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
+ '@libp2p/websockets': 9.2.18
'@peerbit/any-store': 2.1.11
'@peerbit/blocks': 3.0.3
'@peerbit/crypto': 2.3.9
'@peerbit/indexer-simple': 1.1.15
'@peerbit/indexer-sqlite3': 1.2.22
'@peerbit/logger': 1.0.3
- '@peerbit/program': 5.2.13(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))
+ '@peerbit/program': 5.2.13(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))
'@peerbit/pubsub': 4.0.6
level: 10.0.0
memory-level: 3.1.0
@@ -10431,11 +10610,11 @@ snapshots:
dependencies:
find-up: 5.0.0
- playwright-core@1.53.1: {}
+ playwright-core@1.54.1: {}
- playwright@1.53.1:
+ playwright@1.54.1:
dependencies:
- playwright-core: 1.53.1
+ playwright-core: 1.54.1
optionalDependencies:
fsevents: 2.3.2
@@ -10445,6 +10624,8 @@ snapshots:
base64-js: 1.5.1
xmlbuilder: 15.1.1
+ pngjs@5.0.0: {}
+
possible-typed-array-names@1.1.0: {}
postcss-selector-parser@6.1.2:
@@ -10556,6 +10737,12 @@ snapshots:
pvutils@1.1.3: {}
+ qrcode@1.5.4:
+ dependencies:
+ dijkstrajs: 1.0.3
+ pngjs: 5.0.0
+ yargs: 15.4.1
+
qs@6.14.0:
dependencies:
side-channel: 1.1.0
@@ -10572,7 +10759,9 @@ snapshots:
quick-lru@5.1.1: {}
- race-event@1.3.0: {}
+ race-event@1.6.1:
+ dependencies:
+ abort-error: 1.0.1
race-signal@1.1.3: {}
@@ -10594,7 +10783,7 @@ snapshots:
minimist: 1.2.8
strip-json-comments: 2.0.1
- react-devtools-core@6.1.2:
+ react-devtools-core@6.1.5:
dependencies:
shell-quote: 1.8.3
ws: 7.5.10
@@ -10604,49 +10793,48 @@ snapshots:
react-is@18.3.1: {}
- react-native-webrtc@124.0.5(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0)):
+ react-native-webrtc@124.0.6(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1)):
dependencies:
base64-js: 1.5.1
debug: 4.3.4
event-target-shim: 6.0.2
- react-native: 0.79.2(@babel/core@7.27.7)(react@19.1.0)
+ react-native: 0.80.2(@babel/core@7.28.0)(react@19.1.1)
transitivePeerDependencies:
- supports-color
- react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0):
+ react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1):
dependencies:
'@jest/create-cache-key-function': 29.7.0
- '@react-native/assets-registry': 0.79.2
- '@react-native/codegen': 0.79.2(@babel/core@7.27.7)
- '@react-native/community-cli-plugin': 0.79.2
- '@react-native/gradle-plugin': 0.79.2
- '@react-native/js-polyfills': 0.79.2
- '@react-native/normalize-colors': 0.79.2
- '@react-native/virtualized-lists': 0.79.2(react-native@0.79.2(@babel/core@7.27.7)(react@19.1.0))(react@19.1.0)
+ '@react-native/assets-registry': 0.80.2
+ '@react-native/codegen': 0.80.2(@babel/core@7.28.0)
+ '@react-native/community-cli-plugin': 0.80.2
+ '@react-native/gradle-plugin': 0.80.2
+ '@react-native/js-polyfills': 0.80.2
+ '@react-native/normalize-colors': 0.80.2
+ '@react-native/virtualized-lists': 0.80.2(react-native@0.80.2(@babel/core@7.28.0)(react@19.1.1))(react@19.1.1)
abort-controller: 3.0.0
anser: 1.4.10
ansi-regex: 5.0.1
- babel-jest: 29.7.0(@babel/core@7.27.7)
- babel-plugin-syntax-hermes-parser: 0.25.1
+ babel-jest: 29.7.0(@babel/core@7.28.0)
+ babel-plugin-syntax-hermes-parser: 0.28.1
base64-js: 1.5.1
chalk: 4.1.2
commander: 12.1.0
- event-target-shim: 5.0.1
flow-enums-runtime: 0.0.6
glob: 7.2.3
invariant: 2.2.4
jest-environment-node: 29.7.0
memoize-one: 5.2.1
- metro-runtime: 0.82.4
- metro-source-map: 0.82.4
+ metro-runtime: 0.82.5
+ metro-source-map: 0.82.5
nullthrows: 1.1.1
pretty-format: 29.7.0
promise: 8.3.0
- react: 19.1.0
- react-devtools-core: 6.1.2
+ react: 19.1.1
+ react-devtools-core: 6.1.5
react-refresh: 0.14.2
regenerator-runtime: 0.13.11
- scheduler: 0.25.0
+ scheduler: 0.26.0
semver: 7.7.2
stacktrace-parser: 0.1.11
whatwg-fetch: 3.6.20
@@ -10661,7 +10849,7 @@ snapshots:
react-refresh@0.14.2: {}
- react@19.1.0: {}
+ react@19.1.1: {}
read-binary-file-arch@1.0.6:
dependencies:
@@ -10719,6 +10907,10 @@ snapshots:
require-directory@2.1.1: {}
+ require-from-string@2.0.2: {}
+
+ require-main-filename@2.0.0: {}
+
resedit@1.7.2:
dependencies:
pe-library: 0.4.1
@@ -10876,7 +11068,7 @@ snapshots:
sax@1.4.1: {}
- scheduler@0.25.0: {}
+ scheduler@0.26.0: {}
scrypt-js@3.0.1: {}
@@ -11252,6 +11444,8 @@ snapshots:
tslib@1.14.1: {}
+ tslib@2.7.0: {}
+
tslib@2.8.1: {}
tsx@4.19.4:
@@ -11324,6 +11518,8 @@ snapshots:
dependencies:
multiformats: 13.3.7
+ undici-types@6.19.8: {}
+
undici-types@6.21.0: {}
unique-filename@2.0.1:
@@ -11573,7 +11769,7 @@ snapshots:
webcrypto-core@1.8.1:
dependencies:
- '@peculiar/asn1-schema': 2.3.15
+ '@peculiar/asn1-schema': 2.4.0
'@peculiar/json-schema': 1.1.12
asn1js: 3.0.6
pvtsutils: 1.3.6
@@ -11591,6 +11787,8 @@ snapshots:
dependencies:
is-electron: 2.2.2
+ which-module@2.0.1: {}
+
which-typed-array@1.1.19:
dependencies:
available-typed-arrays: 1.0.7
@@ -11616,6 +11814,12 @@ snapshots:
word-wrap@1.2.5: {}
+ wrap-ansi@6.2.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
@@ -11641,7 +11845,9 @@ snapshots:
ws@7.5.10: {}
- ws@8.18.2: {}
+ ws@8.17.1: {}
+
+ ws@8.18.3: {}
xml-name-validator@4.0.0: {}
@@ -11662,14 +11868,35 @@ snapshots:
xtend@4.0.2: {}
+ y18n@4.0.3: {}
+
y18n@5.0.8: {}
yallist@3.1.1: {}
yallist@4.0.0: {}
+ yargs-parser@18.1.3:
+ dependencies:
+ camelcase: 5.3.1
+ decamelize: 1.2.0
+
yargs-parser@21.1.1: {}
+ yargs@15.4.1:
+ dependencies:
+ cliui: 6.0.0
+ decamelize: 1.2.0
+ find-up: 4.1.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ require-main-filename: 2.0.0
+ set-blocking: 2.0.0
+ string-width: 4.2.3
+ which-module: 2.0.1
+ y18n: 4.0.3
+ yargs-parser: 18.1.3
+
yargs@17.7.2:
dependencies:
cliui: 8.0.1
From 9c73e497f9a11330d8cf3f3d4db00263e9edc95d Mon Sep 17 00:00:00 2001
From: benya7
Date: Thu, 31 Jul 2025 20:59:20 +0200
Subject: [PATCH 08/11] fix: minors
---
.../src/components/account/RegisterForm.vue | 105 ------------------
.../src/components/home/featuredSlider.vue | 3 +-
packages/renderer/src/types.ts | 2 -
packages/renderer/src/utils.ts | 10 +-
4 files changed, 8 insertions(+), 112 deletions(-)
delete mode 100644 packages/renderer/src/components/account/RegisterForm.vue
diff --git a/packages/renderer/src/components/account/RegisterForm.vue b/packages/renderer/src/components/account/RegisterForm.vue
deleted file mode 100644
index 71615305..00000000
--- a/packages/renderer/src/components/account/RegisterForm.vue
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
-
- Register to upload content
-
- Complete a simple proof of work to register and get upload access.
- You are now registered and can upload content!
-
-
-
- Start Registration
-
-
-
-
-
-
Performing proof of work... {{ powProgress }}%
-
-
-
-
- Registration successful! Your ID: {{ userId }}
-
-
- Start Uploading
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/packages/renderer/src/components/home/featuredSlider.vue b/packages/renderer/src/components/home/featuredSlider.vue
index 023215c8..6735d621 100644
--- a/packages/renderer/src/components/home/featuredSlider.vue
+++ b/packages/renderer/src/components/home/featuredSlider.vue
@@ -173,10 +173,9 @@ import {parseUrlOrCid} from '/@/utils';
import {useShowDefederation} from '/@/composables/showDefed';
import { useSiteColors } from '/@/composables/siteColors';
import type { ReleaseItem } from '/@/types';
-import type { AnyObject } from '@riffcc/lens-sdk';
const props = defineProps<{
- promotedFeaturedReleases: ReleaseItem[];
+ promotedFeaturedReleases: ReleaseItem[];
}>();
const router = useRouter();
const {showDefederation} = useShowDefederation();
diff --git a/packages/renderer/src/types.ts b/packages/renderer/src/types.ts
index 89810fd4..80330ac0 100644
--- a/packages/renderer/src/types.ts
+++ b/packages/renderer/src/types.ts
@@ -7,8 +7,6 @@ import type {
ContentCategoryMetadataField,
} from '@riffcc/lens-sdk';
-export type { AnyObject };
-
export type ReleaseItem= ImmutableProps & ReleaseData;
export type FeaturedReleaseItem = ImmutableProps & FeaturedReleaseData;
diff --git a/packages/renderer/src/utils.ts b/packages/renderer/src/utils.ts
index e352f46c..aab0dd24 100644
--- a/packages/renderer/src/utils.ts
+++ b/packages/renderer/src/utils.ts
@@ -41,14 +41,18 @@ export async function copyText(text: string | undefined) {
}
export const formatTime = (ms: number): string => {
- if (ms === 0 || isNaN(ms)) {
+ if (ms === 0 || !Number.isFinite(ms)) {
return '00:00';
}
- const duration = Duration.fromObject({ seconds: ms });
+ const duration = Duration.fromMillis(ms);
const hours = duration.as('hours');
- return (hours >= 1) ? duration.toFormat('hh:mm:ss') : duration.toFormat('mm:ss');
+ if (hours >= 1) {
+ return duration.toFormat('hh:mm:ss');
+ } else {
+ return duration.toFormat('mm:ss');
+ }
};
// Colors
From eb7cd235f87dda6bcaa42c7227345f685488c870 Mon Sep 17 00:00:00 2001
From: benya7
Date: Thu, 31 Jul 2025 21:00:39 +0200
Subject: [PATCH 09/11] update:gh workflows, tests, eslintconfig
---
.github/workflows/ci.yml | 161 +++++++---
.github/workflows/lint.yml | 56 ----
.github/workflows/mergePr.yml | 17 --
.github/workflows/publishPage.yml | 32 --
.github/workflows/pullRequest.yml | 20 --
.github/workflows/release.yml | 67 -----
.github/workflows/tests.yml | 46 ---
.github/workflows/typechecking.yml | 31 --
.github/workflows/webTests.yml | 44 ---
.gitignore | 3 +
eslint.config.js | 111 +++----
packages/main/tests/unit.spec.ts | 11 -
packages/preload/tests/unit.spec.ts | 4 -
playwright.config.ts | 56 ++++
tests/benchmark.spec.ts | 255 ----------------
tests/content-verification-benchmark.spec.ts | 76 -----
tests/detailed-benchmark.spec.ts | 100 ------
tests/dev-server-benchmark.spec.ts | 284 ------------------
tests/e2e.spec.ts | 62 ----
tests/e2e/basic-smoke.spec.ts | 21 ++
tests/fast-benchmark.spec.ts | 68 -----
tests/fresh-load-benchmark.spec.ts | 58 ----
tests/http-benchmark.spec.ts | 202 -------------
tests/minimal-main.js | 46 ---
tests/prod-server-benchmark.spec.ts | 284 ------------------
tests/simple-benchmark.spec.ts | 133 --------
tests/timing-benchmark.spec.ts | 108 -------
tests/timing-with-site-logs.spec.ts | 42 ---
tests/ui-debug-investigation.spec.ts | 106 -------
.../renderer/src => tests/unit}/utils.spec.ts | 4 +-
tests/utils.ts | 18 +-
vitest.config.js | 33 +-
32 files changed, 266 insertions(+), 2293 deletions(-)
delete mode 100644 .github/workflows/lint.yml
delete mode 100644 .github/workflows/mergePr.yml
delete mode 100644 .github/workflows/publishPage.yml
delete mode 100644 .github/workflows/pullRequest.yml
delete mode 100644 .github/workflows/release.yml
delete mode 100644 .github/workflows/tests.yml
delete mode 100644 .github/workflows/typechecking.yml
delete mode 100644 .github/workflows/webTests.yml
delete mode 100644 packages/main/tests/unit.spec.ts
delete mode 100644 packages/preload/tests/unit.spec.ts
create mode 100644 playwright.config.ts
delete mode 100644 tests/benchmark.spec.ts
delete mode 100644 tests/content-verification-benchmark.spec.ts
delete mode 100644 tests/detailed-benchmark.spec.ts
delete mode 100644 tests/dev-server-benchmark.spec.ts
delete mode 100644 tests/e2e.spec.ts
create mode 100644 tests/e2e/basic-smoke.spec.ts
delete mode 100644 tests/fast-benchmark.spec.ts
delete mode 100644 tests/fresh-load-benchmark.spec.ts
delete mode 100644 tests/http-benchmark.spec.ts
delete mode 100644 tests/minimal-main.js
delete mode 100644 tests/prod-server-benchmark.spec.ts
delete mode 100644 tests/simple-benchmark.spec.ts
delete mode 100644 tests/timing-benchmark.spec.ts
delete mode 100644 tests/timing-with-site-logs.spec.ts
delete mode 100644 tests/ui-debug-investigation.spec.ts
rename {packages/renderer/src => tests/unit}/utils.spec.ts (93%)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b1bf0ecb..9cbe6e3c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,54 +1,129 @@
-# This workflow is the entry point for all CI processes.
-# It is from here that all other workflows are launched.
-name: Orbiter tests
+name: Continuous Integration
+# This workflow runs on pushes to the main branch and on any pull request.
on:
- workflow_dispatch:
push:
branches:
- main
- - 'renovate/**'
- tags:
- - v*
- paths-ignore:
- - '.github/**'
- - '!.github/workflows/*.yml'
- - '**.md'
- - .editorconfig
- - .gitignore
- - '.idea/**'
- - '.vscode/**'
pull_request:
- paths-ignore:
- - '.github/**'
- - '!.github/workflows/*.yml'
- - '**.md'
- - .editorconfig
- - .gitignore
- - '.idea/**'
- - '.vscode/**'
+# Ensures that only the latest commit for a branch/PR gets run.
concurrency:
- group: ci-${{ github.ref }}
+ group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
- typechecking:
- uses: ./.github/workflows/typechecking.yml
- # tests:
- # uses: ./.github/workflows/tests.yml
- # web_tests:
- # uses: ./.github/workflows/webTests.yml
- # publish_web_app:
- # needs: [ web_tests ]
- # uses: ./.github/workflows/publishPage.yml
- # draft_release:
- # permissions:
- # contents: write # Allows this job to create releases
- # with:
- # dry-run: ${{ github.event_name != 'push' || github.ref_name != 'main' }}
- # needs: [ typechecking, tests ]
- # uses: ./.github/workflows/release.yml
- # merge_pr:
- # needs: [ typechecking, publish_web_app, draft_release ]
- # uses: ./.github/workflows/mergePr.yml
+ # ----------------------------------------------------
+ # Job 1: Quick checks (Linting & Type-checking)
+ # This job runs first. It's fast and provides quick feedback.
+ # ----------------------------------------------------
+ quality_checks:
+ name: Lint & Type-Check
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: latest
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20' # Specify a Node.js version
+ cache: 'pnpm'
+
+ - name: Install Dependencies
+ run: pnpm install --frozen-lockfile
+ # We skip downloading browsers here because this job doesn't need them.
+ env:
+ PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
+
+ - name: Run Linting
+ run: pnpm run lint
+
+ - name: Run Type-Checking
+ run: pnpm run typecheck
+
+ # ----------------------------------------------------
+ # Job 2: Unit Tests
+ # This runs in parallel with quality_checks. It's also fast.
+ # ----------------------------------------------------
+ unit_tests:
+ name: Unit Tests
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: latest
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: 'pnpm'
+
+ - name: Install Dependencies
+ run: pnpm install --frozen-lockfile
+ env:
+ PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
+
+ - name: Run Unit Tests
+ run: pnpm run test:unit
+
+ # ----------------------------------------------------
+ # Job 3: End-to-End Tests
+ # This is the most comprehensive job. It builds the app and then runs Playwright tests.
+ # It depends on the faster jobs to ensure we don't waste time if basic checks fail.
+ # ----------------------------------------------------
+ e2e_tests:
+ name: Build & E2E Tests
+ # This job will only start if the quality_checks and unit_tests jobs succeed.
+ needs: [quality_checks, unit_tests]
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: latest
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ cache: 'pnpm'
+
+ - name: Install Dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Install Playwright Browsers
+ # This command specifically downloads the browser binaries needed for Playwright.
+ run: pnpm exec playwright install --with-deps
+
+ - name: Build Web Application
+ run: pnpm run build
+
+ - name: Run E2E Tests
+ # We start the preview server in the background (&) and then run Playwright.
+ # This simulates the local testing environment.
+ run: |
+ pnpm run preview &
+ pnpm run test:e2e
+
+ - name: Upload Test Report
+ # This step runs only if the E2E tests fail, to help with debugging.
+ if: failure()
+ uses: actions/upload-artifact@v4
+ with:
+ name: playwright-report
+ path: playwright-report/
+ retention-days: 7
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
deleted file mode 100644
index 70e26a0a..00000000
--- a/.github/workflows/lint.yml
+++ /dev/null
@@ -1,56 +0,0 @@
-name: Lint
-on:
- workflow_dispatch:
- push:
- paths:
- - '**.js'
- - '**.mjs'
- - '**.cjs'
- - '**.jsx'
- - '**.ts'
- - '**.mts'
- - '**.cts'
- - '**.tsx'
- - '**.vue'
- - '**.json'
- pull_request:
- paths:
- - '**.js'
- - '**.mjs'
- - '**.cjs'
- - '**.jsx'
- - '**.ts'
- - '**.mts'
- - '**.cts'
- - '**.tsx'
- - '**.vue'
- - '**.json'
-
-concurrency:
- group: lint-${{ github.ref }}
- cancel-in-progress: true
-
-defaults:
- run:
- shell: 'bash'
-
-jobs:
- eslint:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
-
- - uses: pnpm/action-setup@v4.0.0
- with:
- version: latest
-
- - uses: actions/setup-node@v4
- with:
- cache: 'pnpm'
-
- - run: pnpm install
- env:
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
-
- - run: pnpm run lint
diff --git a/.github/workflows/mergePr.yml b/.github/workflows/mergePr.yml
deleted file mode 100644
index cdcb758c..00000000
--- a/.github/workflows/mergePr.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-name: Merge pull request
-on: workflow_call
-
-concurrency:
- group: merge-pull-request-${{ github.ref }}
- cancel-in-progress: true
-
-jobs:
- merge_pull_request:
- runs-on: ubuntu-latest
- env:
- GH_TOKEN: ${{ github.token }}
- steps:
- - uses: actions/checkout@v4
- - name: Merge pull request
- run: |
- gh pr merge dev
\ No newline at end of file
diff --git a/.github/workflows/publishPage.yml b/.github/workflows/publishPage.yml
deleted file mode 100644
index 8b0fbe8c..00000000
--- a/.github/workflows/publishPage.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: Web app
-on: [ workflow_call ]
-
-concurrency:
- group: web-app-publish-${{ github.ref }}
- cancel-in-progress: true
-
-jobs:
- publish_web_app:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
-
- - uses: pnpm/action-setup@v4
- with:
- version: latest
-
- - name: Setup Node
- uses: actions/setup-node@v4
- with:
- cache: 'pnpm'
-
- - run: pnpm install
- - run: pnpm compile:web
-
- - name: Deploy
- uses: peaceiris/actions-gh-pages@v4
- if: ${{ github.ref_name == 'main' }}
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- publish_dir: packages/renderer/dist/web
- cname: orbiter.riff.cc
diff --git a/.github/workflows/pullRequest.yml b/.github/workflows/pullRequest.yml
deleted file mode 100644
index 3c52aa75..00000000
--- a/.github/workflows/pullRequest.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: Pull request to main
-on:
- push:
- branches:
- - dev
-
-concurrency:
- group: pull-request-${{ github.ref }}
- cancel-in-progress: true
-
-jobs:
- pull_request_to_main:
- runs-on: ubuntu-latest
- env:
- GH_TOKEN: ${{ github.token }}
- steps:
- - uses: actions/checkout@v4
- - name: Create pull request if necessary
- run: |
- gh pr create --title "Merge dev" --body "Automatic pull request to merge dev into main" --base main || $? == *already exists*
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index 4946db6d..00000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: Release
-on:
- workflow_call:
- inputs:
- dry-run:
- description: 'Compiles the app but does not upload artifacts to distribution server'
- default: false
- required: false
- type: boolean
-
-concurrency:
- group: release-${{ github.ref }}
- cancel-in-progress: true
-
-
-defaults:
- run:
- shell: 'bash'
-
-
-jobs:
- draft_release:
-
- permissions:
- contents: write # Allows this job to create releases
-
- strategy:
- fail-fast: true
- matrix:
- os: [ macos-latest, ubuntu-latest, windows-latest ]
-
- runs-on: ${{ matrix.os }}
-
- steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
-
- - uses: pnpm/action-setup@v4.0.0
- with:
- version: latest
-
- - uses: actions/setup-node@v4
-
- - run: pnpm install
- env:
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
-
- - run: pnpm run build
-
- - name: Compile artifacts ${{ inputs.dry-run && '' || 'and upload them to github release' }}
- # I use this action because it is capable of retrying multiple times if there are any issues with the distribution server
- uses: nick-fields/retry@v3
- with:
- timeout_minutes: 15
- max_attempts: 6
- retry_wait_seconds: 15
- retry_on: error
- shell: 'bash'
- # Due to this issue https://github.com/electron-userland/electron-builder/issues/6411 the build with npx when rebuilding native dependencies hangs forever
- # see https://github.com/cawa-93/vite-electron-builder/pull/953
- command: ./node_modules/.bin/electron-builder --config .electron-builder.config.cjs --publish ${{ inputs.dry-run && 'never' || 'always' }}
- env:
- # Code Signing params
- # See https://www.electron.build/code-signing
- # CSC_LINK: ''
- # CSC_KEY_PASSWORD: ''
- # Publishing artifacts
- GH_TOKEN: ${{ secrets.github_token }} # GitHub token, automatically provided (No need to define this secret in the repo settings)
\ No newline at end of file
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
deleted file mode 100644
index 0baf3bf5..00000000
--- a/.github/workflows/tests.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-name: Tests
-on: [ workflow_call ]
-
-concurrency:
- group: tests-${{ github.ref }}
- cancel-in-progress: true
-
-defaults:
- run:
- shell: 'bash'
-
-jobs:
- tests:
- strategy:
- fail-fast: false
- matrix:
- os: [ windows-latest, ubuntu-22.04, macos-latest ]
- runs-on: ${{ matrix.os }}
- steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
-
- - uses: pnpm/action-setup@v4.0.0
- with:
- version: latest
-
- - uses: actions/setup-node@v4
- with:
- cache: 'pnpm'
- - run: pnpm install
- env:
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
- - run: pnpm test:main
- - run: pnpm test:preload
- - run: pnpm test:renderer
-
- # I ran into problems trying to run an electron window in ubuntu due to a missing graphics server.
- # That's why this special command for Ubuntu is here
- - run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- pnpm test:e2e
- if: contains(matrix.os, 'ubuntu')
-
- - run: pnpm test:e2e
- if: "!contains(matrix.os, 'ubuntu')"
-
- # Publish test converage
- - name: Send coverage to CodeCov
- uses: codecov/codecov-action@v4
diff --git a/.github/workflows/typechecking.yml b/.github/workflows/typechecking.yml
deleted file mode 100644
index 3075fdab..00000000
--- a/.github/workflows/typechecking.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-name: Typechecking
-on: [ workflow_call ]
-
-concurrency:
- group: typechecking-${{ github.ref }}
- cancel-in-progress: true
-
-defaults:
- run:
- shell: 'bash'
-
-jobs:
- typescript:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
-
- - uses: pnpm/action-setup@v4.0.0
- with:
- version: latest
-
- - uses: actions/setup-node@v4
- with:
- cache: 'pnpm'
-
- - run: pnpm install
- env:
- PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
-
- - run: pnpm run typecheck
diff --git a/.github/workflows/webTests.yml b/.github/workflows/webTests.yml
deleted file mode 100644
index 42b30024..00000000
--- a/.github/workflows/webTests.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-name: Web app tests
-on: [ workflow_call ]
-
-concurrency:
- group: web-app-tests-${{ github.ref }}
- cancel-in-progress: true
-
-defaults:
- run:
- shell: 'bash'
-
-jobs:
- tests_navig:
- strategy:
- fail-fast: false
- matrix:
- navig: [ firefox, chromium ] # , webkit ]
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
-
- - uses: pnpm/action-setup@v4.0.0
- with:
- version: latest
-
- - uses: actions/setup-node@v4
- with:
- cache: 'pnpm'
- - run: pnpm install
-
- - run: pnpm exec playwright install
-
- - run: pnpm test:webkit
- if: ${{ matrix.navig == 'webkit' }}
-
- - run: pnpm test:chrome
- if: ${{ matrix.navig == 'chromium' }}
-
- - run: pnpm test:firefox
- if: ${{ matrix.navig == 'firefox' }}
-
- # Publish coverage to CodeCov
- - name: Send to Codecov
- uses: codecov/codecov-action@v4
diff --git a/.gitignore b/.gitignore
index 4c8d0909..420b4627 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,8 +39,11 @@ Thumbs.db
# Testing
test-results/
+playwright-report/
# Build tools
.eslintcache
.prettierrc
.electron-vendors.cache.json
+
+*.txt
diff --git a/eslint.config.js b/eslint.config.js
index 1a179e48..ef5aa0ab 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -1,106 +1,85 @@
import eslint from '@eslint/js';
import pluginVue from 'eslint-plugin-vue';
import tseslint from 'typescript-eslint';
-
import globals from 'globals';
export default [
+ // --- Global Ignores ---
{
- ignores: ['**/dist/**'],
+ ignores: [
+ '**/node_modules/**',
+ '**/dist/**',
+ '**/coverage/**',
+ 'packages/renderer/public/**',
+ 'playwright-report/**',
+ 'test-results/**',
+ ],
},
+
+ // Base configurations
eslint.configs.recommended,
...tseslint.configs.recommended,
...pluginVue.configs['flat/recommended'],
+
+ // --- Configuration for Browser/Vue Application Code ---
{
- files: ['**/*.{js,mjs,cjs,ts,mts,cts,vue}'],
+ files: ['packages/renderer/src/**/*.{js,ts,vue}'],
languageOptions: {
+ globals: {
+ ...globals.browser,
+ },
parserOptions: {
sourceType: 'module',
- parser: '@typescript-eslint/parser',
+ parser: tseslint.parser,
},
},
- ignores: ['**/node_modules/**', '**/dist/**', '**/coverage/**'],
rules: {
- '@typescript-eslint/no-var-requires': 'off',
- '@typescript-eslint/consistent-type-imports': 'error',
+ // --- THIS IS THE FIX ---
+ // Disable the base rule to prevent conflicts with the @typescript-eslint rule
+ 'no-unused-vars': 'off',
+
+ // Your correctly configured @typescript-eslint rule
'@typescript-eslint/no-unused-vars': [
'error',
- {
- argsIgnorePattern: '^_',
- varsIgnorePattern: '^_',
- caughtErrorsIgnorePattern: '^_',
- },
+ { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' },
],
- /**
- * Having a semicolon helps the optimizer interpret your code correctly.
- * This avoids rare errors in optimized code.
- * @see https://twitter.com/alex_kozack/status/1364210394328408066
- */
- semi: ['error', 'always'],
- /**
- * This will make the history of changes in the hit a little cleaner
- */
+
+ // Other rules...
+ '@typescript-eslint/consistent-type-imports': 'error',
+ 'semi': ['error', 'always'],
'comma-dangle': ['warn', 'always-multiline'],
- /**
- * Just for beauty
- */
- quotes: [
- 'warn',
- 'single',
- {
- avoidEscape: true,
- },
- ],
- /** These rules are disabled because they are incompatible with prettier */
+ 'quotes': ['warn', 'single', { avoidEscape: true }],
'vue/html-self-closing': 'off',
'vue/singleline-html-element-content-newline': 'off',
- /** DƩsactivƩe pour incompatibilitƩ internationale*/
'vue/multi-word-component-names': 'off',
},
},
+
+ // --- Configuration for Node.js files (Configs, Scripts, etc.) ---
{
- files: ['**/*.{js,mjs,cjs,ts,mts,cts}'],
+ files: [
+ '*.{js,cjs,mjs,ts}',
+ 'scripts/**/*.{js,mjs,ts}',
+ 'version/**/*.{js,mjs,ts}',
+ 'packages/main/src/**/*.{js,ts}',
+ 'packages/preload/src/**/*.{js,ts}',
+ 'packages/**/vite.config.{js,ts}',
+ 'tests/**/*.{js,ts}',
+ 'playwright.config.ts',
+ ],
languageOptions: {
- parserOptions: {
- sourceType: 'module',
- parser: '@typescript-eslint/parser',
- },
globals: {
...globals.node,
},
},
- ignores: ['**/node_modules/**', '**/dist/**', '**/coverage/**'],
rules: {
- '@typescript-eslint/no-var-requires': 'off',
- '@typescript-eslint/consistent-type-imports': 'error',
+ // Also disable the base rule here for consistency
+ 'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
- {
- argsIgnorePattern: '^_',
- varsIgnorePattern: '^_',
- caughtErrorsIgnorePattern: '^_',
- },
- ],
- /**
- * Having a semicolon helps the optimizer interpret your code correctly.
- * This avoids rare errors in optimized code.
- * @see https://twitter.com/alex_kozack/status/1364210394328408066
- */
- semi: ['error', 'always'],
- /**
- * This will make the history of changes in the hit a little cleaner
- */
- 'comma-dangle': ['warn', 'always-multiline'],
- /**
- * Just for beauty
- */
- quotes: [
- 'warn',
- 'single',
- {
- avoidEscape: true,
- },
+ { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' },
],
+ '@typescript-eslint/no-var-requires': 'off',
},
},
];
diff --git a/packages/main/tests/unit.spec.ts b/packages/main/tests/unit.spec.ts
deleted file mode 100644
index cdb6f6df..00000000
--- a/packages/main/tests/unit.spec.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-
-import {vi} from 'vitest';
-
-// Mock import.meta.env to ensure stability for Vite-specific environment variables
-vi.mock('import.meta', () => ({
- env: {
- DEV: false, // Simulates a production or test build environment
- VITE_DEV_SERVER_URL: undefined,
- // Add any other VITE_ variables used by mainWindow.ts or its dependencies here
- },
-}));
diff --git a/packages/preload/tests/unit.spec.ts b/packages/preload/tests/unit.spec.ts
deleted file mode 100644
index 80459d8d..00000000
--- a/packages/preload/tests/unit.spec.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import {test} from 'vitest';
-
-// Add new preload unit tests here if needed in the future.
-test.todo('should have tests for preload script functionality');
diff --git a/playwright.config.ts b/playwright.config.ts
new file mode 100644
index 00000000..5e071cfa
--- /dev/null
+++ b/playwright.config.ts
@@ -0,0 +1,56 @@
+import { defineConfig, devices } from '@playwright/test';
+
+export default defineConfig({
+ // Look for test files in the 'tests/e2e' directory.
+ testDir: './tests/e2e',
+
+ // Timeout for each test in milliseconds.
+ timeout: 30 * 1000,
+
+ // Global expect timeout.
+ expect: {
+ timeout: 5000,
+ },
+
+ // Run tests in files in parallel.
+ fullyParallel: true,
+
+ // Fail the build on CI if you accidentally leave test.only in the source code.
+ forbidOnly: !!process.env.CI,
+
+ // Retry on CI only.
+ retries: process.env.CI ? 2 : 0,
+
+ // Opt out of parallel tests on CI.
+ workers: process.env.CI ? 1 : undefined,
+
+ // Reporter to use. See https://playwright.dev/docs/test-reporters
+ reporter: 'html',
+
+ // Shared settings for all the projects below.
+ use: {
+ // Base URL to use in actions like `await page.goto('/')`.
+ // Make sure your dev server runs on this port.
+ baseURL: 'http://localhost:5175',
+
+ // Collect trace when retrying the failed test.
+ trace: 'on-first-retry',
+ },
+
+ // Configure projects for major browsers.
+ projects: [
+ {
+ name: 'chromium',
+ use: { ...devices['Desktop Chrome'] },
+ },
+ // Uncomment to test against other browsers.
+ // {
+ // name: 'firefox',
+ // use: { ...devices['Desktop Firefox'] },
+ // },
+ // {
+ // name: 'webkit',
+ // use: { ...devices['Desktop Safari'] },
+ // },
+ ],
+});
diff --git a/tests/benchmark.spec.ts b/tests/benchmark.spec.ts
deleted file mode 100644
index ffc123ca..00000000
--- a/tests/benchmark.spec.ts
+++ /dev/null
@@ -1,255 +0,0 @@
-import type {Browser, Page, ElectronApplication} from 'playwright';
-import {afterAll, beforeAll, describe, expect, test} from 'vitest';
-import {onBrowser} from './utils';
-
-interface LoadingMetrics {
- startTime: number;
- firstContentfulPaint?: number;
- domContentLoaded?: number;
- featuredContentAppeared?: number;
- totalLoadTime: number;
- hadFeaturedContent: boolean;
- errorCount: number;
-}
-
-interface BenchmarkResults {
- runs: LoadingMetrics[];
- minLoadTime: number;
- maxLoadTime: number;
- avgLoadTime: number;
- successRate: number;
- avgFeaturedContentTime?: number;
-}
-
-const BENCHMARK_RUNS = 5;
-const MAX_WAIT_TIME = 30000; // 30 seconds max wait
-
-describe('Loading Benchmark Suite', function () {
- const browser: Browser | undefined = undefined;
- const electronApp: ElectronApplication | undefined = undefined;
-
- beforeAll(async () => {
- console.log('š Starting Loading Benchmark Suite');
- console.log(`Running ${BENCHMARK_RUNS} iterations to measure load performance`);
- });
-
- afterAll(async () => {
- if (electronApp) {
- await electronApp.close();
- } else if (browser) {
- await browser.close();
- }
- });
-
- async function measureSingleLoad(runNumber: number): Promise {
- const metrics: LoadingMetrics = {
- startTime: Date.now(),
- totalLoadTime: 0,
- hadFeaturedContent: false,
- errorCount: 0,
- };
-
- let page: Page;
- let currentElectronApp: ElectronApplication | undefined;
- let currentBrowser: Browser | undefined;
-
- try {
- // Launch fresh instance for each run
- const testEnvironment = 'chromium'; // Can be made configurable
-
- if (testEnvironment === 'electron') {
- const result = await onBrowser({ typeNavigateur: 'electron' });
- page = result.page;
- currentElectronApp = result.electronApp;
- } else {
- const result = await onBrowser({ typeNavigateur: 'chromium' });
- page = result.page;
- currentBrowser = result.browser;
- }
-
- // Track console errors
- page.on('console', msg => {
- if (msg.type() === 'error') {
- metrics.errorCount++;
- console.log(`Run ${runNumber} Console Error: ${msg.text()}`);
- }
- });
-
- // Track performance events
- await page.evaluate(() => {
- // Mark when DOM content is loaded
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', () => {
- (window as unknown as { domContentLoadedTime: number }).domContentLoadedTime = Date.now();
- });
- } else {
- (window as unknown as { domContentLoadedTime: number }).domContentLoadedTime = Date.now();
- }
- });
-
- // Wait for app to be ready
- await page.waitForSelector('#app', { timeout: 10000 });
-
- // Get DOM content loaded time
- const domLoadedTime = await page.evaluate(() => (window as unknown as { domContentLoadedTime: number }).domContentLoadedTime);
- if (domLoadedTime) {
- metrics.domContentLoaded = domLoadedTime - metrics.startTime;
- }
-
- // Wait for Vue to be mounted and check for featured content
- await page.waitForFunction(() => {
- const app = document.querySelector('#app');
- return app && app.innerHTML.trim() !== '';
- }, { timeout: 15000 });
-
- // Check for featured content or "No featured content" message
- let featuredContentFound = false;
- let _noContentMessageFound = false;
-
- const startWait = Date.now();
-
- while (Date.now() - startWait < MAX_WAIT_TIME) {
- try {
- // Check for featured content cards
- const featuredContent = await page.$$('[data-testid="featured-release"], .featured-content, .release-card');
- if (featuredContent.length > 0) {
- featuredContentFound = true;
- metrics.featuredContentAppeared = Date.now() - metrics.startTime;
- metrics.hadFeaturedContent = true;
- break;
- }
-
- // Check for "No featured content yet" message
- const noContentElement = await page.$('text="No featured content yet"');
- if (noContentElement) {
- _noContentMessageFound = true;
- break;
- }
-
- // Check for any loading indicators
- const loadingIndicators = await page.$$('.v-progress-circular, .loading, [data-testid="loading"]');
- if (loadingIndicators.length === 0) {
- // No loading indicators visible, assume load is complete
- break;
- }
-
- await page.waitForTimeout(100); // Short wait before next check
- } catch (_error) {
- // Continue checking
- }
- }
-
- metrics.totalLoadTime = Date.now() - metrics.startTime;
-
- console.log(`Run ${runNumber}: ${metrics.totalLoadTime}ms total, ` +
- `${featuredContentFound ? 'featured content found' : 'no featured content'}, ` +
- `${metrics.errorCount} errors`);
-
- } catch (_error) {
- console.error(`Run ${runNumber} failed:`, _error);
- metrics.errorCount++;
- metrics.totalLoadTime = Date.now() - metrics.startTime;
- } finally {
- // Clean up
- try {
- if (currentElectronApp) {
- await currentElectronApp.close();
- } else if (currentBrowser) {
- await currentBrowser.close();
- }
- } catch (_error) {
- console.error('Cleanup error:', error);
- }
- }
-
- return metrics;
- }
-
- async function runBenchmark(): Promise {
- const results: LoadingMetrics[] = [];
-
- for (let i = 1; i <= BENCHMARK_RUNS; i++) {
- const metrics = await measureSingleLoad(i);
- results.push(metrics);
-
- // Small delay between runs to avoid resource conflicts
- await new Promise(resolve => setTimeout(resolve, 500));
- }
-
- // Calculate statistics
- const loadTimes = results.map(r => r.totalLoadTime);
- const successfulRuns = results.filter(r => r.errorCount === 0);
- const _runsWithFeaturedContent = results.filter(r => r.hadFeaturedContent);
- const featuredContentTimes = results
- .filter(r => r.featuredContentAppeared)
- .map(r => r.featuredContentAppeared!);
-
- const benchmarkResults: BenchmarkResults = {
- runs: results,
- minLoadTime: Math.min(...loadTimes),
- maxLoadTime: Math.max(...loadTimes),
- avgLoadTime: loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length,
- successRate: (successfulRuns.length / results.length) * 100,
- };
-
- if (featuredContentTimes.length > 0) {
- benchmarkResults.avgFeaturedContentTime =
- featuredContentTimes.reduce((a, b) => a + b, 0) / featuredContentTimes.length;
- }
-
- return benchmarkResults;
- }
-
- test('Loading Performance Benchmark', async () => {
- const results = await runBenchmark();
-
- console.log('\nš BENCHMARK RESULTS:');
- console.log(`Total runs: ${results.runs.length}`);
- console.log(`Success rate: ${results.successRate.toFixed(1)}%`);
- console.log(`Min load time: ${results.minLoadTime}ms`);
- console.log(`Max load time: ${results.maxLoadTime}ms`);
- console.log(`Avg load time: ${results.avgLoadTime.toFixed(1)}ms`);
-
- const runsWithFeaturedContent = results.runs.filter(r => r.hadFeaturedContent);
- console.log(`Runs with featured content: ${runsWithFeaturedContent.length}/${results.runs.length} (${((runsWithFeaturedContent.length / results.runs.length) * 100).toFixed(1)}%)`);
-
- if (results.avgFeaturedContentTime) {
- console.log(`Avg time to featured content: ${results.avgFeaturedContentTime.toFixed(1)}ms`);
- }
-
- const errorCounts = results.runs.map(r => r.errorCount);
- const totalErrors = errorCounts.reduce((a, b) => a + b, 0);
- console.log(`Total console errors: ${totalErrors}`);
-
- // Write detailed results to file for analysis
- const detailedResults = {
- timestamp: new Date().toISOString(),
- summary: {
- totalRuns: results.runs.length,
- successRate: results.successRate,
- minLoadTime: results.minLoadTime,
- maxLoadTime: results.maxLoadTime,
- avgLoadTime: results.avgLoadTime,
- runsWithFeaturedContent: runsWithFeaturedContent.length,
- featuredContentRate: (runsWithFeaturedContent.length / results.runs.length) * 100,
- avgFeaturedContentTime: results.avgFeaturedContentTime,
- totalErrors: totalErrors,
- },
- runs: results.runs,
- };
-
- // This assertion will help track if we're consistently failing to load featured content
- expect(runsWithFeaturedContent.length).toBeGreaterThan(0,
- 'No runs successfully loaded featured content - this indicates a race condition or loading issue');
-
- // Performance expectations (these can be adjusted based on baseline)
- expect(results.avgLoadTime).toBeLessThan(15000,
- `Average load time ${results.avgLoadTime.toFixed(1)}ms exceeds 15 second threshold`);
-
- expect(results.successRate).toBeGreaterThan(80,
- `Success rate ${results.successRate.toFixed(1)}% is below 80% threshold`);
-
- console.log('\nš¾ Detailed results saved for analysis');
- console.log(JSON.stringify(detailedResults, null, 2));
- });
-});
\ No newline at end of file
diff --git a/tests/content-verification-benchmark.spec.ts b/tests/content-verification-benchmark.spec.ts
deleted file mode 100644
index 7192d1bc..00000000
--- a/tests/content-verification-benchmark.spec.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { test } from 'vitest';
-import { chromium } from 'playwright';
-
-test('Verify Actual Content Loading', async () => {
- const browser = await chromium.launch({ headless: true });
- const page = await browser.newPage();
-
- const testStart = Date.now();
- const milestones: Record = {};
-
- // Track console logs
- page.on('console', msg => {
- const text = msg.text();
- if (text.includes('HomePage Debug')) {
- console.log(`[${Date.now() - testStart}ms] ${text.substring(0, 150)}`);
- }
- });
-
- try {
- await page.goto('http://localhost:5175');
- milestones.navigation = Date.now() - testStart;
-
- // Wait for app
- await page.waitForSelector('#app', { state: 'visible' });
- milestones.appVisible = Date.now() - testStart;
-
- // Wait for loading to finish (spinner gone)
- try {
- await page.waitForSelector('.v-progress-circular', { state: 'hidden', timeout: 10000 });
- milestones.loadingComplete = Date.now() - testStart;
- } catch {
- console.log('No loading spinner detected or it never disappeared');
- }
-
- // Check what content is actually displayed
- const content = await page.evaluate(() => {
- const app = document.querySelector('#app');
- const text = app?.textContent || '';
-
- return {
- fullText: text.substring(0, 500),
- hasNavigation: text.includes('Home') && text.includes('Music'),
- hasNoContentMessage: text.includes('No featured content') || text.includes('No content'),
- hasFeaturedSlider: !!document.querySelector('.featured-slider'),
- hasContentCards: document.querySelectorAll('.content-card, .v-card').length,
- hasImages: document.querySelectorAll('img[src*="ipfs"], img[src*="mock"]').length,
- hasContentSections: document.querySelectorAll('.content-section').length,
- };
- });
-
- milestones.contentChecked = Date.now() - testStart;
-
- console.log('\nš TIMING MILESTONES:');
- Object.entries(milestones).forEach(([name, time]) => {
- console.log(`${name}: ${time}ms`);
- });
-
- console.log('\nš CONTENT VERIFICATION:');
- console.log('Has Navigation:', content.hasNavigation);
- console.log('Has "No Content" Message:', content.hasNoContentMessage);
- console.log('Has Featured Slider:', content.hasFeaturedSlider);
- console.log('Number of Content Cards:', content.hasContentCards);
- console.log('Number of Images:', content.hasImages);
- console.log('Number of Content Sections:', content.hasContentSections);
-
- console.log('\nš PAGE CONTENT PREVIEW:');
- console.log(content.fullText);
-
- // Take a screenshot
- await page.screenshot({ path: '/tmp/content-verification.png', fullPage: true });
- console.log('\nšø Screenshot saved to /tmp/content-verification.png');
-
- } finally {
- await browser.close();
- }
-});
\ No newline at end of file
diff --git a/tests/detailed-benchmark.spec.ts b/tests/detailed-benchmark.spec.ts
deleted file mode 100644
index d5c5e75b..00000000
--- a/tests/detailed-benchmark.spec.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { test } from 'vitest';
-import { chromium } from 'playwright';
-
-test('Detailed Performance Breakdown', async () => {
- const browser = await chromium.launch({ headless: true });
- const page = await browser.newPage();
-
- const timings: Record = {};
- const startTime = Date.now();
-
- // Track performance marks
- await page.evaluateOnNewDocument(() => {
- window.performanceMarks = {};
-
- // Override performance.mark to capture all marks
- const originalMark = performance.mark.bind(performance);
- performance.mark = (name: string) => {
- window.performanceMarks[name] = performance.now();
- return originalMark(name);
- };
- });
-
- // Track console logs with timestamps
- page.on('console', msg => {
- const elapsed = Date.now() - startTime;
- if (msg.text().includes('Connecting to bootstrappers') ||
- msg.text().includes('Connected to') ||
- msg.text().includes('Debug')) {
- console.log(`[${elapsed}ms] ${msg.text()}`);
- }
- });
-
- try {
- // Start navigation
- const navStart = Date.now();
- await page.goto('http://localhost:5175');
- timings['navigation'] = Date.now() - navStart;
-
- // Wait for Vue app mount
- const appMountStart = Date.now();
- await page.waitForSelector('#app', { state: 'visible' });
- timings['app_mount'] = Date.now() - appMountStart;
-
- // Check for loading spinner
- const spinnerCheck = Date.now();
- const hasSpinner = await page.$('.v-progress-circular') !== null;
- timings['spinner_check'] = Date.now() - spinnerCheck;
-
- if (hasSpinner) {
- console.log('Loading spinner detected, waiting for it to disappear...');
- const spinnerWaitStart = Date.now();
- await page.waitForSelector('.v-progress-circular', { state: 'hidden', timeout: 10000 });
- timings['spinner_wait'] = Date.now() - spinnerWaitStart;
- }
-
- // Wait for content
- const contentWaitStart = Date.now();
- await page.waitForFunction(() => {
- const app = document.querySelector('#app');
- const text = app?.textContent || '';
- return text.includes('Featured') || text.includes('No featured content');
- });
- timings['content_wait'] = Date.now() - contentWaitStart;
-
- timings['total'] = Date.now() - startTime;
-
- // Get performance entries from the page
- const perfData = await page.evaluate(() => ({
- marks: window.performanceMarks || {},
- resources: performance.getEntriesByType('resource').map(r => ({
- name: r.name.split('/').pop(),
- duration: Math.round(r.duration),
- })).filter(r => r.duration > 100), // Only show resources taking >100ms
- }));
-
- console.log('\nā±ļø PERFORMANCE BREAKDOWN:');
- console.log('Navigation:', timings.navigation + 'ms');
- console.log('App Mount:', timings.app_mount + 'ms');
- console.log('Spinner Check:', timings.spinner_check + 'ms');
- if (timings.spinner_wait) {
- console.log('Waiting for spinner:', timings.spinner_wait + 'ms');
- }
- console.log('Content Wait:', timings.content_wait + 'ms');
- console.log('TOTAL:', timings.total + 'ms');
-
- if (perfData.resources.length > 0) {
- console.log('\nš¦ Slow Resources (>100ms):');
- perfData.resources.forEach(r => console.log(` ${r.name}: ${r.duration}ms`));
- }
-
- if (Object.keys(perfData.marks).length > 0) {
- console.log('\nš Performance Marks:');
- Object.entries(perfData.marks).forEach(([name, time]) =>
- console.log(` ${name}: ${Math.round(time as number)}ms`));
- }
-
- } finally {
- await browser.close();
- }
-});
\ No newline at end of file
diff --git a/tests/dev-server-benchmark.spec.ts b/tests/dev-server-benchmark.spec.ts
deleted file mode 100644
index 10f9898f..00000000
--- a/tests/dev-server-benchmark.spec.ts
+++ /dev/null
@@ -1,284 +0,0 @@
-import { test, expect } from 'vitest';
-import { chromium } from 'playwright';
-
-interface LoadingMetrics {
- startTime: number;
- totalLoadTime: number;
- hadFeaturedContent: boolean;
- hadNoFeaturedMessage: boolean;
- hadLoadingSpinner: boolean;
- stuckInLoading: boolean;
- errorCount: number;
- peerbitConnected: boolean;
-}
-
-const BENCHMARK_RUNS = 3;
-const DEV_SERVER_URL = 'http://localhost:5175'; // Default Vite dev server port
-
-test('Dev Server Loading Benchmark - REAL CONDITIONS', async () => {
- console.log('š Starting REAL Loading Benchmark');
- console.log(`Testing against: ${DEV_SERVER_URL}`);
- console.log(`Running ${BENCHMARK_RUNS} iterations to measure ACTUAL load performance`);
- console.log('ā ļø Make sure dev server is running: pnpm watch:web');
-
- const results: LoadingMetrics[] = [];
-
- // Test if dev server is available
- try {
- const testBrowser = await chromium.launch({ headless: true });
- const testPage = await testBrowser.newPage();
- await testPage.goto(DEV_SERVER_URL, { timeout: 5000 });
- await testBrowser.close();
- console.log('ā
Dev server is accessible');
- } catch (_error) {
- console.error('ā Dev server not accessible. Run: pnpm watch:web');
- throw new Error('Dev server not running. Please start with: pnpm watch:web');
- }
-
- for (let i = 1; i <= BENCHMARK_RUNS; i++) {
- const startTime = Date.now();
- const metrics: LoadingMetrics = {
- startTime,
- totalLoadTime: 0,
- hadFeaturedContent: false,
- hadNoFeaturedMessage: false,
- hadLoadingSpinner: false,
- stuckInLoading: false,
- errorCount: 0,
- peerbitConnected: false,
- };
-
- const browser = await chromium.launch({ headless: true });
- const page = await browser.newPage();
-
- // Track console logs for Peerbit connection status
- page.on('console', msg => {
- const text = msg.text();
- if (msg.type() === 'error') {
- // BLOCKLIST: Ignore expected P2P/networking errors that are normal
- const ignoredErrors = [
- 'ws://127.0.0.1:', 'ERR_CONNECTION_REFUSED', // Peer advertising local addresses
- 'mdi-', 'Expected number', // MDI icon loading issues
- 'lazystream', 'UnexpectedEOFError', // P2P stream errors
- 'unexpected end of input', // Network/stream termination
- 'outbound inflight queue error', // P2P queue errors
- 'WebSocket connection', // WebSocket connection issues
- 'net::ERR_', 'Failed to load resource', // General network errors
- ];
-
- if (ignoredErrors.some(ignored => text.includes(ignored))) {
- return; // These are expected in P2P environment
- }
-
- metrics.errorCount++;
- console.log(`Run ${i} Console Error: ${text}`);
- }
-
- // Check for Peerbit connection indicators
- if (text.includes('peer') || text.includes('Peerbit') || text.includes('connected') || text.includes('node')) {
- console.log(`Run ${i} Peerbit Activity: ${text}`);
- if (text.includes('connected') || text.includes('ready')) {
- metrics.peerbitConnected = true;
- }
- }
- });
-
- try {
- console.log(`Run ${i}: Starting...`);
-
- // Navigate to the app
- await page.goto(DEV_SERVER_URL, { waitUntil: 'domcontentloaded' });
-
- // Wait for #app to be visible - this should be immediate now
- const appStart = Date.now();
- await page.waitForSelector('#app', { state: 'visible', timeout: 8000 });
- const appLoadTime = Date.now() - appStart;
- console.log(`Run ${i}: #app visible in ${appLoadTime}ms`);
-
- // Check for loading spinner at multiple points
- let foundLoadingSpinner = false;
-
- // Check immediately after app loads
- const initialLoadingSpinner = await page.$('[data-testid="loading"], .v-progress-circular');
- if (initialLoadingSpinner) {
- foundLoadingSpinner = true;
- metrics.hadLoadingSpinner = true;
- console.log(`Run ${i}: Loading spinner detected initially`);
- }
-
- // Also check after a short delay (in case it appears after Vue renders)
- await page.waitForTimeout(100);
- const delayedLoadingSpinner = await page.$('[data-testid="loading"], .v-progress-circular');
- if (delayedLoadingSpinner && !foundLoadingSpinner) {
- foundLoadingSpinner = true;
- metrics.hadLoadingSpinner = true;
- console.log(`Run ${i}: Loading spinner detected after delay`);
- }
-
- if (foundLoadingSpinner) {
- // Wait up to 15 seconds to see if it resolves
- try {
- await page.waitForSelector('[data-testid="loading"], .v-progress-circular', { state: 'hidden', timeout: 15000 });
- console.log(`Run ${i}: Loading spinner resolved`);
- } catch {
- metrics.stuckInLoading = true;
- console.log(`Run ${i}: STUCK IN LOADING STATE`);
- }
- } else {
- console.log(`Run ${i}: No loading spinner detected`);
- }
-
- // Wait longer for content to potentially appear (Peerbit can be slow)
- await page.waitForTimeout(5000);
-
- // Check for featured content with much broader selectors
- const featuredContentSelectors = [
- '[data-testid="featured-content"]',
- '.featured-content',
- '.release-card',
- '.content-card',
- '.v-card', // Vuetify cards
- '.featured-slider',
- '.content-section',
- 'img[src*="mock"]', // Mock images from static data
- 'img[src*="bafkrei"]', // IPFS images
- '.v-container .v-sheet:not([data-testid="loading"])', // Content containers
- 'h1, h2, h3', // Any headings that might indicate content
- ];
-
- let foundContent = false;
- for (const selector of featuredContentSelectors) {
- const elements = await page.$$(selector);
- if (elements.length > 0) {
- foundContent = true;
- console.log(`Run ${i}: ā
Found content with selector "${selector}" (${elements.length} items)`);
- break;
- }
- }
-
- if (foundContent) {
- metrics.hadFeaturedContent = true;
- }
-
- // Check for "No featured content" message with broader detection
- const noContentSelectors = [
- '[data-testid="no-featured-content"]',
- 'text="No featured content yet"',
- 'text="No content here"',
- ':text("No featured content")',
- ':text("No content")',
- ];
-
- for (const selector of noContentSelectors) {
- try {
- const element = await page.$(selector);
- if (element) {
- metrics.hadNoFeaturedMessage = true;
- console.log(`Run ${i}: ā ļø "No featured content" message found with selector "${selector}"`);
- break;
- }
- } catch (_e) {
- // Ignore errors from text selectors
- }
- }
-
- // Debug: Log page content to understand what's actually rendered
- const appContent = await page.textContent('#app');
- const hasLoadingText = appContent?.includes('Loading') || false;
- const hasContentText = appContent?.includes('Featured') || appContent?.includes('Music') || appContent?.includes('Movies') || false;
- console.log(`Run ${i}: Page text includes Loading: ${hasLoadingText}, Content keywords: ${hasContentText}`);
-
- // Take screenshots for all runs to debug
- await page.screenshot({ path: `/tmp/dev-benchmark-run-${i}.png`, fullPage: true });
-
- } catch (_error) {
- console.log(`Run ${i} ā FAILED:`, _error.message);
- metrics.errorCount++;
- } finally {
- metrics.totalLoadTime = Date.now() - startTime;
- await browser.close();
- }
-
- results.push(metrics);
-
- const status = metrics.hadFeaturedContent ? 'ā
SUCCESS' :
- metrics.stuckInLoading ? 'š STUCK' :
- metrics.hadNoFeaturedMessage ? 'ā ļø NO CONTENT' : 'ā FAILED';
-
- console.log(`Run ${i}: ${metrics.totalLoadTime}ms ${status} (errors: ${metrics.errorCount})`);
-
- // Small delay between runs
- await new Promise(resolve => setTimeout(resolve, 1000));
- }
-
- // Calculate statistics
- const loadTimes = results.map(r => r.totalLoadTime);
- const successfulRuns = results.filter(r => r.hadFeaturedContent);
- const stuckRuns = results.filter(r => r.stuckInLoading);
- const noContentRuns = results.filter(r => r.hadNoFeaturedMessage);
- const peerbitConnectedRuns = results.filter(r => r.peerbitConnected);
-
- console.log('\nš REAL PERFORMANCE RESULTS:');
- console.log(`Total runs: ${results.length}`);
- console.log(`Min load time: ${Math.min(...loadTimes)}ms`);
- console.log(`Max load time: ${Math.max(...loadTimes)}ms`);
- console.log(`Avg load time: ${(loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length).toFixed(1)}ms`);
-
- console.log('\nšÆ SUCCESS RATES:');
- console.log(`ā
Featured content loaded: ${successfulRuns.length}/${results.length} (${((successfulRuns.length / results.length) * 100).toFixed(1)}%)`);
- console.log(`š Stuck in loading: ${stuckRuns.length}/${results.length} (${((stuckRuns.length / results.length) * 100).toFixed(1)}%)`);
- console.log(`ā ļø "No content" message: ${noContentRuns.length}/${results.length} (${((noContentRuns.length / results.length) * 100).toFixed(1)}%)`);
- console.log(`š Peerbit connected: ${peerbitConnectedRuns.length}/${results.length} (${((peerbitConnectedRuns.length / results.length) * 100).toFixed(1)}%)`);
-
- const totalErrors = results.reduce((sum, r) => sum + r.errorCount, 0);
- console.log(`ā Total console errors: ${totalErrors}`);
-
- // Race condition analysis
- const raceConditionIndicators = {
- inconsistentResults: new Set([successfulRuns.length, stuckRuns.length, noContentRuns.length]).size > 1,
- lowSuccessRate: (successfulRuns.length / results.length) < 0.8,
- highStuckRate: (stuckRuns.length / results.length) > 0.2,
- peerbitConnectionIssues: (peerbitConnectedRuns.length / results.length) < 0.8,
- };
-
- console.log('\nš RACE CONDITION ANALYSIS:');
- Object.entries(raceConditionIndicators).forEach(([key, value]) => {
- const icon = value ? 'ā' : 'ā
';
- console.log(`${icon} ${key}: ${value}`);
- });
-
- // Log baseline results for comparison
- const baselineResults = {
- timestamp: new Date().toISOString(),
- version: 'baseline-before-optimization',
- testType: 'dev-server-real-conditions',
- summary: {
- totalRuns: results.length,
- successRate: (successfulRuns.length / results.length) * 100,
- stuckInLoadingRate: (stuckRuns.length / results.length) * 100,
- noContentMessageRate: (noContentRuns.length / results.length) * 100,
- peerbitConnectionRate: (peerbitConnectedRuns.length / results.length) * 100,
- minLoadTime: Math.min(...loadTimes),
- maxLoadTime: Math.max(...loadTimes),
- avgLoadTime: loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length,
- totalErrors: totalErrors,
- raceConditionDetected: Object.values(raceConditionIndicators).some(Boolean),
- },
- runs: results,
- };
-
- console.log('\nš¾ BASELINE RESULTS:');
- console.log(JSON.stringify(baselineResults, null, 2));
-
- // Validate that we got real data
- expect(results.length).toBe(BENCHMARK_RUNS);
-
- // This test should demonstrate the race condition - if success rate is too low, we have a problem
- if ((successfulRuns.length / results.length) < 0.5) {
- console.log('\nšØ RACE CONDITION CONFIRMED: Success rate below 50%');
- }
-
- // Don't fail the test - we want to see the real numbers
- console.log('\nā
Benchmark completed - data collected for optimization');
-
-}, 600000); // 10 minute timeout
\ No newline at end of file
diff --git a/tests/e2e.spec.ts b/tests/e2e.spec.ts
deleted file mode 100644
index 83891730..00000000
--- a/tests/e2e.spec.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import type {Browser, Page, ElectronApplication} from 'playwright';
-import {afterAll, beforeAll, describe, expect, test} from 'vitest';
-import {onBrowser} from './utils';
-
-const environnement = process.env.ENVIRONNEMENT_TESTS;
-
-describe('Test app window', function () {
- let browser: Browser | undefined = undefined;
- let electronApp: ElectronApplication | undefined = undefined;
- let page: Page;
-
- beforeAll(async () => {
- const testEnvironment = (environnement || 'electron') as 'firefox' | 'chromium' | 'webkit' | 'electron';
-
- if (testEnvironment === 'electron') {
- const result = await onBrowser({ typeNavigateur: 'electron' });
- page = result.page;
- electronApp = result.electronApp;
- } else if (['firefox', 'chromium', 'webkit'].includes(testEnvironment)) {
- const result = await onBrowser({ typeNavigateur: testEnvironment as 'firefox' | 'chromium' | 'webkit' });
- page = result.page;
- browser = result.browser;
- } else {
- throw new Error(`Unsupported test environment: ${environnement}. Must be 'firefox', 'chromium', 'webkit', or 'electron'.`);
- }
-
- // Listen for console messages from the page to aid debugging
- page.on('console', msg => {
- const msgType = msg.type().toUpperCase();
- const msgText = msg.text();
- console.log(`E2E BROWSER CONSOLE [${msgType}]: ${msgText}`);
- // Log arguments if any, useful for complex objects or multiple args
- if (msg.args().length > 0) {
- for (let i = 0; i < msg.args().length; ++i) {
- // Attempt to get a string representation of the argument
- msg.args()[i].jsonValue().then(value => {
- console.log(` ARG ${i}:`, value);
- }).catch(() => {
- // Fallback if jsonValue fails (e.g., for non-serializable objects like functions)
- console.log(` ARG ${i}: (Could not serialize)`);
- });
- }
- }
- });
- });
-
- afterAll(async () => {
- if (electronApp) {
- await electronApp.close();
- } else if (browser) {
- await browser.close();
- }
- });
-
- test('Main window web content', async () => {
- const element = await page.$('#app', {strict: true});
- expect(element, 'Was unable to find the root element').toBeDefined();
- expect((await element!.innerHTML()).trim(), 'Window content was empty').not.equal('');
- });
-
-});
-
diff --git a/tests/e2e/basic-smoke.spec.ts b/tests/e2e/basic-smoke.spec.ts
new file mode 100644
index 00000000..44b3e4a4
--- /dev/null
+++ b/tests/e2e/basic-smoke.spec.ts
@@ -0,0 +1,21 @@
+import { test, expect } from '@playwright/test';
+
+test.describe('Basic Smoke Test', () => {
+
+ test('should load the homepage and display the main layout', async ({ page }) => {
+ await page.goto('/');
+
+ // 1. Look for the rendered by . This appears immediately.
+ const appBar = page.locator('header.v-app-bar');
+ await expect(appBar).toBeVisible();
+
+ // 2. Check for the logo inside the app bar.
+ const logo = appBar.locator('img[src="/logo.svg"]');
+ await expect(logo).toBeVisible();
+
+ // 3. Look for the tag rendered by . This is a better selector.
+ // This confirms the core layout of the app is present.
+ const mainElement = page.locator('main.v-main');
+ await expect(mainElement).toBeVisible();
+ });
+});
diff --git a/tests/fast-benchmark.spec.ts b/tests/fast-benchmark.spec.ts
deleted file mode 100644
index 4177df5d..00000000
--- a/tests/fast-benchmark.spec.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { test, expect } from 'vitest';
-import { chromium } from 'playwright';
-
-const BENCHMARK_RUNS = 5;
-const DEV_SERVER_URL = 'http://localhost:5175';
-
-test('Fast Loading Benchmark - Actual Performance', async () => {
- console.log('š Starting Fast Loading Benchmark');
- console.log(`Running ${BENCHMARK_RUNS} iterations`);
-
- const results: number[] = [];
-
- for (let i = 1; i <= BENCHMARK_RUNS; i++) {
- const browser = await chromium.launch({ headless: true });
- const page = await browser.newPage();
-
- const startTime = Date.now();
-
- try {
- // Navigate and wait for content to appear
- await page.goto(DEV_SERVER_URL);
-
- // Wait for either content or "no content" message - whichever comes first
- await page.waitForFunction(() => {
- const app = document.querySelector('#app');
- if (!app) return false;
-
- const text = app.textContent || '';
- // Content is ready when we see actual content OR the "no content" message
- return (
- text.includes('Featured') ||
- text.includes('No featured content') ||
- text.includes('Movies') ||
- text.includes('Music') ||
- document.querySelector('.content-card') !== null ||
- document.querySelector('.v-card') !== null
- );
- }, { timeout: 30000 });
-
- const loadTime = Date.now() - startTime;
- results.push(loadTime);
- console.log(`Run ${i}: ${loadTime}ms`);
-
- } catch (error) {
- console.error(`Run ${i} failed:`, error.message);
- results.push(30000); // Timeout value
- } finally {
- await browser.close();
- }
- }
-
- // Calculate stats
- const avg = results.reduce((a, b) => a + b, 0) / results.length;
- const min = Math.min(...results);
- const max = Math.max(...results);
-
- console.log('\nš RESULTS:');
- console.log(`Average: ${avg.toFixed(0)}ms`);
- console.log(`Min: ${min}ms`);
- console.log(`Max: ${max}ms`);
-
- // Check if we achieved sub-2s loading
- const sub2s = results.filter(t => t < 2000).length;
- console.log(`\nSub-2s loads: ${sub2s}/${results.length} (${(sub2s/results.length*100).toFixed(0)}%)`);
-
- expect(avg).toBeLessThan(3000); // Expect average under 3s
- expect(min).toBeLessThan(2000); // Expect at least one sub-2s load
-});
\ No newline at end of file
diff --git a/tests/fresh-load-benchmark.spec.ts b/tests/fresh-load-benchmark.spec.ts
deleted file mode 100644
index 9a850819..00000000
--- a/tests/fresh-load-benchmark.spec.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import { test } from 'vitest';
-import { chromium } from 'playwright';
-
-test('Fresh Load Performance', async () => {
- const browser = await chromium.launch({ headless: false }); // Not headless to ensure fresh load
- const context = await browser.newContext({
- // Disable cache
- bypassCSP: true,
- ignoreHTTPSErrors: true,
- extraHTTPHeaders: {
- 'Cache-Control': 'no-cache',
- },
- });
- const page = await context.newPage();
-
- const logs: Array<{time: number, text: string}> = [];
- const testStart = Date.now();
-
- // Capture ALL console logs
- page.on('console', msg => {
- const text = msg.text();
- if (text.includes('Site.open') || text.includes('bootstrap') || text.includes('Connected')) {
- logs.push({
- time: Date.now() - testStart,
- text: text,
- });
- }
- });
-
- try {
- // Force fresh load
- await page.goto('http://localhost:5175', { waitUntil: 'domcontentloaded' });
-
- // Wait for content
- await page.waitForFunction(() => {
- const app = document.querySelector('#app');
- const text = app?.textContent || '';
- return text.includes('Featured') || text.includes('No featured content') || text.includes('Movies');
- }, { timeout: 10000 });
-
- const totalTime = Date.now() - testStart;
-
- console.log(`\nā±ļø TOTAL LOAD TIME: ${totalTime}ms`);
-
- if (totalTime < 2000) {
- console.log('š SUB-2s LOAD ACHIEVED!');
- }
-
- // Print Site.open logs
- console.log('\nš Key Timeline Events:');
- logs.forEach(log => {
- console.log(`[${log.time}ms] ${log.text}`);
- });
-
- } finally {
- await browser.close();
- }
-});
\ No newline at end of file
diff --git a/tests/http-benchmark.spec.ts b/tests/http-benchmark.spec.ts
deleted file mode 100644
index 5ad36a18..00000000
--- a/tests/http-benchmark.spec.ts
+++ /dev/null
@@ -1,202 +0,0 @@
-import { test, expect } from 'vitest';
-import { chromium } from 'playwright';
-import { createServer } from 'http';
-import { createReadStream, statSync } from 'fs';
-import path, { dirname } from 'path';
-import { fileURLToPath } from 'url';
-
-interface LoadingMetrics {
- startTime: number;
- totalLoadTime: number;
- hadFeaturedContent: boolean;
- hadNoFeaturedMessage: boolean;
- hadLoadingSpinner: boolean;
- errorCount: number;
-}
-
-const BENCHMARK_RUNS = 10;
-
-function createSimpleServer(port: number, webRoot: string): Promise {
- return new Promise((resolve) => {
- const server = createServer((req, res) => {
- const filePath = path.join(webRoot, req.url === '/' ? 'index.html' : req.url!);
-
- try {
- const stat = statSync(filePath);
- if (stat.isFile()) {
- const ext = path.extname(filePath);
- const contentType = {
- '.html': 'text/html',
- '.js': 'application/javascript',
- '.css': 'text/css',
- '.png': 'image/png',
- '.svg': 'image/svg+xml',
- '.wasm': 'application/wasm',
- }[ext] || 'application/octet-stream';
-
- res.writeHead(200, { 'Content-Type': contentType });
- createReadStream(filePath).pipe(res);
- } else {
- res.writeHead(404);
- res.end('Not found');
- }
- } catch (_error) {
- res.writeHead(404);
- res.end('Not found');
- }
- });
-
- server.listen(port, () => {
- resolve(server);
- });
- });
-}
-
-test('HTTP Loading Benchmark', async () => {
- console.log('š Starting HTTP Loading Benchmark');
- console.log(`Running ${BENCHMARK_RUNS} iterations to measure load performance`);
-
- // Start HTTP server
- const __dirname_test = dirname(fileURLToPath(import.meta.url));
- const webRoot = path.join(__dirname_test, '..', 'packages', 'renderer', 'dist', 'web');
- const port = 8099;
- const server = await createSimpleServer(port, webRoot);
- const baseUrl = `http://localhost:${port}`;
-
- const results: LoadingMetrics[] = [];
-
- try {
- for (let i = 1; i <= BENCHMARK_RUNS; i++) {
- const startTime = Date.now();
- const metrics: LoadingMetrics = {
- startTime,
- totalLoadTime: 0,
- hadFeaturedContent: false,
- hadNoFeaturedMessage: false,
- hadLoadingSpinner: false,
- errorCount: 0,
- };
-
- const browser = await chromium.launch({ headless: true });
- const page = await browser.newPage();
-
- // Track console errors and logs
- page.on('console', msg => {
- if (msg.type() === 'error') {
- metrics.errorCount++;
- console.log(`Run ${i} Console Error: ${msg.text()}`);
- }
- });
-
- try {
- // Navigate to the app
- await page.goto(baseUrl, { waitUntil: 'networkidle' });
-
- // Wait for #app to be visible
- await page.waitForSelector('#app', { state: 'visible', timeout: 10000 });
-
- // Wait a bit more for app initialization
- await page.waitForTimeout(3000);
-
- // Check for loading spinner
- const loadingSpinner = await page.$('[data-testid="loading"]');
- if (loadingSpinner) {
- metrics.hadLoadingSpinner = true;
- console.log(`Run ${i}: Loading spinner detected`);
- }
-
- // Check for featured content
- const featuredContent = await page.$$('[data-testid="featured-content"], .featured-content, .release-card');
- if (featuredContent.length > 0) {
- metrics.hadFeaturedContent = true;
- console.log(`Run ${i}: Featured content detected`);
- }
-
- // Check for "No featured content" message
- const noContentMessage = await page.$('[data-testid="no-featured-content"]');
- if (noContentMessage) {
- metrics.hadNoFeaturedMessage = true;
- console.log(`Run ${i}: No featured content message detected`);
- }
-
- // Take screenshots for debugging
- if (i <= 3) {
- await page.screenshot({ path: `/tmp/http-benchmark-run-${i}.png` });
- }
-
- } catch (_error) {
- console.log(`Run ${i} failed:`, _error);
- metrics.errorCount++;
- } finally {
- metrics.totalLoadTime = Date.now() - startTime;
- await browser.close();
- }
-
- results.push(metrics);
- console.log(`Run ${i}: ${metrics.totalLoadTime}ms, featured=${metrics.hadFeaturedContent}, noMessage=${metrics.hadNoFeaturedMessage}, loading=${metrics.hadLoadingSpinner}, errors=${metrics.errorCount}`);
- }
-
- } finally {
- server.close();
- }
-
- // Calculate statistics
- const loadTimes = results.map(r => r.totalLoadTime);
- const successfulRuns = results.filter(r => r.errorCount === 0);
- const runsWithFeaturedContent = results.filter(r => r.hadFeaturedContent);
- const runsWithNoContentMessage = results.filter(r => r.hadNoFeaturedMessage);
- const runsWithLoadingSpinner = results.filter(r => r.hadLoadingSpinner);
-
- console.log('\nš BENCHMARK RESULTS:');
- console.log(`Total runs: ${results.length}`);
- console.log(`Success rate: ${((successfulRuns.length / results.length) * 100).toFixed(1)}%`);
- console.log(`Min load time: ${Math.min(...loadTimes)}ms`);
- console.log(`Max load time: ${Math.max(...loadTimes)}ms`);
- console.log(`Avg load time: ${(loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length).toFixed(1)}ms`);
- console.log(`Runs with featured content: ${runsWithFeaturedContent.length}/${results.length} (${((runsWithFeaturedContent.length / results.length) * 100).toFixed(1)}%)`);
- console.log(`Runs with "no featured content" message: ${runsWithNoContentMessage.length}/${results.length} (${((runsWithNoContentMessage.length / results.length) * 100).toFixed(1)}%)`);
- console.log(`Runs with loading spinner: ${runsWithLoadingSpinner.length}/${results.length} (${((runsWithLoadingSpinner.length / results.length) * 100).toFixed(1)}%)`);
-
- const totalErrors = results.reduce((sum, r) => sum + r.errorCount, 0);
- console.log(`Total console errors: ${totalErrors}`);
-
- // Log baseline results
- const baselineResults = {
- timestamp: new Date().toISOString(),
- version: 'baseline-before-optimization',
- summary: {
- totalRuns: results.length,
- successRate: (successfulRuns.length / results.length) * 100,
- minLoadTime: Math.min(...loadTimes),
- maxLoadTime: Math.max(...loadTimes),
- avgLoadTime: loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length,
- featuredContentRate: (runsWithFeaturedContent.length / results.length) * 100,
- noContentMessageRate: (runsWithNoContentMessage.length / results.length) * 100,
- loadingSpinnerRate: (runsWithLoadingSpinner.length / results.length) * 100,
- totalErrors: totalErrors,
- },
- runs: results,
- };
-
- console.log('\nš¾ BASELINE RESULTS (save this for comparison):');
- console.log(JSON.stringify(baselineResults, null, 2));
-
- // Create a simple comparison object for easy tracking
- const summary = {
- avgLoadTime: baselineResults.summary.avgLoadTime,
- featuredContentRate: baselineResults.summary.featuredContentRate,
- noContentMessageRate: baselineResults.summary.noContentMessageRate,
- successRate: baselineResults.summary.successRate,
- };
-
- console.log('\nšÆ KEY METRICS TO TRACK:');
- console.log(`Average Load Time: ${summary.avgLoadTime.toFixed(1)}ms`);
- console.log(`Featured Content Success Rate: ${summary.featuredContentRate.toFixed(1)}%`);
- console.log(`"No Content" Message Rate: ${summary.noContentMessageRate.toFixed(1)}%`);
- console.log(`Overall Success Rate: ${summary.successRate.toFixed(1)}%`);
-
- // Basic expectations to validate the benchmark works
- expect(results.length).toBe(BENCHMARK_RUNS);
- // We expect at least some runs to complete without major errors
- expect(successfulRuns.length).toBeGreaterThan(0);
-}, 300000); // 5 minute timeout
\ No newline at end of file
diff --git a/tests/minimal-main.js b/tests/minimal-main.js
deleted file mode 100644
index fec92a1b..00000000
--- a/tests/minimal-main.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import { app, BrowserWindow } from 'electron';
-
-// ES modules don't have __dirname by default. We need to derive it.
-// const __filename = fileURLToPath(import.meta.url);
-// const __dirname = path.dirname(__filename);
-
-app.whenReady().then(() => {
- console.log('[MinimalMain E2E] App ready, creating window...');
- const win = new BrowserWindow({
- show: false,
- webPreferences: {
- nodeIntegration: false, // Default and good practice
- contextIsolation: true, // Default and good practice
- sandbox: false, // Matching your app's setting for now
- // preload: path.join(__dirname, '../packages/preload/dist/index.cjs'), // Path using __dirname
- preload: '/Users/wings/projects/flagship/packages/preload/dist/index.cjs', // Hardcoded absolute path
- },
- });
-
- win.webContents.on('did-finish-load', () => {
- console.log('[MinimalMain E2E] Window finished loading content (about:blank).');
- });
-
- win.webContents.on('console-message', (event, level, message, line, sourceId) => {
- console.log(`[MinimalMain E2E - Renderer Console] ${message} (Source: ${sourceId}:${line})`);
- });
-
- win.on('ready-to-show', () => {
- console.log('[MinimalMain E2E] Window ready-to-show, showing window.');
- win.show();
- });
-
- win.loadURL('about:blank');
- console.log('[MinimalMain E2E] Window created, loadURL(\'about:blank\') called.');
-});
-
-app.on('window-all-closed', () => {
- console.log('[MinimalMain E2E] All windows closed.');
- if (process.platform !== 'darwin') {
- app.quit();
- }
-});
-
-app.on('quit', () => {
- console.log('[MinimalMain E2E] App quitting.');
-});
diff --git a/tests/prod-server-benchmark.spec.ts b/tests/prod-server-benchmark.spec.ts
deleted file mode 100644
index 1a399959..00000000
--- a/tests/prod-server-benchmark.spec.ts
+++ /dev/null
@@ -1,284 +0,0 @@
-import { test, expect } from 'vitest';
-import { chromium } from 'playwright';
-
-interface LoadingMetrics {
- startTime: number;
- totalLoadTime: number;
- hadFeaturedContent: boolean;
- hadNoFeaturedMessage: boolean;
- hadLoadingSpinner: boolean;
- stuckInLoading: boolean;
- errorCount: number;
- peerbitConnected: boolean;
-}
-
-const BENCHMARK_RUNS = 3;
-const DEV_SERVER_URL = 'https://pb.riff.cc'; // Default Vite dev server port
-
-test('Dev Server Loading Benchmark - REAL CONDITIONS', async () => {
- console.log('š Starting REAL Loading Benchmark');
- console.log(`Testing against: ${DEV_SERVER_URL}`);
- console.log(`Running ${BENCHMARK_RUNS} iterations to measure ACTUAL load performance`);
- console.log('ā ļø Make sure dev server is running: pnpm watch:web');
-
- const results: LoadingMetrics[] = [];
-
- // Test if dev server is available
- try {
- const testBrowser = await chromium.launch({ headless: true });
- const testPage = await testBrowser.newPage();
- await testPage.goto(DEV_SERVER_URL, { timeout: 5000 });
- await testBrowser.close();
- console.log('ā
Dev server is accessible');
- } catch (_error) {
- console.error('ā Dev server not accessible. Run: pnpm watch:web');
- throw new Error('Dev server not running. Please start with: pnpm watch:web');
- }
-
- for (let i = 1; i <= BENCHMARK_RUNS; i++) {
- const startTime = Date.now();
- const metrics: LoadingMetrics = {
- startTime,
- totalLoadTime: 0,
- hadFeaturedContent: false,
- hadNoFeaturedMessage: false,
- hadLoadingSpinner: false,
- stuckInLoading: false,
- errorCount: 0,
- peerbitConnected: false,
- };
-
- const browser = await chromium.launch({ headless: true });
- const page = await browser.newPage();
-
- // Track console logs for Peerbit connection status
- page.on('console', msg => {
- const text = msg.text();
- if (msg.type() === 'error') {
- // BLOCKLIST: Ignore expected P2P/networking errors that are normal
- const ignoredErrors = [
- 'ws://127.0.0.1:', 'ERR_CONNECTION_REFUSED', // Peer advertising local addresses
- 'mdi-', 'Expected number', // MDI icon loading issues
- 'lazystream', 'UnexpectedEOFError', // P2P stream errors
- 'unexpected end of input', // Network/stream termination
- 'outbound inflight queue error', // P2P queue errors
- 'WebSocket connection', // WebSocket connection issues
- 'net::ERR_', 'Failed to load resource', // General network errors
- ];
-
- if (ignoredErrors.some(ignored => text.includes(ignored))) {
- return; // These are expected in P2P environment
- }
-
- metrics.errorCount++;
- console.log(`Run ${i} Console Error: ${text}`);
- }
-
- // Check for Peerbit connection indicators
- if (text.includes('peer') || text.includes('Peerbit') || text.includes('connected') || text.includes('node')) {
- console.log(`Run ${i} Peerbit Activity: ${text}`);
- if (text.includes('connected') || text.includes('ready')) {
- metrics.peerbitConnected = true;
- }
- }
- });
-
- try {
- console.log(`Run ${i}: Starting...`);
-
- // Navigate to the app
- await page.goto(DEV_SERVER_URL, { waitUntil: 'domcontentloaded' });
-
- // Wait for #app to be visible - this should be immediate now
- const appStart = Date.now();
- await page.waitForSelector('#app', { state: 'visible', timeout: 8000 });
- const appLoadTime = Date.now() - appStart;
- console.log(`Run ${i}: #app visible in ${appLoadTime}ms`);
-
- // Check for loading spinner at multiple points
- let foundLoadingSpinner = false;
-
- // Check immediately after app loads
- const initialLoadingSpinner = await page.$('[data-testid="loading"], .v-progress-circular');
- if (initialLoadingSpinner) {
- foundLoadingSpinner = true;
- metrics.hadLoadingSpinner = true;
- console.log(`Run ${i}: Loading spinner detected initially`);
- }
-
- // Also check after a short delay (in case it appears after Vue renders)
- await page.waitForTimeout(100);
- const delayedLoadingSpinner = await page.$('[data-testid="loading"], .v-progress-circular');
- if (delayedLoadingSpinner && !foundLoadingSpinner) {
- foundLoadingSpinner = true;
- metrics.hadLoadingSpinner = true;
- console.log(`Run ${i}: Loading spinner detected after delay`);
- }
-
- if (foundLoadingSpinner) {
- // Wait up to 15 seconds to see if it resolves
- try {
- await page.waitForSelector('[data-testid="loading"], .v-progress-circular', { state: 'hidden', timeout: 15000 });
- console.log(`Run ${i}: Loading spinner resolved`);
- } catch {
- metrics.stuckInLoading = true;
- console.log(`Run ${i}: STUCK IN LOADING STATE`);
- }
- } else {
- console.log(`Run ${i}: No loading spinner detected`);
- }
-
- // Wait longer for content to potentially appear (Peerbit can be slow)
- await page.waitForTimeout(5000);
-
- // Check for featured content with much broader selectors
- const featuredContentSelectors = [
- '[data-testid="featured-content"]',
- '.featured-content',
- '.release-card',
- '.content-card',
- '.v-card', // Vuetify cards
- '.featured-slider',
- '.content-section',
- 'img[src*="mock"]', // Mock images from static data
- 'img[src*="bafkrei"]', // IPFS images
- '.v-container .v-sheet:not([data-testid="loading"])', // Content containers
- 'h1, h2, h3', // Any headings that might indicate content
- ];
-
- let foundContent = false;
- for (const selector of featuredContentSelectors) {
- const elements = await page.$$(selector);
- if (elements.length > 0) {
- foundContent = true;
- console.log(`Run ${i}: ā
Found content with selector "${selector}" (${elements.length} items)`);
- break;
- }
- }
-
- if (foundContent) {
- metrics.hadFeaturedContent = true;
- }
-
- // Check for "No featured content" message with broader detection
- const noContentSelectors = [
- '[data-testid="no-featured-content"]',
- 'text="No featured content yet"',
- 'text="No content here"',
- ':text("No featured content")',
- ':text("No content")',
- ];
-
- for (const selector of noContentSelectors) {
- try {
- const element = await page.$(selector);
- if (element) {
- metrics.hadNoFeaturedMessage = true;
- console.log(`Run ${i}: ā ļø "No featured content" message found with selector "${selector}"`);
- break;
- }
- } catch (_e) {
- // Ignore errors from text selectors
- }
- }
-
- // Debug: Log page content to understand what's actually rendered
- const appContent = await page.textContent('#app');
- const hasLoadingText = appContent?.includes('Loading') || false;
- const hasContentText = appContent?.includes('Featured') || appContent?.includes('Music') || appContent?.includes('Movies') || false;
- console.log(`Run ${i}: Page text includes Loading: ${hasLoadingText}, Content keywords: ${hasContentText}`);
-
- // Take screenshots for all runs to debug
- await page.screenshot({ path: `/tmp/dev-benchmark-run-${i}.png`, fullPage: true });
-
- } catch (_error) {
- console.log(`Run ${i} ā FAILED:`, _error.message);
- metrics.errorCount++;
- } finally {
- metrics.totalLoadTime = Date.now() - startTime;
- await browser.close();
- }
-
- results.push(metrics);
-
- const status = metrics.hadFeaturedContent ? 'ā
SUCCESS' :
- metrics.stuckInLoading ? 'š STUCK' :
- metrics.hadNoFeaturedMessage ? 'ā ļø NO CONTENT' : 'ā FAILED';
-
- console.log(`Run ${i}: ${metrics.totalLoadTime}ms ${status} (errors: ${metrics.errorCount})`);
-
- // Small delay between runs
- await new Promise(resolve => setTimeout(resolve, 1000));
- }
-
- // Calculate statistics
- const loadTimes = results.map(r => r.totalLoadTime);
- const successfulRuns = results.filter(r => r.hadFeaturedContent);
- const stuckRuns = results.filter(r => r.stuckInLoading);
- const noContentRuns = results.filter(r => r.hadNoFeaturedMessage);
- const peerbitConnectedRuns = results.filter(r => r.peerbitConnected);
-
- console.log('\nš REAL PERFORMANCE RESULTS:');
- console.log(`Total runs: ${results.length}`);
- console.log(`Min load time: ${Math.min(...loadTimes)}ms`);
- console.log(`Max load time: ${Math.max(...loadTimes)}ms`);
- console.log(`Avg load time: ${(loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length).toFixed(1)}ms`);
-
- console.log('\nšÆ SUCCESS RATES:');
- console.log(`ā
Featured content loaded: ${successfulRuns.length}/${results.length} (${((successfulRuns.length / results.length) * 100).toFixed(1)}%)`);
- console.log(`š Stuck in loading: ${stuckRuns.length}/${results.length} (${((stuckRuns.length / results.length) * 100).toFixed(1)}%)`);
- console.log(`ā ļø "No content" message: ${noContentRuns.length}/${results.length} (${((noContentRuns.length / results.length) * 100).toFixed(1)}%)`);
- console.log(`š Peerbit connected: ${peerbitConnectedRuns.length}/${results.length} (${((peerbitConnectedRuns.length / results.length) * 100).toFixed(1)}%)`);
-
- const totalErrors = results.reduce((sum, r) => sum + r.errorCount, 0);
- console.log(`ā Total console errors: ${totalErrors}`);
-
- // Race condition analysis
- const raceConditionIndicators = {
- inconsistentResults: new Set([successfulRuns.length, stuckRuns.length, noContentRuns.length]).size > 1,
- lowSuccessRate: (successfulRuns.length / results.length) < 0.8,
- highStuckRate: (stuckRuns.length / results.length) > 0.2,
- peerbitConnectionIssues: (peerbitConnectedRuns.length / results.length) < 0.8,
- };
-
- console.log('\nš RACE CONDITION ANALYSIS:');
- Object.entries(raceConditionIndicators).forEach(([key, value]) => {
- const icon = value ? 'ā' : 'ā
';
- console.log(`${icon} ${key}: ${value}`);
- });
-
- // Log baseline results for comparison
- const baselineResults = {
- timestamp: new Date().toISOString(),
- version: 'baseline-before-optimization',
- testType: 'dev-server-real-conditions',
- summary: {
- totalRuns: results.length,
- successRate: (successfulRuns.length / results.length) * 100,
- stuckInLoadingRate: (stuckRuns.length / results.length) * 100,
- noContentMessageRate: (noContentRuns.length / results.length) * 100,
- peerbitConnectionRate: (peerbitConnectedRuns.length / results.length) * 100,
- minLoadTime: Math.min(...loadTimes),
- maxLoadTime: Math.max(...loadTimes),
- avgLoadTime: loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length,
- totalErrors: totalErrors,
- raceConditionDetected: Object.values(raceConditionIndicators).some(Boolean),
- },
- runs: results,
- };
-
- console.log('\nš¾ BASELINE RESULTS:');
- console.log(JSON.stringify(baselineResults, null, 2));
-
- // Validate that we got real data
- expect(results.length).toBe(BENCHMARK_RUNS);
-
- // This test should demonstrate the race condition - if success rate is too low, we have a problem
- if ((successfulRuns.length / results.length) < 0.5) {
- console.log('\nšØ RACE CONDITION CONFIRMED: Success rate below 50%');
- }
-
- // Don't fail the test - we want to see the real numbers
- console.log('\nā
Benchmark completed - data collected for optimization');
-
-}, 600000); // 10 minute timeout
diff --git a/tests/simple-benchmark.spec.ts b/tests/simple-benchmark.spec.ts
deleted file mode 100644
index 8a225efc..00000000
--- a/tests/simple-benchmark.spec.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-import { test, expect } from 'vitest';
-import { chromium } from 'playwright';
-import path, { dirname } from 'path';
-import { fileURLToPath } from 'url';
-
-interface LoadingMetrics {
- startTime: number;
- totalLoadTime: number;
- hadFeaturedContent: boolean;
- hadNoFeaturedMessage: boolean;
- errorCount: number;
-}
-
-const BENCHMARK_RUNS = 10;
-
-test('Simple Loading Benchmark', async () => {
- console.log('š Starting Simple Loading Benchmark');
- console.log(`Running ${BENCHMARK_RUNS} iterations to measure load performance`);
-
- const results: LoadingMetrics[] = [];
-
- for (let i = 1; i <= BENCHMARK_RUNS; i++) {
- const startTime = Date.now();
- const metrics: LoadingMetrics = {
- startTime,
- totalLoadTime: 0,
- hadFeaturedContent: false,
- hadNoFeaturedMessage: false,
- errorCount: 0,
- };
-
- const browser = await chromium.launch({ headless: true });
- const page = await browser.newPage();
-
- // Track console errors
- page.on('console', msg => {
- if (msg.type() === 'error') {
- metrics.errorCount++;
- console.log(`Run ${i} Console Error: ${msg.text()}`);
- }
- });
-
- try {
- // Navigate to the built web app
- const __dirname_test = dirname(fileURLToPath(import.meta.url));
- const htmlFile = path.join(__dirname_test, '..', 'packages', 'renderer', 'dist', 'web', 'index.html');
-
- await page.goto(`file://${htmlFile}`);
-
- // Wait for #app to exist (but not necessarily be visible)
- await page.waitForSelector('#app', { timeout: 15000 });
-
- // Wait a bit for the app to initialize
- await page.waitForTimeout(2000);
-
- // Check for various states
- try {
- // Check for featured content
- const featuredContent = await page.$$('[data-testid="featured-content"], .featured-content, .release-card');
- if (featuredContent.length > 0) {
- metrics.hadFeaturedContent = true;
- }
-
- // Check for "No featured content" message
- const noContentMessage = await page.$('[data-testid="no-featured-content"]');
- if (noContentMessage) {
- metrics.hadNoFeaturedMessage = true;
- }
-
- // Take a screenshot for debugging the first few runs
- if (i <= 3) {
- await page.screenshot({ path: `/tmp/benchmark-run-${i}.png` });
- }
-
- } catch (error) {
- console.log(`Run ${i} content check failed:`, error);
- metrics.errorCount++;
- }
-
- } catch (error) {
- console.log(`Run ${i} failed:`, error);
- metrics.errorCount++;
- } finally {
- metrics.totalLoadTime = Date.now() - startTime;
- await browser.close();
- }
-
- results.push(metrics);
- console.log(`Run ${i}: ${metrics.totalLoadTime}ms, featured=${metrics.hadFeaturedContent}, noMessage=${metrics.hadNoFeaturedMessage}, errors=${metrics.errorCount}`);
- }
-
- // Calculate statistics
- const loadTimes = results.map(r => r.totalLoadTime);
- const successfulRuns = results.filter(r => r.errorCount === 0);
- const runsWithFeaturedContent = results.filter(r => r.hadFeaturedContent);
- const runsWithNoContentMessage = results.filter(r => r.hadNoFeaturedMessage);
-
- console.log('\nš BENCHMARK RESULTS:');
- console.log(`Total runs: ${results.length}`);
- console.log(`Success rate: ${((successfulRuns.length / results.length) * 100).toFixed(1)}%`);
- console.log(`Min load time: ${Math.min(...loadTimes)}ms`);
- console.log(`Max load time: ${Math.max(...loadTimes)}ms`);
- console.log(`Avg load time: ${(loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length).toFixed(1)}ms`);
- console.log(`Runs with featured content: ${runsWithFeaturedContent.length}/${results.length} (${((runsWithFeaturedContent.length / results.length) * 100).toFixed(1)}%)`);
- console.log(`Runs with "no featured content" message: ${runsWithNoContentMessage.length}/${results.length} (${((runsWithNoContentMessage.length / results.length) * 100).toFixed(1)}%)`);
-
- const totalErrors = results.reduce((sum, r) => sum + r.errorCount, 0);
- console.log(`Total console errors: ${totalErrors}`);
-
- // Log baseline results
- const baselineResults = {
- timestamp: new Date().toISOString(),
- version: 'baseline-before-optimization',
- summary: {
- totalRuns: results.length,
- successRate: (successfulRuns.length / results.length) * 100,
- minLoadTime: Math.min(...loadTimes),
- maxLoadTime: Math.max(...loadTimes),
- avgLoadTime: loadTimes.reduce((a, b) => a + b, 0) / loadTimes.length,
- featuredContentRate: (runsWithFeaturedContent.length / results.length) * 100,
- noContentMessageRate: (runsWithNoContentMessage.length / results.length) * 100,
- totalErrors: totalErrors,
- },
- runs: results,
- };
-
- console.log('\nš¾ BASELINE RESULTS (save this for comparison):');
- console.log(JSON.stringify(baselineResults, null, 2));
-
- // Basic expectations to validate the benchmark works
- expect(results.length).toBe(BENCHMARK_RUNS);
- expect(successfulRuns.length).toBeGreaterThan(0);
-}, { timeout: 180000 });
\ No newline at end of file
diff --git a/tests/timing-benchmark.spec.ts b/tests/timing-benchmark.spec.ts
deleted file mode 100644
index 97d2b8b9..00000000
--- a/tests/timing-benchmark.spec.ts
+++ /dev/null
@@ -1,108 +0,0 @@
-import { test } from 'vitest';
-import { chromium } from 'playwright';
-
-test('Timing Analysis - Where is the 3 seconds?', async () => {
- const browser = await chromium.launch({ headless: true });
- const page = await browser.newPage();
-
- const timings: Record = {};
- let lastMilestone = Date.now();
-
- const mark = (name: string) => {
- const now = Date.now();
- timings[name] = now - lastMilestone;
- lastMilestone = now;
- };
-
- // Track important console logs
- const logs: Array<{time: number, text: string}> = [];
- const testStart = Date.now();
-
- page.on('console', msg => {
- const text = msg.text();
- if (text.includes('bootstrap') || text.includes('Connected') ||
- text.includes('Debug') || text.includes('stage')) {
- logs.push({
- time: Date.now() - testStart,
- text: text.substring(0, 100),
- });
- }
- });
-
- try {
- // Initial navigation
- await page.goto('http://localhost:5175');
- mark('1_initial_load');
-
- // Wait for Vue app
- await page.waitForSelector('#app');
- mark('2_app_visible');
-
- // Check what's in the app initially
- let appContent = await page.textContent('#app');
- console.log('Initial app content:', appContent?.substring(0, 50) + '...');
-
- // Wait for loading to complete (either content or "no content" message)
- const waitStart = Date.now();
- let iterations = 0;
- let foundContent = false;
-
- while (Date.now() - waitStart < 5000 && !foundContent) {
- iterations++;
- appContent = await page.textContent('#app');
-
- if (appContent?.includes('Featured') ||
- appContent?.includes('No featured content') ||
- appContent?.includes('Movies')) {
- foundContent = true;
- break;
- }
-
- // Check for spinner
- const hasSpinner = await page.$('.v-progress-circular') !== null;
- if (iterations === 1 && hasSpinner) {
- console.log('Loading spinner present');
- }
-
- await page.waitForTimeout(100);
- }
-
- mark('3_content_appears');
-
- console.log(`Content found after ${iterations} checks (${iterations * 100}ms)`);
- console.log('Final content preview:', appContent?.substring(0, 100) + '...');
-
- // Print timing breakdown
- console.log('\nā±ļø TIMING BREAKDOWN:');
- let total = 0;
- Object.entries(timings).forEach(([name, time]) => {
- console.log(`${name}: ${time}ms`);
- total += time;
- });
- console.log(`TOTAL: ${total}ms`);
-
- // Print console logs timeline
- if (logs.length > 0) {
- console.log('\nš Console Timeline:');
- logs.forEach(log => {
- console.log(`[${log.time}ms] ${log.text}`);
- });
- }
-
- // Check network activity
- const metrics = await page.evaluate(() => {
- const perf = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
- return {
- domContentLoaded: Math.round(perf.domContentLoadedEventEnd - perf.fetchStart),
- loadComplete: Math.round(perf.loadEventEnd - perf.fetchStart),
- };
- });
-
- console.log('\nš Page Load Metrics:');
- console.log(`DOM Content Loaded: ${metrics.domContentLoaded}ms`);
- console.log(`Load Event Complete: ${metrics.loadComplete}ms`);
-
- } finally {
- await browser.close();
- }
-});
\ No newline at end of file
diff --git a/tests/timing-with-site-logs.spec.ts b/tests/timing-with-site-logs.spec.ts
deleted file mode 100644
index dd676f78..00000000
--- a/tests/timing-with-site-logs.spec.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { test } from 'vitest';
-import { chromium } from 'playwright';
-
-test('Capture Site.open timing', async () => {
- const browser = await chromium.launch({ headless: true });
- const page = await browser.newPage();
-
- const logs: Array<{time: number, text: string}> = [];
- const testStart = Date.now();
-
- // Capture ALL console logs
- page.on('console', msg => {
- logs.push({
- time: Date.now() - testStart,
- text: msg.text(),
- });
- });
-
- try {
- await page.goto('http://localhost:5175');
-
- // Wait for content
- await page.waitForFunction(() => {
- const app = document.querySelector('#app');
- const text = app?.textContent || '';
- return text.includes('Featured') || text.includes('No featured content') || text.includes('Movies');
- }, { timeout: 5000 });
-
- const totalTime = Date.now() - testStart;
-
- console.log(`\nā±ļø TOTAL LOAD TIME: ${totalTime}ms\n`);
-
- // Print all logs with Site.open timing
- console.log('š Full Console Timeline:');
- logs.forEach(log => {
- console.log(`[${log.time}ms] ${log.text}`);
- });
-
- } finally {
- await browser.close();
- }
-});
\ No newline at end of file
diff --git a/tests/ui-debug-investigation.spec.ts b/tests/ui-debug-investigation.spec.ts
deleted file mode 100644
index fac7bba0..00000000
--- a/tests/ui-debug-investigation.spec.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import type {Browser, Page, ElectronApplication} from 'playwright';
-import {afterAll, beforeAll, describe, expect, test} from 'vitest';
-import {onBrowser} from './utils';
-
-describe('UI Debug Investigation - Detailed Logging', function () {
- let browser: Browser | undefined = undefined;
- const electronApp: ElectronApplication | undefined = undefined;
- let page: Page;
-
- beforeAll(async () => {
- const result = await onBrowser({ typeNavigateur: 'chromium' });
- page = result.page;
- browser = result.browser;
- });
-
- afterAll(async () => {
- if (electronApp) {
- await electronApp.close();
- } else if (browser) {
- await browser.close();
- }
- });
-
- test('Debug Vue component logging', async () => {
- console.log('š Starting UI Debug Investigation');
-
- // Capture console logs
- const consoleLogs: string[] = [];
- page.on('console', msg => {
- const text = msg.text();
- if (text.includes('[HomePage Debug]')) {
- consoleLogs.push(`${msg.type()}: ${text}`);
- console.log(`š ${msg.type()}: ${text}`);
- }
- });
-
- // Start timing
- const startTime = Date.now();
-
- console.log('š Navigating to homepage...');
- await page.goto('http://localhost:5175', {
- waitUntil: 'domcontentloaded',
- timeout: 30000,
- });
-
- // Wait for initial render
- await page.waitForSelector('#app', { timeout: 5000 });
- console.log('š± App element found');
-
- // Wait a bit for Vue to initialize and logs to start
- await page.waitForTimeout(2000);
-
- // Check loading states
- const isLoadingVisible = await page.isVisible('[data-testid="loading"]');
- console.log(`š Loading spinner visible: ${isLoadingVisible}`);
-
- // Wait for content or timeout
- console.log('ā³ Waiting for content to load...');
-
- let finalState = 'unknown';
- try {
- // Wait for either content or no-content message
- await Promise.race([
- page.waitForSelector('[data-testid="featured-content"]', { timeout: 25000 }),
- page.waitForSelector('[data-testid="no-featured-content"]', { timeout: 25000 }),
- ]);
-
- const hasFeaturedContent = await page.isVisible('[data-testid="featured-content"]');
- const hasNoContentMessage = await page.isVisible('[data-testid="no-featured-content"]');
- const isStillLoading = await page.isVisible('[data-testid="loading"]');
-
- if (hasFeaturedContent) {
- finalState = 'featured-content-visible';
- } else if (hasNoContentMessage) {
- finalState = 'no-content-message-visible';
- } else if (isStillLoading) {
- finalState = 'stuck-in-loading';
- }
-
- console.log(`šÆ Final state: ${finalState}`);
- console.log(`š Loading visible: ${isStillLoading}`);
- console.log(`ā
Featured content visible: ${hasFeaturedContent}`);
- console.log(`ā No content message visible: ${hasNoContentMessage}`);
-
- } catch (error) {
- console.log(`ā ļø Timeout waiting for content: ${error}`);
- finalState = 'timeout';
- }
-
- const totalTime = Date.now() - startTime;
- console.log(`ā±ļø Total time: ${totalTime}ms`);
-
- // Summary of debug logs
- console.log(`š Debug logs captured: ${consoleLogs.length}`);
-
- if (consoleLogs.length === 0) {
- console.log('ā NO DEBUG LOGS CAPTURED - Vue component may not be logging');
- } else {
- console.log('ā
Debug logs found:');
- consoleLogs.forEach(log => console.log(` ${log}`));
- }
-
- // Always pass to see the results
- expect(true).toBe(true);
- });
-});
\ No newline at end of file
diff --git a/packages/renderer/src/utils.spec.ts b/tests/unit/utils.spec.ts
similarity index 93%
rename from packages/renderer/src/utils.spec.ts
rename to tests/unit/utils.spec.ts
index 57d2d613..6ab98de0 100644
--- a/packages/renderer/src/utils.spec.ts
+++ b/tests/unit/utils.spec.ts
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
-import { formatTime } from './utils';
+import { formatTime } from '../../packages/renderer/src/utils';
describe('formatTime', () => {
it('should format milliseconds to HH:MM:SS or MM:SS', () => {
@@ -21,4 +21,4 @@ describe('formatTime', () => {
expect(formatTime(5 * 60 * 1000)).toBe('05:00'); // 5 minutes
expect(formatTime(5 * 60 * 60 * 1000)).toBe('05:00:00'); // 5 hours
});
-});
\ No newline at end of file
+});
diff --git a/tests/utils.ts b/tests/utils.ts
index 684ac36c..dc75bb10 100644
--- a/tests/utils.ts
+++ b/tests/utils.ts
@@ -1,5 +1,5 @@
-import type {Browser, Page, ElectronApplication} from 'playwright';
-import {_electron as electron, chromium, firefox, webkit} from 'playwright';
+import type {Browser, Page, ElectronApplication} from '@playwright/test';
+import {_electron as electron, chromium, firefox, webkit} from '@playwright/test';
import path, {dirname} from 'path';
import {fileURLToPath} from 'url';
@@ -18,16 +18,16 @@ export const onBrowser = async ({
const __dirname = dirname(fileURLToPath(import.meta.url));
const projectRoot = path.join(__dirname, '..'); // Assumes utils.ts is in tests/ subdir of project root
console.log(`[E2E Utils] Electron project root for CWD: ${projectRoot}`);
-
- const electronApp = await electron.launch({
+
+ const electronApp = await electron.launch({
args: ['packages/main/dist/index.js'],
cwd: projectRoot,
- env: {
- ...process.env,
+ env: {
+ ...process.env,
NODE_ENV: 'production',
- NODE_OPTIONS: '',
- ELECTRON_ENABLE_LOGGING: 'false',
- ELECTRON_ENABLE_STACK_DUMPING: 'false',
+ NODE_OPTIONS: '',
+ ELECTRON_ENABLE_LOGGING: 'false',
+ ELECTRON_ENABLE_STACK_DUMPING: 'false',
},
});
console.log('[E2E Utils] Electron app launched with original main.js. Waiting for first window...');
diff --git a/vitest.config.js b/vitest.config.js
index de85d9d6..e43bb126 100644
--- a/vitest.config.js
+++ b/vitest.config.js
@@ -1,23 +1,14 @@
-/**
- * Configuration for the global end-to-end testing,
- * placed in the project's root 'tests' folder.
- * @type {import('vite').UserConfig}
- * @see https://vitest.dev/config/
- */
-const config = {
- test: {
- /**
- * By default, vitest searches for the test files in all packages.
- * For e2e tests, have vitest search only in the project root 'tests' folder.
- */
- include: ['./tests/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
+// vite.config.ts
+import { defineConfig } from 'vite';
+import vue from '@vitejs/plugin-vue';
- /**
- * The default timeout of 5000ms is sometimes not enough for playwright.
- */
- testTimeout: 30_000,
- hookTimeout: 30_000,
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [vue()],
+ // Add this 'test' property
+ test: {
+ globals: true,
+ environment: 'happy-dom',
+ exclude: ['**/node_modules/**', '**/dist/**', 'tests/e2e/**'],
},
-};
-
-export default config;
+});
From cdfee35105724e1364372794c3d52b066273df3b Mon Sep 17 00:00:00 2001
From: benya7
Date: Thu, 31 Jul 2025 21:55:52 +0200
Subject: [PATCH 10/11] fix: formatTime util
---
packages/renderer/src/utils.ts | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/packages/renderer/src/utils.ts b/packages/renderer/src/utils.ts
index aab0dd24..11d26e23 100644
--- a/packages/renderer/src/utils.ts
+++ b/packages/renderer/src/utils.ts
@@ -41,18 +41,14 @@ export async function copyText(text: string | undefined) {
}
export const formatTime = (ms: number): string => {
- if (ms === 0 || !Number.isFinite(ms)) {
+ if (ms === 0 || isNaN(ms)) {
return '00:00';
}
- const duration = Duration.fromMillis(ms);
+ const duration = Duration.fromObject({ seconds: ms });
const hours = duration.as('hours');
- if (hours >= 1) {
- return duration.toFormat('hh:mm:ss');
- } else {
- return duration.toFormat('mm:ss');
- }
+ return (hours >= 1) ? duration.toFormat('hh:mm:ss') : duration.toFormat('mm:ss');
};
// Colors
@@ -60,7 +56,6 @@ export const lensColorHash = (siteAddress: string): string => {
console.log('#' + CID.parse(siteAddress).toString(base16.encoder));
return '#' + CID.parse(siteAddress).toString(base16.encoder).slice(-6);
};
-
// export function getStatusColor(status: ItemStatus) {
// if (status === 'pending') {
// return 'blue';
From 050b12ca098ed736687f61e231b3b1604a535347 Mon Sep 17 00:00:00 2001
From: benya7
Date: Thu, 31 Jul 2025 22:00:58 +0200
Subject: [PATCH 11/11] fix: actions
---
.github/workflows/ci.yml | 21 ++-------------------
1 file changed, 2 insertions(+), 19 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9cbe6e3c..b7370610 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,13 +1,11 @@
name: Continuous Integration
-# This workflow runs on pushes to the main branch and on any pull request.
on:
push:
branches:
- main
pull_request:
-# Ensures that only the latest commit for a branch/PR gets run.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
@@ -15,7 +13,6 @@ concurrency:
jobs:
# ----------------------------------------------------
# Job 1: Quick checks (Linting & Type-checking)
- # This job runs first. It's fast and provides quick feedback.
# ----------------------------------------------------
quality_checks:
name: Lint & Type-Check
@@ -25,19 +22,17 @@ jobs:
uses: actions/checkout@v4
- name: Setup pnpm
+ # The action will automatically use the version from package.json
uses: pnpm/action-setup@v4
- with:
- version: latest
- name: Setup Node.js
uses: actions/setup-node@v4
with:
- node-version: '20' # Specify a Node.js version
+ node-version: '20'
cache: 'pnpm'
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- # We skip downloading browsers here because this job doesn't need them.
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
@@ -49,7 +44,6 @@ jobs:
# ----------------------------------------------------
# Job 2: Unit Tests
- # This runs in parallel with quality_checks. It's also fast.
# ----------------------------------------------------
unit_tests:
name: Unit Tests
@@ -60,8 +54,6 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
- with:
- version: latest
- name: Setup Node.js
uses: actions/setup-node@v4
@@ -79,12 +71,9 @@ jobs:
# ----------------------------------------------------
# Job 3: End-to-End Tests
- # This is the most comprehensive job. It builds the app and then runs Playwright tests.
- # It depends on the faster jobs to ensure we don't waste time if basic checks fail.
# ----------------------------------------------------
e2e_tests:
name: Build & E2E Tests
- # This job will only start if the quality_checks and unit_tests jobs succeed.
needs: [quality_checks, unit_tests]
runs-on: ubuntu-latest
steps:
@@ -93,8 +82,6 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
- with:
- version: latest
- name: Setup Node.js
uses: actions/setup-node@v4
@@ -106,21 +93,17 @@ jobs:
run: pnpm install --frozen-lockfile
- name: Install Playwright Browsers
- # This command specifically downloads the browser binaries needed for Playwright.
run: pnpm exec playwright install --with-deps
- name: Build Web Application
run: pnpm run build
- name: Run E2E Tests
- # We start the preview server in the background (&) and then run Playwright.
- # This simulates the local testing environment.
run: |
pnpm run preview &
pnpm run test:e2e
- name: Upload Test Report
- # This step runs only if the E2E tests fail, to help with debugging.
if: failure()
uses: actions/upload-artifact@v4
with: