mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-08-22 13:39:30 -04:00
Merge branch 'feature/wasm-example-bench' into 'main'
Add test-bench example for veilid-wasm See merge request veilid/veilid!397
This commit is contained in:
commit
ec887d3bec
18 changed files with 3539 additions and 0 deletions
24
veilid-wasm/example/test-bench/.gitignore
vendored
Normal file
24
veilid-wasm/example/test-bench/.gitignore
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
7
veilid-wasm/example/test-bench/README.md
Normal file
7
veilid-wasm/example/test-bench/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# Veilid WASM Example - Test Bench
|
||||||
|
|
||||||
|
This is an example application used as a test bench for veilid-wasm.
|
||||||
|
|
||||||
|
* `npm install` to install dependencies.
|
||||||
|
* `npm run build:wasm` to build veilid-wasm so it can be used by the test bench.
|
||||||
|
* `npm run dev` to start the development server.
|
28
veilid-wasm/example/test-bench/eslint.config.js
Normal file
28
veilid-wasm/example/test-bench/eslint.config.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import js from '@eslint/js'
|
||||||
|
import globals from 'globals'
|
||||||
|
import reactHooks from 'eslint-plugin-react-hooks'
|
||||||
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
|
||||||
|
export default tseslint.config(
|
||||||
|
{ ignores: ['dist'] },
|
||||||
|
{
|
||||||
|
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
globals: globals.browser,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
'react-hooks': reactHooks,
|
||||||
|
'react-refresh': reactRefresh,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...reactHooks.configs.recommended.rules,
|
||||||
|
'react-refresh/only-export-components': [
|
||||||
|
'warn',
|
||||||
|
{ allowConstantExport: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
16
veilid-wasm/example/test-bench/index.html
Normal file
16
veilid-wasm/example/test-bench/index.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Veilid WASM Example - Test Bench</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
2931
veilid-wasm/example/test-bench/package-lock.json
generated
Normal file
2931
veilid-wasm/example/test-bench/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
36
veilid-wasm/example/test-bench/package.json
Normal file
36
veilid-wasm/example/test-bench/package.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"name": "veilid-wasm-example-test-bench",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "npm run build:wasm && tsc -b && vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"build:wasm": "cd ../../ && wasm-pack build --release --target web --weak-refs --out-dir ./pkg"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"react": "^19.0.0",
|
||||||
|
"react-dom": "^19.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.21.0",
|
||||||
|
"@types/node": "^22.13.10",
|
||||||
|
"@types/react": "^19.0.10",
|
||||||
|
"@types/react-dom": "^19.0.4",
|
||||||
|
"@types/uuid": "^10.0.0",
|
||||||
|
"@vitejs/plugin-react-swc": "^3.8.0",
|
||||||
|
"eslint": "^9.21.0",
|
||||||
|
"eslint-plugin-react-hooks": "^5.1.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.19",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"globals": "^15.15.0",
|
||||||
|
"typescript": "~5.7.2",
|
||||||
|
"typescript-eslint": "^8.24.1",
|
||||||
|
"uuid": "^11.1.0",
|
||||||
|
"vite": "^6.2.0",
|
||||||
|
"vite-plugin-wasm": "^3.4.1",
|
||||||
|
"veilid-wasm": "file:../../pkg"
|
||||||
|
}
|
||||||
|
}
|
12
veilid-wasm/example/test-bench/src/App.tsx
Normal file
12
veilid-wasm/example/test-bench/src/App.tsx
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { DhtStressTest } from './components/DhtStressTest';
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h1>DHT Stress Test</h1>
|
||||||
|
<DhtStressTest />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { getRoutingContext } from '../veilid/veilid-core';
|
||||||
|
|
||||||
|
async function dhtStressTest() {
|
||||||
|
const routingContext = getRoutingContext();
|
||||||
|
|
||||||
|
const recordCount = 30;
|
||||||
|
const subkeyCount = 32;
|
||||||
|
const inspectCount = 1;
|
||||||
|
|
||||||
|
// Create a 32KB data buffer
|
||||||
|
const dataSize = 32 * 1024; // 32KB in bytes
|
||||||
|
const dataArray = new Uint8Array(dataSize);
|
||||||
|
|
||||||
|
// Fill the array with some pattern (using values 0-255 repeating)
|
||||||
|
for (let i = 0; i < dataSize; i++) {
|
||||||
|
dataArray[i] = i % 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
let a = Array();
|
||||||
|
for (var r = 0; r < recordCount; r++) {
|
||||||
|
let dhtRecord = await routingContext.createDhtRecord(
|
||||||
|
{
|
||||||
|
kind: 'DFLT',
|
||||||
|
o_cnt: subkeyCount,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set all subkeys
|
||||||
|
for (var n = 0; n < subkeyCount; n++) {
|
||||||
|
a.push((async () => {
|
||||||
|
// const measureName = `${r}-setDhtValue-${n}`;
|
||||||
|
|
||||||
|
// performance.mark(measureName + "-start")
|
||||||
|
await routingContext.setDhtValue(
|
||||||
|
dhtRecord.key,
|
||||||
|
n,
|
||||||
|
dataArray,
|
||||||
|
);
|
||||||
|
|
||||||
|
// performance.measure(measureName, measureName + "-start")
|
||||||
|
})());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inspect all records N times while sets are happening
|
||||||
|
for (var n = 0; n < inspectCount; n++) {
|
||||||
|
a.push((async () => {
|
||||||
|
const measureName = `${r}-inspectDhtRecord-${n}`;
|
||||||
|
|
||||||
|
performance.mark(measureName + "-start")
|
||||||
|
await routingContext.inspectDhtRecord(
|
||||||
|
dhtRecord.key,
|
||||||
|
null,
|
||||||
|
"SyncSet",
|
||||||
|
);
|
||||||
|
|
||||||
|
performance.measure(measureName, measureName + "-start")
|
||||||
|
})());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all results
|
||||||
|
await Promise.all(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function DhtStressTest() {
|
||||||
|
const [isRunning, setIsRunning] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button onClick={() => {
|
||||||
|
if (isRunning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setIsRunning(true);
|
||||||
|
dhtStressTest().finally(() => {
|
||||||
|
setIsRunning(false);
|
||||||
|
});
|
||||||
|
}} disabled={isRunning}>
|
||||||
|
{isRunning ? 'Running...' : 'Run DHT Stress Test'}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
20
veilid-wasm/example/test-bench/src/main.tsx
Normal file
20
veilid-wasm/example/test-bench/src/main.tsx
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { StrictMode } from 'react'
|
||||||
|
import { createRoot } from 'react-dom/client'
|
||||||
|
import App from './App.tsx'
|
||||||
|
import { initVeilid, startVeilid } from './veilid/veilid-core.ts'
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
await initVeilid();
|
||||||
|
await startVeilid();
|
||||||
|
|
||||||
|
createRoot(document.getElementById('root')!).render(
|
||||||
|
<StrictMode>
|
||||||
|
<App />
|
||||||
|
</StrictMode>,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((e) => {
|
||||||
|
console.error(e);
|
||||||
|
});
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
export const textDecoder = new TextDecoder();
|
||||||
|
export const textEncoder = new TextEncoder();
|
154
veilid-wasm/example/test-bench/src/veilid/veilid-config.ts
Normal file
154
veilid-wasm/example/test-bench/src/veilid/veilid-config.ts
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
import { VeilidConfigInner, VeilidWASMConfig } from 'veilid-wasm';
|
||||||
|
export interface VeilidConfigOptions {
|
||||||
|
namespace: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const veildCoreInitConfig: VeilidWASMConfig = {
|
||||||
|
logging: {
|
||||||
|
api: {
|
||||||
|
enabled: true,
|
||||||
|
level: 'Info',
|
||||||
|
ignore_log_targets: [],
|
||||||
|
},
|
||||||
|
performance: {
|
||||||
|
enabled: false,
|
||||||
|
level: 'Info',
|
||||||
|
logs_in_timings: false,
|
||||||
|
logs_in_console: false,
|
||||||
|
ignore_log_targets: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getVeilidCoreStartupConfig(options: VeilidConfigOptions) {
|
||||||
|
const config: VeilidConfigInner = {
|
||||||
|
program_name: 'veilid-wasm-test-bench',
|
||||||
|
namespace: options.namespace,
|
||||||
|
capabilities: {
|
||||||
|
disable: [],
|
||||||
|
},
|
||||||
|
protected_store: {
|
||||||
|
allow_insecure_fallback: true,
|
||||||
|
always_use_insecure_storage: true,
|
||||||
|
directory: '',
|
||||||
|
delete: false,
|
||||||
|
device_encryption_key_password: options.password,
|
||||||
|
// "new_device_encryption_key_password": "<secret>"
|
||||||
|
},
|
||||||
|
table_store: {
|
||||||
|
directory: 'table_store',
|
||||||
|
delete: false,
|
||||||
|
},
|
||||||
|
block_store: {
|
||||||
|
directory: 'block_store',
|
||||||
|
delete: false,
|
||||||
|
},
|
||||||
|
network: {
|
||||||
|
connection_initial_timeout_ms: 2000,
|
||||||
|
connection_inactivity_timeout_ms: 60000,
|
||||||
|
max_connections_per_ip4: 32,
|
||||||
|
max_connections_per_ip6_prefix: 32,
|
||||||
|
max_connections_per_ip6_prefix_size: 56,
|
||||||
|
max_connection_frequency_per_min: 128,
|
||||||
|
client_allowlist_timeout_ms: 300000,
|
||||||
|
reverse_connection_receipt_time_ms: 5000,
|
||||||
|
hole_punch_receipt_time_ms: 5000,
|
||||||
|
network_key_password: '',
|
||||||
|
routing_table: {
|
||||||
|
node_id: [],
|
||||||
|
node_id_secret: [],
|
||||||
|
bootstrap: [
|
||||||
|
'ws://bootstrap.veilid.net:5150/ws'
|
||||||
|
],
|
||||||
|
limit_over_attached: 64,
|
||||||
|
limit_fully_attached: 32,
|
||||||
|
limit_attached_strong: 16,
|
||||||
|
limit_attached_good: 8,
|
||||||
|
limit_attached_weak: 4,
|
||||||
|
},
|
||||||
|
rpc: {
|
||||||
|
concurrency: 8,
|
||||||
|
queue_size: 1024,
|
||||||
|
max_timestamp_behind_ms: 10000,
|
||||||
|
max_timestamp_ahead_ms: 10000,
|
||||||
|
timeout_ms: 10000,
|
||||||
|
max_route_hop_count: 4,
|
||||||
|
default_route_hop_count: 1,
|
||||||
|
},
|
||||||
|
dht: {
|
||||||
|
max_find_node_count: 20,
|
||||||
|
resolve_node_timeout_ms: 10000,
|
||||||
|
resolve_node_count: 1,
|
||||||
|
resolve_node_fanout: 4,
|
||||||
|
get_value_timeout_ms: 10000,
|
||||||
|
get_value_count: 3,
|
||||||
|
get_value_fanout: 4,
|
||||||
|
set_value_timeout_ms: 10000,
|
||||||
|
set_value_count: 5,
|
||||||
|
set_value_fanout: 4,
|
||||||
|
min_peer_count: 20,
|
||||||
|
min_peer_refresh_time_ms: 60000,
|
||||||
|
validate_dial_info_receipt_time_ms: 2000,
|
||||||
|
local_subkey_cache_size: 128,
|
||||||
|
local_max_subkey_cache_memory_mb: 256,
|
||||||
|
remote_subkey_cache_size: 0,
|
||||||
|
remote_max_records: 0,
|
||||||
|
remote_max_subkey_cache_memory_mb: 0,
|
||||||
|
remote_max_storage_space_mb: 0,
|
||||||
|
public_watch_limit: 32,
|
||||||
|
member_watch_limit: 32,
|
||||||
|
max_watch_expiration_ms: 600000,
|
||||||
|
},
|
||||||
|
upnp: true,
|
||||||
|
detect_address_changes: true,
|
||||||
|
restricted_nat_retries: 0,
|
||||||
|
tls: {
|
||||||
|
certificate_path: '',
|
||||||
|
private_key_path: '',
|
||||||
|
connection_initial_timeout_ms: 2000,
|
||||||
|
},
|
||||||
|
application: {
|
||||||
|
https: {
|
||||||
|
enabled: false,
|
||||||
|
listen_address: ':5150',
|
||||||
|
path: 'app',
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
enabled: false,
|
||||||
|
listen_address: ':5150',
|
||||||
|
path: 'app',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
protocol: {
|
||||||
|
udp: {
|
||||||
|
enabled: false,
|
||||||
|
socket_pool_size: 0,
|
||||||
|
listen_address: '',
|
||||||
|
},
|
||||||
|
tcp: {
|
||||||
|
connect: false,
|
||||||
|
listen: false,
|
||||||
|
max_connections: 32,
|
||||||
|
listen_address: '',
|
||||||
|
},
|
||||||
|
ws: {
|
||||||
|
connect: true,
|
||||||
|
listen: true,
|
||||||
|
max_connections: 128,
|
||||||
|
listen_address: ':5150',
|
||||||
|
path: 'ws',
|
||||||
|
},
|
||||||
|
wss: {
|
||||||
|
connect: true,
|
||||||
|
listen: false,
|
||||||
|
max_connections: 32,
|
||||||
|
listen_address: '',
|
||||||
|
path: 'ws',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
100
veilid-wasm/example/test-bench/src/veilid/veilid-core.ts
Normal file
100
veilid-wasm/example/test-bench/src/veilid/veilid-core.ts
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
import * as veilid from 'veilid-wasm';
|
||||||
|
import loadVeilidWasm, {
|
||||||
|
veilidClient,
|
||||||
|
VeilidRoutingContext,
|
||||||
|
} from 'veilid-wasm'
|
||||||
|
import { getVeilidCoreStartupConfig, veildCoreInitConfig } from './veilid-config';
|
||||||
|
import { veilidEventEmitter } from './veilid-event-emitter';
|
||||||
|
import { v4 as uuidV4 } from 'uuid';
|
||||||
|
|
||||||
|
let loadVeilidWasmPromise: Promise<veilid.InitOutput>;
|
||||||
|
let isVeilidWasmLoaded = false;
|
||||||
|
export async function initVeilid() {
|
||||||
|
if (isVeilidWasmLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!loadVeilidWasmPromise) {
|
||||||
|
console.log('loading veilid-wasm...');
|
||||||
|
loadVeilidWasmPromise = loadVeilidWasm();
|
||||||
|
}
|
||||||
|
await loadVeilidWasmPromise;
|
||||||
|
isVeilidWasmLoaded = true;
|
||||||
|
console.log('veilid-wasm loaded!');
|
||||||
|
}
|
||||||
|
|
||||||
|
let IS_VEILID_RUNNING = false;
|
||||||
|
|
||||||
|
export function isVeilidRunning() {
|
||||||
|
return IS_VEILID_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function startVeilid() {
|
||||||
|
const config = getVeilidCoreStartupConfig({
|
||||||
|
namespace: `example-bench-${uuidV4()}`,
|
||||||
|
password: 'singleton',
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('starting veilid core...');
|
||||||
|
await veilidClient.initializeCore(veildCoreInitConfig);
|
||||||
|
|
||||||
|
veilidClient.startupCore(async (data) => {
|
||||||
|
veilidEventEmitter.emit(data.kind, data);
|
||||||
|
}, JSON.stringify(config));
|
||||||
|
|
||||||
|
return veilidClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen to updates, and `attach()` once startup is complete.
|
||||||
|
veilidEventEmitter.on('Log', (data) => {
|
||||||
|
switch (data?.log_level) {
|
||||||
|
case 'Warn':
|
||||||
|
console.warn(data.message);
|
||||||
|
break;
|
||||||
|
case 'Info':
|
||||||
|
console.info(data.message);
|
||||||
|
break;
|
||||||
|
case 'Debug':
|
||||||
|
console.log(data.message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log(data.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Wonder if there's a better way to detect startup complete.
|
||||||
|
if (data.message?.includes('Veilid API startup complete')) {
|
||||||
|
console.log('veilid core started!');
|
||||||
|
IS_VEILID_RUNNING = true;
|
||||||
|
console.log('Veilid Version', veilidClient.versionString());
|
||||||
|
console.log('attaching to veilid network');
|
||||||
|
veilidClient.attach();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
veilidEventEmitter.on('RouteChange', (routeChange) => {
|
||||||
|
console.log('ROUTE CHANGE', routeChange);
|
||||||
|
});
|
||||||
|
|
||||||
|
veilidEventEmitter.on('ValueChange', (valueChange) => {
|
||||||
|
console.log('VALUE CHANGE', valueChange);
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function stopVeilid() {
|
||||||
|
if (ROUTING_CONTEXT_SINGLETON) {
|
||||||
|
ROUTING_CONTEXT_SINGLETON.free();
|
||||||
|
ROUTING_CONTEXT_SINGLETON = undefined;
|
||||||
|
}
|
||||||
|
if (isVeilidRunning()) {
|
||||||
|
IS_VEILID_RUNNING = false;
|
||||||
|
await veilidClient.detach();
|
||||||
|
await veilidClient.shutdownCore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ROUTING_CONTEXT_SINGLETON: VeilidRoutingContext | undefined;
|
||||||
|
export function getRoutingContext() {
|
||||||
|
if (!ROUTING_CONTEXT_SINGLETON) {
|
||||||
|
ROUTING_CONTEXT_SINGLETON = VeilidRoutingContext.create();
|
||||||
|
}
|
||||||
|
return ROUTING_CONTEXT_SINGLETON;
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
import * as veilid from 'veilid-wasm';
|
||||||
|
import EventEmitter from 'events';
|
||||||
|
|
||||||
|
export type VeilidUpdateKind = veilid.VeilidUpdate['kind'];
|
||||||
|
type VeilidUpdateKindMap = {
|
||||||
|
[TKind in VeilidUpdateKind]: Extract<veilid.VeilidUpdate, { kind: TKind }>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type VeilidUpdateType<TKind extends VeilidUpdateKind> =
|
||||||
|
VeilidUpdateKindMap[TKind];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A typesafe event emitter for VeilidUpdate events.
|
||||||
|
*/
|
||||||
|
class VeilidEventEmitter extends EventEmitter {
|
||||||
|
on<TKind extends VeilidUpdateKind>(
|
||||||
|
event: TKind,
|
||||||
|
listener: (veilidUpdate: VeilidUpdateType<TKind>) => void
|
||||||
|
): this {
|
||||||
|
super.on(event, listener);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit<TKind extends VeilidUpdateKind>(
|
||||||
|
event: TKind,
|
||||||
|
veilidUpdate: VeilidUpdateType<TKind>
|
||||||
|
): boolean {
|
||||||
|
return super.emit(event, veilidUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeListener<TKind extends VeilidUpdateKind>(
|
||||||
|
event: TKind,
|
||||||
|
listener: (veilidUpdate: VeilidUpdateType<TKind>) => void
|
||||||
|
): this {
|
||||||
|
super.removeListener(event, listener);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a singleton instance of VeilidEventEmitter.
|
||||||
|
*/
|
||||||
|
export const veilidEventEmitter = new VeilidEventEmitter();
|
1
veilid-wasm/example/test-bench/src/vite-env.d.ts
vendored
Normal file
1
veilid-wasm/example/test-bench/src/vite-env.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="vite/client" />
|
26
veilid-wasm/example/test-bench/tsconfig.app.json
Normal file
26
veilid-wasm/example/test-bench/tsconfig.app.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"target": "ES2020",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
7
veilid-wasm/example/test-bench/tsconfig.json
Normal file
7
veilid-wasm/example/test-bench/tsconfig.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.app.json" },
|
||||||
|
{ "path": "./tsconfig.node.json" }
|
||||||
|
]
|
||||||
|
}
|
24
veilid-wasm/example/test-bench/tsconfig.node.json
Normal file
24
veilid-wasm/example/test-bench/tsconfig.node.json
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"target": "ES2022",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
25
veilid-wasm/example/test-bench/vite.config.ts
Normal file
25
veilid-wasm/example/test-bench/vite.config.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import { defineConfig, searchForWorkspaceRoot } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react-swc'
|
||||||
|
import wasm from 'vite-plugin-wasm';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
// search up for workspace root
|
||||||
|
const workspaceRoot = searchForWorkspaceRoot(process.cwd());
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react(), wasm()],
|
||||||
|
server: {
|
||||||
|
port: 5001,
|
||||||
|
fs: {
|
||||||
|
allow: [
|
||||||
|
workspaceRoot,
|
||||||
|
path.resolve(
|
||||||
|
workspaceRoot,
|
||||||
|
'../../pkg/'
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
})
|
Loading…
Add table
Add a link
Reference in a new issue