@spearwolf/shadow-objects 0.26.4 → 0.28.0
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.
- package/CHANGELOG.md +43 -0
- package/README.md +11 -192
- package/bundle.js +2 -2
- package/package.json +1 -1
- package/src/elements/ShaeWorkerElement.d.ts.map +1 -1
- package/src/elements/ShaeWorkerElement.js +7 -1
- package/src/elements/ShaeWorkerElement.js.map +1 -1
- package/src/in-the-dark/Entity.d.ts +2 -1
- package/src/in-the-dark/Entity.d.ts.map +1 -1
- package/src/in-the-dark/Entity.js +1 -1
- package/src/in-the-dark/Entity.js.map +1 -1
- package/src/in-the-dark/Kernel.d.ts.map +1 -1
- package/src/in-the-dark/Kernel.js +25 -2
- package/src/in-the-dark/Kernel.js.map +1 -1
- package/src/in-the-dark/events.d.ts +4 -4
- package/src/in-the-dark/events.d.ts.map +1 -1
- package/src/in-the-dark/events.js +4 -4
- package/src/in-the-dark/events.js.map +1 -1
- package/src/types.d.ts +15 -5
- package/src/types.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,49 @@ All notable changes to [@spearwolf/shadow-objects](https://github.com/spearwolf/
|
|
|
5
5
|
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.28.0] - 2026-01-20
|
|
9
|
+
|
|
10
|
+
- **API Update:** `on()` and `once()` in `ShadowObjectCreationAPI` now support an implicit event source.
|
|
11
|
+
- If the first argument is a `string`, `symbol`, or `[]`, the `entity` is automatically used as the event source.
|
|
12
|
+
- Example: `on('eventName', callback)` is equivalent to `on(entity, 'eventName', callback)`.
|
|
13
|
+
- This simplifies the common case of listening to entity events.
|
|
14
|
+
- **API Update:** introduce `onViewEvent()` in `ShadowObjectCreationAPI`
|
|
15
|
+
- Simplifies listening to view events dispatched to the entity.
|
|
16
|
+
- Example:
|
|
17
|
+
```typescript
|
|
18
|
+
onViewEvent((type, data) => {
|
|
19
|
+
if (type === 'my-event') {
|
|
20
|
+
// handle event
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
- **Refactor** the `EntityApi` type
|
|
25
|
+
- **Refactor** the `useProperties` supports type maps now
|
|
26
|
+
- **Documentation:** Comprehensive update to the documentation structure and content.
|
|
27
|
+
|
|
28
|
+
### ⚠️ Breaking Changes
|
|
29
|
+
- The _entity_ events `onCreate`, `onDestroy`, `onParentChanged` and `onViewEvent` changed to _symbols_.
|
|
30
|
+
- Update your event listeners accordingly:
|
|
31
|
+
- import the event symbols from the package:
|
|
32
|
+
```typescript
|
|
33
|
+
import { onCreate, onDestroy, onParentChanged, onViewEvent } from '@spearwolf/shadow-objects/shadow-objects.js';
|
|
34
|
+
```
|
|
35
|
+
- _Functional Shadow-Objects:_
|
|
36
|
+
- **Before:** `on(entity, 'onCreate', ...)`
|
|
37
|
+
- **After:** `on(onCreate, ...)`
|
|
38
|
+
- _Class-based Shadow-Objects:_
|
|
39
|
+
- **Before:** `onCreate(entity)`
|
|
40
|
+
- **After:** `[onCreate](entity)`
|
|
41
|
+
|
|
42
|
+
## [0.27.0] - 2026-01-19
|
|
43
|
+
|
|
44
|
+
### ⚠️ Breaking Changes
|
|
45
|
+
|
|
46
|
+
- **API Update:** `dispatchMessageToView` has been moved from the `entity` instance to the `ShadowObjectCreationAPI`.
|
|
47
|
+
- **Before:** `entity.dispatchMessageToView(...)`
|
|
48
|
+
- **After:** `dispatchMessageToView(...)` (available as an argument in the constructor/factory function)
|
|
49
|
+
- **Type Definitions:** Removed `dispatchMessageToView` from `EntityApi` interface.
|
|
50
|
+
|
|
8
51
|
## [0.26.4] - 2026-01-15
|
|
9
52
|
|
|
10
53
|
- fix return type definitions for `provideContext()` and `provideGlobalContext()`
|
package/README.md
CHANGED
|
@@ -1,199 +1,18 @@
|
|
|
1
|
-
# Shadow Objects Framework
|
|
1
|
+
# Shadow Objects Framework
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This package contains the core library for the **Shadow Objects Framework**.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
> 🚀 This is a highly experimental framework that is slowly maturing. Use at your own risk. 🔥
|
|
5
|
+
**👉 [Read the Documentation](./docs/README.md)**
|
|
7
6
|
|
|
8
|
-
##
|
|
7
|
+
## Contents
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- **Context**: Entities participate in a hierarchical context system (dependency injection).
|
|
9
|
+
* [**Concepts**](./docs/01-concepts/): Understand the mental model, architecture, and lifecycle.
|
|
10
|
+
* [**Guides**](./docs/02-guides/): Step-by-step instructions.
|
|
11
|
+
* [**API Reference**](./docs/03-api/): Detailed API docs.
|
|
12
|
+
* [**Best Practices & Patterns**](./docs/04-patterns/): Idiomatic usage and design patterns.
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
A **Shadow Object** is a functional unit of logic attached to an Entity.
|
|
18
|
-
- **Logic Containers**: They contain the state, effects, and business logic for a specific feature.
|
|
19
|
-
- **Lifecycle**: They are automatically created and destroyed by the **Kernel** based on the Entity's **Token**.
|
|
20
|
-
- **Reactivity**: They use **Signals** and **Effects** (via `@spearwolf/signalize`) to react to changes in properties or context.
|
|
14
|
+
## Installation
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- **Manages Entities**: Handles creation, destruction, and hierarchy updates of Entities.
|
|
25
|
-
- **Orchestrates Shadow Objects**: Instantiates the correct Shadow Objects for each Entity based on its Token and the Registry.
|
|
26
|
-
- **Message Dispatch**: Handles communication between the View (UI) and the Shadow World.
|
|
27
|
-
|
|
28
|
-
### 4. The Registry
|
|
29
|
-
The **Registry** maps **Tokens** to **Shadow Object Constructors**.
|
|
30
|
-
- **Tokens**: Strings that identify what logic an Entity should have (e.g., `"my-component"`).
|
|
31
|
-
- **Routes**: Defines rules for composing multiple Shadow Objects. For example, a token can "route" to other tokens, causing multiple Shadow Objects to be instantiated for a single Entity.
|
|
32
|
-
- **Conditional Routing**: Routes can be triggered based on the presence of specific "truthy" properties on the Entity (e.g., `@myProp` routes only if `myProp` is set).
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Developer Guide
|
|
37
|
-
|
|
38
|
-
### 1. Defining Shadow Objects
|
|
39
|
-
|
|
40
|
-
You can define a Shadow Object as a **Function** or a **Class**. Both receive a `ShadowObjectCreationAPI` object containing the API methods.
|
|
41
|
-
|
|
42
|
-
#### Function-based (Recommended)
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
import { ShadowObjectCreationAPI } from "@spearwolf/shadow-objects";
|
|
46
|
-
|
|
47
|
-
export function MyShadowObject({
|
|
48
|
-
useProperty,
|
|
49
|
-
createEffect,
|
|
50
|
-
onDestroy
|
|
51
|
-
}: ShadowObjectCreationAPI) {
|
|
52
|
-
|
|
53
|
-
// Read Properties
|
|
54
|
-
const title = useProperty("title");
|
|
55
|
-
|
|
56
|
-
// React to changes
|
|
57
|
-
createEffect(() => {
|
|
58
|
-
console.log("Title is now:", title());
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
// Handle Lifecycle
|
|
62
|
-
onDestroy(() => {
|
|
63
|
-
console.log("Shadow Object destroyed");
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// Return public methods (optional)
|
|
67
|
-
// These can be called by events (more on that later)
|
|
68
|
-
return {
|
|
69
|
-
doSomething() { /* ... */ }
|
|
70
|
-
};
|
|
71
|
-
}
|
|
16
|
+
```bash
|
|
17
|
+
npm install @spearwolf/shadow-objects
|
|
72
18
|
```
|
|
73
|
-
|
|
74
|
-
#### Class-based
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
import { ShadowObjectCreationAPI } from "@spearwolf/shadow-objects";
|
|
78
|
-
|
|
79
|
-
export class MyShadowObject {
|
|
80
|
-
constructor({ useProperty, createEffect, onDestroy }: ShadowObjectCreationAPI) {
|
|
81
|
-
const title = useProperty("title");
|
|
82
|
-
|
|
83
|
-
createEffect(() => {
|
|
84
|
-
console.log("Title is now:", title());
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
onDestroy(() => this.cleanup());
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
cleanup() {
|
|
91
|
-
console.log("Shadow Object destroyed");
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### 2. The Shadow Object Creation API
|
|
97
|
-
|
|
98
|
-
The `ShadowObjectCreationAPI` object provides all necessary tools to interact with the Entity, the View, and the Context system.
|
|
99
|
-
|
|
100
|
-
| Method | Description |
|
|
101
|
-
| :--- | :--- |
|
|
102
|
-
| **`useProperty(name)`** | Returns a signal reader for a specific property on the Entity. Updates when the view property changes. |
|
|
103
|
-
| **`useProperties(map)`** | Returns an object of signal readers for multiple properties. |
|
|
104
|
-
| **`useContext(name)`** | Consumes a context value provided by a parent Entity. |
|
|
105
|
-
| **`useParentContext(name)`** | Skips the current Entity and consumes context directly from the parent. |
|
|
106
|
-
| **`provideContext(name, value)`** | Provides a context value (or signal) to descendant Entities. |
|
|
107
|
-
| **`provideGlobalContext(name, value)`** | Provides a context value globally to all Entities. |
|
|
108
|
-
| **`createResource(factory, cleanup)`** | Manages an external resource (e.g., a Three.js object) with automatic cleanup when dependencies change. |
|
|
109
|
-
| **`createEffect(callback)`** | Runs a side effect whenever accessed signals change. |
|
|
110
|
-
| **`createSignal(initialValue)`** | Creates a local reactive state signal. |
|
|
111
|
-
| **`createMemo(factory)`** | Creates a derived signal that updates only when dependencies change. |
|
|
112
|
-
| **`on(target, event, callback)`** | Listens for events on the Entity or other event targets. |
|
|
113
|
-
| **`once(target, event, callback)`** | Listens for an event exactly once. |
|
|
114
|
-
| **`onDestroy(callback)`** | Registers a callback to be executed when the Shadow Object is destroyed. |
|
|
115
|
-
|
|
116
|
-
### 3. Registering Shadow Objects
|
|
117
|
-
|
|
118
|
-
Shadow Objects are organized in **Modules**. A module defines which Tokens map to which Shadow Objects.
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
// my-module.ts
|
|
122
|
-
import { MyShadowObject } from "./MyShadowObject";
|
|
123
|
-
|
|
124
|
-
export default {
|
|
125
|
-
// Map tokens to constructors
|
|
126
|
-
define: {
|
|
127
|
-
"my-component": MyShadowObject,
|
|
128
|
-
},
|
|
129
|
-
// Define routing rules
|
|
130
|
-
routes: {
|
|
131
|
-
"my-component": ["mixin-logger", "mixin-analytics"], // Composition
|
|
132
|
-
"@debug": ["debug-overlay"], // Conditional routing based on 'debug' property
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### 4. View Integration
|
|
138
|
-
|
|
139
|
-
In your HTML or View layer, you use the provided Web Components to create the Entity hierarchy.
|
|
140
|
-
|
|
141
|
-
```html
|
|
142
|
-
<!-- 1. Initialize the Environment -->
|
|
143
|
-
<shae-worker-env src="./my-module.js"></shae-worker-env>
|
|
144
|
-
|
|
145
|
-
<!-- 2. Create Entities -->
|
|
146
|
-
<shae-ent token="my-entity">
|
|
147
|
-
<!-- Properties -->
|
|
148
|
-
<shae-prop name="title" value="Hello World"></shae-prop>
|
|
149
|
-
|
|
150
|
-
<!-- Nested Entities -->
|
|
151
|
-
<shae-ent token="child-entity"></shae-ent>
|
|
152
|
-
</shae-ent>
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## Architecture & Internals
|
|
158
|
-
|
|
159
|
-
### Lifecycle
|
|
160
|
-
|
|
161
|
-
1. **Creation**: When an Entity is created (e.g., `<shae-ent>` connects to the document), the Kernel looks up its Token in the Registry.
|
|
162
|
-
2. **Instantiation**: The Kernel instantiates all Shadow Objects associated with that Token (and its routes).
|
|
163
|
-
3. **Execution**: The Shadow Object function runs, setting up signals, effects, and context providers.
|
|
164
|
-
4. **Updates**:
|
|
165
|
-
* **Properties**: When view properties change, the Entity's signals update, triggering any dependent effects in the Shadow Object.
|
|
166
|
-
* **Context**: If a parent Entity changes a provided context, child Shadow Objects consuming that context automatically update.
|
|
167
|
-
5. **Destruction**: When an Entity is removed or its Token changes, the Kernel destroys the associated Shadow Objects, cleaning up all signals and effects.
|
|
168
|
-
|
|
169
|
-
### Architecture Diagram
|
|
170
|
-
|
|
171
|
-
```mermaid
|
|
172
|
-
graph TD
|
|
173
|
-
View[View / DOM] -->|Messages| Kernel
|
|
174
|
-
Kernel -->|Updates| EntityTree[Entity Tree]
|
|
175
|
-
|
|
176
|
-
subgraph "Shadow World"
|
|
177
|
-
EntityTree
|
|
178
|
-
Entity[Entity]
|
|
179
|
-
SO[Shadow Object]
|
|
180
|
-
|
|
181
|
-
EntityTree --> Entity
|
|
182
|
-
Entity -->|Has| SO
|
|
183
|
-
|
|
184
|
-
SO -->|Reads| Props[Properties]
|
|
185
|
-
SO -->|Reads/Writes| Context
|
|
186
|
-
SO -->|Runs| Logic[Business Logic]
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
Logic -->|Updates| Signals
|
|
190
|
-
Signals -->|Triggers| Effects
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
### Further Reading
|
|
194
|
-
|
|
195
|
-
For deep dives into specific subsystems:
|
|
196
|
-
|
|
197
|
-
- [**ShadowEnv**](src/view/README.md): The environment wrapper.
|
|
198
|
-
- [**ComponentContext**](src/view/ComponentContext.md): Context implementation details.
|
|
199
|
-
- [**ViewComponent**](src/view/ViewComponent.md): Base class for view components.
|