Skip to content

Commit eea99c7

Browse files
committed
working on documentation
1 parent 8a69c24 commit eea99c7

6 files changed

Lines changed: 284 additions & 4 deletions

File tree

docs/components.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ ojs(MyComponent);
4343
4. **`ojs(MyComponent)`**: Registers the component with the framework.
4444
5. **Passing Arguments**: The `render` method receives `...args` which can contain parent elements, attributes, or other data passed during rendering. Always spread `...args` in your root element or handle them appropriately.
4545

46+
> [!IMPORTANT]
47+
> **Registration is Required Before Use**
48+
> You **MUST** call `ojs(YourComponent)` to register the component in the IoC container. This **MUST** happen before you try to use the component (e.g., `h.YourComponent()`).
49+
>
50+
> The most common pattern is to call `ojs(YourComponent)` at the very end of your component file, ensuring it is registered as soon as the file is imported.
51+
4652
## Functional Components
4753

4854
Functional components are simpler and are best used for presentational components that don't require complex state management or lifecycle hooks.

docs/container.md

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# IoC Container & `app()` Service
2+
3+
OpenScript uses an **Inversion of Control (IoC) Container** to manage dependencies and global services. This promotes loose coupling and makes your application easier to test and maintain.
4+
5+
## The `app()` Helper
6+
7+
The most common way to interact with the container is via the `app()` helper function.
8+
9+
### Accessing Services
10+
11+
You can retrieve any registered service by passing its name to `app()`.
12+
13+
```javascript
14+
import { app } from "modular-openscriptjs";
15+
16+
// Get the Router instance
17+
const router = app("router");
18+
19+
// Get the Broker
20+
const broker = app("broker");
21+
22+
// Get a context (if registered)
23+
const globalContext = app("gc");
24+
```
25+
26+
### Accessing the Container
27+
28+
Calling `app()` without arguments returns the **Container** instance itself. This is useful when you need to register new services or values.
29+
30+
```javascript
31+
const container = app();
32+
33+
// Register a new value
34+
container.value("myConfig", { apiKey: "12345" });
35+
```
36+
37+
## Registering Services
38+
39+
You typically register services in your `ojs.config.js` or a setup file.
40+
41+
### `container.value(name, value)`
42+
43+
Registers a constant value or an existing instance. This is the most common method for configuration or pre-instantiated classes.
44+
45+
```javascript
46+
import { app } from "modular-openscriptjs";
47+
import { appEvents } from "./events.js";
48+
49+
// Registering appEvents so it can be resolved anywhere
50+
app().value("appEvents", appEvents);
51+
```
52+
53+
### `container.singleton(name, Class, dependencies)`
54+
55+
Registers a class as a singleton. The container will create **one** instance the first time it is resolved and return that same instance forever.
56+
57+
```javascript
58+
// Register API Service
59+
app().singleton("api", ApiService);
60+
61+
// Later...
62+
const api = app("api"); // Creates instance
63+
const api2 = app("api"); // Returns same instance
64+
```
65+
66+
### `container.transient(name, Class, dependencies)`
67+
68+
Registers a class as transient. The container will create a **new** instance every time it is resolved.
69+
70+
```javascript
71+
app().transient("logger", Logger);
72+
```
73+
74+
### `container.factory(name, factoryFunction)`
75+
76+
Registers a factory function. The function is called to produce the value.
77+
78+
```javascript
79+
app().factory("timestamp", () => Date.now());
80+
```
81+
82+
## Resolving Services
83+
84+
While `app('name')` is the shortcut, you can also use `container.resolve('name')`.
85+
86+
```javascript
87+
const myService = app().resolve("myService", "defaultValue");
88+
```
89+
90+
### Dependency Injection
91+
92+
When defining services that depend on others, you can pass an array of dependency names.
93+
94+
```javascript
95+
class UserService {
96+
constructor(api, broker) {
97+
this.api = api;
98+
this.broker = broker;
99+
}
100+
}
101+
102+
// Register UserService with dependencies 'api' and 'broker'
103+
app().singleton("userService", UserService, ["api", "broker"]);
104+
105+
// When resolving, container auto-injects "api" and "broker"
106+
const userService = app("userService");
107+
```
108+
109+
## Core Services
110+
111+
The following services are registered by default:
112+
113+
- `"h"`: The Markup Engine (Proxy)
114+
- `"router"`: The Router instance
115+
- `"broker"`: The Event Broker
116+
- `"repository"`: Internal Component Repository
117+
- `"contextProvider"`: The Context Provider

docs/helpers.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Helper Functions
2+
3+
OpenScript provides a set of global helper functions and utilities to simplify common tasks, DOM manipulation, and framework interaction.
4+
5+
## Logic Helpers
6+
7+
These helpers are available globally (e.g., `window.ifElse`) and can be used directly in your code or templates.
8+
9+
### `ifElse(condition, trueValue, falseValue)`
10+
11+
Evaluates a condition and returns one of two values. If the values are functions, they are executed.
12+
13+
```javascript
14+
// Basic usage
15+
const status = ifElse(isOnline, "Online", "Offline");
16+
17+
// With functions (lazy evaluation)
18+
const result = ifElse(
19+
isValid,
20+
() => complexCalculation(),
21+
() => "Invalid",
22+
);
23+
```
24+
25+
### `coalesce(value1, value2)`
26+
27+
Returns the first non-null/undefined value. Handy for defaults.
28+
29+
```javascript
30+
const name = coalesce(userInput, "Guest");
31+
```
32+
33+
### `each(iterable, callback)`
34+
35+
Safely iterates over arrays or objects. Returns an array of results.
36+
37+
```javascript
38+
// Array
39+
each([1, 2, 3], (num) => console.log(num));
40+
41+
// Object
42+
each({ a: 1, b: 2 }, (val, key) => console.log(key, val));
43+
```
44+
45+
### `lazyFor(array, callback)`
46+
47+
Iterates over an array asynchronously using `setTimeout(..., 0)` to avoid blocking the main thread during large operations.
48+
49+
```javascript
50+
lazyFor(hugeArray, (item) => {
51+
// Process item without freezing UI
52+
});
53+
```
54+
55+
---
56+
57+
## DOM Utilities (`dom`)
58+
59+
The `dom` object provides shortcuts for common DOM operations.
60+
61+
### Selection
62+
63+
- **`dom.id(id)`**: wrapper for `document.getElementById`.
64+
- **`dom.get(selector, parent?)`**: wrapper for `querySelector`.
65+
- **`dom.all(selector, parent?)`**: wrapper for `querySelectorAll`.
66+
- **`dom.byClass(className, parent?)`**: wrapper for `getElementsByClassName`.
67+
68+
### Manipulation
69+
70+
- **`dom.create(type)`**: wrapper for `document.createElement`.
71+
- **`dom.put(html, element, append = false)`**: Sets `innerHTML`.
72+
- **`dom.clear(element)`**: Clears `innerHTML`.
73+
- **`dom.disable(element)` / `dom.enable(element)`**: Toggles `disabled` attribute.
74+
75+
### Positioning
76+
77+
- **`dom.centerInside(container, element)`**: Centers an absolutely positioned element within a container.
78+
79+
---
80+
81+
## Framework Helpers
82+
83+
### `app(serviceName?)`
84+
85+
Access the IoC Container.
86+
87+
- `app("router")`: Get Router.
88+
- `app("broker")`: Get Event Broker.
89+
- `app()`: Get the Container instance itself.
90+
91+
### `component(id)`
92+
93+
Retrieves a Component instance by its unique ID (UID).
94+
Useful in event listeners where you have the UID but not the instance.
95+
96+
```javascript
97+
const myComp = component(123);
98+
myComp?.setState(newState);
99+
```
100+
101+
### `context(name)` & `putContext(name, value)`
102+
103+
Shortcuts for the Context API.
104+
105+
- `context("theme")`: Get the "theme" context.
106+
- `putContext("theme", "dark")`: Define/Update the "theme" context.
107+
108+
### `state(initialValue)`
109+
110+
Creates a new State object.
111+
112+
```javascript
113+
const count = state(0);
114+
```
115+
116+
### `v(state, callback)`
117+
118+
Creates an "Anonymous Component" that updates when the bound state changes.
119+
120+
```javascript
121+
// Renders text that updates automatically
122+
h.div(
123+
{},
124+
v(countState, (val) => `Count is: ${val}`),
125+
);
126+
```
127+
128+
### `ojs(...classes)`
129+
130+
The main entry point to run the application runner.
131+
132+
```javascript
133+
ojs(AppClass);
134+
```

docs/mediators.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,38 @@ Mediators act as the bridge between your application's logic (backend/services)
77
Mediators are **stateless** classes that listen for events, execute logic (like API calls or data processing), and then potentially emit new events. They do not manipulate the DOM directly.
88

99
```javascript
10-
// Example Mediator structure
10+
// AuthMediator.js
1111
export default class AuthMediator extends Mediator {
1212
shouldRegister() {
13-
return true; // Control registration logic
13+
return true;
1414
}
1515
}
1616
```
1717

18+
### Best Practice: `boot.js`
19+
20+
For Mediators, it is best practice to have a dedicated `boot.js` (or `mediators.js`) file that imports and registers them all. This ensures they are registered early in the application lifecycle.
21+
22+
```javascript
23+
// src/boot.js
24+
import { ojs } from "modular-openscriptjs";
25+
import AuthMediator from "./mediators/AuthMediator";
26+
import CartMediator from "./mediators/CartMediator";
27+
28+
export default function boot() {
29+
ojs(AuthMediator, CartMediator);
30+
}
31+
```
32+
33+
Then, in your `main.js`:
34+
35+
```javascript
36+
// src/main.js
37+
import boot from "./boot";
38+
39+
boot(); // Registers all mediators
40+
```
41+
1842
## Broker Registration
1943

2044
When you define a Mediator, it is automatically registered with the **Broker** if `shouldRegister()` returns `true`. The broker scans the mediator for special properties to set up event listeners.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "modular-openscriptjs",
3-
"version": "2.0.13",
3+
"version": "2.0.14",
44
"description": "OpenScriptJs Framework - A lightweight, reactive JavaScript framework for building modern web applications",
55
"type": "module",
66
"main": "./dist/modular-openscriptjs.umd.js",

src/utils/helpers.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export function namespace(name) {
2323

2424
export function cleanUpNode(node) {
2525
node.__openscript_cleanup__?.();
26-
node.__eventListeners = null;
2726
}
2827

2928
/**

0 commit comments

Comments
 (0)