Inicio › Proyecto
Registro de cambios
AngeLite is a signals framework with Angular-style templates: a ~6 KB gzip core (precompiled), secure by default, with forms, HTTP, i18n, animations, router, SSR, DevTools and a 33-component
Esta página solo está disponible en inglés.
1.1.0 — English by default#
- UI defaults are English:
closeLabelis'Close',removeLabel'Remove',Spinner'Loading',Pagination'Previous'/'Next'/'Pagination'and'Page N'on page buttons,Combobox'Search…'/'No matches',Table'No data',CodeBlock'Copy'/'Copied',Dropdown'Menu',Popover'Open',Progress/Stepper'Progress',Rating'Rating',Breadcrumb'Breadcrumb',EmptyState'No results'. Pass the inputs to localize them. Behaviour change for anyone relying on the old Spanish defaults. @duvanjamid/angelite/ui/metais in English and its groups areBasics,Forms,Navigation,OverlaysandData.- README, CONTRIBUTING and ROADMAP are in English; the documentation site is English first, with a Spanish version.
1.0.0 — first release#
AngeLite is a signals framework with Angular-style templates: a ~6 KB gzip core (precompiled), secure by default, with forms, HTTP, i18n, animations, router, SSR, DevTools and a 33-component accessible UI library as optional modules. Everything below landed in this release.
Renamed: AngeLite is just AngeLite#
There is one framework now, so nothing carries the "lite" name any more. The package is new and unused, so this is a clean break with no aliases:
@duvanjamid/angeliteis the framework (it used to be@duvanjamid/angelite/lite). Subpaths lose the prefix:/runtime,/runtime-plus,/pipes,/testing,/forms,/http,/i18n,/devtools,/hydrate,/addons,/ui,/ui/meta,/tools/*.mjs.- Bundles:
dist/angelite.min.jsanddist/angelite.esm.js(wereangelite-lite.*); the global staysAngeLite. - Sources moved from
src/lite/tosrc/; tests lost theirlite-prefix; benchmark apps and result keys areangeliteandangelite-aot. - The old, unhardened framework (
src/angelite.js,src/core,src/decorators,src/directives,src/forms,src/pipes,src/router,test-app/,examples/) is removed; it stays in the git history. - New logo (pink mascot) and pink palette (
#d6336c,#ff6b9ain dark mode) over slate neutrals; the UI library follows it.
UI library v2 (@duvanjamid/angelite/ui)#
- 33 components (was 21), all accessible and keyboard-operable: Button, Badge, Chip, Avatar, Divider, Card, Alert, Spinner, Progress, Skeleton, EmptyState; TextField, Textarea, Select, Checkbox, RadioGroup, Toggle, Slider, Rating, Combobox; Tabs, Breadcrumb, Pagination, Stepper, AccordionItem, Dropdown; Modal, Drawer, Popover, Tooltip, Toasts; Table, CodeBlock.
- Accessibility: labels wired to controls (
for/id,aria-describedby,aria-invalid),role="switch"toggle, radiogroup rating, combobox pattern,aria-sorttables,aria-expanded/aria-controlsaccordions, live regions for alerts and toasts; Modal and Drawer move focus in, trap Tab, close on Escape, lock page scroll and give focus back; Dropdown, Tabs, Rating and Combobox have full arrow-key support;prefers-reduced-motionslows animations. - Theming: CSS variables (
--ui-*), dark mode follows the system or<html data-theme="light|dark">; the default palette now comes from the logo (teal and orange). Behaviour change:Toggleis a<button role="switch">,Tableheaders sort through buttons,Modalno longer swallows clicks withstopPropagationand its backdrop is detected by class,Tooltipis a focusable span with a realrole="tooltip",Ratingis a radiogroup,Paginationis windowed with ellipsis, andStepperis an ordered list. - New inputs on existing components (
type,block,disabled,readonly,required,hint,size,caption,dense,striped,rowKey,indeterminate...) andToastService.show(message, type, ms)withms: 0for sticky toasts plusclear(). - Each component is marked pure, so a bundler keeps only the ones imported (a Button-only app is ~7 KB gzip smaller than importing everything); the
dist/angelite-ui.min.jsbundle with all of them is ~11.8 KB gzip (budget raised on purpose from 5.5 KB). src/ui/meta.js(@duvanjamid/angelite/ui/meta): the documentation metadata (inputs, outputs, slots, accessibility notes) andtests/ui-meta.test.mjs, which fails if it drifts from the real components.- Found by the new tests: with delegated events
event.currentTargetis the document, so overlays must testevent.target.
Documentation moved#
The documentation site (guide with live examples, component library, benchmarks page, feature comparison, gap analysis, performance and security guides) now lives in duvanjamid/angelite-docs. docs/ is gone from this repository; npm run build:docs only prints where to go. The docs repository's scripts/sync.mjs rebuilds the bundles from this repository and brings the benchmark results.
Framework completeness, wave 2 (AngeLite)#
All of it is optional: separate modules built against the lite bundle (dist/angelite-<name>.esm.js, or angelite-addons.min.js with the global AngeLiteAddons for a plain <script>), so there is one reactive core and an app pays only for what it imports.
- Reactive forms (
lite/forms):FormControl,FormGroup(nested,get('a.b'), group validators),FormArray;value,errors,valid,touched,dirtyare signals, andvaluebinds with[(ngModel)]. Validators:required,minLength,maxLength,min,max,pattern,email,matches. No async validators yet. - HTTP (
lite/http):createHttp({ baseUrl, headers, interceptors })overfetch(JSON in and out, query params,timeout,AbortSignal,HttpError),retry()interceptor, andresource(() => ...):data/loading/errorsignals that reload when the signals the loader reads change and ignore stale answers. - i18n (
lite/i18n):createI18n()with a locale signal,{param}interpolation, plurals throughIntl.PluralRules, regional fallback, lazyload(), number/date/relative formatting, and the pipest,num,date. Messages are always text. - Animations (
animate.js, in the full bundle):animate.enter="cls"andanimate.leave="cls"; a leaving element stays in the DOM until its animation or transition ends (with a safety timeout) andprefers-reduced-motionis honoured. - Router:
historymode (provideRouter(routes, { mode: 'history', base })),router.query(),resolvefunctions withrouter.data(),navigate(to, { replace }). In history mode//hostpaths cannot leave the origin. - SSR (
tools/ssr.mjs):renderToString,renderPage(shell with<!--app-->and<!--state-->),serializeState(safe inside<script>); renders run in jsdom and are queued.hydrate()(lite/hydrate) replaces the server markup with the live app; it does not adopt the existing nodes. - DevTools (
lite/devtools):enableDevtools({ panel })exposeswindow.__ANGELITE__(tree,inspect,state,set) and an optional floating panel; component hosts now remember their instance ($c). - Tooling: Vite plugin (
tools/vite.mjs, reloads on template edits) andangelite-check(tools/check.mjs,file:1: messageoutput) that reuse the AOT template checks. - Core: element removal goes through a
detachhook so animated elements can finish leaving (+28 B on the precompiled benchmark app). - Size budgets now cover the add-ons (measured minified): forms 0.9 KB, http 1.3 KB, i18n 0.7 KB, devtools 0.9 KB, hydrate 0.1 KB, testing 0.7 KB gzip.
Framework completeness, wave 1 (AngeLite)#
Every optional piece lives in its own module, so an app that does not import it does not ship it (@duvanjamid/angelite/lite and /lite/runtime-plus include them; with a bundler import them from src/lite/).
- Named slots:
<ng-content select="x">receives the children that carryslot="x"; the rest still goes to the default<ng-content>. - Portals (
portal.js):<ng-portal to="#id">renders its content inside another element (defaultdocument.body), in the component's scope, and cleans up with its block. @defer(defer.js):@defer (on idle; on viewport; on interaction; on hover; on timer(2s); on immediate; when expr) { ... } @placeholder { ... }.- Template references (
refs.js):#name+viewChild('name')(a signal with the element, or the component instance on a component tag; back tonullwhen it leaves the DOM). - Error boundaries: a component with
ngOnError(error, where)receives the errors of its bindings and handlers and of the content projected into it; the nearest one up the tree wins; without any, errors are logged as before. - Scoped dependency injection:
component(X, { providers: [Service, { provide, useClass | useValue | useFactory }] })gives the component and its descendants their own instance;inject()outside any provider still returns the shared instance. - Router: nested routes (
children+ a<router-outlet>in the parent, which is not rebuilt when only the child changes),canActivateguards (true/false/ redirect path, sync or async, a newer navigation cancels an older one),load: () => import(...)code splitting,redirectTo.provideRouter()can be called again without stacking listeners. - TypeScript:
.d.tsfor the whole public API (types/), checked withtscin CI (npm run typecheck), including negative cases that must fail to compile. - Testing helpers (
@duvanjamid/angelite/lite/testing):render(Comp, { props, provide }),click,type,fire,flush,unmount,cleanup. - Development warnings (
enableDevWarnings()): unknown inputs on component tags, duplicate@forkeys, unknown elements, and optional modules that a template needs but were not imported. - Template checks in the AOT compiler: unknown elements, unknown pipes and, with
members(ormembers: 'auto'), names the component does not have;check: 'warn' | 'error' | false;checkTemplate()anddiscoverMembers()are exported. mount()returns{ instance, destroy }; newruntime-plusandtestingbundles.- The features table in
docs/benchmarks.htmlnow says where each framework provides each feature (integrated, optional module, official package, third party) and counts what ships in the package itself.
Cost: the in-browser compiler build grew from 9.1 KB to 10.0 KB gzip and the precompiled app from 5.8 KB to 6.0 KB (the hooks and the component context are in the core). Budgets in scripts/check-size.mjs were raised on purpose and benchmarks/size-lite.mjs measures both AngeLite apps without rebuilding the other frameworks.
Performance (AngeLite)#
- First paint: the root host created by
mount()now hasdisplay: contents(an inline host around block content made the browser split boxes: ~1.5 ms after mount). Behaviour change: style the element you mount into, or the component's own root, not the host. @forskips node placement entirely when a list update keeps the same keys in the same order; precompiled templates parse their HTML lazily.- Benchmark runner: startup is measured with interleaved, shuffled loads and 41 samples (p25/p75 reported);
STARTUP_ONLY=1andONLY=op1,op2re-run part of the suite.
Security hardening (AngeLite)#
- URL attributes (
href,src,action,formaction,data,xlink:href) only accepthttp,https,mailto,tel,sms,ftpand relative URLs; anything else becomesunsafe:<url>with a warning.trustUrl()allows your own scheme. Behaviour change. [innerHTML]only renders markup wrapped intrustHtml(); any other value is inserted as text. Behaviour change.- Compile-time errors (browser compiler and AOT tool) for
[on*],[attr.on*],on*="{{ }}",[srcdoc],[outerHTML], and for bindings/interpolation on<script>,<style>,<base>,<link>,<meta>. Behaviour change. - Expression sandbox: the global object and documents are never returned to a template (by value, whichever way they were reached) and DOM methods that turn strings into markup or attributes (
insertAdjacentHTML,setAttribute,write...) are blocked. - Trusted Types: templates and
trustHtml()values go through one policy namedangelite. - UI package: constructable stylesheets instead of an inline
<style>, with a nonce-aware fallback. SECURITY.md, CodeQL (security-extended), Dependabot andnpm auditin CI.tests/security.test.mjsholds the attack matrix; it fails if a gap is reopened.
Framework comparison#
docs/gap-analysis.md: what React, Preact, Vue and Angular have that AngeLite lacks (and the reverse), a security review, an architecture critique and a prioritised roadmap. Each claim says how it was verified.docs/benchmarks.htmlgains a 37-row feature comparison (security, speed, architecture, ecosystem) with the source of every datum.tests/security.test.mjs: enforced checks for what is already safe plus 6todotests for the known gaps (javascript:URLs,[attr.on*],[innerHTML],[srcdoc], window reachable through$el); they turn into real failures once flipped.benchmarks/security-probe.mjs(npm run probe:security) runs the same attack inputs against AngeLite, Preact, Vue and React.
AngeLite — runtime split and ahead-of-time templates#
- AngeLite is now split into a template-free runtime (
@duvanjamid/angelite/lite/runtime, ~4.5 KB gzip), a backend-agnostic compiler and an in-browser backend (jit.js).@duvanjamid/angelite/litestill compiles templates in the browser, with no build step. tools/aot.mjs(CLI + esbuild plugin) compiles templates to JS at build time so apps ship only the runtime. A test asserts precompiled templates render exactly like in-browser ones.- The expression parser is single-pass with a pluggable emitter (closures in the browser, JS source in the AOT tool) and is ~40% smaller.
- Built-in pipes are opt-in (
@duvanjamid/angelite/lite/pipes; the full bundle includes them); the router is tree-shakable. benchmarks/gains thelite-aotapp: the same table app with a precompiled template.
AngeLite (new, @duvanjamid/angelite/lite)#
- New minimal core in
src/lite/(~9 KB min+gzip vs ~16 KB for the full bundle): signals (signal,computed,effect), templates with@if/@else/@for/@empty,[prop]/(event)/[(ngModel)]bindings, components withinput()/output()/<ng-content>, pipes,inject()and a hash router. - Updates are batched per view and only write to the DOM when a value actually changed.
- Performance: templates compile once into a blueprint (flat op list), one lean effect per view, delegated events, plain-object
@forrows. Inbenchmarks/AngeLite matches or beats Preact/Vue/React/Angular on most operations and uses the least memory at 10k rows. - Interactive documentation with live examples in
docs/index.html(npm run build:docsrefreshesdocs/angelite-lite.min.js). src/ui/@duvanjamid/angelite/ui: 21 components (button, modal, tabs, table, toast, …), ~5 KB gzip with CSS. Page:docs/components.html, itself an AngeLite app.benchmarks/: identical table app in AngeLite, Preact, Vue, React and Angular, run in headless Chromium. Results page:docs/benchmarks.html.- AngeLite:
$elandngAfterViewIniton components; compiled expressions, template caches and LIS-based@forreordering; views are tracked by range so nested@if/@formove and remove cleanly. - The existing full bundle is untouched.
Security#
- Interpolated values (
{{ }}) are now HTML-escaped in@for,*ngForand component templates. Use bound properties instead of interpolating raw HTML.
Added#
utils/expression.js: a single safe expression evaluator (noeval) shared by all directives. Supports comparisons, logical operators, ternary,?.,??, indexing and method calls.setDebug(true)to enable debug logging; logs are silent by default.- Test suite (
npm test) and GitHub Actions CI. exports/sideEffects/enginesinpackage.json.
Fixed#
- Components marked dirty during a change-detection cycle are re-scheduled instead of being dropped.
removeEventListenerworks again after change detection patchesaddEventListener; patching is idempotent.@for/*ngForaccept expressions (item of data.items), not just plain property names.
Changed#
- Removed the duplicated
src/lagunlar.js; all remaining "Lagunlar" references are now "AngeLite". - Moved root demos into
examples/.