docker run --rm -it $(docker build -q .)
docker build -t gobi301/p2p-network-rust . && docker push gobi301/p2p-network-rust:latest
- nat traversal
- dht
- lan discovery
import type { CSSProp } from "styled-components/index"; | |
declare module "react" { | |
interface Attributes { | |
css?: CSSProp; | |
css?: any // if compilation times becomes too high | |
} | |
} | |
// import "styled-components/macro" must be imported in every file that uses css={`color: red`} |
#!/usr/bin/env bash | |
cat > Dockerfile << EOF | |
FROM ubuntu | |
RUN apt-get update | |
RUN apt-get install -y wget | |
RUN wget -O teams-for-linux.deb --quiet "https://teams.microsoft.com/downloads/desktopurl?env=production&plat=linux&arch=x64&download=true&linuxArchiveType=deb" |
use std::assert; | |
use std::rc::Rc; | |
mod rust_hooks { | |
use std::cell::{Cell, RefCell}; | |
use std::rc::Rc; | |
pub trait Notifiable { | |
fn notify(&self); | |
} |
function getBroadcastAddress({ address, netmask }: NetworkInterfaceInfo) { | |
const addressBytes = address.split(".").map(Number); | |
const netmaskBytes = netmask.split(".").map(Number); | |
const subnetBytes = netmaskBytes.map( | |
(_, index) => addressBytes[index] & netmaskBytes[index] | |
); | |
const broadcastBytes = netmaskBytes.map( | |
(_, index) => subnetBytes[index] | (~netmaskBytes[index] + 256) | |
); | |
return broadcastBytes.map(String).join(".") |
/* | |
Channel based coroutines with await syntax and backpressure | |
`await send(item);` blocks execution until a corresponding `const item = await receive()` is called | |
`const item = await receive();` blocks execution until a corresponding `await send(item);` is called | |
the send function should be used by a single producer (for code readability) | |
the receive function should be used by a single consumer (for code readabilty) | |
see examples at bottom | |
a channel is single use (if multiple threads subscribe, every thread will get an item at round robin) | |
if multicast semantics are needed, this could be accomodated with an operator | |
backpressure is for free, is send and receive are awaited |
import { useState } from "react"; | |
export function useLocalStorage<T>(key: string, initialValue: T) { | |
const [storedValue, setStoredValue] = useState(() => { | |
try { | |
const item = window.localStorage.getItem(key); | |
return item ? JSON.parse(item) : initialValue; | |
} catch (error) { | |
return initialValue; | |
} |
import { useEffect, useRef } from "react"; | |
type TimeoutCallback = (timestamp: number) => void; | |
export function useScheduledEffect( | |
callback: TimeoutCallback, | |
timestamp: number | null, | |
) { | |
const savedCallback = useRef<TimeoutCallback | null>(callback); |
import React from "react"; | |
export function useReferentialCallback<F extends (...args: any[]) => any>( | |
fn: F, | |
deps?: any[], | |
): F { | |
const fnRef = React.useRef<F>(fn); | |
React.useLayoutEffect(() => { | |
fnRef.current = fn; | |
}, deps); // eslint-disable-line |
import React, { Dispatch, SetStateAction } from "react"; | |
type ViolationMessage = string | (() => string); | |
function useStableValue<V>( | |
value: V, | |
message: ViolationMessage = "Violation: cannot change value between re-renders", | |
) { | |
const ref = React.useRef(value); |