ladrillosjs 2.0.0-beta.3.2 → 2.0.0-beta.3.4
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 +418 -28
- package/dist/index-CBW3yTb-.js +19 -0
- package/dist/index-CBW3yTb-.js.map +1 -0
- package/dist/{index-JWdjGiUA.mjs → index-COl4zCLy.mjs} +176 -142
- package/dist/index-COl4zCLy.mjs.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/ladrillosjs.cjs.js +1 -1
- package/dist/ladrillosjs.es.js +8 -7
- package/dist/ladrillosjs.umd.js +30 -20
- package/dist/ladrillosjs.umd.js.map +1 -1
- package/dist/vite/copyComponentsPlugin.d.ts +39 -0
- package/dist/vite/index.d.ts +4 -0
- package/dist/webcomponent-BdxW-3sK.js +89 -0
- package/dist/webcomponent-BdxW-3sK.js.map +1 -0
- package/dist/webcomponent-WCW6485Z.mjs +1250 -0
- package/dist/webcomponent-WCW6485Z.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/index-JWdjGiUA.mjs.map +0 -1
- package/dist/index-qEisp6n5.js +0 -19
- package/dist/index-qEisp6n5.js.map +0 -1
- package/dist/webcomponent-B-2Pj2ku.js +0 -79
- package/dist/webcomponent-B-2Pj2ku.js.map +0 -1
- package/dist/webcomponent-DT_kduma.mjs +0 -1059
- package/dist/webcomponent-DT_kduma.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ A lightweight, zero-dependency web component framework for building modular web
|
|
|
12
12
|
|
|
13
13
|
- [Features](#features)
|
|
14
14
|
- [Installation](#installation)
|
|
15
|
+
- [Using with Vite](#using-with-vite)
|
|
15
16
|
- [Quick Start](#quick-start)
|
|
16
17
|
- [Core Concepts](#core-concepts)
|
|
17
18
|
- [Component Registration](#component-registration)
|
|
@@ -79,6 +80,131 @@ npm install ladrillosjs
|
|
|
79
80
|
</script>
|
|
80
81
|
```
|
|
81
82
|
|
|
83
|
+
## Using with Vite
|
|
84
|
+
|
|
85
|
+
LadrillosJS includes a Vite plugin to automatically copy your component files to the distribution folder during build. This is useful when you have static component files that need to be served with your application.
|
|
86
|
+
|
|
87
|
+
### Installation
|
|
88
|
+
|
|
89
|
+
If you haven't already:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npm install --save-dev vite
|
|
93
|
+
npm install ladrillosjs
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Setup
|
|
97
|
+
|
|
98
|
+
Create or update your `vite.config.js`:
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
import { defineConfig } from "vite";
|
|
102
|
+
import { copyComponentsPlugin } from "ladrillosjs/vite";
|
|
103
|
+
|
|
104
|
+
export default defineConfig({
|
|
105
|
+
plugins: [
|
|
106
|
+
copyComponentsPlugin({
|
|
107
|
+
src: "components", // Source directory with your components
|
|
108
|
+
dest: "components", // Destination in dist/ folder
|
|
109
|
+
copyOnDev: false, // Only copy during build (not dev server)
|
|
110
|
+
}),
|
|
111
|
+
],
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Basic Usage
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
// vite.config.js with default settings
|
|
119
|
+
import { defineConfig } from "vite";
|
|
120
|
+
import { copyComponentsPlugin } from "ladrillosjs/vite";
|
|
121
|
+
|
|
122
|
+
export default defineConfig({
|
|
123
|
+
plugins: [copyComponentsPlugin()],
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The plugin will:
|
|
128
|
+
|
|
129
|
+
- 📁 Copy your `components/` folder to `dist/components/` during build
|
|
130
|
+
- 🛡️ Handle errors gracefully with helpful logging
|
|
131
|
+
- ⚙️ Use sensible defaults (src: 'components', dest: 'components')
|
|
132
|
+
|
|
133
|
+
### Plugin Options
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
interface CopyComponentsOptions {
|
|
137
|
+
/** Source directory containing components (default: 'components') */
|
|
138
|
+
src?: string;
|
|
139
|
+
|
|
140
|
+
/** Destination directory in dist/ (default: 'components') */
|
|
141
|
+
dest?: string;
|
|
142
|
+
|
|
143
|
+
/** Copy during development server (default: false) */
|
|
144
|
+
copyOnDev?: boolean;
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Complete Example
|
|
149
|
+
|
|
150
|
+
Project structure:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
my-app/
|
|
154
|
+
├── components/
|
|
155
|
+
│ ├── header.html
|
|
156
|
+
│ ├── footer.html
|
|
157
|
+
│ └── card.html
|
|
158
|
+
├── src/
|
|
159
|
+
│ └── main.js
|
|
160
|
+
├── index.html
|
|
161
|
+
└── vite.config.js
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Configuration:
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
import { defineConfig } from "vite";
|
|
168
|
+
import { copyComponentsPlugin } from "ladrillosjs/vite";
|
|
169
|
+
|
|
170
|
+
export default defineConfig({
|
|
171
|
+
plugins: [
|
|
172
|
+
copyComponentsPlugin({
|
|
173
|
+
src: "components",
|
|
174
|
+
dest: "components",
|
|
175
|
+
}),
|
|
176
|
+
],
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Usage in your app:
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
// src/main.js
|
|
184
|
+
import { registerComponents } from "ladrillosjs";
|
|
185
|
+
|
|
186
|
+
await registerComponents([
|
|
187
|
+
{ name: "app-header", path: "./components/header.html" },
|
|
188
|
+
{ name: "app-footer", path: "./components/footer.html" },
|
|
189
|
+
{ name: "app-card", path: "./components/card.html" },
|
|
190
|
+
]);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
After running `npm run build`, your components will be copied to `dist/components/` and be ready for production deployment.
|
|
194
|
+
|
|
195
|
+
### Development Workflow
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# Start dev server (components served from source)
|
|
199
|
+
npm run dev
|
|
200
|
+
|
|
201
|
+
# Build for production (components copied to dist)
|
|
202
|
+
npm run build
|
|
203
|
+
|
|
204
|
+
# Preview production build
|
|
205
|
+
npm run preview
|
|
206
|
+
```
|
|
207
|
+
|
|
82
208
|
## Quick Start
|
|
83
209
|
|
|
84
210
|
### 1. Create Your First Component
|
|
@@ -742,33 +868,9 @@ $listen("user-logged-in", (data) => {
|
|
|
742
868
|
|
|
743
869
|
LadrillosJS supports three ways to include external JavaScript:
|
|
744
870
|
|
|
745
|
-
#### 1.
|
|
746
|
-
|
|
747
|
-
Regular script tags execute within the component's context and have access to component state and utilities:
|
|
748
|
-
|
|
749
|
-
```html
|
|
750
|
-
<!-- alert-button.html -->
|
|
751
|
-
<button onclick="increaseCount()">{title}: {count}</button>
|
|
752
|
-
|
|
753
|
-
<!-- This script runs in the component context -->
|
|
754
|
-
<script src="./alert.js"></script>
|
|
755
|
-
```
|
|
756
|
-
|
|
757
|
-
**alert.js:**
|
|
758
|
-
|
|
759
|
-
```javascript
|
|
760
|
-
// Variables and functions are available to the component
|
|
761
|
-
let count = 0;
|
|
762
|
-
const title = "Button Count";
|
|
763
|
-
|
|
764
|
-
const increaseCount = () => {
|
|
765
|
-
count++; // Updates component state
|
|
766
|
-
};
|
|
767
|
-
```
|
|
768
|
-
|
|
769
|
-
#### 2. ES Modules
|
|
871
|
+
#### 1. ES Modules (Recommended for Complex Logic)
|
|
770
872
|
|
|
771
|
-
Use `type="module"` for standard ES
|
|
873
|
+
Use `type="module"` for standard ES modules with automatic state synchronization. Variables declared in modules are automatically initialized in component state and mutations are automatically synced:
|
|
772
874
|
|
|
773
875
|
```html
|
|
774
876
|
<!-- side-nav.html -->
|
|
@@ -778,7 +880,7 @@ Use `type="module"` for standard ES module imports:
|
|
|
778
880
|
<ul></ul>
|
|
779
881
|
</nav>
|
|
780
882
|
|
|
781
|
-
<!-- Load as ES module -->
|
|
883
|
+
<!-- Load as ES module - variables and exports are auto-synced to state -->
|
|
782
884
|
<script type="module" src="../js/side.js"></script>
|
|
783
885
|
```
|
|
784
886
|
|
|
@@ -787,9 +889,21 @@ Use `type="module"` for standard ES module imports:
|
|
|
787
889
|
```javascript
|
|
788
890
|
import { registerComponent, $listen, $querySelector } from "ladrillosjs";
|
|
789
891
|
|
|
892
|
+
// Declare variables that are used in template bindings
|
|
893
|
+
// They are automatically initialized in component state
|
|
790
894
|
const notes = [];
|
|
895
|
+
|
|
791
896
|
registerComponent("note-item", "./components/note-item.html");
|
|
792
897
|
|
|
898
|
+
// Export functions so they're available to event handlers
|
|
899
|
+
export const createNote = () => {
|
|
900
|
+
const title = prompt("Note title:");
|
|
901
|
+
if (title) {
|
|
902
|
+
notes.push({ title, content: "" });
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
// Listen to global events
|
|
793
907
|
$listen("note_saved", (data) => {
|
|
794
908
|
notes.push({ ...data });
|
|
795
909
|
const ul = $querySelector("ul");
|
|
@@ -801,6 +915,110 @@ $listen("note_saved", (data) => {
|
|
|
801
915
|
});
|
|
802
916
|
```
|
|
803
917
|
|
|
918
|
+
**How Module State Sync Works:**
|
|
919
|
+
|
|
920
|
+
When a module script is loaded, LadrillosJS:
|
|
921
|
+
|
|
922
|
+
1. **Detects variables used in template bindings** (e.g., variables in `{}` expressions)
|
|
923
|
+
2. **Initializes them in component state** automatically when declared
|
|
924
|
+
3. **Syncs mutations to state** automatically when assigned
|
|
925
|
+
4. **Auto-attaches exports** to the component so event handlers can access them
|
|
926
|
+
|
|
927
|
+
This means you write natural JavaScript without boilerplate:
|
|
928
|
+
|
|
929
|
+
```javascript
|
|
930
|
+
// ✨ This is all you need!
|
|
931
|
+
let count = 0; // Auto-initialized in state
|
|
932
|
+
let user = { name: "" }; // Works with objects too
|
|
933
|
+
|
|
934
|
+
export const increment = () => {
|
|
935
|
+
count++; // Auto-synced to state!
|
|
936
|
+
};
|
|
937
|
+
|
|
938
|
+
export const updateUser = (name) => {
|
|
939
|
+
user.name = name; // Auto-synced to state!
|
|
940
|
+
};
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
**ES Module Benefits:**
|
|
944
|
+
|
|
945
|
+
- ✅ Import external libraries and utilities
|
|
946
|
+
- ✅ Organize code across multiple files
|
|
947
|
+
- ✅ Automatic state initialization for binding variables
|
|
948
|
+
- ✅ Automatic state sync on variable mutations
|
|
949
|
+
- ✅ Clean separation of concerns
|
|
950
|
+
- ✅ Standard JavaScript module syntax
|
|
951
|
+
|
|
952
|
+
**Example: Counter Component**
|
|
953
|
+
|
|
954
|
+
```html
|
|
955
|
+
<!-- counter.html -->
|
|
956
|
+
<div>
|
|
957
|
+
<h2>Counter: {count}</h2>
|
|
958
|
+
<button onclick="increment()">+1</button>
|
|
959
|
+
<button onclick="decrement()">-1</button>
|
|
960
|
+
<button onclick="reset()">Reset</button>
|
|
961
|
+
</div>
|
|
962
|
+
|
|
963
|
+
<script type="module" src="./counter.js"></script>
|
|
964
|
+
|
|
965
|
+
<style>
|
|
966
|
+
div {
|
|
967
|
+
text-align: center;
|
|
968
|
+
padding: 2rem;
|
|
969
|
+
}
|
|
970
|
+
button {
|
|
971
|
+
padding: 0.5rem 1rem;
|
|
972
|
+
margin: 0.5rem;
|
|
973
|
+
cursor: pointer;
|
|
974
|
+
}
|
|
975
|
+
</style>
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
**counter.js:**
|
|
979
|
+
|
|
980
|
+
```javascript
|
|
981
|
+
// Variables used in template are auto-initialized
|
|
982
|
+
let count = 0;
|
|
983
|
+
|
|
984
|
+
// Exports are auto-attached to component for event handlers
|
|
985
|
+
export const increment = () => {
|
|
986
|
+
count++;
|
|
987
|
+
};
|
|
988
|
+
|
|
989
|
+
export const decrement = () => {
|
|
990
|
+
count--;
|
|
991
|
+
};
|
|
992
|
+
|
|
993
|
+
export const reset = () => {
|
|
994
|
+
count = 0;
|
|
995
|
+
};
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
#### 2. Component-Scoped Scripts
|
|
999
|
+
|
|
1000
|
+
Regular script tags execute within the component's context and have access to component state and utilities:
|
|
1001
|
+
|
|
1002
|
+
```html
|
|
1003
|
+
<!-- alert-button.html -->
|
|
1004
|
+
<button onclick="increaseCount()">{title}: {count}</button>
|
|
1005
|
+
|
|
1006
|
+
<!-- This script runs in the component context -->
|
|
1007
|
+
<script src="./alert.js"></script>
|
|
1008
|
+
```
|
|
1009
|
+
|
|
1010
|
+
**alert.js:**
|
|
1011
|
+
|
|
1012
|
+
```javascript
|
|
1013
|
+
// Variables and functions are available to the component
|
|
1014
|
+
let count = 0;
|
|
1015
|
+
const title = "Button Count";
|
|
1016
|
+
|
|
1017
|
+
const increaseCount = () => {
|
|
1018
|
+
count++; // Updates component state
|
|
1019
|
+
};
|
|
1020
|
+
```
|
|
1021
|
+
|
|
804
1022
|
#### 3. External Libraries
|
|
805
1023
|
|
|
806
1024
|
Use the `external` attribute for third-party libraries that shouldn't be bound to component context:
|
|
@@ -834,6 +1052,177 @@ Use the `external` attribute for third-party libraries that shouldn't be bound t
|
|
|
834
1052
|
- Libraries that need to be loaded globally
|
|
835
1053
|
- Scripts that don't need component context or utilities
|
|
836
1054
|
|
|
1055
|
+
#### Module Script Best Practices
|
|
1056
|
+
|
|
1057
|
+
**✅ Use modules for:**
|
|
1058
|
+
|
|
1059
|
+
- Component-specific logic and functions
|
|
1060
|
+
- Local state management
|
|
1061
|
+
- Importing utilities and helpers
|
|
1062
|
+
- Organizing complex components
|
|
1063
|
+
|
|
1064
|
+
**❌ Don't use modules for:**
|
|
1065
|
+
|
|
1066
|
+
- Simple inline event handlers (use inline scripts)
|
|
1067
|
+
- Global libraries (use `external` attribute)
|
|
1068
|
+
- Scripts that need global scope
|
|
1069
|
+
|
|
1070
|
+
**Relative Imports:**
|
|
1071
|
+
|
|
1072
|
+
Modules automatically resolve relative imports to their proper URLs:
|
|
1073
|
+
|
|
1074
|
+
```javascript
|
|
1075
|
+
// These work automatically with modules
|
|
1076
|
+
import { helper } from "./utils.js";
|
|
1077
|
+
import { Component } from "../components/component.js";
|
|
1078
|
+
import { api } from "../../api/client.js";
|
|
1079
|
+
```
|
|
1080
|
+
|
|
1081
|
+
#### Legacy: Using `$reactive` (Optional)
|
|
1082
|
+
|
|
1083
|
+
The `$reactive` function is still available for explicit state initialization in edge cases:
|
|
1084
|
+
|
|
1085
|
+
```javascript
|
|
1086
|
+
import { $reactive } from "ladrillosjs";
|
|
1087
|
+
|
|
1088
|
+
let count = 0;
|
|
1089
|
+
const setCount = $reactive("count", count); // Manual initialization
|
|
1090
|
+
|
|
1091
|
+
// Later updates
|
|
1092
|
+
setCount(newValue);
|
|
1093
|
+
```
|
|
1094
|
+
|
|
1095
|
+
However, this is **no longer necessary for module scripts** since variables are automatically initialized. Use it only if you need:
|
|
1096
|
+
|
|
1097
|
+
- Explicit control over initialization timing
|
|
1098
|
+
- Manual setter functions
|
|
1099
|
+
- Backward compatibility with older code
|
|
1100
|
+
|
|
1101
|
+
#### Advanced Module Patterns
|
|
1102
|
+
|
|
1103
|
+
**Pattern 1: Async Data Loading**
|
|
1104
|
+
|
|
1105
|
+
```html
|
|
1106
|
+
<!-- user-profile.html -->
|
|
1107
|
+
<div $if="{loading}">Loading user...</div>
|
|
1108
|
+
<div $else-if="{error}">{error}</div>
|
|
1109
|
+
<div $else>
|
|
1110
|
+
<h1>{user.name}</h1>
|
|
1111
|
+
<p>Email: {user.email}</p>
|
|
1112
|
+
<p>Bio: {user.bio}</p>
|
|
1113
|
+
</div>
|
|
1114
|
+
|
|
1115
|
+
<script type="module" src="./user-profile.js"></script>
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
**user-profile.js:**
|
|
1119
|
+
|
|
1120
|
+
```javascript
|
|
1121
|
+
// Variables auto-initialized in component state
|
|
1122
|
+
let user = { name: "", email: "", bio: "" };
|
|
1123
|
+
let loading = true;
|
|
1124
|
+
let error = null;
|
|
1125
|
+
|
|
1126
|
+
// Auto-exported so it's available as event handler
|
|
1127
|
+
export const loadUser = async (userId) => {
|
|
1128
|
+
loading = true;
|
|
1129
|
+
error = null;
|
|
1130
|
+
|
|
1131
|
+
try {
|
|
1132
|
+
const response = await fetch(`/api/users/${userId}`);
|
|
1133
|
+
user = await response.json();
|
|
1134
|
+
} catch (e) {
|
|
1135
|
+
error = e.message;
|
|
1136
|
+
} finally {
|
|
1137
|
+
loading = false;
|
|
1138
|
+
}
|
|
1139
|
+
};
|
|
1140
|
+
|
|
1141
|
+
// Load user on component mount
|
|
1142
|
+
loadUser(1);
|
|
1143
|
+
```
|
|
1144
|
+
|
|
1145
|
+
**Pattern 2: Composable Logic**
|
|
1146
|
+
|
|
1147
|
+
```javascript
|
|
1148
|
+
// utils/counter.js
|
|
1149
|
+
export const createCounter = (initial = 0) => {
|
|
1150
|
+
let count = initial;
|
|
1151
|
+
|
|
1152
|
+
return {
|
|
1153
|
+
increment: () => count++,
|
|
1154
|
+
decrement: () => count--,
|
|
1155
|
+
reset: () => (count = initial),
|
|
1156
|
+
get value() {
|
|
1157
|
+
return count;
|
|
1158
|
+
},
|
|
1159
|
+
};
|
|
1160
|
+
};
|
|
1161
|
+
|
|
1162
|
+
// counter.js (module script)
|
|
1163
|
+
import { createCounter } from "./utils/counter.js";
|
|
1164
|
+
|
|
1165
|
+
const counter = createCounter(0);
|
|
1166
|
+
|
|
1167
|
+
export const increment = () => counter.increment();
|
|
1168
|
+
export const decrement = () => counter.decrement();
|
|
1169
|
+
export const reset = () => counter.reset();
|
|
1170
|
+
```
|
|
1171
|
+
|
|
1172
|
+
**Pattern 3: Shared State Between Components**
|
|
1173
|
+
|
|
1174
|
+
```javascript
|
|
1175
|
+
// store.js - shared module
|
|
1176
|
+
export let globalState = {
|
|
1177
|
+
user: null,
|
|
1178
|
+
notifications: [],
|
|
1179
|
+
theme: "light",
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
export const updateUser = (user) => {
|
|
1183
|
+
globalState.user = user;
|
|
1184
|
+
};
|
|
1185
|
+
|
|
1186
|
+
export const addNotification = (msg) => {
|
|
1187
|
+
globalState.notifications.push(msg);
|
|
1188
|
+
};
|
|
1189
|
+
|
|
1190
|
+
// In component module script:
|
|
1191
|
+
import { globalState, updateUser } from "./store.js";
|
|
1192
|
+
|
|
1193
|
+
let user = globalState.user;
|
|
1194
|
+
|
|
1195
|
+
export const switchTheme = () => {
|
|
1196
|
+
globalState.theme = globalState.theme === "light" ? "dark" : "light";
|
|
1197
|
+
};
|
|
1198
|
+
```
|
|
1199
|
+
|
|
1200
|
+
**Pattern 4: Event-Driven Updates**
|
|
1201
|
+
|
|
1202
|
+
```javascript
|
|
1203
|
+
import { $listen, $emit } from "ladrillosjs";
|
|
1204
|
+
|
|
1205
|
+
let items = [];
|
|
1206
|
+
let selectedId = null;
|
|
1207
|
+
|
|
1208
|
+
$listen("item:created", (item) => {
|
|
1209
|
+
items = [...items, item];
|
|
1210
|
+
});
|
|
1211
|
+
|
|
1212
|
+
$listen("item:deleted", (itemId) => {
|
|
1213
|
+
items = items.filter((i) => i.id !== itemId);
|
|
1214
|
+
});
|
|
1215
|
+
|
|
1216
|
+
export const selectItem = (id) => {
|
|
1217
|
+
selectedId = id;
|
|
1218
|
+
$emit("item:selected", { id, item: items.find((i) => i.id === id) });
|
|
1219
|
+
};
|
|
1220
|
+
|
|
1221
|
+
export const deleteItem = (id) => {
|
|
1222
|
+
$emit("item:delete-request", { id });
|
|
1223
|
+
};
|
|
1224
|
+
```
|
|
1225
|
+
|
|
837
1226
|
### Shadow DOM
|
|
838
1227
|
|
|
839
1228
|
Components use Shadow DOM by default for style encapsulation:
|
|
@@ -1108,7 +1497,8 @@ $listen(eventName: string, callback: (data?) => void): () => void
|
|
|
1108
1497
|
$querySelector(selector: string): Element | null
|
|
1109
1498
|
$querySelectorAll(selector: string): NodeListOf<Element>
|
|
1110
1499
|
|
|
1111
|
-
//
|
|
1500
|
+
// Manual reactive initialization (optional - mainly for backward compatibility)
|
|
1501
|
+
// Module scripts automatically initialize and sync variables
|
|
1112
1502
|
$reactive(name: string, initialValue: any): (value: any) => void
|
|
1113
1503
|
```
|
|
1114
1504
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";var X=Object.defineProperty,J=Object.defineProperties;var V=Object.getOwnPropertyDescriptors;var L=Object.getOwnPropertySymbols;var Y=Object.prototype.hasOwnProperty,Q=Object.prototype.propertyIsEnumerable;var z=t=>{throw TypeError(t)};var _=(t,e,r)=>e in t?X(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,m=(t,e)=>{for(var r in e||(e={}))Y.call(e,r)&&_(t,r,e[r]);if(L)for(var r of L(e))Q.call(e,r)&&_(t,r,e[r]);return t},h=(t,e)=>J(t,V(e));var U=(t,e,r)=>e.has(t)||z("Cannot "+r);var N=(t,e,r)=>e.has(t)?z("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r);var b=(t,e,r)=>(U(t,e,"access private method"),r);var p=(t,e,r)=>new Promise((s,o)=>{var i=c=>{try{l(r.next(c))}catch(d){o(d)}},a=c=>{try{l(r.throw(c))}catch(d){o(d)}},l=c=>c.done?s(c.value):Promise.resolve(c.value).then(i,a);l((r=r.apply(t,e)).next())});const H=()=>{try{return!1}catch(t){return process.env.NODE_ENV==="development"}},n={log(t,...e){H()&&console.log(t,...e)},error(t,...e){console.error(t,...e)},warn(t,...e){H()&&console.warn(t,...e)}},g=(t,e)=>{const r=[t];return e&&(e.componentName&&r.push(`
|
|
2
|
+
Component: <${e.componentName}>`),e.componentPath&&r.push(`
|
|
3
|
+
File: ${e.componentPath}`),e.expression&&r.push(`
|
|
4
|
+
Expression: ${e.expression}`),e.attributeName&&r.push(`
|
|
5
|
+
Attribute: ${e.attributeName}`),e.eventType&&r.push(`
|
|
6
|
+
Event: ${e.eventType}`),e.elementTag&&r.push(`
|
|
7
|
+
Element: <${e.elementTag}>`),e.lineHint&&r.push(`
|
|
8
|
+
Location: ${e.lineHint}`)),r.join("")},Z=(t,e,r)=>{const s=g("⚠️ Binding Error: Failed to evaluate expression",h(m({},r),{expression:t,lineHint:(r==null?void 0:r.lineHint)||"Template binding expression"}));n.error(s),n.error(` Error details: ${e.message}`),e.stack&&console.debug(" Stack trace:",e.stack)},ee=(t,e,r,s)=>{const o=g("⚠️ Event Handler Error: Failed to execute handler",h(m({},s),{eventType:t,expression:e,lineHint:(s==null?void 0:s.lineHint)||`on${t} handler`}));n.error(o),n.error(` Error details: ${r.message}`),r.stack&&console.debug(" Stack trace:",r.stack)},te=(t,e,r)=>{const s=g("⚠️ Conditional Error: Failed to evaluate condition",h(m({},r),{expression:t,lineHint:(r==null?void 0:r.lineHint)||"$if/$else-if condition"}));n.error(s),n.error(` Error details: ${e.message}`),e.stack&&console.debug(" Stack trace:",e.stack)},re=(t,e,r)=>{const s=g("⚠️ Loop Error: Failed to process loop",h(m({},r),{expression:t,lineHint:(r==null?void 0:r.lineHint)||"$for loop expression"}));n.error(s),n.error(` Error details: ${e.message}`),e.stack&&console.debug(" Stack trace:",e.stack)},M=(t,e,r)=>{const s=g("⚠️ Registration Error: Failed to register component",{componentName:t,componentPath:e});n.error(s),n.error(` Error details: ${r.message}`),r.stack&&console.debug(" Stack trace:",r.stack)},x=(t,e,r)=>{const s=g("⚠️ Fetch Error: Failed to load resource",h(m({},r),{componentPath:t}));n.error(s),n.error(` Error details: ${e.message}`)},P=(t,e)=>{const r=g(`⚠️ Parse Error: ${t}`,e);n.error(r)},se=(t,e)=>{const r=g("⚠️ Script Error: Failed to execute component script",e);n.error(r),n.error(` Error details: ${t.message}`),t.stack&&console.debug(" Stack trace:",t.stack)},oe=(t,e,r)=>{const s=g("⚠️ Two-Way Binding Error: Failed to setup binding",h(m({},r),{expression:t,lineHint:(r==null?void 0:r.lineHint)||"$model binding"}));n.error(s),n.error(` Error details: ${e.message}`)},ne=(t,e)=>{var r;return m({componentName:(t==null?void 0:t.tagName)||((r=t==null?void 0:t.constructor)==null?void 0:r.name),componentPath:(t==null?void 0:t.sourcePath)||(t==null?void 0:t._sourcePath)},e)},u=new Map,ie=25,le=t=>{const e=u.get(t);return e&&(u.delete(t),u.set(t,e)),e},ae=(t,e)=>{if(u.has(t))u.delete(t);else if(u.size>=ie){const r=u.keys().next().value;r&&u.delete(r)}u.set(t,e)},T=t=>p(null,null,function*(){if(!t)throw new Error("Path cannot be null or empty");const e=le(t);if(e)return e;try{const r=yield fetch(t);if(!r.ok)throw new Error(`Failed to fetch component from ${t}: ${r.statusText}`);const s=yield r.text();return ae(t,s),s}catch(r){x(t,r,{componentPath:t})}}),ce=t=>p(null,null,function*(){try{const e=yield fetch(t);if(!e.ok)throw new Error(`HTTP ${e.status}`);return yield e.text()}catch(e){return x(t,e),""}}),$={bindings:/{([^}]+)}/g,comments:{js:/\/\*[\s\S]*?\*\/|\/\/.*$/gm,css:/\/\*[\s\S]*?\*\//g,html:/<!--[\s\S]*?-->/g}},de=new DOMParser,A=(t,e)=>p(null,null,function*(){const r=pe(t),{scripts:s,externalScripts:o}=ge(r),i=yield he(r),a=r.body.innerHTML.trim();return{tagName:e,template:a,scripts:s,externalScripts:o,styles:i}}),pe=t=>de.parseFromString(t.replace($.comments.html,""),"text/html"),ue=t=>["/@vite/","/__vite","/webpack-dev-server","/hot-update","/__webpack_hmr","/browser-sync/","/livereload.js"].some(r=>t.includes(r)),ge=t=>{var s,o;const e=[],r=[];for(const i of t.querySelectorAll("script")){if(i.src){if(ue(i.src)){i.remove();continue}const a=i.hasAttribute("external");r.push({src:i.getAttribute("src")||i.src,type:(s=i.type)!=null?s:null,external:a})}else if(i.textContent){let a=i.textContent.trim();a=a.replace($.comments.js,"").trim(),e.push({content:a,type:(o=i.type)!=null?o:null})}i.remove()}return{scripts:e,externalScripts:r}},me=t=>{const e=t.match(/const __vite__css = "((?:[^"\\]|\\.)*)"/);if(e&&e[1])return e[1].replace(/\\r\\n/g,`
|
|
9
|
+
`).replace(/\\n/g,`
|
|
10
|
+
`).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\");const r=t.match(/export\s+default\s+"((?:[^"\\]|\\.)*)"/);return r&&r[1]?r[1].replace(/\\r\\n/g,`
|
|
11
|
+
`).replace(/\\n/g,`
|
|
12
|
+
`).replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\"):t.includes("import")||t.includes("export")?(n.warn("CSS file returned JavaScript module format. CSS may not load correctly."),""):t},he=t=>p(null,null,function*(){let e="";const r=t.querySelectorAll("style, link[rel='stylesheet']");for(const s of r){if(s.tagName==="LINK"){const i=yield ce(s.href),a=me(i);a&&(e+=`
|
|
13
|
+
`+a)}else if(s.tagName==="STYLE"){const o=s;if(o.textContent){let i=o.textContent.trim();i=i.replace($.comments.css,"").trim(),e+=`
|
|
14
|
+
`+i}}s.remove()}return e.trim()});var E,q,F;class fe{constructor(){N(this,E);this.components={},this.lazyComponents=new Set,this.intersectionObserver=null,this.lazyLoadingInProgress=new Map,this.lazyComponentsLoaded=new Set}registerComponent(e,r,s=!0,o=!1){return p(this,null,function*(){if(this.components[e]){n.warn(`Component with name "${e}" is already registered.`);return}if(o){this.lazyComponents.add(e),b(this,E,q).call(this,e,r,s),n.log(`Component ${e} registered as lazy-loaded`);return}try{const i=yield T(r),a=yield A(i,e);this.components[e]={tagName:e,template:a.template,scripts:a.scripts,externalScripts:a.externalScripts,styles:a.styles,sourcePath:r,lazy:!1},n.log(`Component ${e} registered successfully`),yield b(this,E,F).call(this,e,s)}catch(i){M(e,r,i);return}})}}E=new WeakSet,q=function(e,r,s){const o=this;class i extends HTMLElement{constructor(){super(),this.loaded=!1,this.observer=null,s&&(this.attachShadow({mode:"open"}),this.shadowRoot&&(this.shadowRoot.innerHTML=`
|
|
15
|
+
<style>
|
|
16
|
+
:host { display: block; min-height: 1px; }
|
|
17
|
+
</style>
|
|
18
|
+
`))}connectedCallback(){if(!this.loaded){if(this.hasAttribute("eager")){this.loaded=!0,this.loadComponent();return}this.observer=new IntersectionObserver(l=>{l.forEach(c=>{c.isIntersecting&&!this.loaded&&(this.loaded=!0,this.loadComponent())})},{rootMargin:"100px"}),this.observer.observe(this)}}disconnectedCallback(){this.observer&&(this.observer.disconnect(),this.observer=null)}loadComponent(){return p(this,null,function*(){try{if(o.lazyComponentsLoaded.has(e)){n.log(`Component ${e} already loaded, upgrading placeholder...`),this.upgradePlaceholder();return}if(o.lazyLoadingInProgress.has(e)){n.log(`Component ${e} is already loading, waiting...`),yield o.lazyLoadingInProgress.get(e),this.upgradePlaceholder();return}const l=this.performLoad();o.lazyLoadingInProgress.set(e,l),yield l,o.lazyLoadingInProgress.delete(e),o.lazyComponentsLoaded.add(e),o.lazyComponents.delete(e),n.log(`Component ${e} lazy-loaded successfully`)}catch(l){o.lazyLoadingInProgress.delete(e),M(e,r,l)}})}performLoad(){return p(this,null,function*(){n.log(`Lazy loading component: ${e}`);const l=this.parentNode;if(this.nextSibling,!l){P(`Placeholder for ${e} has no parent node`,{componentName:e,componentPath:r});return}const c=yield T(r),d=yield A(c,e);n.log(`Component ${e} parsed successfully`),o.components[e]={tagName:e,template:d.template,scripts:d.scripts,externalScripts:d.externalScripts,styles:d.styles,sourcePath:r,lazy:!0};const f=`${e}-real`;n.log(`Defining real component with temp name: ${f}`);const y=o.components[e].tagName;o.components[e].tagName=f;const{defineWebComponent:C}=yield Promise.resolve().then(()=>require("./webcomponent-BdxW-3sK.js"));C(o.components[e],s),n.log(`Real component ${f} defined`),o.components[e].tagName=y,this.upgradePlaceholder()})}upgradePlaceholder(){const l=this,c=this.parentNode,d=this.nextSibling;if(!c){P(`Placeholder for ${e} has no parent node`,{componentName:e,componentPath:r});return}const f=`${e}-real`,y=document.createElement(f);for(n.log(`Created real component instance: ${f}`),Array.from(l.attributes).forEach(C=>{C.name!=="eager"&&y.setAttribute(C.name,C.value)});l.firstChild;)y.appendChild(l.firstChild);d?(c.insertBefore(y,d),n.log("Inserted real component before next sibling")):(c.appendChild(y),n.log("Appended real component to parent")),c.removeChild(l),n.log("Removed placeholder element")}}customElements.get(e)||customElements.define(e,i)},F=function(e,r){return p(this,null,function*(){const{defineWebComponent:s}=yield Promise.resolve().then(()=>require("./webcomponent-BdxW-3sK.js"));this.components[e]&&s(this.components[e],r)})};const R=new fe;class ye{constructor(){this.listeners=new Map}emit(e,r){const s=new CustomEvent(e,{detail:r,bubbles:!0,composed:!0});document.dispatchEvent(s);const o=this.listeners.get(e);if(!o||o.size===0)return Promise.resolve();const i=[];return o.forEach(a=>{try{const l=a(r);l instanceof Promise&&i.push(l)}catch(l){n.error(`⚠️ Event Bus Error: Failed to execute listener for "${e}"`),n.error(` Error details: ${l.message}`),i.push(Promise.reject(l))}}),i.length>0?Promise.all(i).then(()=>{}):Promise.resolve()}listen(e,r){return this.listeners.has(e)||this.listeners.set(e,new Set),this.listeners.get(e).add(r),()=>{this.off(e,r)}}off(e,r){const s=this.listeners.get(e);s&&(s.delete(r),s.size===0&&this.listeners.delete(e))}clear(e){e?this.listeners.delete(e):this.listeners.clear()}listenerCount(e){var r,s;return(s=(r=this.listeners.get(e))==null?void 0:r.size)!=null?s:0}}const k=new ye,w={};function we(t={}){const{src:e="components",dest:r="components",copyOnDev:s=!1}=t;return{name:"ladrillosjs:copy-components",apply:s?"serve":"build",generateBundle(i,a){return p(this,null,function*(){const l=w.resolve(process.cwd(),e),c=w.resolve(process.cwd(),"dist",r);if(!w.existsSync(l)){console.warn(`[ladrillosjs:copy-components] Source directory not found: ${l}`);return}try{w.existsSync(c)&&w.rmSync(c,{recursive:!0,force:!0}),w.cpSync(l,c,{recursive:!0}),console.log(`[ladrillosjs:copy-components] Copied components from ${l} to ${c}`)}catch(d){throw console.error("[ladrillosjs:copy-components] Error copying components:",d),d}})}}}const B=(t,e,r,s)=>R.registerComponent(t,e,r,s),j=t=>p(null,null,function*(){yield Promise.all(t.map(({name:e,path:r,useShadowDOM:s,lazy:o})=>R.registerComponent(e,r,s,o)))}),I=(t,e)=>k.listen(t,e),D=(t,e)=>{k.emit(t,e)},Ee=(t,e)=>{if(e){const r=e.tagName.toLowerCase();window.__ladrilloContexts||(window.__ladrilloContexts=new Map),window.__ladrilloContexts.set(r,{shadowRoot:t,element:e})}},v=()=>{const t=window.__ladrilloContexts;if(t&&t.size>0){const e=Array.from(t.values());return e[e.length-1]}return null},W=()=>{const t=v();return t&&t.element?t.element.state||{}:{}},S=t=>{const e=v();e&&e.setState&&e.setState(t)},O=(t,e)=>(S({[t]:e}),r=>{S({[t]:r})}),G=(t,e)=>{if(e)return e.querySelector(t);const r=v();if(r){const s=r.shadowRoot||r.element;if(s){const o=s.querySelector(t);if(o)return o}}return document.querySelector(t)},K=(t,e)=>{if(e)return e.querySelectorAll(t);const r=v();if(r){const s=r.shadowRoot||r.element;if(s){const o=s.querySelectorAll(t);if(o.length>0)return o}}return document.querySelectorAll(t)};typeof window!="undefined"&&(window.ladrillosjs={registerComponent:B,registerComponents:j},window.$listen=I,window.$emit=D,window.$querySelector=G,window.$querySelectorAll=K,window.$reactive=O,window.$setState=S,window.$getState=W);exports.$emit=D;exports.$getState=W;exports.$listen=I;exports.$querySelector=G;exports.$querySelectorAll=K;exports.$reactive=O;exports.$setState=S;exports.REGEX_PATTERNS=$;exports.__setComponentContext=Ee;exports.copyComponentsPlugin=we;exports.createErrorContext=ne;exports.eventBus=k;exports.logBindingError=Z;exports.logConditionalError=te;exports.logEventHandlerError=ee;exports.logLoopError=re;exports.logParseError=P;exports.logScriptError=se;exports.logTwoWayBindingError=oe;exports.logger=n;exports.registerComponent=B;exports.registerComponents=j;
|
|
19
|
+
//# sourceMappingURL=index-CBW3yTb-.js.map
|