newOS for Developers
Utilities
Helper functions, type guards, and data transformations used across newOS.
packages/newgraph-signals/src/utils/
XPromise
Externally resolvable promise. Unlike standard promises, XPromise can be resolved or rejected from outside the executor function.
class XPromise<T = void> {
// Standard promise interface
then<TResult1, TResult2>(
onfulfilled?: (value: T) => TResult1,
onrejected?: (reason: any) => TResult2
): Promise<TResult1 | TResult2>;
catch<TResult>(
onrejected?: (reason: any) => TResult
): Promise<T | TResult>;
finally(onfinally?: () => void): Promise<T>;
// External resolution
resolve(value: T): void;
reject(reason?: any): void;
}Usage Example
// Create an externally resolvable promise
const xp = new XPromise<string>();
// Resolve from anywhere
setTimeout(() => {
xp.resolve("Complete!");
}, 1000);
// Await like a normal promise
const result = await xp;
console.log(result); // "Complete!"Common Use Cases
- Transaction queue management in the cache system
- Coordinating async operations across components
- Building custom async control flow
batchAsync
Batches multiple async function calls into a single execution based on batch size and time constraints.
batchAsync<T, S extends Function, U>(
f: S, // Function to batch
opts: {
batchSize: number; // Max items before flush
maxSecondsRetention: number; // Max seconds before flush
}
): (...params: S[]) => Promise<void>Usage Example
// Create a batched API call
const batchedSave = batchAsync(
async (items) => {
await api.bulkSave(items);
},
{ batchSize: 100, maxSecondsRetention: 5 }
);
// Items are collected and sent in batches
batchedSave(item1);
batchedSave(item2);
batchedSave(item3);
// Automatically flushes when 100 items or 5 secondsBehavior
- Accumulates parameters until batch size is reached
- Sets up interval to flush after maxSecondsRetention
- Waits for previous batch to complete before starting new one
Counters
Simple named counter utility for tracking quantities (e.g., concurrent transactions).
const counters = Counters();
counters.increment("transactions"); // 1
counters.increment("transactions"); // 2
counters.get("transactions"); // 2
counters.decrement("transactions"); // 1 (min: 0)
counters.getAll(); // { transactions: 1 }
counters.table("Debug"); // Logs table to console| Method | Description |
|---|---|
| increment(name) | Increase counter by 1 |
| decrement(name) | Decrease counter by 1 (min: 0) |
| get(name) | Get current value (default: 0) |
| getAll() | Get all counters as object |
| table(title?) | Log all counters as console.table |
getBase64
Convert a File object to a base64-encoded data URL string.
function getBase64(file: File | undefined): Promise<string>Usage Example
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const base64 = await getBase64(file);
// "data:image/png;base64,iVBORw0KGgo..."
// Use for preview or upload
img.src = base64;Error: Throws if file is undefined.
resizeImage
Resize an image blob to fit within a maximum dimension while maintaining aspect ratio.
function resizeImage(src: Blob): Promise<string>
// Default dimensions
const defaults = {
width: 180,
height: 180
};Usage Example
const imageBlob = await fetch(imageUrl).then(r => r.blob());
// Resize to fit in 180x180 box
const resizedDataUrl = await resizeImage(imageBlob);
// Use for thumbnails
thumbnail.src = resizedDataUrl;Behavior
- Maintains aspect ratio
- Uses createImageBitmap for high-quality resize
- Returns base64 data URL (toDataURL)
- Default max size: 180x180 pixels
Stats
Performance timing utility for measuring operation durations.
const stats = Stats();
stats.start("apiCall");
await fetch("/api/data");
stats.end("apiCall");
console.log(stats.get("apiCall")); // Duration in ms
console.log(stats.getNoGap("apiCall")); // Total time since start
stats.table("Performance"); // Log all stats| Method | Description |
|---|---|
| start(name) | Start timing for named stat |
| end(name) | Stop timing and accumulate duration |
| get(name) | Get accumulated time in ms |
| getNoGap(name) | Get total elapsed time since first start |
| showAll() | Get all stats as object |
| table(title?) | Log all stats as console.table |
Advanced Usage
// Track multiple operations
stats.start("fetch");
const data = await fetchData();
stats.end("fetch");
stats.start("process");
const processed = processData(data);
stats.end("process");
stats.start("save");
await saveData(processed);
stats.end("save");
// View breakdown
stats.table("Pipeline Performance");
// | Name | Duration (ms) |
// |---------|---------------|
// | fetch | 245 |
// | process | 12 |
// | save | 89 |Summary
| Utility | File | Purpose |
|---|---|---|
| XPromise | XPromise.ts | Externally resolvable promise |
| batchAsync | batchAsync.ts | Batch async calls by size/time |
| Counters | counters.ts | Named counter tracking |
| getBase64 | getBase64.ts | File to base64 conversion |
| resizeImage | resizeImage.ts | Image thumbnail generation |
| Stats | stats.ts | Performance timing |