Web APIs
Andromeda provides implementations of standard web APIs to ensure compatibility with existing web code and standards. This includes event handling, text encoding, and other essential web platform features.
Overview
The Web APIs in Andromeda follow WHATWG specifications and provide a familiar programming model for developers coming from browser environments.
Event API
Event Class
The Event API provides a standard way to handle events, following the WHATWG HTML Living Standard for event handling.
Constructor
new Event(type: string, eventInitDict?: EventInit)
Creates a new Event object.
Parameters:
type
: The event type (e.g., "click", "load", "custom")eventInitDict
(optional): Configuration object with properties:bubbles
: Whether the event bubbles (default: false)cancelable
: Whether the event can be canceled (default: false)composed
: Whether the event will trigger listeners outside of a shadow root (default: false)
Properties
type
: The event type stringtarget
: The event target (read-only)currentTarget
: The current target during event propagation (read-only)eventPhase
: The current phase of event propagation (read-only)bubbles
: Whether the event bubbles (read-only)cancelable
: Whether the event can be canceled (read-only)defaultPrevented
: Whether preventDefault() was called (read-only)isTrusted
: Whether the event was generated by user action (read-only)timeStamp
: The time when the event was created (read-only)
Methods
preventDefault(): void
Cancels the event's default action if it's cancelable.
const event = new Event("submit", { cancelable: true });
event.preventDefault();
console.log(event.defaultPrevented); // true
stopPropagation(): void
Stops the event from propagating further through the event flow.
const event = new Event("click", { bubbles: true });
event.stopPropagation();
// Event will not bubble to parent elements
stopImmediatePropagation(): void
Stops the event from propagating and prevents other listeners on the same element from being called.
element.addEventListener("click", (event) => {
event.stopImmediatePropagation();
// Other click listeners on this element won't be called
});
Event Usage Examples
Creating Custom Events
// Create a simple custom event
const customEvent = new Event("myCustomEvent");
// Create an event with options
const configurableEvent = new Event("userAction", {
bubbles: true,
cancelable: true,
});
// Check event properties
console.log(customEvent.type); // "myCustomEvent"
console.log(customEvent.bubbles); // false
console.log(configurableEvent.bubbles); // true
Event Handling Patterns
// Event listener function
function handleCustomEvent(event: Event) {
console.log(`Received event: ${event.type}`);
if (event.cancelable) {
event.preventDefault();
console.log("Default action prevented");
}
}
// Create and dispatch custom event
const event = new Event("dataProcessed", {
bubbles: false,
cancelable: true,
});
// Simulate event handling
handleCustomEvent(event);
Event State Management
class EventProcessor {
processEvent(event: Event): boolean {
// Check if event is valid for processing
if (!event.isTrusted) {
console.warn("Untrusted event, skipping processing");
return false;
}
// Process different event phases
switch (event.eventPhase) {
case Event.CAPTURING_PHASE:
console.log("Event in capturing phase");
break;
case Event.AT_TARGET:
console.log("Event at target");
break;
case Event.BUBBLING_PHASE:
console.log("Event in bubbling phase");
break;
}
return true;
}
}
Text Encoding API
The Text Encoding API provides utilities for encoding and decoding text, implementing the WHATWG Encoding Standard.
TextEncoder
Encodes strings into UTF-8 byte sequences.
TextEncoder Constructor
new TextEncoder();
Creates a new TextEncoder instance. Always uses UTF-8 encoding.
TextEncoder Properties
encoding
: Always returns "utf-8"
TextEncoder Methods
encode(input?: string): Uint8Array
Encodes a string into a Uint8Array of UTF-8 bytes.
const encoder = new TextEncoder();
// Encode ASCII text
const ascii = encoder.encode("Hello, World!");
console.log(ascii); // Uint8Array with UTF-8 bytes
// Encode Unicode text
const unicode = encoder.encode("你好世界");
console.log(unicode); // Uint8Array with UTF-8 bytes for Chinese characters
// Empty string
const empty = encoder.encode("");
console.log(empty.length); // 0
encodeInto(source: string, destination: Uint8Array): TextEncoderEncodeIntoResult
Encodes a string into an existing Uint8Array buffer.
const encoder = new TextEncoder();
const buffer = new Uint8Array(50);
const result = encoder.encodeInto("Hello, 世界!", buffer);
console.log(result.read); // Number of characters read
console.log(result.written); // Number of bytes written
TextDecoder
Decodes byte sequences into strings using specified encoding.
TextDecoder Constructor
new TextDecoder(label?: string, options?: TextDecoderOptions)
Creates a new TextDecoder instance.
Parameters:
label
(optional): The encoding label (default: "utf-8")options
(optional): Configuration object:fatal
: Whether to throw on invalid sequences (default: false)ignoreBOM
: Whether to ignore byte order mark (default: false)
TextDecoder Properties
encoding
: The encoding being usedfatal
: Whether fatal error mode is enabledignoreBOM
: Whether BOM is ignored
TextDecoder Methods
decode(input?: BufferSource, options?: TextDecodeOptions): string
Decodes a byte sequence into a string.
const decoder = new TextDecoder();
// Decode UTF-8 bytes
const bytes = new Uint8Array([72, 101, 108, 108, 111]); // "Hello"
const text = decoder.decode(bytes);
console.log(text); // "Hello"
// Streaming decode
const stream = { stream: true };
const partial1 = decoder.decode(bytes1, stream);
const partial2 = decoder.decode(bytes2, stream);
const final = decoder.decode(); // Finish stream
Text Encoding Examples
Basic Encoding/Decoding
const encoder = new TextEncoder();
const decoder = new TextDecoder();
// Round-trip encoding
const originalText = "Hello, 世界! 🌍";
const encoded = encoder.encode(originalText);
const decoded = decoder.decode(encoded);
console.log(originalText === decoded); // true
console.log(encoded.length); // Number of bytes (varies with Unicode)
Working with Different Text Types
const encoder = new TextEncoder();
const decoder = new TextDecoder();
// ASCII text
const ascii = "Simple ASCII text";
const asciiBytes = encoder.encode(ascii);
console.log(`ASCII: ${ascii.length} chars → ${asciiBytes.length} bytes`);
// Unicode text (2-byte characters)
const latin = "Café résumé naïve";
const latinBytes = encoder.encode(latin);
console.log(`Latin: ${latin.length} chars → ${latinBytes.length} bytes`);
// Unicode text (3-byte characters)
const chinese = "你好世界";
const chineseBytes = encoder.encode(chinese);
console.log(`Chinese: ${chinese.length} chars → ${chineseBytes.length} bytes`);
// Emoji (4-byte characters)
const emoji = "🌍🚀⭐";
const emojiBytes = encoder.encode(emoji);
console.log(`Emoji: ${emoji.length} chars → ${emojiBytes.length} bytes`);
Streaming Text Processing
const decoder = new TextDecoder();
function processTextStream(chunks: Uint8Array[]): string {
let result = "";
// Process all chunks except the last with streaming
for (let i = 0; i < chunks.length - 1; i++) {
result += decoder.decode(chunks[i], { stream: true });
}
// Process final chunk without streaming
if (chunks.length > 0) {
result += decoder.decode(chunks[chunks.length - 1]);
}
return result;
}
// Example usage with chunked data
const textData = "This is a long text that might be received in chunks";
const encoded = new TextEncoder().encode(textData);
// Split into chunks
const chunk1 = encoded.slice(0, 10);
const chunk2 = encoded.slice(10, 20);
const chunk3 = encoded.slice(20);
const reconstructed = processTextStream([chunk1, chunk2, chunk3]);
console.log(textData === reconstructed); // true
Error Handling
// Fatal mode - throws on invalid sequences
const fatalDecoder = new TextDecoder("utf-8", { fatal: true });
try {
// Invalid UTF-8 sequence
const invalidBytes = new Uint8Array([0xFF, 0xFE, 0xFD]);
const result = fatalDecoder.decode(invalidBytes);
} catch (error) {
console.error("Decoding failed:", error.message);
}
// Non-fatal mode - replaces invalid sequences
const tolerantDecoder = new TextDecoder("utf-8", { fatal: false });
const invalidBytes = new Uint8Array([0xFF, 0xFE, 0xFD]);
const result = tolerantDecoder.decode(invalidBytes);
console.log(result); // Contains replacement characters
Performance Optimization
// Reuse encoder/decoder instances
const globalEncoder = new TextEncoder();
const globalDecoder = new TextDecoder();
function efficientTextProcessing(texts: string[]): Uint8Array[] {
// Reuse the same encoder instance
return texts.map((text) => globalEncoder.encode(text));
}
// Pre-allocate buffers for encodeInto
const encoder = new TextEncoder();
const buffer = new Uint8Array(1024); // Reusable buffer
function encodeWithBuffer(text: string): Uint8Array {
const result = encoder.encodeInto(text, buffer);
return buffer.slice(0, result.written);
}
Validation and Testing
Text Encoding Validation
function validateTextEncoding(): boolean {
const encoder = new TextEncoder();
const decoder = new TextDecoder();
// Test cases
const testCases = [
"Hello, World!", // ASCII
"Café résumé", // Latin-1 supplement
"你好世界", // CJK
"🌍🚀⭐", // Emoji
"", // Empty string
"\0\x01\x02", // Control characters
];
for (const testCase of testCases) {
const encoded = encoder.encode(testCase);
const decoded = decoder.decode(encoded);
if (testCase !== decoded) {
console.error(`Failed for: "${testCase}"`);
return false;
}
}
console.log("✓ All text encoding tests passed");
return true;
}
// Run validation
validateTextEncoding();
Event System Testing
function testEventSystem(): boolean {
// Test basic event creation
const event1 = new Event("test");
if (event1.type !== "test" || event1.bubbles !== false) {
return false;
}
// Test event with options
const event2 = new Event("custom", { bubbles: true, cancelable: true });
if (!event2.bubbles || !event2.cancelable) {
return false;
}
// Test preventDefault
event2.preventDefault();
if (!event2.defaultPrevented) {
return false;
}
console.log("✓ All event tests passed");
return true;
}
// Run validation
testEventSystem();
Browser Compatibility
Andromeda's Web APIs are designed to be compatible with standard browser implementations:
- Event API: Follows WHATWG HTML Living Standard
- Text Encoding: Implements WHATWG Encoding Standard
- Standard Behavior: Compatible error handling and edge cases
- Performance: Optimized for server-side and CLI usage
Best Practices
Text Encoding
- Reuse Instances: Create encoder/decoder instances once and reuse them
- Handle Errors: Use fatal mode when data integrity is critical
- Stream Processing: Use streaming for large text data
- Buffer Management: Pre-allocate buffers for better performance
Events
- Use Standard Types: Use well-known event types when possible
- Configure Appropriately: Set bubbles and cancelable based on needs
- Handle Errors: Check event state before processing
- Performance: Avoid creating excessive event objects
Related APIs
- Console API - For debugging and logging
- Performance API - For timing and performance measurement
- Fetch API - For network requests using standard web APIs
- URL API - For URL parsing and manipulation