今日已更新 84 条资讯 | 累计 37333 条内容
关于我们

标签:#signal

找到 10 篇相关文章

AI 资讯

validateHttp() Has No Async Machinery: A Trace From Signal Forms Down to fetch() 🔍🚀

Let's be honest: async validation is the part of any forms library where you brace yourself. Debouncing, cancelling the request the user just invalidated by typing another character, keeping a "checking..." spinner honest, not letting a slow response overwrite a fast one. Every library that has ever done this has grown a pile of bespoke machinery for it. So when Signal Forms shipped validateHttp() and it just worked, I wanted to see the pile. I opened the source expecting a few hundred lines of async bookkeeping, and instead found a function whose entire body is a single call to something else. That turned into a trace all the way down, from a form field to the line where bytes actually leave the browser. Six layers, and only two of them add anything you could call new async machinery. ✅ Availability: validateHttp() is @publicApi 22.0 , stable. Every source reference in this article is pinned to the v22.1.1 tag , so the line numbers stay valid even as main moves. 🧩 The View From Outside The usage is unremarkable, which is the point. You declare that a field validates against an endpoint, and you're done: const schema = form ( this . model , ( path ) => { validateHttp ( path . username , { request : ({ value }) => `/api/username-available?u= ${ value ()} ` , debounce : 300 , onError : () => ({ kind : ' server-unreachable ' }), onSuccess : ( res : { available : boolean }) => res . available ? undefined : { kind : ' username-taken ' }, }); }); Sync validators run first, the request waits until they pass, field().pending() is true while it's in flight, and typing again cancels the previous call. If you've read Part 3 of my Signal Forms series , that's the behaviour contract you already know. The question here is who implements it. 🔍 Layer 1: validateHttp() Is a Delegation Here is the whole function, from validate_http.ts : export function validateHttp ( path , opts ) { validateAsync ( path , { params : opts . request , debounce : opts . debounce , factory : ( request )

2026-08-27 原文 →
AI 资讯

AI Reviewing AI Is Not Review

Originally published at tddbuddy.com . Related reading: Where the Review Point Moved is the direct predecessor; this post argues the industry's response to that shift is doubling down on the wrong surface at higher throughput. What "Senior" Means When Typing Is Free and The Test Pyramid Was an Economic Argument name where signal actually lives now. The review agent left fourteen comments on the pull request and none of them were the reason the PR should not have merged. That is the shape of the failure. The reviewer that shipped the review was a tool built to catch what a human reviewer no longer had time for. Three of the comments were genuine issues, unused imports, a typo in a log message, a dead branch. Eleven were style opinions, restatements of what the diff already made obvious, or false positives on patterns the codebase had chosen deliberately. The human on the PR spent more time filtering the review than reading the diff. The change that actually needed a second pair of eyes (a renamed field in a shared DTO that had already broken a downstream consumer twice this year) merged without a comment on it from either the human or the machine. The industry response to agent-generated pull-request volume has been to deploy more agents. The response is understandable. It is also empirically counterproductive. A 2026 study measured what happens when only a code-review agent reviews an agent-authored PR: 60.2% of closed pull requests sat in the 0 to 30 percent signal-ratio range, and twelve of the thirteen review agents evaluated averaged below a 60% signal ratio. Signal is what a human reviewer needs. The review agent produces less of it per unit of reviewer attention than the diff would have without a bot in the middle. The Volume Problem Is Real Four hundred thousand pull requests in two months from a single code-writing agent. One in five reviews on the largest hosting platform now involves an agent. Pickup time on agent-authored PRs is 5.3 times longer than on h

2026-08-20 原文 →
开发者

I built a Signals-first toolkit for Angular. Here is the problem I could not stop hitting.

Every Angular application I have worked on in the last few years had the same three kinds of state: URL state — the page number, the active filter, the selected tab. Client state — what the user typed, what is expanded, what is selected. Server state — the thing you fetched, and everything that can go wrong while fetching it. And every application handled them three completely different ways. ActivatedRoute and a Router.navigate call for the first. Signals or a store for the second. A service returning an Observable , plus a loading boolean, plus an error field, plus a subscribe somewhere, for the third. None of that is wrong. It is just that the glue between them is written by hand, in every app, every time. And the glue is where the bugs live. This article is about the specific piece of that problem I could not let go of, and about the toolkit I ended up building around it. It is called craft-ng , it is in beta, and I would genuinely rather have your objections than your stars. The code I kept running into Here is the shape. I should be honest: I did not write much of it myself — I had a drawer of RxJS helpers that hid most of it. But I have read it in a lot of codebases, reviewed it in a lot of pull requests, and inherited it in a lot of projects. That turned out to matter more, because a helper that only I understand is not a solution to anything. @ Injectable () export class TaskListService { private http = inject ( HttpClient ); tasks = signal < Task [] > ([]); isLoading = signal ( false ); error = signal < string | null > ( null ); load ( done : boolean ) { this . isLoading . set ( true ); this . error . set ( null ); this . http . get < Task [] > ( `/api/tasks?done= ${ done } ` ). subscribe ({ next : ( tasks ) => { this . tasks . set ( tasks ); this . isLoading . set ( false ); }, error : ( err ) => { this . error . set ( ' Something went wrong ' ); this . isLoading . set ( false ); }, }); } } Four fields, one method, and roughly six ways to get it subtly wr

2026-08-11 原文 →
AI 资讯

Signal vs. Noise in Code Evaluations: How to Accurately Measure Developer Skill

Originally published on tamiz.pro . The Signal: Core Developer Competencies Effective code evaluations must identify signal - the skills that directly impact software quality and long-term maintainability. Focus on: Problem-Solving Approach : How candidates break down complex problems Code Structure : Organization, modularity, and separation of concerns Edge Case Handling : Proactive identification of boundary conditions Test Coverage : Implementation of meaningful unit/integration tests Performance Awareness : Appropriate algorithm selection and resource management These elements predict real-world engineering capabilities, not just syntax mastery. The Noise: Common Evaluation Pitfalls Avoid overemphasizing noise - factors that correlate weakly with actual job performance: Noise Factor Why It Fails Signal Alternative Coding style Reflects personal preference Consistency within project conventions Syntax errors Easily fixed with linters Code correctness after tooling Solution speed Varies by individual Final solution quality Language trivia Library/framework knowledge changes Core programming principles Interview anxiety Doesn't reflect daily work Paired programming sessions Measuring Signal Effectively Task Design : Create realistic coding challenges that mirror production problems Rubric-Based Evaluation : Use weighted scoring matrices focused on signal factors Code Review Simulations : Evaluate candidates' ability to interpret and improve existing codebases Collaboration Metrics : Track communication clarity during pair programming sessions Iterative Development : Assess how well candidates refine solutions based on feedback Signal Amplification Techniques Time-Bounded Challenges : Set strict time limits to reduce focus on perfectionism Tooling Freedom : Allow candidates to use their preferred IDEs and debugging tools Post-Coding Debrief : Ask candidates to explain their design choices and tradeoffs Follow-Up Questions : Test understanding of implementation decis

2026-07-09 原文 →
AI 资讯

Why I Stopped Writing tap() Inside rxResource Streams

There's a pattern I see a lot in Angular codebases that adopted Signals early: a developer discovers rxResource , loves that it handles loading and error state automatically, and then immediately reaches for tap() to write a signal inside the stream. private readonly resource = rxResource ({ params : () => this . paramsSignal (), stream : ({ params }) => this . api . fetch ( params ). pipe ( tap ( data => this . sideSignal . set ( data . meta )) // 💥 ) }); This looks harmless. It runs in development without complaint in zone-based Angular. Then you enable zoneless — or Angular tightens its reactive graph enforcement — and you get NG0600: Writing to signals is not allowed in a reactive context . The rxResource stream runs inside Angular's reactive scheduler. Signal writes there aren't just discouraged — they're illegal by design. The scheduler assumes computed signals and reactive contexts are read-only during evaluation. A write mid-computation breaks the glitch-free guarantee Angular's signal graph is built on. The fix I landed on: make the stream return everything it needs to return, as a single typed value. interface ResourceValue { readonly sections : Section []; readonly meta : Meta ; } private readonly resource = rxResource < ResourceValue , Params > ({ stream : ({ params }) => this . api . fetch ( params ). pipe ( map ( data => ({ sections : transform ( data ), meta : data . meta })) ) }); No tap . No side signal. Everything the rest of the store needs lives in resource.value() and can be read via computed . The lesson isn't "don't use tap". The lesson is that rxResource has a contract: it is a read primitive . Its stream is for fetching and transforming. If you're writing signals inside it, you're treating it as a command bus — and that's a different tool. Originally published on ysndmr.com .

2026-07-08 原文 →
AI 资讯

Signal Forms vs. Reactive Forms: When Should You Upgrade Your Forms? (Angular 22 Guide)

TL;DR — Angular 22 promoted Signal Forms from experimental to stable. This is not "Reactive Forms are dead." It's a real architectural trade-off, and this post walks through both APIs in full, with production-realistic code, so you can decide feature-by-feature instead of framework-war-by-framework-war. Table of Contents Why This Matters Now The Core Question Reactive Forms: Why It Became the Standard Full Example: Reactive Forms Login Where Reactive Forms Still Excel Signal Forms: What Actually Changed in Angular 22 Full Example: Signal Forms Login Where Signal Forms Shine Side-by-Side: Core Concepts Mapped Deep Dive: Validation Synchronous Validation Cross-Field Validation Conditional Validation with when() Async Validation Deep Dive: Dynamic and Nested Forms Nested Form Groups Dynamic Collections (FormArray-style) Deep Dive: Form State — Dirty, Touched, Errors, Submission Developer Experience and Testing Performance Considerations Interop: Migrating Without a Big-Bang Rewrite Migration Strategy for Enterprise Teams When NOT to Migrate Decision Framework FAQ Closing Thoughts Why This Matters Now With Angular 22 (released June 3, 2026), Signal Forms left experimental status and became part of the stable, supported API — alongside resource() and httpResource() . That's a meaningful milestone: it means the Angular team ran extensive internal case studies across real form-heavy applications at Google before committing to stability, and the interop story with Reactive Forms has matured enough that a big-bang rewrite is no longer the only migration path. At the same time, Angular 22 also flips two important defaults: components now use OnPush change detection by default, and zoneless change detection continues its push toward becoming the standard. Signal Forms is part of that same story — Angular's reactivity model finally speaking one dialect end-to-end, from component state to form state to async data. None of this makes Reactive Forms obsolete. It changes what "the

2026-07-07 原文 →
AI 资讯

Why we kept named MCP tools despite a 96% token saving

The boat-agent stack here runs on a prime directive: if there's something usable out there, improve it; build our own only as a last resort. So when we needed a SignalK MCP server, the honest first move wasn't to write one — it was to evaluate the one that already exists. VesselSense/signalk-mcp-server (TypeScript, MIT) is good work. It exposes SignalK to an agent through a single execute_code tool: the model writes JavaScript, the server runs it in a sandboxed V8 isolate ( isolated-vm ), and only the result comes back. Its README claims a 90–96% token reduction versus traditional named MCP tools — 2,000 tokens down to 120 for a vessel-state query, 13,000 down to 300 for a multi-call workflow. Those numbers are plausible, and they line up with the broader industry result that code execution beats tool-calling on token efficiency for complex multi-step work. We read it, ran the numbers against our own agent, and kept our discrete-named-tool signalk-mcp anyway — then harvested three of VesselSense's ideas into our roadmap. This post is that evaluation: the two philosophies, why the obvious-sounding win doesn't bind for a voice-first agent, and a decision framework you can reuse before you adopt-or-build your own MCP server. This is a design-reasoning post, not a debugging saga, but it maps to the same arc: a question, the dead-end that looks like an obvious yes, and the call that actually held. The question Two SignalK MCP servers, two genuinely different designs: VesselSense/signalk-mcp-server sailingnaturali/signalk-mcp ───────────────────────────── ─────────────────────────── one tool: execute_code discrete named tools: → agent writes JavaScript read_sensor(path) → runs in a V8 isolate battery_state(bank) → queries SignalK, returns depth_state() only the result get_route() get_local_time() TypeScript / Node + isolated-vm list_paths(prefix) claims 90–96% fewer tokens get_active_alarms() Python, end-to-end The adopt-vs-keep question: does the token-efficiency win bin

2026-06-24 原文 →