Skip to content

Instantly share code, notes, and snippets.

View compulim's full-sized avatar

William Wong compulim

View GitHub Profile
@compulim
compulim / index.js
Last active October 8, 2022 00:14
Generating self-signed certificate with subject alternate name using `selfsigned`
import { createServer } from 'https';
import { generate } from 'selfsigned';
const certAttrs = [{ name: 'commonName', value: 'www.compulim.com' }];
const certOptions = {
// Options copied from default values
// https://github.com/jfromaniello/selfsigned/blob/master/index.js#L85
extensions: [
{
name: 'subjectAltName',
@compulim
compulim / dump.sh
Created June 7, 2021 03:41
RTMP server to show live stream and dump it to disk
#!/bin/sh
# This script will act as a RTMP server and archive your RTMP live stream as-is without transcoding.
# Prerequisites: ffmpeg.
# Configure your RTMP source to stream to rtmp://your-ip-address:5555/.
ffmpeg -listen 1 -i rtmp://0.0.0.0:5555 -c copy -c:v copy -c:a copy your-video.m4v
@compulim
compulim / imageAsLog.js
Last active May 28, 2021 14:22
Image to `console.log`
// Inspired from https://github.com/adriancooney/console.image
async function getBlobURL(base64) {
const res = await fetch(`data:image/png;base64,${base64}`);
const blob = await res.blob();
return URL.createObjectURL(blob);
}
async function getImageSize(url) {
@compulim
compulim / parseURLSearchParams.js
Last active March 11, 2020 23:56
parseURLSearchParams
function parseURLSearchParams(search) {
return search
.replace(/^\?/, '')
.split('&')
.reduce((params, keyValue) => {
const [key, value] = keyValue.split('=');
const decodedKey = decodeURIComponent(key);
if (key && key !== '__proto__' && key !== 'constructor' && key !== 'prototype') {
params[decodedKey] = decodeURIComponent(value);
@compulim
compulim / custom-activity-status.js
Created March 4, 2020 20:21
Intercept observable using middleware pattern
function interceptObservable(observable, middleware) {
return new Observable(observer => {
const initializedMiddleware = middleware(observer);
const subscription = observable.subscribe({
close() {
observer.close();
},
error(err) {
observer.error(err);
},
@compulim
compulim / setIntervalAsync.js
Created January 31, 2020 23:29
setIntervalAsync
function setIntervalAsync(fn, interval) {
let stopped;
let timeout;
const schedule = () => {
timeout = setTimeout(async () => {
await fn();
stopped || schedule();
}, interval);
@compulim
compulim / useApp.js
Created January 26, 2020 00:31
useReducerWithSaga
import { useCallback } from 'react';
import useReducerWithSaga from './useReducerWithSaga';
import saga from '../data/saga';
const DEFAULT_STATE = {
localStream: null,
remoteStreams: []
};
@compulim
compulim / useDebugDeps.js
Last active February 19, 2020 10:17
Track changes on every render via React hooks
import { useRef } from 'react';
export default function useDebugDeps(depsMap, name) {
const lastDepsMapRef = useRef({});
const { current: lastDepsMap } = lastDepsMapRef;
const keys = new Set([...Object.keys(depsMap), ...Object.keys(lastDepsMap)]);
const keysChanged = Array.from(keys).filter(key => !Object.is(depsMap[key], lastDepsMap[key]));
if (keysChanged.length) {
@compulim
compulim / useDetectDepsChange.js
Created December 3, 2019 01:20
Detect deps change in React
export default function useDetectDepsChange(deps) {
const prevDeps = useRef([]);
deps.forEach((value, index) => {
if (prevDeps.current[index] !== value) {
console.log('Dep changed', { index, dep, prevDep: prevDeps.current[index] });
}
});
prevDeps.current = [...deps];
@compulim
compulim / createMemoizedFetchCredentials.js
Created December 2, 2019 07:51
Create memoized fetch credentials
const TOKEN_EXPIRE_AFTER = 300000;
// This function will create a memoized fetchCredentials function and reduce the call to the function.
// The memoized result is time-sensitive and will be invalidated after 5 minutes (specified in TOKEN_EXPIRE_AFTER).
const createMemoizedFetchCredentials = () => {
let lastFetch = 0;
let lastPromise;
return () => {
const now = Date.now();