kopular 0.21.3 → 0.21.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/LLM.md +14 -12
  2. package/README.md +21 -17
  3. package/package.json +2 -2
package/LLM.md CHANGED
@@ -300,12 +300,12 @@ w.Bump(); // re-render + diff + patch
300
300
  now returns (see `kopscript`'s own `LLM.md`) for a subscription made in the constructor.
301
301
  A component built once at app startup and never removed (every `Router` page, most real
302
302
  apps' top-level structure) never needs this at all.
303
- - `Router`'s own outlet still uses the older `AfterRender` pattern above a single,
304
- always-present slot has nothing to reorder or remove, so this mechanism wouldn't add
305
- anything there. Reach for `VElement.Mount` for anything genuinely dynamic: a list of
306
- components, a modal that comes and goes.
307
- - Hand-written `Render()` only there's no template (`.html`) syntax yet for embedding a
308
- child component the way `*if`/`*for` embed structural logic.
303
+ - `Router`'s own outlet uses this mechanism too — `Render()` embeds the matched page via
304
+ `VElement.Mount`, not the older `AfterRender` pattern above (that migration landed once
305
+ this existed; a single, always-present slot never needed the reordering/removal part,
306
+ but there was no reason not to use the same real mechanism everywhere).
307
+ - Templates get the same capability via `*mount="expr"` see `kopscript`'s own `LLM.md`
308
+ for the syntax; it desugars to exactly this `VElement.Mount` call.
309
309
  - **Content projection (React's `children`/Angular's `<ng-content>`) needs no separate
310
310
  mechanism** — pass a `() => VElement` into a child's constructor and call it from inside
311
311
  its own `Render()`; it's invoked fresh every render and closes over the parent's `this`,
@@ -766,12 +766,14 @@ class CounterService {
766
766
  of the tree's own data, not wired against a live DOM node until `Materialize`/`Patch`
767
767
  runs) — an event Kopular doesn't have a named field for isn't reachable from `Render()`
768
768
  at all yet.
769
- - **A `Component` embedded via `AfterRender`/`Mount()` (imperative, `Router`'s own outlet
770
- pattern) is NOT the same as one embedded via `VElement.Mount()` (declarative, part of
771
- the tree)** — only the latter gets real reconciliation (patch in place, reorder, tear
772
- down). If you find yourself calling `.Mount()`/`.Update()` on a child by hand from
773
- `AfterRender` for anything that needs to be added, removed, or reordered, use
774
- `VElement.Mount(component)` in `Render()` instead see "Component" above.
769
+ - **A `Component` embedded via `AfterRender`/`Mount()` (imperative) is NOT the same as one
770
+ embedded via `VElement.Mount()` (declarative, part of the tree)** — only the latter gets
771
+ real reconciliation (patch in place, reorder, tear down); this includes `Router`'s own
772
+ outlet, which uses `VElement.Mount` internally, not the older `AfterRender` pattern. If
773
+ you find yourself calling `.Mount()`/`.Update()` on a child by hand from `AfterRender`
774
+ for anything that needs to be added, removed, or reordered, use
775
+ `VElement.Mount(component)` in `Render()` (or `*mount="expr"` in a template) instead —
776
+ see "Component" above.
775
777
 
776
778
  ## Does not exist
777
779
 
package/README.md CHANGED
@@ -188,11 +188,12 @@ class RoutedApp : Component {
188
188
  return VElement.Create("div");
189
189
  }
190
190
 
191
- // Mounting the Router a live, nested Component — isn't something a
192
- // VElement tree can express as data (see "Component" above). AfterRender
193
- // is called with the real DOM node Render()'s tree just became, once
194
- // Mount()/Update() has actually materialized/patched ithere, that's
195
- // the container itself.
191
+ // VElement.Mount(this.Nav) in Render() (see "Nested component composition"
192
+ // below) would work here too, but a single, always-present root slot has
193
+ // no reordering or removal to get right, so the older, simpler
194
+ // AfterRender is just as correctit's called with the real DOM node
195
+ // Render()'s tree just became, once Mount()/Update() has actually
196
+ // materialized/patched it, here that's the container itself.
196
197
  protected override void AfterRender(Element root) {
197
198
  this.Nav.Mount(root);
198
199
  }
@@ -245,10 +246,10 @@ nav.AddRoute("/dogs/:id", new DogPage(nav));
245
246
  el.TextContent = "Dog #" + this.Nav.Param;
246
247
  ```
247
248
 
248
- `Param` is a plain `string`, deliberately not `state<T>` — Router's own `AfterRender`
249
- already re-`Mount()`s the matched page into its outlet on every `Navigate()`/`popstate`,
250
- which re-runs that page's `Render()` (reading the fresh `Param`) with no extra step. No
251
- `Subscribe()` needed on it.
249
+ `Param` is a plain `string`, deliberately not `state<T>` — `Router`'s own `Render()` already
250
+ re-embeds the matched page into its outlet (via `VElement.Mount`) on every
251
+ `Navigate()`/`popstate`, which re-runs that page's `Render()` (reading the fresh `Param`)
252
+ with no extra step. No `Subscribe()` needed on it.
252
253
 
253
254
  **More than one dynamic segment**, and a trailing **wildcard** segment, both work too —
254
255
  read each by name via `Router.Params(name)` instead (`Param` above still holds the
@@ -493,11 +494,14 @@ must stop, not just outlive an app that was going to unload anyway. Removing a c
493
494
  that itself mounted further children tears the *whole* subtree down, however many levels
494
495
  deep — a middle component overriding its own `OnUnmount()` doesn't skip its children's.
495
496
 
496
- `Router`'s own outlet still uses the older `AfterRender`-based pattern (see "Router, and
497
- deploying it" below) rather than this a single, always-present slot has no reordering or
498
- removal to get right, so there's nothing this mechanism would add there. Reach for
497
+ `Router`'s own outlet uses this mechanism too its `Render()` embeds the matched page via
498
+ `VElement.Mount`, not the older `AfterRender`-based pattern still shown in "Router, and
499
+ deploying it" below for mounting the `Router` itself into an app's root container (a
500
+ single, always-present slot, where there's nothing this mechanism would add). Reach for
499
501
  `VElement.Mount` for anything with real add/remove/reorder: a list of components, a modal
500
- that comes and goes, anything genuinely dynamic.
502
+ that comes and goes, anything genuinely dynamic. A template gets the same capability via
503
+ `*mount="expr"` — see "Templates" in `kopscript`'s own README/LLM.md for the syntax; it
504
+ desugars to exactly this call.
501
505
 
502
506
  ## Content projection — a parent giving a child what to render
503
507
 
@@ -863,10 +867,10 @@ v1 / hobby-project scope, same as KopScript itself. `Update()` diffs and patches
863
867
  live child Component can be embedded directly in a parent's own tree via
864
868
  `VElement.Mount(child)` — see "Nested component composition" above — so a parent's
865
869
  re-render really can create/patch/reorder/tear down nested children declaratively now,
866
- closing what used to be documented here as the framework's biggest reconciliation gap.
867
- The one real limit that remains: this only works from a hand-written `Render()` today
868
- there's no template (`.html`) syntax yet for embedding a child component the way `*if`/
869
- `*for` embed structural logic. A list child (`Mounted` or plain) without a stable
870
+ closing what used to be documented here as the framework's biggest reconciliation gap. A
871
+ template (`.html`) embeds one too, via `*mount="expr"` (`kopscript@0.25.0`+), the same way
872
+ `*if`/`*for` embed structural logic see "Templates" in `kopscript`'s own docs. A list
873
+ child (`Mounted` or plain) without a stable
870
874
  `VElement.Id` still renders correctly across a reorder, but isn't guaranteed to keep the
871
875
  same real DOM node (see "Structural directives" above). `Update()` called before `Mount()`
872
876
  is a safe no-op — see `LLM.md`'s `Component` section for exactly when that happens
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kopular",
3
- "version": "0.21.3",
3
+ "version": "0.21.4",
4
4
  "description": "Kopular: a small component framework for KopScript — components, reactive state, constructor-injected services, routing, real compiled templates, and HTTP, with no DI container",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -62,7 +62,7 @@
62
62
  "@types/jsdom": "^30.0.0",
63
63
  "@types/node": "^20.14.0",
64
64
  "jsdom": "^25.0.1",
65
- "kopscript": "^0.24.0",
65
+ "kopscript": "^0.25.0",
66
66
  "typescript": "^5.5.0",
67
67
  "vitest": "^4.1.11"
68
68
  },