redgin 0.1.19 → 0.2.2
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/README.md +149 -204
- package/dist/directives/attr.d.ts +11 -0
- package/dist/directives/events.d.ts +13 -1
- package/dist/directives/index.d.ts +2 -0
- package/dist/directives/stream.d.ts +17 -0
- package/dist/directives/watch.d.ts +10 -2
- package/dist/props/getset.d.ts +8 -0
- package/dist/props/propReflect.d.ts +8 -0
- package/dist/redgin.d.ts +78 -15
- package/dist/redgin.min.js +1 -12
- package/dist/utils.d.ts +1 -1
- package/index.d.ts +20 -0
- package/package.json +35 -7
- package/vite.config.js +5 -0
- package/dist/props/directives.d.ts +0 -5
- package/dist/props/events.d.ts +0 -4
- package/dist/props/watch.d.ts +0 -2
package/README.md
CHANGED
|
@@ -1,268 +1,219 @@
|
|
|
1
|
-
|
|
1
|
+
[](https://nodei.co/npm/redgin/)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# RedGin
|
|
4
4
|
|
|
5
|
+
A lightweight (~5.3kb) library that solves the pain points of native Web Components. RedGin offers fine-grained reactivity, surgical updates, and intuitive APIs - making Web Components actually enjoyable to build.
|
|
5
6
|
|
|
7
|
+
## Why RedGin?
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
Native Web Components are powerful but come with friction:
|
|
8
10
|
|
|
11
|
+
| Pain Point | Native Web Components | RedGin |
|
|
12
|
+
|------------|----------------------|--------|
|
|
13
|
+
| **Boilerplate** | Manual lifecycle callbacks, attributeChangedCallback, getters/setters | Zero boilerplate with `getset` and `propReflect` |
|
|
14
|
+
| **Reactivity** | Manual observation with `attributeChangedCallback` | Automatic reactivity with `watch`, `s()`, and fine-grained updates |
|
|
15
|
+
| **Template Updates** | Manual DOM manipulation | Surgical updates - only changed parts re-render |
|
|
16
|
+
| **Attribute Reflection** | Manual sync between properties and attributes | Automatic with `propReflect` |
|
|
17
|
+
| **Event Binding** | `addEventListener` boilerplate | Inline events with `on()` |
|
|
18
|
+
| **Style Sharing** | Duplicated styles per component | Global `shareStyle` injection |
|
|
19
|
+
| **Performance** | Full re-renders on any change | Only changed elements update |
|
|
20
|
+
| **TypeScript** | Complex typing for custom elements | First-class TypeScript support |
|
|
9
21
|
|
|
22
|
+
## Core Philosophy
|
|
10
23
|
|
|
11
|
-
|
|
24
|
+
RedGin is built around **surgical updates** - only the elements that need to change, change. No virtual DOM, no heavy diffing, just precise, targeted updates to your components.
|
|
12
25
|
|
|
26
|
+
## Key Features
|
|
13
27
|
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- **Create Property Reflection with propReflect**: Reflect property changes to corresponding attributes.[`propReflect`](https://stackblitz.com/edit/typescript-hlms7u?file=index.html)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- **Create Inline Events with event**: Attach events directly in your component's template.[`event`](https://stackblitz.com/edit/typescript-t3fqo8?file=sampleWatch.ts)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- **Create Custom Events with emit**: Emit custom events from your components.[`emit`](https://stackblitz.com/edit/redgin-childtoparent?file=index.ts)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- **Inject Global Styles with injectStyles**: Apply global styles for your components.[`injectStyles`](https://stackblitz.com/edit/redgin-bootstrap?file=index.ts)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- **Support for TypeScript**: Enjoy type safety when using Redgin with TypeScript.[Support Typescript](https://stackblitz.com/edit/typescript-ue61k6?file=index.ts)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- **Build SPAs (Single-Page Applications)**: Simplify the development of SPAs using Redgin.[Single Page Application](https://stackblitz.com/edit/typescript-ezsw6j)
|
|
28
|
+
- **🎯 Surgical Rendering**: Update only what changes - perfect for large lists
|
|
29
|
+
- **📝 Template Literals**: Write components using familiar JS template syntax
|
|
30
|
+
- **⚡️ Fine-grained Reactivity**: Multiple reactivity patterns (`watch`, `s()`, `getset`, `propReflect`)
|
|
31
|
+
- **🔗 Attribute Binding**: Smart `attr()` helper for dynamic attributes
|
|
32
|
+
- **🔄 Property Reflection**: Sync properties with attributes using `propReflect`
|
|
33
|
+
- **📊 Reactive Getters/Setters**: Create reactive state with `getset`
|
|
34
|
+
- **🎨 Style Management**: Global style injection with `shareStyle` and scoped styles with `css`
|
|
35
|
+
- **📘 TypeScript Ready**: Full type safety and IntelliSense
|
|
45
36
|
|
|
46
37
|
## Installation
|
|
47
38
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Include the Redgin library in your project.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
```html
|
|
54
|
-
// via html
|
|
55
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/redgin@latest/dist/redgin.min.js"></script>
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
Or install it via npm:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
39
|
+
### Via npm
|
|
64
40
|
```bash
|
|
65
|
-
|
|
66
41
|
npm i redgin
|
|
67
|
-
|
|
68
42
|
```
|
|
69
|
-
## Usage
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
1. **Import the Library:**
|
|
74
|
-
|
|
75
43
|
|
|
44
|
+
## Via CDN
|
|
76
45
|
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
// via js
|
|
80
|
-
|
|
81
|
-
import { Redgin, watch, getset, html } from 'https://cdn.jsdelivr.net/npm/redgin@latest/dist/redgin.min.js';
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
// via npm
|
|
86
|
-
|
|
87
|
-
import { Redgin, watch, getset, html } from 'redgin';
|
|
88
|
-
|
|
46
|
+
```js
|
|
47
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/redgin@latest/dist/redgin.min.js"></script>
|
|
89
48
|
```
|
|
90
49
|
|
|
91
50
|
|
|
51
|
+
## Quick Start
|
|
92
52
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
```javascript
|
|
98
|
-
|
|
99
|
-
// FetchApiComponent.ts
|
|
53
|
+
```js
|
|
54
|
+
import { RedGin, getset, on, html } from 'redgin';
|
|
100
55
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// Reactive properties using getset
|
|
104
|
-
ready = getset<boolean>(false);
|
|
105
|
-
todos: any;
|
|
56
|
+
class Counter extends RedGin {
|
|
57
|
+
count = getset(0);
|
|
106
58
|
|
|
107
|
-
|
|
108
|
-
onInit() {
|
|
109
|
-
fetch('https://jsonplaceholder.typicode.com/todos/1')
|
|
110
|
-
.then(response => response.json())
|
|
111
|
-
.then(json => {
|
|
112
|
-
this.todos = json;
|
|
113
|
-
this.ready = true;
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Render method for displaying the fetched data
|
|
118
|
-
render() {
|
|
59
|
+
render() {
|
|
119
60
|
return html`
|
|
120
|
-
${
|
|
121
|
-
|
|
122
|
-
|
|
61
|
+
<button ${on('click', () => this.count++)}>
|
|
62
|
+
Count: ${this.count}
|
|
63
|
+
</button>
|
|
64
|
+
`;
|
|
123
65
|
}
|
|
124
66
|
}
|
|
125
67
|
|
|
126
|
-
|
|
127
|
-
customElements.define('fetch-api', FetchApi);
|
|
128
|
-
|
|
68
|
+
customElements.define('my-counter', Counter);
|
|
129
69
|
```
|
|
130
70
|
|
|
71
|
+
## API Reference
|
|
131
72
|
|
|
132
|
-
3. **Passing data from Parent to Child component**
|
|
133
73
|
|
|
74
|
+
### Core Helpers
|
|
134
75
|
|
|
76
|
+
| Helper | Purpose | Example |
|
|
77
|
+
| :--- | :--- | :--- |
|
|
78
|
+
| `getset(initial)` | Creates reactive property with getter/setter | `count = getset(0)` |
|
|
79
|
+
| `propReflect(initial)` | Reactive property that reflects to attribute | `theme = propReflect('light')` |
|
|
80
|
+
| `watch(deps, callback)` | Fine-grained control - rerenders when specified dependencies change | `${watch(['count', 'theme'], () => html`<div>...</div>`)}` |
|
|
81
|
+
| `s(callback)` | Shorthand for reactive value binding | `${s(() => this.count)}` |
|
|
82
|
+
| `attr(name, callback)` | Surgical attribute binding | `${attr('disabled', () => !this.editable)}` |
|
|
83
|
+
| `on(event, handler)` | Event listener binding | `${on('click', () => this.save())}` |
|
|
84
|
+
| `html` | Template literal tag for HTML | `html`<div>Hello</div>`` |
|
|
135
85
|
|
|
136
|
-
|
|
86
|
+
### Style Helpers
|
|
137
87
|
|
|
138
|
-
|
|
88
|
+
| Helper | Purpose | Example |
|
|
89
|
+
| :--- | :--- | :--- |
|
|
90
|
+
| `css` | Template literal tag for component-scoped styles | `styles = [css`.card { padding: 1rem; }`]` |
|
|
91
|
+
| `shareStyle(styles)` | Injects global styles across all components | `shareStyle(css:host { --brand: blue; })` |
|
|
139
92
|
|
|
140
|
-
class ParentComp extends RedGin {
|
|
141
|
-
currentItem: string = 'Laptop';
|
|
142
93
|
|
|
143
|
-
|
|
144
|
-
onInit() {
|
|
145
|
-
// Option 1: Send data to child component using properties
|
|
146
|
-
const child: IChild = this.shadowRoot?.querySelector('child-comp')!;
|
|
147
|
-
child.item = this.currentItem;
|
|
148
|
-
}
|
|
94
|
+
## Lifecycle Methods
|
|
149
95
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
<child-comp></child-comp>
|
|
96
|
+
* onInit() - After first render
|
|
97
|
+
* onDoUpdate() - After data sync
|
|
98
|
+
* onUpdated() - After every attribute change/requestUpdate
|
|
154
99
|
|
|
155
|
-
|
|
156
|
-
<child2-comp item="${this.currentItem}"></child2-comp>
|
|
157
|
-
`;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
```
|
|
100
|
+
## Style Management Examples
|
|
163
101
|
|
|
164
|
-
|
|
165
|
-
|
|
102
|
+
### Global Design System with shareStyle
|
|
103
|
+
import { RedGin, shareStyle, css, html } from 'redgin';
|
|
166
104
|
|
|
167
|
-
//
|
|
105
|
+
// Share Bootstrap globally (injected once, used everywhere)
|
|
106
|
+
shareStyle('<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">')
|
|
168
107
|
|
|
169
|
-
//
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
`;
|
|
108
|
+
// Share design tokens across all components
|
|
109
|
+
```js
|
|
110
|
+
shareStyle(css`
|
|
111
|
+
:host {
|
|
112
|
+
--brand-primary: #007bff;
|
|
113
|
+
--brand-success: #28a745;
|
|
114
|
+
--card-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
|
177
115
|
}
|
|
178
|
-
|
|
116
|
+
|
|
117
|
+
.rg-card {
|
|
118
|
+
border-radius: 8px;
|
|
119
|
+
box-shadow: var(--card-shadow);
|
|
120
|
+
transition: transform 0.2s;
|
|
121
|
+
}
|
|
122
|
+
`);
|
|
123
|
+
|
|
124
|
+
class ProductCard extends RedGin {
|
|
125
|
+
// Component-specific styles (merged with shared styles)
|
|
126
|
+
styles = [css`
|
|
127
|
+
.local-price { color: var(--brand-success); font-weight: bold; }
|
|
128
|
+
`]
|
|
179
129
|
|
|
180
|
-
// Parent component for receiving the custom event
|
|
181
|
-
class ParentComp extends RedGin {
|
|
182
130
|
render() {
|
|
131
|
+
// Bootstrap classes work without local import!
|
|
183
132
|
return html`
|
|
184
|
-
<
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
</
|
|
133
|
+
<div class="rg-card p-3">
|
|
134
|
+
<div class="local-price">$120.00</div>
|
|
135
|
+
<button class="btn btn-primary">Buy Now</button>
|
|
136
|
+
</div>
|
|
188
137
|
`;
|
|
189
138
|
}
|
|
190
139
|
}
|
|
191
|
-
|
|
192
140
|
```
|
|
193
141
|
|
|
194
|
-
|
|
142
|
+
## Reactivity Patterns: watch vs s()
|
|
195
143
|
|
|
196
|
-
|
|
144
|
+
### RedGin offers two complementary reactivity patterns:
|
|
197
145
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
146
|
+
## s() - Smart Auto-detection
|
|
147
|
+
```js
|
|
148
|
+
// Automatically tracks dependencies
|
|
149
|
+
render() {
|
|
150
|
+
return html`
|
|
151
|
+
<div>${s(() => this.count)}</div>
|
|
152
|
+
<div>${s(() => this.theme)}</div>
|
|
153
|
+
`;
|
|
154
|
+
}
|
|
155
|
+
```
|
|
206
156
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
157
|
+
## watch - Explicit Control
|
|
158
|
+
```js
|
|
159
|
+
// Fine-grained control over dependencies
|
|
160
|
+
render() {
|
|
161
|
+
return html`
|
|
162
|
+
${watch(['count', 'theme'], () => html`
|
|
163
|
+
<div class="${this.theme}">
|
|
164
|
+
Count: ${this.count}
|
|
165
|
+
</div>
|
|
212
166
|
`)}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
|
|
167
|
+
`;
|
|
168
|
+
}
|
|
217
169
|
```
|
|
218
170
|
|
|
219
|
-
5. For Loop through the list of Products
|
|
220
|
-
``` javascript
|
|
221
|
-
|
|
222
|
-
// ProductListRenderer.ts
|
|
223
|
-
|
|
224
|
-
// For Loop through the List of Products
|
|
225
|
-
class ProductListRenderer extends RedGin {
|
|
226
|
-
// Reactive property using getset
|
|
227
|
-
products = getset<IProduct[]>([
|
|
228
|
-
{ id: 1, name: 'Laptop' },
|
|
229
|
-
{ id: 2, name: 'Camera' },
|
|
230
|
-
]);
|
|
231
|
-
|
|
232
|
-
// Render method for displaying the list of products
|
|
233
|
-
render() {
|
|
234
|
-
return html`
|
|
235
|
-
<ul>
|
|
236
|
-
${watch(['products'], () =>
|
|
237
|
-
this.products.map(product =>
|
|
238
|
-
html`<li>${product.id} - ${product.name}</li>`
|
|
239
|
-
)
|
|
240
|
-
)}
|
|
241
|
-
</ul>`;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
171
|
|
|
172
|
+
## Examples
|
|
245
173
|
|
|
174
|
+
Check out these live examples demonstrating RedGin's capabilities:
|
|
246
175
|
|
|
247
|
-
|
|
248
|
-
|
|
176
|
+
### Basic Examples
|
|
177
|
+
* [Simple Counter](https://github.com/josnin/redgin/tree/Dev/samples) - Getting started with RedGin
|
|
178
|
+
* [Two-way Data Binding](https://github.com/josnin/redgin/tree/Dev/samples) - Using getset and events
|
|
179
|
+
* [Todo App](https://github.com/josnin/redgin/tree/Dev/samples) - Classic todo example
|
|
249
180
|
|
|
250
181
|
|
|
182
|
+
### Style Examples
|
|
251
183
|
|
|
184
|
+
* [Bootstrap Integration](https://github.com/josnin/redgin/tree/Dev/samples) - Using shareStyle with CSS frameworks
|
|
185
|
+
* [Design Tokens](https://github.com/josnin/redgin/tree/Dev/samples) - Global theme variables
|
|
186
|
+
* [Scoped Styles](https://github.com/josnin/redgin/tree/Dev/samples) - Component-specific CSS
|
|
252
187
|
|
|
253
188
|
|
|
189
|
+
### Advanced Patterns
|
|
190
|
+
* [Surgical List Updates (1,000+ items)](https://github.com/josnin/redgin/tree/Dev/samples) - Only updated rows re-render
|
|
191
|
+
* [E-commerce Application](https://github.com/josnin/redgin/tree/Dev/samples) - Cart, checkout, and async operations
|
|
192
|
+
* [CRM Dashboard](https://github.com/josnin/redgin/tree/Dev/samples) - Multi-view with modals and pipeline
|
|
193
|
+
* [Parent-Child Communication](https://github.com/josnin/redgin/tree/Dev/samples) - Custom events and props
|
|
254
194
|
|
|
255
|
-
|
|
195
|
+
### Integration Examples
|
|
256
196
|
|
|
257
|
-
|
|
197
|
+
* [TypeScript Support](https://github.com/josnin/redgin/tree/Dev/samples) - Full type safety
|
|
198
|
+
* [With Bootstrap](https://github.com/josnin/redgin/tree/Dev/samples) - Using CSS frameworks
|
|
199
|
+
* [Property Reflection](https://github.com/josnin/redgin/tree/Dev/samples) - Syncing props with attributes
|
|
258
200
|
|
|
259
|
-
|
|
260
|
-
render() {
|
|
261
|
-
return html`<div>with syntax highlighted</div>`
|
|
262
|
-
}
|
|
263
|
-
```
|
|
201
|
+
## Performance
|
|
264
202
|
|
|
203
|
+
* Surgical Updates: Only changed elements re-render
|
|
204
|
+
* Bundle Size: ~5.3kb minified + gzipped
|
|
205
|
+
* Memory: Zero virtual DOM overhead
|
|
206
|
+
* Style Injection: Global styles shared once, not duplicated per component
|
|
265
207
|
|
|
208
|
+
## Contributing
|
|
209
|
+
|
|
210
|
+
We welcome contributions!
|
|
211
|
+
```
|
|
212
|
+
git clone https://github.com/josnin/redgin.git
|
|
213
|
+
cd redgin
|
|
214
|
+
npm install
|
|
215
|
+
npm run dev
|
|
216
|
+
```
|
|
266
217
|
|
|
267
218
|
## Reference
|
|
268
219
|
https://web.dev/custom-elements-best-practices/
|
|
@@ -270,14 +221,6 @@ https://web.dev/custom-elements-best-practices/
|
|
|
270
221
|
https://web.dev/shadowdom-v1/
|
|
271
222
|
|
|
272
223
|
|
|
273
|
-
## How to run development server?
|
|
274
|
-
```
|
|
275
|
-
git clone git@github.com:josnin/redgin.git
|
|
276
|
-
cd ~/Documents/redgin/
|
|
277
|
-
npm install
|
|
278
|
-
npm run dev
|
|
279
|
-
```
|
|
280
|
-
|
|
281
224
|
## Help
|
|
282
225
|
|
|
283
226
|
Need help? Open an issue in: [ISSUES](https://github.com/josnin/redgin/issues)
|
|
@@ -285,3 +228,5 @@ Need help? Open an issue in: [ISSUES](https://github.com/josnin/redgin/issues)
|
|
|
285
228
|
|
|
286
229
|
## Contributing
|
|
287
230
|
Want to improve and add feature? Fork the repo, add your changes and send a pull request.
|
|
231
|
+
|
|
232
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* watchProp: Specifically for component attributes/props.
|
|
3
|
+
* Returns a marker string that the RedGin core parses as a "Directive on a Tag".
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Type definition for the reactive expression.
|
|
7
|
+
* 'this' is typed as the component instance.
|
|
8
|
+
*/
|
|
9
|
+
type WatchExpression<T = any> = (this: T) => any;
|
|
10
|
+
export declare const attr: (attrName: string, exp: WatchExpression) => string;
|
|
11
|
+
export {};
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type EventHandler = (this: any, e: any) => any;
|
|
2
|
+
export declare const event: (type: string, fn: EventHandler) => string;
|
|
3
|
+
/**
|
|
4
|
+
* Alias for 'event'. Moving forward, use 'on' for a more
|
|
5
|
+
* declarative feel (e.g., on('click', ...))
|
|
6
|
+
*/
|
|
7
|
+
export declare const on: (type: string, fn: EventHandler) => string;
|
|
2
8
|
export declare function emit(this: any, customEvent: string, value: any, options?: CustomEvent): void;
|
|
9
|
+
/**
|
|
10
|
+
* Attach all events for this component
|
|
11
|
+
*/
|
|
3
12
|
export declare function applyEventListeners(this: any): void;
|
|
13
|
+
/**
|
|
14
|
+
* Remove all events for this component
|
|
15
|
+
*/
|
|
4
16
|
export declare function removeEventListeners(this: any): void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definition for the reactive expression.
|
|
3
|
+
* 'this' is typed as the component instance.
|
|
4
|
+
*/
|
|
5
|
+
type WatchExpression<T = any> = (this: T) => any;
|
|
6
|
+
/**
|
|
7
|
+
* The 's' (stream) utility: Provides "Auto-Tracked" reactivity.
|
|
8
|
+
*
|
|
9
|
+
* Unlike standard 'watch', it treats the expression as a dynamic stream.
|
|
10
|
+
* It surgically extracts dependencies via regex from the function source,
|
|
11
|
+
* removing the need for manual reference arrays.
|
|
12
|
+
*
|
|
13
|
+
* It creates a placeholder <in-watch> and registers it to the component
|
|
14
|
+
* instance for O(1) targeted updates.
|
|
15
|
+
*/
|
|
16
|
+
export declare const s: (exp: WatchExpression) => string;
|
|
17
|
+
export {};
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Type definition for the reactive expression.
|
|
3
|
+
* 'this' is typed as the component instance.
|
|
4
|
+
*/
|
|
5
|
+
export type WatchExpression<T = any> = (this: T) => any;
|
|
6
|
+
/**
|
|
7
|
+
* The 'watch' utility used inside render().
|
|
8
|
+
* It creates a placeholder and registers dependencies to the current component instance.
|
|
9
|
+
*/
|
|
10
|
+
export declare const watch: (refs: string[], exp?: WatchExpression) => string;
|
package/dist/props/getset.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for the getset behavior.
|
|
3
|
+
* forWatch: determines if changing this property should trigger a DOM update.
|
|
4
|
+
*/
|
|
1
5
|
interface IGetSet {
|
|
2
6
|
forWatch?: boolean;
|
|
3
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Factory function to mark a property as reactive state.
|
|
10
|
+
* Usage: myData = getset(0)
|
|
11
|
+
*/
|
|
4
12
|
export declare function getset<T>(value: T, options?: IGetSet): T;
|
|
5
13
|
export {};
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for propReflect options.
|
|
3
|
+
* Allows custom conversion logic and explicit type declarations.
|
|
4
|
+
*/
|
|
1
5
|
interface IPropReflect<T = any> {
|
|
2
6
|
serializerFn?: (this: any, prop: string, type: any, _default: T) => T;
|
|
3
7
|
deserializerFn?: (this: any, prop: string, type: any, _default: T, value: T) => void;
|
|
4
8
|
type?: any;
|
|
5
9
|
name?: string;
|
|
6
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Marks a property for reflection.
|
|
13
|
+
* Usage: myProp = propReflect(false)
|
|
14
|
+
*/
|
|
7
15
|
export declare function propReflect<T>(value: T, options?: IPropReflect<T>): T;
|
|
8
16
|
export {};
|
package/dist/redgin.d.ts
CHANGED
|
@@ -1,25 +1,88 @@
|
|
|
1
|
-
|
|
1
|
+
import { WatchExpression } from './directives/index';
|
|
2
|
+
export { on, event, // to obsolete
|
|
3
|
+
emit, s, watch, attr, customDirectives, } from './directives/index';
|
|
2
4
|
export { getset, propReflect, customPropsBehavior } from './props/index';
|
|
3
|
-
export declare const
|
|
4
|
-
export declare
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
export declare const shared: string[];
|
|
6
|
+
export declare const defaultStyle = ":host{display:block}";
|
|
7
|
+
/**
|
|
8
|
+
* Handles style injection with support for adoptedStyleSheets (faster memory sharing)
|
|
9
|
+
* and standard <style>/<link> fallbacks.
|
|
10
|
+
*/
|
|
11
|
+
export declare function _applyStyle(styles: string | string[], shadowRoot?: ShadowRoot): string;
|
|
12
|
+
/**
|
|
13
|
+
* Add global styles that will be applied to every RedGin component
|
|
14
|
+
*/
|
|
15
|
+
export declare function shareStyle(style: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* THE SURGICAL FLATTENER:
|
|
18
|
+
* 1. Recursively flattens arrays.
|
|
19
|
+
* 2. Joins with EMPTY STRING '' (kills the comma). --> Note: watcher do this
|
|
20
|
+
* 3. Filters out 'dead' values (null, undefined, false).
|
|
21
|
+
*/
|
|
22
|
+
export declare const _f: (v: any) => string;
|
|
23
|
+
export declare const html: (raw: TemplateStringsArray, ...vals: any[]) => string;
|
|
24
|
+
export declare const safe: (val: any) => string;
|
|
25
|
+
export declare const css: (raw: TemplateStringsArray, ...vals: any[]) => string;
|
|
8
26
|
export declare class RedGin extends HTMLElement {
|
|
27
|
+
private _pending;
|
|
28
|
+
private _changed;
|
|
29
|
+
private _connected;
|
|
30
|
+
private _reactiveCache;
|
|
31
|
+
/**
|
|
32
|
+
* INSTANCE-LEVEL CACHING
|
|
33
|
+
* These Maps allow O(1) lookups for data-binding.
|
|
34
|
+
* We store direct references to HTMLElements so we never use querySelector during updates.
|
|
35
|
+
*/
|
|
36
|
+
_watchRegistry: Map<string, Map<string, WatchExpression<any>>>;
|
|
37
|
+
_idToProps: Map<string, string[]>;
|
|
38
|
+
_watchElements: Map<string, HTMLElement>;
|
|
39
|
+
_attrRegistry: Map<string, Map<string, WatchExpression<any>>>;
|
|
40
|
+
_attrElements: Map<string, HTMLElement>;
|
|
41
|
+
_eventElements: Map<string, HTMLElement>;
|
|
42
|
+
styles: string[];
|
|
9
43
|
constructor();
|
|
10
44
|
connectedCallback(): void;
|
|
11
|
-
attributeChangedCallback(prop: any, oldValue: any, newValue: any): void;
|
|
12
45
|
disconnectedCallback(): void;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
46
|
+
attributeChangedCallback(prop: string, oldV: any, newV: any): void;
|
|
47
|
+
/**
|
|
48
|
+
* Schedules a DOM update using a Microtask.
|
|
49
|
+
* If 5 properties change at once, only 1 DOM update is triggered.
|
|
50
|
+
*/
|
|
51
|
+
protected requestUpdate(prop: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* The "Tick" where DOM updates actually happen.
|
|
54
|
+
*/
|
|
55
|
+
private _flush;
|
|
56
|
+
/**
|
|
57
|
+
* Initial setup: Sets up props, applies styles, renders HTML, and caches DOM nodes.
|
|
58
|
+
*/
|
|
59
|
+
private _init;
|
|
60
|
+
private _collectElements;
|
|
61
|
+
/**
|
|
62
|
+
* Garbage collection: Removes watcher references when an <in-watch> element is removed.
|
|
63
|
+
*/
|
|
64
|
+
_cleanupWatch(uniqId: string): void;
|
|
65
|
+
/**
|
|
66
|
+
* First-time synchronization of property values to DOM.
|
|
67
|
+
*/
|
|
68
|
+
private _sync;
|
|
69
|
+
/**
|
|
70
|
+
* Core update logic: Calls registered directives (like watchFn)
|
|
71
|
+
*/
|
|
72
|
+
private _update;
|
|
73
|
+
/**
|
|
74
|
+
* Lifecycle hook triggered after DOM updates are finished.
|
|
75
|
+
*/
|
|
76
|
+
private _afterUpdate;
|
|
77
|
+
private _afterUpdateNoDomChange;
|
|
78
|
+
/**
|
|
79
|
+
* Identifies all class properties to be made reactive.
|
|
80
|
+
* Caches the list to avoid repeat CPU-heavy property reflection.
|
|
81
|
+
*/
|
|
82
|
+
private _setupProps;
|
|
83
|
+
private _reactiveProps;
|
|
20
84
|
onInit(): void;
|
|
21
85
|
onDoUpdate(): void;
|
|
22
86
|
onUpdated(): void;
|
|
23
|
-
styles: string[];
|
|
24
87
|
render(): string;
|
|
25
88
|
}
|
package/dist/redgin.min.js
CHANGED
|
@@ -1,13 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
DOM already provided built-in props reflection for this attribute.`);break}}return t};function j(s,t){if(t===void 0||t?.name!="propReflect")return;let{type:e,value:o,serializerFn:r,deserializerFn:i}=t,l=this.constructor.observedAttributes,w=u(s),n=v(s);if(l===void 0||!l.includes(n)){console.error(`Unable to apply propReflect '${w}' for attribute '${n}',
|
|
3
|
-
Please add '${n}' in the observedAttributes of ${this.constructor.name} component`);return}!P(n)||Object.defineProperty(this,w,{configurable:!0,set(a){if(i)return i.call(this,n,e,o,a);(e===Boolean||typeof a=="boolean"||g.includes(n))&&a===!0?this.setAttribute(n,""):(e===Boolean||g.includes(n))&&a===!1?this.removeAttribute(n):([Object,Array].includes(e)||["object","array"].includes(typeof a))&&a?this.setAttribute(n,JSON.stringify(a)):([String,Number].includes(e)||["string","number"].includes(typeof a))&&a?this.setAttribute(n,a):this.removeAttribute(n)},get(){if(r)return r.call(this,n,e,o);if(n in g||e===Boolean||typeof o=="boolean")return this.hasAttribute(n);if(([String,Array,Object].includes(e)||["number","string","array","object"].includes(typeof o))&&!this.hasAttribute(n))return o;if((e===String||typeof o=="string")&&this.hasAttribute(n))return this.getAttribute(n);if((e===Number||typeof o=="number")&&this.hasAttribute(n))return Number(this.getAttribute(n));if(([Array,Object].includes(e)||["array","object"].includes(typeof o))&&this.hasAttribute(n))return JSON.parse(this.getAttribute(n))}})}function k(s,t){return{value:s,...t,name:"propReflect"}}c.define(j);function B(s,t){if(t===void 0||t?.name!="getset")return;let{value:e,forWatch:o}=t;this[`#${s}`]=e,Object.defineProperty(this,s,{configurable:!0,set(r){this[`#${s}`]=r,o&&this.updateContents(s)&&this._onUpdated()},get(){return this[`#${s}`]}})}function M(s,t){return{value:s,...{forWatch:!0},...t,name:"getset"}}c.define(B);var N={mode:"open",delegatesFocus:!0},q=[],F=[` /* Custom elements are display: inline by default,
|
|
4
|
-
* so setting their width or height will have no effect
|
|
5
|
-
*/
|
|
6
|
-
:host { display: block; }
|
|
7
|
-
`],H=(s,...t)=>String.raw({raw:s},...t),bt=H,A=class extends HTMLElement{constructor(){super(),this.attachShadow(N)}connectedCallback(){this._onInit(),this._onDoUpdate()}attributeChangedCallback(t,e,o){if(e===o)return;this.updateContents(t)&&this._onUpdated()}disconnectedCallback(){T.call(this)}updateContents(t){return x.call(this,t)}setEventListeners(){R.call(this)}setPropsBehavior(){let t=Object.getOwnPropertyNames(this).filter(e=>e!="styles");for(let e of t){let o=this[e];U.call(this,e,o)}}getStyles(t){let e=[],o=[],r=this.shadowRoot?.adoptedStyleSheets;for(let i of t)if(i.startsWith("<link"))e.push(i);else if(i.startsWith("@import")||!r){let l=document.createElement("style");l.innerHTML=i,e.push(l.outerHTML)}else{let l=new CSSStyleSheet;l.replaceSync(i),o.push(l)}return this.shadowRoot&&o.length>0&&(this.shadowRoot.adoptedStyleSheets=[...this.shadowRoot.adoptedStyleSheets,...o]),e.join("")}_onInit(){this.setPropsBehavior(),this.shadowRoot&&(this.shadowRoot.innerHTML=`
|
|
8
|
-
${this.getStyles(q)}
|
|
9
|
-
${this.getStyles(F)}
|
|
10
|
-
${this.getStyles(this.styles)}
|
|
11
|
-
${this.render()}
|
|
12
|
-
`),this.onInit()}_onDoUpdate(){let t=Object.getOwnPropertyNames(this).filter(e=>e!="styles");for(let e of t)this.updateContents(e)&&this._onUpdated();this.setEventListeners(),this.onDoUpdate()}_onUpdated(){this.setEventListeners(),this.onUpdated()}onInit(){}onDoUpdate(){}onUpdated(){}styles=[];render(){return""}};export{A as RedGin,N as attachShadow,bt as css,h as customDirectives,c as customPropsBehavior,F as defaultStyles,I as emit,C as event,M as getset,H as html,q as injectStyles,k as propReflect,L as watch};
|
|
1
|
+
var U=Object.defineProperty;var W=(e,t,n)=>t in e?U(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var g=(e,t,n)=>(W(e,typeof t!="symbol"?t+"":t,n),n);function d(){return"id-"+Math.random().toString(16).slice(2)+"-"+Date.now()}var S=e=>e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`),u=e=>e.replace(/-./g,t=>t[1].toUpperCase());function T(e){let t=[];for(let n of p.reg)t.push(n.call(this,e));return t.filter(n=>n===!0).length>0}var m=class{static define(t){m.reg.push(t)}},p=m;g(p,"reg",[]);var k=(e,t)=>{let n=d(),r=window.__redgin_current_instance;if(r){for(let s=0;s<e.length;s++){let a=e[s],c=r._watchRegistry.get(a);c||(c=new Map,r._watchRegistry.set(a,c)),c.set(n,t)}r._idToProps.set(n,e)}return`<in-watch data-watch="${n}"></in-watch>`},y=class extends HTMLElement{disconnectedCallback(){let t=this.dataset.watch,r=this.getRootNode()?.host;t&&r&&r._cleanupWatch(t)}};customElements.get("in-watch")||customElements.define("in-watch",y);var A=e=>Array.isArray(e)?e.map(A).join(""):e===void 0?"":String(e);p.define(function(t){let n=u(t),r=this._watchRegistry.get(n);if(!r)return!1;let s=!1;for(let[a,c]of r){let i=this._watchElements.get(a);if((!i||!i.isConnected)&&(i=this.shadowRoot.querySelector(`[data-watch="${a}"]`),i&&this._watchElements.set(a,i)),i){let o=c?c.call(this):this[n],l=A(o);i.innerHTML!==String(l)&&(i.innerHTML=l,s=!0)}}return s});var q=e=>{let t=d(),n=window.__redgin_current_instance;if(n){let r=e.toString(),s=/this\.([a-zA-Z_$][\w$]*)/g,a,c=new Set;for(;(a=s.exec(r))!==null;){let i=a[1];n._reactiveCache?.includes(i)&&c.add(i)}for(let i of c){let o=n._watchRegistry.get(i);o||(o=new Map,n._watchRegistry.set(i,o)),o.set(t,e)}n._idToProps.set(t,Array.from(c))}return`<in-watch data-watch="${t}"></in-watch>`};var I=(e,t)=>{let n=d(),r=window.__redgin_current_instance;if(r){let s=t.toString(),a=/this\.([a-zA-Z_$][\w$]*)/g,c,i=new Set;for(;(c=a.exec(s))!==null;){let o=c[1];r._reactiveCache&&r._reactiveCache.includes(o)&&i.add(o)}for(let o of i){r._attrRegistry||(r._attrRegistry=new Map);let l=r._attrRegistry.get(o);l||(l=new Map,r._attrRegistry.set(o,l)),l.set(n,{attrName:e,exp:t})}}return`rg-attr__${e}="${n}"`};p.define(function(t){let n=u(t),r=this._attrRegistry?.get(n);if(!r)return!1;let s=!1;for(let[a,c]of r){let i=this._attrElements.get(a);if((!i||!i.isConnected)&&(i=this.shadowRoot.querySelector(`[rg-attr__${c.attrName}="${a}"]`),i&&this._attrElements.set(a,i)),i){let o=c.exp?c.exp.call(this):this[n],l=c.attrName;if(o===!1||o===null||o===void 0)i.hasAttribute(l)&&(i.removeAttribute(l),s=!0);else{let _=o===!0?"":String(o);i.getAttribute(l)!==_&&(i.setAttribute(l,_),s=!0)}}}return s});var C=(e,t)=>{let n=d(),r=window.__redgin_current_instance;return r&&(r._eventRegistry||(r._eventRegistry=new Map),r._eventRegistry.set(n,[e,t])),`rg-evt__${e}="${n}"`},L=C;function O(e,t,n){let r={detail:t,composed:!0},s=new CustomEvent(e,{...r,...n});this.shadowRoot&&this.shadowRoot.dispatchEvent(s)}function w(){if(!(!this._eventElements||!this._eventRegistry))for(let[e,t]of this._eventElements){let n=this._eventRegistry.get(e);if(!n)continue;let[r,s]=n;t.addEventListener(r,s)}}function $(){if(!(!this._eventElements||!this._eventRegistry))for(let[e,t]of this._eventElements){let n=this._eventRegistry.get(e);if(!n)continue;let[r,s]=n;t.removeEventListener(r,s)}}function P(e,t){for(let n of f.reg)n.call(this,e,t)}var b=class{static define(t){b.reg.push(t)}},f=b;g(f,"reg",[]);var D=["^class$","^style$","^className$","^classList$","^dataset$","^data-","^aria-","^hidden$","^tabindex$","^slot$","^contenteditable$","^draggable$","^spellcheck$"],F=D.map(e=>new RegExp(e)),j=new Set(["disabled","hidden","checked","selected","readonly","multiple"]),H=e=>{for(let t of F)if(t.test(e))return console.error(`Please remove attribute '${e}' from observedAttributes; browser already provides built-in reflection.`),!1;return!0};function z(e,t){if(!t||t.name!=="propReflect")return;let{type:n,value:r,serializerFn:s,deserializerFn:a}=t,c=this.constructor.observedAttributes,i=u(e),o=S(e);if(!c?.includes(o)){console.error(`propReflect '${i}' cannot map to '${o}'. Add '${o}' to observedAttributes of ${this.constructor.name}.`);return}if(!H(o))return;let l=n===Boolean||j.has(o)||typeof r=="boolean",_=n===Object||n===Array||["object","array"].includes(typeof r),R=n===String||n===Number||["string","number"].includes(typeof r);Object.defineProperty(this,i,{configurable:!0,set(h){if(a)return a.call(this,o,n,r,h);l?h?this.setAttribute(o,""):this.removeAttribute(o):_&&h!=null?this.setAttribute(o,JSON.stringify(h)):R&&h!=null?this.setAttribute(o,h):this.removeAttribute(o)},get(){if(s)return s.call(this,o,n,r);if(l)return this.hasAttribute(o);if(!this.hasAttribute(o))return r;if(_)try{return JSON.parse(this.getAttribute(o))}catch{return r}if(R){let h=this.getAttribute(o);return n===Number?Number(h):h}return this.getAttribute(o)}})}function B(e,t){return{value:e,...t,name:"propReflect"}}f.define(z);function G(e,t){if(t===void 0||t?.name!="getset")return;let{value:n,forWatch:r}=t,s=`#${e}`;this[s]=n,Object.defineProperty(this,e,{configurable:!0,set(a){this[s]!==a&&(this[s]=a,r&&this.requestUpdate(e))},get(){return this[s]}})}function K(e,t){return{value:e,...{forWatch:!0},...t,name:"getset"}}f.define(G);var M=new Map,E=[],Z=":host{display:block}";function v(e,t){let n=Array.isArray(e)?e:[e],r=[];if(!t)return n.join("");for(let s of n){if(s.startsWith("<link")){let a=s.match(/href="([^"]+)"/)?.[1];if(a&&!t.querySelector(`link[href="${a}"]`)){let c=document.createElement("div");c.innerHTML=s;let i=c.firstElementChild;i&&t.appendChild(i)}continue}if("adoptedStyleSheets"in t){let a=M.get(s);a||(a=new CSSStyleSheet,a.replaceSync(s),M.set(s,a)),t.adoptedStyleSheets=[...t.adoptedStyleSheets,a];continue}r.push(`<style>${s}</style>`)}return r.join("")}function Mt(e){E.includes(e)||E.push(e)}var x=e=>Array.isArray(e)?e.map(x).join(""):e===void 0?"":String(e),J=(e,...t)=>e.reduce((n,r,s)=>n+r+x(t[s]),""),V={"&":"&","<":"<",">":">",'"':""","'":"'"},Nt=e=>x(e).replace(/[&<>"']/g,n=>V[n]),Ut=J,N=class extends HTMLElement{_pending=!1;_changed=new Set;_connected=!1;_reactiveCache=[];_watchRegistry=new Map;_idToProps=new Map;_watchElements=new Map;_attrRegistry=new Map;_attrElements=new Map;_eventElements=new Map;styles=[];constructor(){super(),this.attachShadow({mode:"open",delegatesFocus:!0})}connectedCallback(){this._connected||(this._connected=!0,this._init())}disconnectedCallback(){$.call(this)}attributeChangedCallback(t,n,r){n!==r&&this.requestUpdate(t)}requestUpdate(t){this._changed.add(t),!this._pending&&(this._pending=!0,queueMicrotask(()=>this._flush()))}_flush(){if(this._pending=!1,!this._changed.size)return;let t=Array.from(this._changed);this._changed.clear();let n=!1;window.__redgin_current_instance=this;for(let r of t)this._update(r)&&(n=!0);window.__redgin_current_instance=null,n?this._afterUpdate():this._afterUpdateNoDomChange()}_init(){this._setupProps(),window.__redgin_current_instance=this,this.shadowRoot&&(v(E,this.shadowRoot),v(Z,this.shadowRoot),v(this.styles,this.shadowRoot),this.shadowRoot.innerHTML+=this.render()),this._collectElements(),this.onInit(),this._sync(),window.__redgin_current_instance=null}_collectElements(t="all"){if(!this.shadowRoot)return;t==="all"&&(this._watchElements.clear(),this._attrElements.clear()),this._eventElements.clear();let n=document.createTreeWalker(this.shadowRoot,NodeFilter.SHOW_ELEMENT,null),r;for(;r=n.nextNode();){let s=r.attributes;for(let a=0;a<s.length;a++){let{name:c,value:i}=s[a];c.startsWith("rg-evt__")?this._eventElements.set(i,r):t==="all"&&(c==="data-watch"?this._watchElements.set(i,r):c.startsWith("rg-attr__")&&this._attrElements.set(i,r))}}}_cleanupWatch(t){let n=this._idToProps.get(t);if(n){for(let r of n){let s=this._watchRegistry.get(r);s&&(s.delete(t),s.size||this._watchRegistry.delete(r))}this._idToProps.delete(t),this._watchElements.delete(t)}}_sync(){for(let t of this._reactiveProps())this._update(t);this._collectElements(),w.call(this),this.onDoUpdate()}_update(t){return T.call(this,t)}_afterUpdate(){this._collectElements("events"),w.call(this),this.onUpdated()}_afterUpdateNoDomChange(){this.onUpdated()}_setupProps(){if(!this._reactiveCache.length){let t=new Set(["styles","_pending","_changed","_connected"]);this._reactiveCache=Object.getOwnPropertyNames(this).filter(n=>!t.has(n))}for(let t of this._reactiveCache)P.call(this,t,this[t])}_reactiveProps(){return this._reactiveCache}onInit(){}onDoUpdate(){}onUpdated(){}render(){return""}};export{N as RedGin,v as _applyStyle,x as _f,I as attr,Ut as css,p as customDirectives,f as customPropsBehavior,Z as defaultStyle,O as emit,C as event,K as getset,J as html,L as on,B as propReflect,q as s,Nt as safe,Mt as shareStyle,E as shared,k as watch};
|
|
13
2
|
//# sourceMappingURL=redgin.min.js.map
|
package/dist/utils.d.ts
CHANGED
package/index.d.ts
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import './samples/sample-styles';
|
|
2
|
+
import './samples/sample-binding';
|
|
3
|
+
import './samples/sampleIf';
|
|
4
|
+
import './samples/sample-nested';
|
|
5
|
+
import './samples/sample-allevents';
|
|
6
|
+
import './samples/ecommerce-app';
|
|
7
|
+
import './samples/todo-catalog';
|
|
8
|
+
import './samples/smart-list';
|
|
9
|
+
import './samples/smart-update-list';
|
|
10
|
+
import './samples/smart-pagination-list';
|
|
11
|
+
import './samples/smart-sort-list';
|
|
12
|
+
import './samples/xss-sandbox';
|
|
13
|
+
import './samples/parentChild/parentChild';
|
|
14
|
+
import './samples/childParent/cart-manager';
|
|
15
|
+
import './samples/modal-app';
|
|
16
|
+
import './samples/master-binding';
|
|
17
|
+
import './samples/smart-grid';
|
|
18
|
+
import './samples/crm-app';
|
|
19
|
+
import './samples/check-search-list';
|
|
20
|
+
import './samples/todo-app';
|
package/package.json
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "redgin",
|
|
3
|
-
"version": "0.
|
|
4
|
-
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "A lightweight (~5.3kb) library for building Web Components with surgical updates and fine-grained reactivity",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"redgin",
|
|
7
6
|
"web components",
|
|
8
|
-
"custom elements"
|
|
7
|
+
"custom elements",
|
|
8
|
+
"reactive",
|
|
9
|
+
"lightweight",
|
|
10
|
+
"tiny",
|
|
11
|
+
"reactive web components",
|
|
12
|
+
"custom elements library",
|
|
13
|
+
"web components framework",
|
|
14
|
+
"shadow dom",
|
|
15
|
+
"vanilla js",
|
|
16
|
+
"no dependencies",
|
|
17
|
+
"reactive programming",
|
|
18
|
+
"fine-grained reactivity",
|
|
19
|
+
"surgical updates",
|
|
20
|
+
"template literals",
|
|
21
|
+
"UI library",
|
|
22
|
+
"component library",
|
|
23
|
+
"frontend",
|
|
24
|
+
"browser",
|
|
25
|
+
"javascript",
|
|
26
|
+
"typescript",
|
|
27
|
+
"reactive state",
|
|
28
|
+
"state management",
|
|
29
|
+
"reactive properties",
|
|
30
|
+
"attribute reflection",
|
|
31
|
+
"custom events",
|
|
32
|
+
"lifecycle hooks",
|
|
33
|
+
"SPA",
|
|
34
|
+
"single page application",
|
|
35
|
+
"micro frontend",
|
|
36
|
+
"framework agnostic"
|
|
9
37
|
],
|
|
10
38
|
"main": "dist/redgin.min.js",
|
|
11
39
|
"types": "dist/redgin.d.ts",
|
|
@@ -19,7 +47,7 @@
|
|
|
19
47
|
"build": "npm run clean && tsc -w",
|
|
20
48
|
"bundle": "npx esbuild --bundle src/redgin.js --minify --sourcemap --format=esm --outfile=dist/redgin.min.js --target=es2022 && npm run copy",
|
|
21
49
|
"copy": "cp -rvf src/*.d.ts dist/. && cp -rfv src/directives/*.d.ts dist/directives/. && cp -rfv src/props/*.d.ts dist/props/.",
|
|
22
|
-
"dev": "node node_modules/vite/bin/vite.js"
|
|
50
|
+
"dev": "node node_modules/vite/bin/vite.js --host 0.0.0.0"
|
|
23
51
|
},
|
|
24
52
|
"repository": {
|
|
25
53
|
"type": "git",
|
|
@@ -32,10 +60,10 @@
|
|
|
32
60
|
},
|
|
33
61
|
"homepage": "https://github.com/josnin/redgin#readme",
|
|
34
62
|
"devDependencies": {
|
|
35
|
-
"@types/node": "^
|
|
63
|
+
"@types/node": "^25.2.3",
|
|
36
64
|
"esbuild": "^0.16.4",
|
|
37
65
|
"rimraf": "^4.1.2",
|
|
38
66
|
"typescript": "^4.9.5",
|
|
39
|
-
"vite": "^
|
|
67
|
+
"vite": "^7.3.1"
|
|
40
68
|
}
|
|
41
69
|
}
|
package/vite.config.js
ADDED
package/dist/props/events.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare const event: (type: string, fn: any) => string;
|
|
2
|
-
export declare function emit(this: any, customEvent: string, value: any, options?: CustomEvent): void;
|
|
3
|
-
export declare function applyEventListeners(this: any): void;
|
|
4
|
-
export declare function removeEventListeners(this: any): void;
|
package/dist/props/watch.d.ts
DELETED