Skip to content

Commit ad9339d

Browse files
authored
Merge branch 'main' into copilot/improve-useproperties-type-definitions
2 parents 685201d + 7677b79 commit ad9339d

4 files changed

Lines changed: 39 additions & 14 deletions

File tree

packages/shadow-objects/CHANGELOG.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@ All notable changes to [@spearwolf/shadow-objects](https://github.com/spearwolf/
55
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## unreleased
8+
## Unreleased
99

10-
- sharpen the `EntityApi` type definitions
1110
- improve `useProperties()` type inference with key-to-type maps
11+
- **API Update:** `on()` and `once()` in `ShadowObjectCreationAPI` now support an implicit event source.
12+
- If the first argument is a `string`, `symbol`, or `[]`, the `entity` is automatically used as the event source.
13+
- Example: `on('eventName', callback)` is equivalent to `on(entity, 'eventName', callback)`.
14+
- This simplifies the common case of listening to entity events.
15+
- **Refactor** the `EntityApi` type
1216
- **Documentation:** Comprehensive update to the documentation structure and content.
13-
- Added dedicated documentation for Web Components (`<shae-worker>`, `<shae-ent>`, `<shae-prop>`) at `docs/03-api/04-web-components.md`.
14-
- Clarified the usage of Component Contexts, Namespacing (`ns` attribute), and decoupled placement of View Components.
15-
- Documented the `local` (Main Thread) and `no-structured-clone` attributes for `<shae-worker>`.
16-
- Documented the `order` property in ViewComponent API and Entity metadata for sorting/layering.
17-
- Updated guides to reflect current API usage (e.g., `.viewComponent`).
1817

1918
## [0.27.0] - 2026-01-19
2019

packages/shadow-objects/docs/03-api/01-shadow-object-api.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,23 +145,32 @@ Shadow Objects can communicate via an event system that mirrors standard DOM eve
145145

146146
Listens for an event on a target.
147147

148-
* **Signature:** `on(target: object, event: string, callback: (type: string, data: any) => void): void`
148+
* **Signature:**
149+
* `on(target: object, event: string, callback: Listener): void`
150+
* `on(event: string | symbol | string[], callback: Listener): void` (implicitly uses `entity` as target)
149151
* **Targets:** Usually `entity` (the current entity instance).
152+
* **Automatic Cleanup:** Subscriptions created via `on()` are automatically removed when the Shadow Object is destroyed.
150153

151154
#### Listening to View Events
152155
To listen to events dispatched from the DOM (View Layer), listen to the special event name `'onViewEvent'` on the `entity` target.
153156

154157
```typescript
155-
on(entity, 'onViewEvent', (type, data) => {
158+
// Implicitly listens on the entity
159+
on('onViewEvent', (type, data) => {
156160
if (type === 'click') {
157161
console.log('Clicked!', data);
158162
}
159163
});
164+
165+
// Explicit target (equivalent to above)
166+
on(entity, 'onViewEvent', (type, data) => {
167+
// ...
168+
});
160169
```
161170

162171
### `once(target, eventName, callback)`
163172

164-
Same as `on`, but the listener is automatically removed after the first trigger.
173+
Same as `on`, but the listener is automatically removed after the first trigger. Like `on`, if the first argument is a string, symbol, or array of strings/symbols, the `entity` is used as the event target.
165174

166175
---
167176

packages/shadow-objects/src/in-the-dark/Kernel.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,14 +588,28 @@ export class Kernel {
588588
return sig;
589589
},
590590

591-
on(...args: Parameters<typeof on>): ReturnType<typeof on> {
591+
on(...args: any[]): ReturnType<typeof on> {
592+
const [firstArg] = args;
593+
if (typeof firstArg === 'string' || typeof firstArg === 'symbol' || Array.isArray(firstArg)) {
594+
// @ts-ignore
595+
const unsub = on(entry.entity, ...args);
596+
unsubscribeSecondary.add(unsub);
597+
return unsub;
598+
}
592599
// @ts-ignore
593600
const unsub = on(...args);
594601
unsubscribeSecondary.add(unsub);
595602
return unsub;
596603
},
597604

598-
once(...args: Parameters<typeof once>): ReturnType<typeof once> {
605+
once(...args: any[]): ReturnType<typeof once> {
606+
const [firstArg] = args;
607+
if (typeof firstArg === 'string' || typeof firstArg === 'symbol' || Array.isArray(firstArg)) {
608+
// @ts-ignore
609+
const unsub = once(entry.entity, ...args);
610+
unsubscribeSecondary.add(unsub);
611+
return unsub;
612+
}
599613
// @ts-ignore
600614
const unsub = once(...args);
601615
unsubscribeSecondary.add(unsub);

packages/shadow-objects/src/types.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,11 @@ export interface ShadowObjectCreationAPI {
142142
createSignal<T = unknown>(...args: Parameters<typeof createSignal<T>>): ReturnType<typeof createSignal<T>>;
143143
createMemo<T = unknown>(...args: Parameters<typeof createMemo<T>>): SignalReader<T>;
144144

145-
on(...args: Parameters<typeof on>): ReturnType<typeof on>; // TODO fix args type
146-
once(...args: Parameters<typeof once>): ReturnType<typeof once>; // TODO fix args type
145+
on(eventName: string | symbol | Array<string | symbol>, ...args: any[]): ReturnType<typeof on>;
146+
on(...args: Parameters<typeof on>): ReturnType<typeof on>;
147+
148+
once(eventName: string | symbol | Array<string | symbol>, ...args: any[]): ReturnType<typeof once>;
149+
once(...args: Parameters<typeof once>): ReturnType<typeof once>;
147150

148151
onDestroy(callback: () => any): void;
149152
}

0 commit comments

Comments
 (0)