You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
value = resolveReactive(reactive) ← auto-tracks signal deps
143
142
if value === RESET → use fallback
144
-
if value === null → delete(target) if available, else use fallback
143
+
if value === null → delete(target) if available, else use fallback
145
144
if value !== current → update(target, value)
146
145
})
147
146
```
@@ -169,8 +168,6 @@ The `Reactive<T>` type is a union of three forms:
169
168
|`show(reactive)`|`p`| Controls `el.hidden`|
170
169
|`setStyle(prop, reactive?)`|`s`| Sets/removes an inline style |
171
170
|`dangerouslySetInnerHTML(reactive, opts?)`|`h`| Sets innerHTML, optionally in a shadow root |
172
-
|`callMethod(name, reactive, args?)`|`m`| Calls a method when reactive is truthy |
173
-
|`focus(reactive)`|`m`| Calls `el.focus()` when truthy |
174
171
175
172
All default their `reactive` parameter to the effect name (e.g., `setAttribute('href')` reads `host.href`).
176
173
@@ -266,22 +263,6 @@ The distinction between Parser (≥2 params) and Reader (1 param) is detected at
266
263
267
264
The dependency resolution catches all errors and runs the callback anyway. The `.catch(() => { callback() })` pattern means even unexpected errors (not just timeouts) are silently swallowed. The `DependencyTimeoutError` is constructed and passed to `reject`, but the actual logging happens... nowhere visible. The error is created inside a `new Promise((_, reject) => { reject(new DependencyTimeoutError(...)) })`, which rejects the race, but the `.catch` just calls `callback()` without logging the error.
268
265
269
-
### `CircularMutationError` is defined but never thrown
270
-
271
-
`CircularMutationError` is exported from `errors.ts` and from `index.ts`, but no code in the repository actually throws it. Is this dead code left from a previous implementation, or is it intended for future use?
272
-
273
-
### `callMethod` reads `() => null` as fallback
274
-
275
-
`callMethod` uses `read: () => null` — it never reads the current state. This means it always runs `update()` when the reactive is truthy, even if the method was already called. For idempotent methods like `focus()` this is fine, but for methods with side effects it could cause redundant calls. The `focus` effect partially addresses this with `read: el => el === document.activeElement`, but this pattern isn't consistent.
276
-
277
-
### Commented-out code in effects.ts
278
-
279
-
`effects.ts` contains a large commented-out `insertOrRemoveElement` function with its `ElementInserter` type. This suggests an in-progress or abandoned feature. Should it be removed, or is it actively being worked on?
The `on()` effect handler receives only the event — it cannot access the component's `ui` object (unlike `createEventsSensor` handlers, which receive `{ event, ui, target, prev }`). This means `on()` handlers can't easily read from other UI elements. Is this intentional to keep `on()` simple, or is it a limitation that should be addressed?
284
-
285
266
### `createEventsSensor` captures `targets` once
286
267
287
268
In `createEventsSensor`, the `targets` array is computed once at sensor creation time from the current state of the `Memo`. If the collection changes later (elements added/removed), the sensor won't pick up new targets. For `Memo`-based collections that are specifically designed to be dynamic, this seems like a gap.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+6Lines changed: 6 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -30,6 +30,12 @@
30
30
### Fixed
31
31
32
32
-**`pass()` no longer requires `configurable` property descriptors** on the target element and no longer leaks state on cleanup.
33
+
-**`pass()` now warns in dev mode** when a property doesn't exist on the target (likely a typo) or has no Slot (non-Le Truc element), instead of silently doing nothing.
34
+
-**`dangerouslySetInnerHTML` script cloning** now copies all functional and security-hardening attributes (`src`, `async`, `defer`, `nomodule`, `crossorigin`, `integrity`, `referrerpolicy`, `fetchpriority`) instead of only `type`. External scripts with `src` no longer become empty inline scripts.
35
+
-**`createEventsSensor` now reacts to collection changes**: For `Memo`-backed element collections, `getTarget()` reads the current elements on each event instead of a stale snapshot captured at sensor creation time. Static single-element targets use a fast path with no array overhead.
36
+
-**Dependency resolution no longer swallows errors silently**: `DependencyTimeoutError` is now logged via `console.warn` in dev mode. Previously, the `.catch` handler discarded all errors without any output.
37
+
-**Dependency resolution filters out already-defined components**: A microtask defer before `Promise.race` filters out components that were defined synchronously after queries ran (e.g. co-bundled components), avoiding unnecessary waits.
38
+
-**Dependency timeout increased from 50ms to 200ms**: Now that structural (CSS-only) custom elements and co-bundled components are filtered out, the timeout only applies to genuinely pending async dependencies and gives them a more realistic window.
33
39
-**`module-dialog` effect cleanup** no longer resets `host.open` to `false`, which was causing all dialog tests to fail.
34
40
-**`form-listbox` keyboard navigation** now uses direct `querySelectorAll` instead of a watched `Memo` that never activated its `MutationObserver` outside reactive contexts.
Copy file name to clipboardExpand all lines: README.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,9 +2,9 @@
2
2
3
3
Version 0.16.0
4
4
5
-
**Le Truc - the thing for type-safe reactive web components**
5
+
**Le Truc - the thing for type-safe reactive Web Components**
6
6
7
-
Le Truc helps you create reusable, interactive web components that work with any backend or static site generator. Build once, use everywhere.
7
+
Le Truc helps you create reusable, interactive Web Components that work with any backend or static site generator. Build once, use everywhere.
8
8
9
9
Le Truc is a set of functions to build reusable, loosely coupled Web Components with reactive properties. It provides structure through components and simplifies state management and DOM synchronization using signals and effects, leading to more organized and maintainable code without a steep learning curve.
10
10
@@ -53,7 +53,7 @@ defineComponent(
53
53
- 🧩 **Function Composition**: Declare component behavior by composing small, reusable functions (parsers and effects).
54
54
- 🛠️ **Customizable**: Le Truc is designed to be easily customizable and extensible. Create your own custom parsers and effects to suit your specific needs.
55
55
- 🌐 **Context Support**: Share global states across components without prop drilling or tightly coupling logic.
- 🛡️ **Type Safety**: Early warnings when types don't match improve code quality and reduce bugs.
58
58
59
59
Le Truc uses [Cause & Effect](https://github.com/zeixcom/cause-effect) internally for state management with signals and glitch-free DOM updates. If wanted, you could fork Le Truc and replace Cause & Effect with a different state management library without changes to the user-facing `defineComponent()` API.
0 commit comments