Skip to content

Instantly share code, notes, and snippets.

View yongjun21's full-sized avatar

Yong Jun yongjun21

  • Singapore
  • 09:00 (UTC +08:00)
View GitHub Profile
@yongjun21
yongjun21 / async.ts
Created February 6, 2026 04:34
Utilities for handling async operations
import { LinkedList } from "./base";
import { OrderedSet } from "./OrderedCollections";
export function delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
export function nextTick(): Promise<void> {
return new Promise(resolve => {
queueMicrotask(() => {
@yongjun21
yongjun21 / useWorker.ts
Last active February 6, 2026 04:19
Utility to simplify Web Worker use
type Callable = (...args: any[]) => any | Promise<any>;
type Streamable = (...args: any[]) => AsyncIterableIterator<any>;
interface Handler {
[key: string]: any;
}
interface Callbacks {
resolve: (value: any) => void;
reject: (reason?: any) => void;
@yongjun21
yongjun21 / bitmaskHelpers3d.ts
Last active February 3, 2026 04:53
A set of helper functions for manipulating 3D bitmask in sparse (run-based) format
import SparseBitmask from "./SparseBitmask";
import { bitmaskFromWeightedRuns } from "./bitmaskHelpers";
import { OrderedMap } from "./OrderedCollections";
import { range } from "./base";
export function cutAndPasteBitmask3d(
from: SparseBitmask,
fromWidth: number,
fromHeight: number,
fromDepth: number,
@yongjun21
yongjun21 / perfectFit.ts
Created March 10, 2025 05:38
Calculates an ideal viewBox that centers on a target object
/**
* Calculates an ideal viewBox that centers on a target object
* @param objectBBox - Bounding box of the target object
* @param assetWidth - Width of the asset
* @param assetHeight - Height of the asset
* @param targetCoverage - target percentage of the viewport width or height the object should take up
* @param viewportAspectRatio - Aspect ratio of the viewport
* @param minFit - Minimum width and height of the viewport
* @returns - [offsetX, offsetY, viewportWidth, viewportHeight]
*/
@yongjun21
yongjun21 / MultiClassBitmask.ts
Last active February 3, 2026 04:58
Data structure for handling multiple bitmasks within one stack
import _noop from "lodash/noop";
import SparseBitmask from "../../utils/SparseBitmask";
import { OrderedSet, OrderedMap } from "../../utils/OrderedCollections";
import { range } from "../../utils/base";
interface RunNode<T> {
currState: OrderedSet<number>;
diff: Set<number>;
pending: Set<number>;
@yongjun21
yongjun21 / bitmaskHelpers.ts
Last active February 3, 2026 04:59
Some helpers functions for manipulating bitmask in sparse (run-based) format
import SparseBitmask, {
unionRunEnds,
intersectionRunEnds,
subtractionRunEnds,
} from "./SparseBitmask";
import {
cutAndPasteBitmask3d,
getBoundingBox3d,
getCentroid3d,
getWindowedRunLengths3d,
@yongjun21
yongjun21 / SparseBitmask.ts
Last active February 3, 2026 04:55
Custom data structure for efficient manipulation of sparse bitmask
import {
iterFilter,
iterFilterIndex,
range,
ArrayConstructor,
ArrayLike,
} from "./base";
import { OrderedSet } from "./OrderedCollections";
@yongjun21
yongjun21 / OrderedCollections.ts
Last active February 3, 2026 04:54
Combining heap with hash table to get a data structure that supports fast iteration even with frequent insert and delete
export class OrderedSet<T> {
private heap: T[] = [];
private sorted: T[] = [];
private heapIndex = new Map<T, number>();
private comparator: (a: T, b: T) => number = (a, b) => (b < a ? 1 : 0);
constructor(compareBy?: (item: T) => any) {
if (compareBy) {
this.comparator = (a, b) => (compareBy(b) < compareBy(a) ? 1 : 0);
}
@yongjun21
yongjun21 / bitmask.ts
Last active February 6, 2024 02:49
Memory efficient implementation of bitmask
import { Stack } from './common.js';
export function decodeBitmask(
encoded: Uint8Array,
maxIndex: number
): Iterable<number> {
return {
*[Symbol.iterator]() {
const n = maxIndex + 1;
const depth = Math.ceil(Math.log2(n));
@yongjun21
yongjun21 / decodeOctree.ts
Last active July 25, 2022 16:53
Fast Octree decoder in JS
const MAX_LEVEL = 30;
const STACK = new Float32Array((7 * MAX_LEVEL + 1) * 4);
interface OctreeHeader {
version: number;
precision: number;
maxLevel: number;
nodeCounts: number[];
leafCount: number;
dataStartOffset: number;