mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
fix(pubsub): repair browser pure p2p publishing
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
diff --git a/dist/browser/helia/helia-for-pkc.js b/dist/browser/helia/helia-for-pkc.js
|
diff --git a/dist/browser/helia/helia-for-pkc.js b/dist/browser/helia/helia-for-pkc.js
|
||||||
index e6821667b0601ac56a850e989bfedf76c14796a2..1a2ae7ab9b0afc605c9b4dcddccf25ac02aa1337 100644
|
index e6821667b0601ac56a850e989bfedf76c14796a2..87d84a502bdbf72b8cf22b7a8ac6bd68e542c611 100644
|
||||||
--- a/dist/browser/helia/helia-for-pkc.js
|
--- a/dist/browser/helia/helia-for-pkc.js
|
||||||
+++ b/dist/browser/helia/helia-for-pkc.js
|
+++ b/dist/browser/helia/helia-for-pkc.js
|
||||||
@@ -145,6 +145,11 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
@@ -145,6 +145,11 @@ export async function createLibp2pJsClientOrUseExistingOne(pkcOptions) {
|
||||||
@@ -45,7 +45,7 @@ index e6821667b0601ac56a850e989bfedf76c14796a2..1a2ae7ab9b0afc605c9b4dcddccf25ac
|
|||||||
unsubscribe: async (topic, handler, options) => {
|
unsubscribe: async (topic, handler, options) => {
|
||||||
throwIfHeliaIsStoppingOrStopped();
|
throwIfHeliaIsStoppingOrStopped();
|
||||||
diff --git a/dist/browser/publications/publication.js b/dist/browser/publications/publication.js
|
diff --git a/dist/browser/publications/publication.js b/dist/browser/publications/publication.js
|
||||||
index 5e17c02a39c2715c7ac932695fe90d5078bce405..2d43d996e2b3cdab759e89c296eb9ed8aae857db 100644
|
index 5e17c02a39c2715c7ac932695fe90d5078bce405..8c61955ee6ef6dd353e57584b4aaf745e143f6d4 100644
|
||||||
--- a/dist/browser/publications/publication.js
|
--- a/dist/browser/publications/publication.js
|
||||||
+++ b/dist/browser/publications/publication.js
|
+++ b/dist/browser/publications/publication.js
|
||||||
@@ -842,8 +842,14 @@ class Publication extends TypedEmitter {
|
@@ -842,8 +842,14 @@ class Publication extends TypedEmitter {
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ const testState = vi.hoisted(() => ({
|
|||||||
isMobile: false,
|
isMobile: false,
|
||||||
isSpecialEnabled: false,
|
isSpecialEnabled: false,
|
||||||
shouldShowSnow: true,
|
shouldShowSnow: true,
|
||||||
|
createAccountMock: vi.fn().mockResolvedValue(undefined),
|
||||||
removeSnowMock: vi.fn(),
|
removeSnowMock: vi.fn(),
|
||||||
|
setAccountMock: vi.fn().mockResolvedValue(undefined),
|
||||||
replyModalState: {
|
replyModalState: {
|
||||||
activeCid: null,
|
activeCid: null,
|
||||||
closeModal: vi.fn(),
|
closeModal: vi.fn(),
|
||||||
@@ -49,7 +51,10 @@ const testState = vi.hoisted(() => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
vi.mock('@bitsocial/bitsocial-react-hooks', () => ({
|
vi.mock('@bitsocial/bitsocial-react-hooks', () => ({
|
||||||
|
createAccount: () => testState.createAccountMock(),
|
||||||
|
setAccount: (account: unknown) => testState.setAccountMock(account),
|
||||||
useAccount: () => testState.account,
|
useAccount: () => testState.account,
|
||||||
|
useAccounts: () => ({ accounts: testState.account ? [testState.account] : [] }),
|
||||||
useAccountComment: ({ commentIndex }: { commentIndex?: number }) => (typeof commentIndex === 'number' ? testState.accountComments[commentIndex] : undefined),
|
useAccountComment: ({ commentIndex }: { commentIndex?: number }) => (typeof commentIndex === 'number' ? testState.accountComments[commentIndex] : undefined),
|
||||||
useCommunity: (options?: { communityAddress?: string; community?: { name?: string; publicKey?: string } }) => {
|
useCommunity: (options?: { communityAddress?: string; community?: { name?: string; publicKey?: string } }) => {
|
||||||
const communityAddress = options?.communityAddress ?? options?.community?.name ?? options?.community?.publicKey;
|
const communityAddress = options?.communityAddress ?? options?.community?.name ?? options?.community?.publicKey;
|
||||||
@@ -365,6 +370,8 @@ describe('App', () => {
|
|||||||
testState.isDirectoryCandidate = false;
|
testState.isDirectoryCandidate = false;
|
||||||
testState.communities = {};
|
testState.communities = {};
|
||||||
testState.useThemeMock.mockReset();
|
testState.useThemeMock.mockReset();
|
||||||
|
testState.createAccountMock.mockReset().mockResolvedValue(undefined);
|
||||||
|
testState.setAccountMock.mockReset().mockResolvedValue(undefined);
|
||||||
testState.closeCreateBoardModalMock.mockReset();
|
testState.closeCreateBoardModalMock.mockReset();
|
||||||
testState.initSnowMock.mockReset();
|
testState.initSnowMock.mockReset();
|
||||||
testState.removeSnowMock.mockReset();
|
testState.removeSnowMock.mockReset();
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import useIsMobile from './hooks/use-is-mobile';
|
|||||||
import { useAccountCommunityAddresses } from './hooks/use-account-community-addresses';
|
import { useAccountCommunityAddresses } from './hooks/use-account-community-addresses';
|
||||||
import useTheme from './hooks/use-theme';
|
import useTheme from './hooks/use-theme';
|
||||||
import { useDirectories } from './hooks/use-directories';
|
import { useDirectories } from './hooks/use-directories';
|
||||||
|
import { useBrowserPureP2PAccountUpgrade } from './hooks/use-browser-pure-p2p-account-upgrade';
|
||||||
import { useCommunityIdentifier } from './hooks/use-community-identifiers';
|
import { useCommunityIdentifier } from './hooks/use-community-identifiers';
|
||||||
import { useResolvedCommunityAddress, useResolvedDirectoryBoardPath } from './hooks/use-resolved-community-address';
|
import { useResolvedCommunityAddress, useResolvedDirectoryBoardPath } from './hooks/use-resolved-community-address';
|
||||||
import useSafeAccountComment from './hooks/use-safe-account-comment';
|
import useSafeAccountComment from './hooks/use-safe-account-comment';
|
||||||
@@ -281,6 +282,8 @@ const ModQueueRoute = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
useBrowserPureP2PAccountUpgrade();
|
||||||
|
|
||||||
// Feed routes are always rendered by FeedCacheContainer (Virtuoso used for all modes)
|
// Feed routes are always rendered by FeedCacheContainer (Virtuoso used for all modes)
|
||||||
const boardFeedElement = null;
|
const boardFeedElement = null;
|
||||||
const catalogFeedElement = null;
|
const catalogFeedElement = null;
|
||||||
|
|||||||
Vendored
+1
@@ -1,5 +1,6 @@
|
|||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING?: boolean;
|
||||||
isElectron: boolean;
|
isElectron: boolean;
|
||||||
defaultPkcOptions?: Record<string, unknown>;
|
defaultPkcOptions?: Record<string, unknown>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { createElement } from 'react';
|
||||||
|
import { createRoot, type Root } from 'react-dom/client';
|
||||||
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
|
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
||||||
|
const act = (React as { act?: (cb: () => void | Promise<void>) => void | Promise<void> }).act as (cb: () => void | Promise<void>) => void | Promise<void>;
|
||||||
|
|
||||||
|
const testState = vi.hoisted(() => ({
|
||||||
|
account: undefined as Record<string, any> | undefined,
|
||||||
|
accounts: [] as Record<string, any>[] | undefined,
|
||||||
|
createAccountMock: vi.fn().mockResolvedValue(undefined),
|
||||||
|
setAccountMock: vi.fn().mockResolvedValue(undefined),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock('@bitsocial/bitsocial-react-hooks', () => ({
|
||||||
|
createAccount: () => testState.createAccountMock(),
|
||||||
|
setAccount: (account: unknown) => testState.setAccountMock(account),
|
||||||
|
useAccount: () => testState.account,
|
||||||
|
useAccounts: () => ({ accounts: testState.accounts }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
let container: HTMLDivElement;
|
||||||
|
const originalLocation = window.location;
|
||||||
|
let reloadMock: ReturnType<typeof vi.fn>;
|
||||||
|
let root: Root;
|
||||||
|
|
||||||
|
const loadHook = async () => (await import('../use-browser-pure-p2p-account-upgrade')).useBrowserPureP2PAccountUpgrade;
|
||||||
|
|
||||||
|
const TestComponent = ({ useUpgrade }: { useUpgrade: () => void }) => {
|
||||||
|
useUpgrade();
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderHook = async () => {
|
||||||
|
const useUpgrade = await loadHook();
|
||||||
|
await act(async () => {
|
||||||
|
root.render(createElement(TestComponent, { useUpgrade }));
|
||||||
|
await Promise.resolve();
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('useBrowserPureP2PAccountUpgrade', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.resetModules();
|
||||||
|
vi.clearAllMocks();
|
||||||
|
localStorage.clear();
|
||||||
|
testState.account = undefined;
|
||||||
|
testState.accounts = [];
|
||||||
|
testState.createAccountMock.mockReset().mockResolvedValue(undefined);
|
||||||
|
testState.setAccountMock.mockReset().mockResolvedValue(undefined);
|
||||||
|
reloadMock = vi.fn();
|
||||||
|
Object.defineProperty(window, 'location', {
|
||||||
|
configurable: true,
|
||||||
|
value: {
|
||||||
|
...originalLocation,
|
||||||
|
hostname: '5chan.app',
|
||||||
|
reload: reloadMock,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
window.electronApi = undefined;
|
||||||
|
window.isElectron = false;
|
||||||
|
container = document.createElement('div');
|
||||||
|
document.body.appendChild(container);
|
||||||
|
root = createRoot(container);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.useRealTimers();
|
||||||
|
if (root) {
|
||||||
|
act(() => root.unmount());
|
||||||
|
}
|
||||||
|
container?.remove();
|
||||||
|
Object.defineProperty(window, 'location', {
|
||||||
|
configurable: true,
|
||||||
|
value: originalLocation,
|
||||||
|
});
|
||||||
|
window.BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING = undefined;
|
||||||
|
window.electronApi = undefined;
|
||||||
|
window.isElectron = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('upgrades stale gateway browser accounts and reloads after saving', async () => {
|
||||||
|
testState.account = {
|
||||||
|
id: 'account-1',
|
||||||
|
name: 'Account 1',
|
||||||
|
pkcOptions: {
|
||||||
|
httpRoutersOptions: ['https://router.old.example'],
|
||||||
|
ipfsGatewayUrls: ['https://gateway.old.example'],
|
||||||
|
pubsubKuboRpcClientsOptions: ['https://pubsub.old.example/api/v0'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
testState.accounts = [testState.account];
|
||||||
|
|
||||||
|
await renderHook();
|
||||||
|
|
||||||
|
expect(testState.setAccountMock).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: 'account-1',
|
||||||
|
pkcOptions: expect.objectContaining({
|
||||||
|
ipfsGatewayUrls: undefined,
|
||||||
|
libp2pJsClientsOptions: [{ key: 'libp2pjs' }],
|
||||||
|
pkcRpcClientsOptions: undefined,
|
||||||
|
pubsubKuboRpcClientsOptions: undefined,
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(reloadMock).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not upgrade browser full-node accounts', async () => {
|
||||||
|
testState.account = {
|
||||||
|
id: 'account-1',
|
||||||
|
name: 'Account 1',
|
||||||
|
pkcOptions: {
|
||||||
|
pkcRpcClientsOptions: ['ws://node.example/key'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
testState.accounts = [testState.account];
|
||||||
|
|
||||||
|
await renderHook();
|
||||||
|
|
||||||
|
expect(testState.setAccountMock).not.toHaveBeenCalled();
|
||||||
|
expect(reloadMock).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('recovers a missing browser account after the hooks store finishes initializing', async () => {
|
||||||
|
vi.useFakeTimers();
|
||||||
|
window.BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING = true;
|
||||||
|
|
||||||
|
await renderHook();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
|
});
|
||||||
|
expect(testState.createAccountMock).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
window.BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING = false;
|
||||||
|
await act(async () => {
|
||||||
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(testState.createAccountMock).toHaveBeenCalledOnce();
|
||||||
|
expect(reloadMock).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('treats temporarily missing accounts as empty while recovering', async () => {
|
||||||
|
vi.useFakeTimers();
|
||||||
|
testState.accounts = undefined;
|
||||||
|
window.BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING = false;
|
||||||
|
|
||||||
|
await renderHook();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
await vi.advanceTimersByTimeAsync(1000);
|
||||||
|
await Promise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(testState.createAccountMock).toHaveBeenCalledOnce();
|
||||||
|
expect(reloadMock).toHaveBeenCalledOnce();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { useEffect, useRef } from 'react';
|
||||||
|
import { createAccount, setAccount, useAccount, useAccounts } from '@bitsocial/bitsocial-react-hooks';
|
||||||
|
import { getBrowserPureP2PAccountOptions, shouldUpgradeBrowserPureP2PAccount } from '../lib/p2p-runtime';
|
||||||
|
|
||||||
|
type AccountShape = Record<string, unknown> & {
|
||||||
|
id?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ACCOUNT_RECOVERY_CHECK_MS = 1000;
|
||||||
|
|
||||||
|
export const useBrowserPureP2PAccountUpgrade = () => {
|
||||||
|
const account = useAccount() as AccountShape | undefined;
|
||||||
|
const { accounts = [] } = useAccounts();
|
||||||
|
const recoveryStartedRef = useRef(false);
|
||||||
|
const upgradeAccountIdRef = useRef<string | undefined>(undefined);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (account?.id || accounts.length > 0 || recoveryStartedRef.current) return;
|
||||||
|
|
||||||
|
const intervalId = window.setInterval(() => {
|
||||||
|
if (window.BITSOCIAL_REACT_HOOKS_ACCOUNTS_STORE_INITIALIZING) return;
|
||||||
|
|
||||||
|
recoveryStartedRef.current = true;
|
||||||
|
window.clearInterval(intervalId);
|
||||||
|
void createAccount()
|
||||||
|
.then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
recoveryStartedRef.current = false;
|
||||||
|
console.error('Failed to recover missing browser account', error);
|
||||||
|
});
|
||||||
|
}, ACCOUNT_RECOVERY_CHECK_MS);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.clearInterval(intervalId);
|
||||||
|
};
|
||||||
|
}, [account?.id, accounts.length]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!account?.id || !shouldUpgradeBrowserPureP2PAccount(account)) return;
|
||||||
|
if (upgradeAccountIdRef.current === account.id) return;
|
||||||
|
|
||||||
|
upgradeAccountIdRef.current = account.id;
|
||||||
|
|
||||||
|
void setAccount({
|
||||||
|
...account,
|
||||||
|
pkcOptions: getBrowserPureP2PAccountOptions(account),
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
upgradeAccountIdRef.current = undefined;
|
||||||
|
console.error('Failed to upgrade browser account to pure P2P options', error);
|
||||||
|
});
|
||||||
|
}, [account]);
|
||||||
|
};
|
||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
getP2PRuntimeMode,
|
getP2PRuntimeMode,
|
||||||
isBrowserPureP2PEnabled,
|
isBrowserPureP2PEnabled,
|
||||||
shouldShowP2PSettingsSection,
|
shouldShowP2PSettingsSection,
|
||||||
|
shouldUpgradeBrowserPureP2PAccount,
|
||||||
} from '../p2p-runtime';
|
} from '../p2p-runtime';
|
||||||
|
|
||||||
const browserWindow = {
|
const browserWindow = {
|
||||||
@@ -91,6 +92,20 @@ describe('p2p-runtime', () => {
|
|||||||
expect(shouldShowP2PSettingsSection(account, browserWindowWithDisabledPureP2P)).toBe(true);
|
expect(shouldShowP2PSettingsSection(account, browserWindowWithDisabledPureP2P)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('upgrades only stale gateway browser accounts when pure p2p is enabled', () => {
|
||||||
|
const gatewayAccount = { pkcOptions: { ipfsGatewayUrls: ['https://gateway.example'] } };
|
||||||
|
const browserAccount = { pkcOptions: { libp2pJsClientsOptions: [{ key: 'libp2pjs' }] } };
|
||||||
|
const mixedBrowserAccount = { pkcOptions: { libp2pJsClientsOptions: [{ key: 'libp2pjs' }], pubsubKuboRpcClientsOptions: ['https://pubsub.example/api/v0'] } };
|
||||||
|
const fullNodeAccount = { pkcOptions: { pkcRpcClientsOptions: ['ws://node.example'] } };
|
||||||
|
|
||||||
|
expect(shouldUpgradeBrowserPureP2PAccount(gatewayAccount, browserWindow)).toBe(true);
|
||||||
|
expect(shouldUpgradeBrowserPureP2PAccount(browserAccount, browserWindow)).toBe(false);
|
||||||
|
expect(shouldUpgradeBrowserPureP2PAccount(mixedBrowserAccount, browserWindow)).toBe(true);
|
||||||
|
expect(shouldUpgradeBrowserPureP2PAccount(fullNodeAccount, browserWindow)).toBe(false);
|
||||||
|
expect(shouldUpgradeBrowserPureP2PAccount(gatewayAccount, browserWindowWithDisabledPureP2P)).toBe(false);
|
||||||
|
expect(shouldUpgradeBrowserPureP2PAccount(gatewayAccount, electronWindow)).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it('builds browser p2p and gateway account options without a direct pkc-js import', () => {
|
it('builds browser p2p and gateway account options without a direct pkc-js import', () => {
|
||||||
const account = {
|
const account = {
|
||||||
pkcOptions: {
|
pkcOptions: {
|
||||||
@@ -104,6 +119,7 @@ describe('p2p-runtime', () => {
|
|||||||
libp2pJsClientsOptions: [{ key: 'libp2pjs' }],
|
libp2pJsClientsOptions: [{ key: 'libp2pjs' }],
|
||||||
ipfsGatewayUrls: undefined,
|
ipfsGatewayUrls: undefined,
|
||||||
pkcRpcClientsOptions: undefined,
|
pkcRpcClientsOptions: undefined,
|
||||||
|
pubsubKuboRpcClientsOptions: undefined,
|
||||||
});
|
});
|
||||||
expect(getBrowserGatewayAccountOptions(account)).toMatchObject({
|
expect(getBrowserGatewayAccountOptions(account)).toMatchObject({
|
||||||
httpRoutersOptions: ['https://custom-router.example'],
|
httpRoutersOptions: ['https://custom-router.example'],
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
export const PURE_P2P_BROWSER_SETTING_KEY = '5chan:pure-p2p-browser-enabled';
|
export const PURE_P2P_BROWSER_SETTING_KEY = '5chan:pure-p2p-browser-enabled';
|
||||||
export const BROWSER_PURE_P2P_DEFAULT_ENABLED = true;
|
export const BROWSER_PURE_P2P_DEFAULT_ENABLED = true;
|
||||||
|
|
||||||
|
const BROWSER_PUBSUB_KUBO_RPC_CLIENTS_OPTIONS = ['https://pubsubprovider.xyz/api/v0', 'https://plebpubsub.xyz/api/v0', 'https://rannithepleb.com/api/v0'];
|
||||||
|
|
||||||
export const P2P_BROWSER_PKC_OPTIONS = {
|
export const P2P_BROWSER_PKC_OPTIONS = {
|
||||||
libp2pJsClientsOptions: [{ key: 'libp2pjs' }],
|
libp2pJsClientsOptions: [{ key: 'libp2pjs' }],
|
||||||
ipfsGatewayUrls: undefined,
|
ipfsGatewayUrls: undefined,
|
||||||
kuboRpcClientsOptions: undefined,
|
kuboRpcClientsOptions: undefined,
|
||||||
pubsubHttpClientsOptions: undefined,
|
pubsubHttpClientsOptions: undefined,
|
||||||
pubsubKuboRpcClientsOptions: undefined,
|
pubsubKuboRpcClientsOptions: undefined as string[] | undefined,
|
||||||
httpRoutersOptions: ['https://peers.plebpubsub.xyz', 'https://routing.lol', 'https://peers.pleb.bot'],
|
httpRoutersOptions: ['https://peers.plebpubsub.xyz', 'https://routing.lol', 'https://peers.pleb.bot'],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -15,7 +17,7 @@ const GATEWAY_BROWSER_PKC_OPTIONS = {
|
|||||||
kuboRpcClientsOptions: undefined,
|
kuboRpcClientsOptions: undefined,
|
||||||
libp2pJsClientsOptions: undefined,
|
libp2pJsClientsOptions: undefined,
|
||||||
pubsubHttpClientsOptions: undefined,
|
pubsubHttpClientsOptions: undefined,
|
||||||
pubsubKuboRpcClientsOptions: ['https://pubsubprovider.xyz/api/v0', 'https://plebpubsub.xyz/api/v0', 'https://rannithepleb.com/api/v0'],
|
pubsubKuboRpcClientsOptions: BROWSER_PUBSUB_KUBO_RPC_CLIENTS_OPTIONS,
|
||||||
httpRoutersOptions: ['https://routing.lol', 'https://peers.pleb.bot', 'https://peers.plebpubsub.xyz', 'https://peers.forumindex.com'],
|
httpRoutersOptions: ['https://routing.lol', 'https://peers.pleb.bot', 'https://peers.plebpubsub.xyz', 'https://peers.forumindex.com'],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -27,9 +29,12 @@ type P2PBrowserConfigWindow = {
|
|||||||
localStorage?: Pick<Storage, 'getItem' | 'setItem'>;
|
localStorage?: Pick<Storage, 'getItem' | 'setItem'>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const cloneArray = <T>(value: T[] | undefined) => (value ? [...value] : undefined);
|
||||||
|
|
||||||
export const getBrowserPureP2PPkcOptions = () => ({
|
export const getBrowserPureP2PPkcOptions = () => ({
|
||||||
...P2P_BROWSER_PKC_OPTIONS,
|
...P2P_BROWSER_PKC_OPTIONS,
|
||||||
libp2pJsClientsOptions: P2P_BROWSER_PKC_OPTIONS.libp2pJsClientsOptions.map((options) => ({ ...options })),
|
libp2pJsClientsOptions: P2P_BROWSER_PKC_OPTIONS.libp2pJsClientsOptions.map((options) => ({ ...options })),
|
||||||
|
pubsubKuboRpcClientsOptions: cloneArray(P2P_BROWSER_PKC_OPTIONS.pubsubKuboRpcClientsOptions),
|
||||||
httpRoutersOptions: [...P2P_BROWSER_PKC_OPTIONS.httpRoutersOptions],
|
httpRoutersOptions: [...P2P_BROWSER_PKC_OPTIONS.httpRoutersOptions],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ const hasArrayItems = (value: unknown) => Array.isArray(value) && value.length >
|
|||||||
|
|
||||||
const hasObjectItems = (value: unknown) => !!value && typeof value === 'object' && Object.keys(value).length > 0;
|
const hasObjectItems = (value: unknown) => !!value && typeof value === 'object' && Object.keys(value).length > 0;
|
||||||
|
|
||||||
|
const hasMixedBrowserPureP2POptions = (protocolOptions: AccountProtocolOptions | undefined) =>
|
||||||
|
hasArrayItems(protocolOptions?.libp2pJsClientsOptions) &&
|
||||||
|
(hasArrayItems(protocolOptions?.kuboRpcClientsOptions) || hasArrayItems(protocolOptions?.pubsubKuboRpcClientsOptions));
|
||||||
|
|
||||||
export const getP2PRuntimeMode = (account?: unknown, targetWindow: Window = window): P2PRuntimeMode | null => {
|
export const getP2PRuntimeMode = (account?: unknown, targetWindow: Window = window): P2PRuntimeMode | null => {
|
||||||
const accountShape = toAccountShape(account);
|
const accountShape = toAccountShape(account);
|
||||||
const protocolOptions = accountShape?.pkcOptions;
|
const protocolOptions = accountShape?.pkcOptions;
|
||||||
@@ -66,6 +70,13 @@ export const getBrowserPureP2PAccountOptions = (account?: unknown) => ({
|
|||||||
pkcRpcClientsOptions: undefined,
|
pkcRpcClientsOptions: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const shouldUpgradeBrowserPureP2PAccount = (account?: unknown, targetWindow: Window = window) => {
|
||||||
|
if (!account || typeof account !== 'object' || !canConfigureBrowserPureP2P(targetWindow) || !isBrowserPureP2PEnabled(account, targetWindow)) return false;
|
||||||
|
|
||||||
|
const protocolOptions = toAccountShape(account)?.pkcOptions;
|
||||||
|
return getP2PRuntimeMode(account, targetWindow) === null || hasMixedBrowserPureP2POptions(protocolOptions);
|
||||||
|
};
|
||||||
|
|
||||||
export const getBrowserGatewayAccountOptions = (account?: unknown) => {
|
export const getBrowserGatewayAccountOptions = (account?: unknown) => {
|
||||||
const protocolOptions = toAccountShape(account)?.pkcOptions;
|
const protocolOptions = toAccountShape(account)?.pkcOptions;
|
||||||
const gatewayOptions = getBrowserGatewayPkcOptions();
|
const gatewayOptions = getBrowserGatewayPkcOptions();
|
||||||
|
|||||||
@@ -6272,7 +6272,7 @@ __metadata:
|
|||||||
|
|
||||||
"@pkcprotocol/pkc-js@patch:@pkcprotocol/pkc-js@npm%3A0.0.47#~/.yarn/patches/@pkcprotocol-pkc-js-npm-0.0.47-e2131d72c8.patch":
|
"@pkcprotocol/pkc-js@patch:@pkcprotocol/pkc-js@npm%3A0.0.47#~/.yarn/patches/@pkcprotocol-pkc-js-npm-0.0.47-e2131d72c8.patch":
|
||||||
version: 0.0.47
|
version: 0.0.47
|
||||||
resolution: "@pkcprotocol/pkc-js@patch:@pkcprotocol/pkc-js@npm%3A0.0.47#~/.yarn/patches/@pkcprotocol-pkc-js-npm-0.0.47-e2131d72c8.patch::version=0.0.47&hash=df4e0a"
|
resolution: "@pkcprotocol/pkc-js@patch:@pkcprotocol/pkc-js@npm%3A0.0.47#~/.yarn/patches/@pkcprotocol-pkc-js-npm-0.0.47-e2131d72c8.patch::version=0.0.47&hash=bbfad6"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@enhances/with-resolvers": "npm:0.0.5"
|
"@enhances/with-resolvers": "npm:0.0.5"
|
||||||
"@helia/block-brokers": "npm:5.2.4"
|
"@helia/block-brokers": "npm:5.2.4"
|
||||||
|
|||||||
Reference in New Issue
Block a user