Recent Posts
Archives

Posts Tagged ‘TypeScript’

PostHeaderIcon [DotJs2024] The Future of Serverless is WebAssembly

Envision a computing paradigm where applications ignite with the swiftness of a spark, unbound by the sluggish boot times of traditional servers, and orchestrated in a symphony of polyglot harmony. David Flanagan, a seasoned software engineer and educator with a storied tenure at Fermyon Technologies, unveiled this vision at dotJS 2024, championing WebAssembly (Wasm) as the linchpin for next-generation serverless architectures. Drawing from his deep immersion in cloud-native ecosystems—from Kubernetes orchestration to edge computing—Flanagan demystified how Wasm’s component model, fortified by WASI Preview 2, ushers in nanosecond-scale invocations, seamless interoperability, and unprecedented portability. This isn’t mere theory; it’s a blueprint for crafting resilient microservices that scale effortlessly across diverse runtimes.

Flanagan’s discourse pivoted on relatability, eschewing abstract metrics for visceral analogies. To grasp nanoseconds’ potency—where a single tick equates to a second in a thrashing Metallica riff like “Master of Puppets”—he likened Wasm’s cold-start latency to everyday marvels. Traditional JavaScript functions, mired in milliseconds, mirror a leisurely coffee brew at Starbucks; Wasm, conversely, evokes an espresso shot from a high-end machine, frothy and instantaneous. Benchmarks underscore this: Spin, Fermyon’s runtime, clocks in at 200 nanoseconds versus AWS Lambda’s 100-500 milliseconds, a gulf vast enough to render prior serverless pains obsolete. Yet, beyond velocity lies versatility—Wasm’s binary format, agnostic to origin languages, enables Rust, Go, Zig, or TypeScript modules to converse fluidly via standardized interfaces, dismantling silos that once plagued polyglot teams.

At the core lies the WIT (WebAssembly Interface Types) component model, a contractual scaffold ensuring type-safe handoffs. Flanagan illustrated with a Spin-powered API: a Rust greeter module yields to a TypeScript processor, each oblivious to the other’s internals yet synchronized via WIT-defined payloads. This modularity extends to stateful persistence—key-value stores mirroring Redis or SQLite datastores—without tethering to vendor lock-in. Cron scheduling, WebSocket subscriptions, even LLM inferences via Hugging Face models, integrate natively; a mere TOML tweak provisions MQTT feeds or GPU-accelerated prompts, all sandboxed for ironclad isolation. Flanagan’s live sketches revealed Spin’s developer bliss: CLI scaffolds in seconds, hot-reloading for iterative bliss, and Fermyon Cloud’s edge deployment scaling to zero cost.

This tapestry of traits—rapidity, portability, composability—positions Wasm as serverless’s salvation. Flanagan evoked Drupal’s Wasm incarnation: a full CMS, sans server, piping content through browser-native execution. For edge warriors, it’s liberation; for monoliths, a migration path sans rewrite. As toolchains mature—Wazero for Go, Wasmer for universal hosting—the ecosystem beckons builders to reimagine distributed systems, where functions aren’t fleeting but foundational.

Nanosecond Precision in Practice

Flanagan anchored abstractions in benchmarks, equating Wasm’s 200ns starts to life’s micro-moments—a blink’s brevity amplified across billions of requests. Spin’s plumbing abstracts complexities: TOML configs summon Redis proxies or SQLite veins, yielding KV/SQL APIs that ORMs like Drizzle embrace. This precision cascades to AI: one-liner prompts leverage remote GPUs, democratizing inference without infrastructural toil.

Polyglot Harmony and Extensibility

WIT’s rigor ensures Rust’s safety meshes with Go’s concurrency, TypeScript’s ergonomics—all via declarative interfaces. Spin’s extensibility invites custom components; 200 Rust lines birth integrations, from Wy modules to templated hooks. Flanagan heralded Fermyon Cloud’s provisioning: edge-global, zero-scale, GPU-ready— a canvas for audacious architectures where Wasm weaves the warp and weft.

Links:

PostHeaderIcon [DevoxxBE2023] A Deep Dive into Advanced TypeScript: A Live Coding Expedition by Christian Wörz

Christian Wörz, a seasoned full-stack engineer and freelancer, captivated the Devoxx Belgium 2023 audience with a hands-on exploration of advanced TypeScript features. Through live coding, Christian illuminated powerful yet underutilized constructs like mapped types, template literals, conditional types, and recursion, demonstrating their practical applications in real-world scenarios. His session, blending technical depth with accessibility, empowered developers to leverage TypeScript’s full potential for creating robust, type-safe codebases.

Mastering Mapped Types and Template Literals

Christian kicked off with mapped types, showcasing their ability to dynamically generate type-safe structures. He defined an Events type with add and remove properties and created an OnEvent type to prefix event keys with “on” (e.g., onAdd, onRemove). Using the keyof operator and template literal syntax, he ensured that OnEvent mirrored Events, enforcing consistency. For instance, adding a move event to Events required updating OnEvent to onMove, providing compile-time safety. He enhanced this with TypeScript’s intrinsic Capitalize function to uppercase property names, ensuring precise naming conventions.

Template literals were explored through a chessboard example, where Christian generated all possible positions (e.g., A1, B2) by combining letter and number types. He extended this to a CSS validator, defining a GapCSS type for properties like margin-left and padding-top, paired with valid CSS sizes (e.g., rem, px). This approach narrowed string types to enforce specific formats, preventing errors like invalid CSS values at compile time.

Leveraging Conditional Types and Never for Safety

Christian delved into conditional types and the never type to enhance compile-time safety. He introduced a NoEmptyString type that prevents empty strings from being assigned, using a conditional check to return never for invalid inputs. Applying this to a failOnEmptyString function ensured that only non-empty strings were accepted, catching errors before runtime. He also demonstrated exhaustive switch cases, using never to enforce complete coverage. For a getCountryForLocation function, assigning an unhandled London case to a never-typed variable triggered a compile-time error, ensuring all cases were addressed.

Unraveling Types with Infer and Recursion

The infer keyword was a highlight, enabling Christian to extract type information dynamically. He created a custom MyReturnType to mimic TypeScript’s ReturnType, inferring a function’s return type (e.g., number for an addition function). This was particularly useful for complex type manipulations. Recursion was showcased through an UnnestArray type, unwrapping deeply nested arrays to access their inner types (e.g., extracting string from string[][][]). He also built a recursive Tuple type, generating fixed-length arrays with specified element types, such as a three-element RGB tuple, with an accumulator to collect elements during recursion.

Branded Types for Enhanced Type Safety

Christian concluded with branded types, a technique to distinguish specific string formats, like emails, without runtime overhead. By defining an Email type as a string intersected with an object containing a _brand property, he ensured that only validated strings could be assigned. A type guard function, isValidEmail, checked for an @ symbol, allowing safe usage in functions like sendEmail. This approach maintained the simplicity of primitive types while enforcing strict validation, applicable to formats like UUIDs or custom date strings.

Links:

PostHeaderIcon [NodeCongress2021] Safely Handling Dynamic Data with TypeScript – Ethan Arrowood

In the realm of full-stack development, where APIs shuttle payloads across boundaries, ensuring type fidelity amid flux poses a perennial puzzle. Ethan Arrowood, a software engineer at Microsoft, navigates this terrain adeptly, advocating schemas as sentinels against runtime surprises. His discourse spotlights TypeScript’s prowess in taming erratic inputs—from form submissions to auth tokens—via symbiotic validation frameworks.

Ethan posits data as the lifeblood of modern apps: JSON’s ubiquity powers endpoints, yet its pliancy invites mismatches. Consider an employee dossier: id, name, employed boolean, company, age, projects array. Static typings guard assignments, but external fetches evade compile-time checks, risking undefined accesses or coerced primitives. Ethan’s remedy? Leverage JSON Schema for declarative constraints, transmuting fluid objects into rigid molds.

Bridging Schemas and Static Guarantees

Enter @sinclair/typebox, a runtime validator that births schemas from TypeScript generics, yielding dual benefits: enforcement and inference. Ethan illustrates with Fastify routes: define bodySchema as TypeBox’s TObject, embedding TString for id/name, TOptional(TBoolean) for employed, mirroring anticipated shapes. This artifact doubles as validator—Fastify’s schema prop ingests it for payload scrutiny—and type oracle, infusing handlers with precise annotations.

In practice, a POST endpoint parses body as TInfer, affording intellisense: body.name yields string, body.age number|undefined. Ethan live-codes this synergy, hovering reveals nested generics—TArray(TString) for projects—ensuring downstream ops like array iterations sidestep guards. Should validation falter, Fastify aborts with 400s, averting tainted flows.

This fusion extends to broader ecosystems: io-ts for branded types, Zod for ergonomic chaining. Ethan cautions reliance on validation logic; a flawed schema propagates peril, echoing JavaScript’s untyped underbelly. Yet, when aligned, it forges ironclad pipelines, where dynamic ingress aligns seamlessly with static egress.

Real-World Integrations and Ecosystem Synergies

Ethan’s Fastify demo crystallizes the workflow: register plugins, await readiness, log addresses— all scaffolded atop schema-derived types. VS Code’s hover unveils the schema’s blueprint, from optional fields to array innards, streamlining refactoring. For authentication, schemas vet JWT claims; forms, user inputs—universal applicability.

Gratitude flows to undraw for visuals, highlight.js for syntax, and tmcw/big for slides, underscoring open-source’s scaffolding role. Ethan’s ethos—connect via GitHub/Twitter—invites dialogue, amplifying Node.js and TypeScript’s communal momentum. By entwining validation with typing, developers reclaim assurance, rendering volatile data a predictable ally in resilient architectures.

Links:

PostHeaderIcon [KotlinConf2019] Exploring the Power of Kotlin/JS

Sebastian Aigner, a developer advocate at JetBrains, captivated KotlinConf2019 with his deep dive into Kotlin/JS, the JavaScript target for Kotlin. With a passion for web development, Sebastian showcased how recent advancements make Kotlin/JS a compelling choice for building web applications. From streamlined tooling to seamless JavaScript interoperability, he outlined the current state and future potential of Kotlin/JS, inspiring both newcomers and seasoned developers to leverage Kotlin’s paradigms in the browser.

Simplifying Development with the New Gradle Plugin

Kotlin/JS has evolved significantly, with the new Kotlin/JS Gradle plugin emerging as the cornerstone for browser and Node.js development. Sebastian explained that this plugin unifies previously fragmented approaches, replacing deprecated plugins like kotlin2js and kotlin-frontend. Its uniform Gradle DSL simplifies project setup, offering sensible defaults for Webpack bundling without requiring extensive configuration. For developers transitioning to multi-platform projects, the plugin’s compatibility with the Kotlin multi-platform DSL minimizes changes, enabling seamless integration of additional targets. By automating JavaScript environment setup, including yarn and package.json, the plugin empowers Kotlin developers to focus on coding rather than managing complex JavaScript tooling.

Mastering Dependency Management with npm

The JavaScript ecosystem, with over a million npm packages, offers unparalleled flexibility, and Kotlin/JS integrates effortlessly with this vast library. Sebastian highlighted how the Gradle plugin manages npm dependencies directly, automatically updating package.json when dependencies like React or styled-components are added. This eliminates the need for separate JavaScript environment setup, saving time, especially on non-standard platforms like Windows. Developers can import Kotlin libraries (e.g., coroutines, serialization) alongside JavaScript packages, with Gradle handling the JavaScript-specific versions. This unified approach bridges the gap between Kotlin’s structured ecosystem and JavaScript’s dynamic world, making dependency management intuitive even for those new to JavaScript.

Bridging Kotlin and TypeScript with Dukat

Interoperating with JavaScript’s dynamic typing can be challenging, but Sebastian introduced Dukat, an experimental tool that converts TypeScript declaration files into Kotlin external declarations. By leveraging TypeScript’s de facto standard for type definitions, Dukat enables type-safe access to npm packages, such as left-pad or react-minimal-pie-chart. While manual external declarations require tedious annotation, Dukat automates this process, generating headers for packages with TypeScript support or community-contributed definitions. Sebastian encouraged early adoption to provide feedback, noting that Dukat already powers browser and Node.js API wrappers. This tool promises to simplify integration with JavaScript libraries, reducing the friction of crossing the static-dynamic typing divide.

Enhancing Testing and Debugging with Source Maps

Testing and debugging are critical for robust applications, and Kotlin/JS delivers with integrated tools. Sebastian demonstrated how the Gradle plugin supports platform-specific test runners like Karma, allowing tests to run across browsers (e.g., Firefox, headless Chrome). Source maps, automatically generated since Kotlin 1.3.60, provide detailed stack traces for Node.js and interactive debugging in browser DevTools. Developers can set breakpoints in Kotlin code, inspect variables, and trace errors directly in Chrome’s console, as shown in Sebastian’s pong game demo. Gradle test reports further enhance diagnostics, offering HTML-based insights into test failures, making Kotlin/JS development as robust as its JVM counterpart.

Optimizing with the IR Backend

The upcoming Intermediate Representation (IR) backend marks a significant leap for Kotlin/JS. Sebastian outlined its benefits, including aggressive code size optimizations through dead code elimination. Unlike the current backend, which may ship the entire standard library, the IR backend, combined with Google Closure Compiler, reduces zipped file sizes dramatically—down to 30 KB from 3.9 MB in some cases. Faster compilation speeds, especially for incremental builds, enhance developer productivity, particularly in continuous build scenarios with Webpack’s dev server. The IR backend also supports platform-agnostic compiler plugins, simplifying multi-platform development. Sebastian noted that pre-alpha IR support in Kotlin 1.3.70 requires manual exports due to its closed-world assumption, urging developers to explore early releases.

Looking Ahead: WebAssembly and Framework Support

Sebastian concluded with a glimpse into Kotlin/JS’s future, highlighting potential support for ECMAScript 6 modules and frameworks like Angular and Vue.js. While JetBrains provides React wrappers, extending first-class support to other frameworks requires addressing their unique tooling and compilers. The IR backend also opens doors to WebAssembly, enabling Kotlin to target browsers more efficiently. Though no timelines were promised, these explorations reflect JetBrains’ commitment to aligning Kotlin/JS with modern web trends. Sebastian’s call to action—trying the Code Quiz app at the Kotlin booth and contributing to Dukat—emphasized community involvement in shaping Kotlin/JS’s evolution.

Links: