@nano-app/frontend 0.3.2 → 0.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/bin/generate-stores.mjs +128 -0
- package/dist/auto-register.mjs +327 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +12 -2
- package/dist/store/{ApiClient.d.ts → ApiStore.d.ts} +4 -3
- package/dist/store/{ApiClient.js → ApiStore.js} +11 -11
- package/dist/store/AppStore.d.ts +25 -0
- package/dist/store/AppStore.js +59 -0
- package/dist/store/RenderManager.d.ts +47 -0
- package/dist/store/RenderManager.js +78 -0
- package/dist/store/StoreManager.d.ts +8 -9
- package/dist/store/StoreManager.js +14 -28
- package/dist/ui/Controller.d.ts +18 -15
- package/dist/ui/Controller.js +43 -14
- package/dist/ui/createComponent.d.ts +16 -4
- package/dist/ui/createComponent.js +26 -18
- package/dist/utils/QueryBuilder.js +4 -2
- package/package.json +6 -2
- package/dist/api/ApiClient.d.ts +0 -16
- package/dist/api/ApiClient.js +0 -69
- package/dist/api/QueryBuilder.d.ts +0 -8
- package/dist/api/QueryBuilder.js +0 -51
- package/dist/components/Controller.d.ts +0 -16
- package/dist/components/Controller.js +0 -29
- package/dist/config/index.d.ts +0 -21
- package/dist/config/index.js +0 -10
- package/dist/hooks/useComponent.d.ts +0 -8
- package/dist/hooks/useComponent.js +0 -10
- package/dist/plugin/index.d.ts +0 -11
- package/dist/plugin/index.js +0 -134
- package/dist/store/StoreClient.d.ts +0 -11
- package/dist/store/StoreClient.js +0 -40
- package/dist/store/bootstrapApp.d.ts +0 -19
- package/dist/store/bootstrapApp.js +0 -25
- package/dist/store/setStores.d.ts +0 -8
- package/dist/store/setStores.js +0 -23
- package/dist/types/api.d.ts +0 -7
- package/dist/types/api.js +0 -2
- package/dist/ui/Component.d.ts +0 -4
- package/dist/ui/Component.js +0 -49
- package/dist/ui/StoreProvider.d.ts +0 -18
- package/dist/ui/StoreProvider.js +0 -62
- package/dist/ui/defineController.d.ts +0 -23
- package/dist/ui/defineController.js +0 -14
- package/dist/ui/defineView.d.ts +0 -3
- package/dist/ui/defineView.js +0 -44
- package/dist/ui/definers.d.ts +0 -1
- package/dist/ui/definers.js +0 -59
- package/dist/ui/useComponent.d.ts +0 -2
- package/dist/ui/useComponent.js +0 -9
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createRequire } from "module";
|
|
4
|
+
import { readdirSync, mkdirSync, writeFileSync, existsSync } from "fs";
|
|
5
|
+
import { resolve, join } from "path";
|
|
6
|
+
|
|
7
|
+
const cwd = process.cwd();
|
|
8
|
+
const srcDir = join(cwd, "src");
|
|
9
|
+
const outDir = join(cwd, "node_modules", "@nano-app", "frontend", "dist");
|
|
10
|
+
const outFile = join(outDir, "auto-register.mjs");
|
|
11
|
+
|
|
12
|
+
// Busca recursivamente archivos *.store.ts
|
|
13
|
+
function findStoreFiles(dir) {
|
|
14
|
+
const results = [];
|
|
15
|
+
if (!existsSync(dir)) return results;
|
|
16
|
+
|
|
17
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
18
|
+
const fullPath = join(dir, entry.name);
|
|
19
|
+
if (entry.isDirectory()) {
|
|
20
|
+
results.push(...findStoreFiles(fullPath));
|
|
21
|
+
} else if (entry.isFile() && entry.name.endsWith(".store.ts")) {
|
|
22
|
+
results.push(fullPath);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return results;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Importa un archivo .ts usando jiti (transpilador de Next.js)
|
|
29
|
+
function loadStoreFile(filePath) {
|
|
30
|
+
try {
|
|
31
|
+
const jitiPath = resolve(cwd, "node_modules", "jiti", "lib", "jiti.cjs");
|
|
32
|
+
const require = createRequire(import.meta.url);
|
|
33
|
+
const jiti = require(jitiPath);
|
|
34
|
+
const load = jiti(filePath, { interopDefault: true });
|
|
35
|
+
const mod = load(filePath);
|
|
36
|
+
return mod?.default ?? mod;
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error(` [ERROR] No se pudo cargar ${filePath}: ${err.message}`);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Valida que el objeto tenga la forma correcta
|
|
44
|
+
function validateEntry(entry, filePath) {
|
|
45
|
+
if (!entry || typeof entry !== "object") {
|
|
46
|
+
console.warn(` [WARN] ${filePath}: el export default no es un objeto, se ignora.`);
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
if (entry.type !== "app" && entry.type !== "api") {
|
|
50
|
+
console.warn(` [WARN] ${filePath}: type debe ser "app" o "api", se ignora.`);
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (entry.type === "api" && !entry.path) {
|
|
54
|
+
console.warn(` [WARN] ${filePath}: type "api" requiere un campo "path", se ignora.`);
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Serializa el objeto de datos a string JS (soporta funciones)
|
|
61
|
+
function serialize(value, indent = 0) {
|
|
62
|
+
const pad = " ".repeat(indent);
|
|
63
|
+
const padInner = " ".repeat(indent + 1);
|
|
64
|
+
|
|
65
|
+
if (value === null) return "null";
|
|
66
|
+
if (value === undefined) return "undefined";
|
|
67
|
+
if (typeof value === "function") return value.toString();
|
|
68
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
69
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
70
|
+
|
|
71
|
+
if (Array.isArray(value)) {
|
|
72
|
+
if (value.length === 0) return "[]";
|
|
73
|
+
const items = value.map((v) => `${padInner}${serialize(v, indent + 1)}`).join(",\n");
|
|
74
|
+
return `[\n${items}\n${pad}]`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (typeof value === "object") {
|
|
78
|
+
const entries = Object.entries(value);
|
|
79
|
+
if (entries.length === 0) return "{}";
|
|
80
|
+
const lines = entries
|
|
81
|
+
.map(([k, v]) => `${padInner}${JSON.stringify(k)}: ${serialize(v, indent + 1)}`)
|
|
82
|
+
.join(",\n");
|
|
83
|
+
return `{\n${lines}\n${pad}}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return String(value);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
const storeFiles = findStoreFiles(srcDir);
|
|
92
|
+
console.log(`\n[nano-app] Buscando archivos *.store.ts en ${srcDir}`);
|
|
93
|
+
console.log(`[nano-app] Encontrados: ${storeFiles.length}\n`);
|
|
94
|
+
|
|
95
|
+
const entries = [];
|
|
96
|
+
|
|
97
|
+
for (const filePath of storeFiles) {
|
|
98
|
+
console.log(` Procesando: ${filePath.replace(cwd, ".")}`);
|
|
99
|
+
const mod = loadStoreFile(filePath);
|
|
100
|
+
if (mod && validateEntry(mod, filePath)) {
|
|
101
|
+
const name = filePath
|
|
102
|
+
.replace(srcDir, "")
|
|
103
|
+
.replace(/\\/g, "/")
|
|
104
|
+
.replace(/^\//, "")
|
|
105
|
+
.replace(/\.store\.ts$/, "")
|
|
106
|
+
.split("/")
|
|
107
|
+
.pop();
|
|
108
|
+
|
|
109
|
+
entries.push({ name, ...mod });
|
|
110
|
+
console.log(` ✓ Store "${name}" (${mod.type})`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Genera el archivo de salida
|
|
115
|
+
mkdirSync(outDir, { recursive: true });
|
|
116
|
+
|
|
117
|
+
const serializedEntries = entries
|
|
118
|
+
.map((entry) => ` ${serialize(entry, 1)}`)
|
|
119
|
+
.join(",\n");
|
|
120
|
+
|
|
121
|
+
const output = `// Auto-generado por @nano-app
|
|
122
|
+
// No editar manualmente.
|
|
123
|
+
export default [\n${serializedEntries}\n];\n`;
|
|
124
|
+
|
|
125
|
+
writeFileSync(outFile, output, "utf-8");
|
|
126
|
+
|
|
127
|
+
console.log(`\n[nano-app] Archivo generado: ${outFile.replace(cwd, ".")}`);
|
|
128
|
+
console.log(`[nano-app] Stores registrados: ${entries.map((e) => `"${e.name}"`).join(", ") || "(ninguno — se usará store app vacío)"}\n`);
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
// Auto-generado por @nano-app
|
|
2
|
+
// No editar manualmente.
|
|
3
|
+
export default [
|
|
4
|
+
{
|
|
5
|
+
"name": "api",
|
|
6
|
+
"type": "api",
|
|
7
|
+
"path": "/api",
|
|
8
|
+
"data": {
|
|
9
|
+
"busy": true,
|
|
10
|
+
"DefaultItems": [],
|
|
11
|
+
"UserStatusItems": [
|
|
12
|
+
{
|
|
13
|
+
"key": "SUSPENDED",
|
|
14
|
+
"text": "Suspendido"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"key": "PENDING",
|
|
18
|
+
"text": "Pendiente"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"key": "ACTIVE",
|
|
22
|
+
"text": "Activo"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "app",
|
|
29
|
+
"type": "app",
|
|
30
|
+
"data": {
|
|
31
|
+
"login": {
|
|
32
|
+
"isRegister": false
|
|
33
|
+
},
|
|
34
|
+
"navbar": {
|
|
35
|
+
"tabs": [],
|
|
36
|
+
"selectedTabKey": "home",
|
|
37
|
+
"selectedTab": {},
|
|
38
|
+
"isMenuOpen": false
|
|
39
|
+
},
|
|
40
|
+
"form": {
|
|
41
|
+
"data": {},
|
|
42
|
+
"validate": []
|
|
43
|
+
},
|
|
44
|
+
"drawer": {
|
|
45
|
+
"isOpen": false,
|
|
46
|
+
"formType": "",
|
|
47
|
+
"title": ""
|
|
48
|
+
},
|
|
49
|
+
"config": {
|
|
50
|
+
"theme": "dark"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "const",
|
|
56
|
+
"type": "app",
|
|
57
|
+
"data": {
|
|
58
|
+
"alias": "42974117.prex",
|
|
59
|
+
"stepSkipTop": 20,
|
|
60
|
+
"tabs": (rolId = 0) => [
|
|
61
|
+
{ key: "home", href: "/", label: "Home", minRole: -1 },
|
|
62
|
+
{ key: "resumen", href: "/resumen", label: "Resumen", minRole: -1 },
|
|
63
|
+
{ key: "admin", href: "/admin", label: "Administración", minRole: -1 },
|
|
64
|
+
{ key: "uli", href: "/", label: "Uli :v", minRole: -1 },
|
|
65
|
+
{ key: "luka", href: "/", label: "Lucas :v", minRole: -1 }].
|
|
66
|
+
filter((tab) => tab.minRole <= rolId),
|
|
67
|
+
"initialForms": {
|
|
68
|
+
"User": {
|
|
69
|
+
"rolId": 1,
|
|
70
|
+
"status": "PENDING"
|
|
71
|
+
},
|
|
72
|
+
"Collection": {
|
|
73
|
+
"total_months": 1,
|
|
74
|
+
"start_date": "2026-03-01T00:00:00.000Z"
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"tableColumns": {
|
|
78
|
+
"Users": [
|
|
79
|
+
"name",
|
|
80
|
+
"phone",
|
|
81
|
+
"mail",
|
|
82
|
+
"pending",
|
|
83
|
+
"favor",
|
|
84
|
+
"rol.name",
|
|
85
|
+
"status"
|
|
86
|
+
],
|
|
87
|
+
"Collections": [
|
|
88
|
+
"user.name",
|
|
89
|
+
"price",
|
|
90
|
+
"description",
|
|
91
|
+
"start_date",
|
|
92
|
+
"total_months",
|
|
93
|
+
"subscription.description"
|
|
94
|
+
],
|
|
95
|
+
"Subscriptions": [
|
|
96
|
+
"description",
|
|
97
|
+
"price"
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
"formField": {
|
|
101
|
+
"pay": [
|
|
102
|
+
{
|
|
103
|
+
"fieldName": "total",
|
|
104
|
+
"valueType": "price",
|
|
105
|
+
"isRequired": true
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
"login": [
|
|
109
|
+
{
|
|
110
|
+
"fieldName": "mail",
|
|
111
|
+
"inputType": "email",
|
|
112
|
+
"isRequired": true
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"fieldName": "password",
|
|
116
|
+
"inputType": "password",
|
|
117
|
+
"isRequired": true,
|
|
118
|
+
"validateFn": (oForm) =>
|
|
119
|
+
(oForm.password?.length || 0) < 4 ?
|
|
120
|
+
"La contraseña debe tener al menos 4 caracteres" :
|
|
121
|
+
""
|
|
122
|
+
}
|
|
123
|
+
],
|
|
124
|
+
"register": [
|
|
125
|
+
{
|
|
126
|
+
"fieldName": "name",
|
|
127
|
+
"isRequired": true
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"fieldName": "phone",
|
|
131
|
+
"isRequired": true
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"fieldName": "mail",
|
|
135
|
+
"inputType": "email",
|
|
136
|
+
"isRequired": true
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"fieldName": "password",
|
|
140
|
+
"inputType": "password",
|
|
141
|
+
"isRequired": true,
|
|
142
|
+
"validateFn": (oForm) =>
|
|
143
|
+
(oForm.password?.length || 0) < 4 ?
|
|
144
|
+
"La contraseña debe tener al menos 4 caracteres" :
|
|
145
|
+
""
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"fieldName": "confirmPassword",
|
|
149
|
+
"inputType": "password",
|
|
150
|
+
"isRequired": true,
|
|
151
|
+
"validateFn": (oForm) =>
|
|
152
|
+
oForm.confirmPassword != oForm.password ?
|
|
153
|
+
'Las contraseñas no coinciden' :
|
|
154
|
+
''
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
"Users": [
|
|
158
|
+
{
|
|
159
|
+
"fieldName": "name",
|
|
160
|
+
"isRequired": true
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"fieldName": "mail",
|
|
164
|
+
"inputType": "email",
|
|
165
|
+
"isRequired": true
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"fieldName": "rolId",
|
|
169
|
+
"valueType": "number",
|
|
170
|
+
"isRequired": true,
|
|
171
|
+
"inputType": "select",
|
|
172
|
+
"select": {
|
|
173
|
+
"items": "/Roles",
|
|
174
|
+
"itemKey": "id",
|
|
175
|
+
"showValues": [
|
|
176
|
+
"name"
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"fieldName": "status",
|
|
182
|
+
"inputType": "select",
|
|
183
|
+
"isRequired": true,
|
|
184
|
+
"select": {
|
|
185
|
+
"items": "/UserStatusItems",
|
|
186
|
+
"itemKey": "key",
|
|
187
|
+
"showValues": [
|
|
188
|
+
"text"
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"fieldName": "pending",
|
|
194
|
+
"valueType": "price"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"fieldName": "favor",
|
|
198
|
+
"valueType": "price"
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
"Collections": [
|
|
202
|
+
{
|
|
203
|
+
"fieldName": "userId",
|
|
204
|
+
"valueType": "number",
|
|
205
|
+
"inputType": "select",
|
|
206
|
+
"isRequired": true,
|
|
207
|
+
"select": {
|
|
208
|
+
"items": "Users",
|
|
209
|
+
"itemKey": "id",
|
|
210
|
+
"showValues": [
|
|
211
|
+
"name"
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"fieldName": "price",
|
|
217
|
+
"valueType": "price",
|
|
218
|
+
"isRequired": true
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"fieldName": "description",
|
|
222
|
+
"isRequired": true
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"fieldName": "total_months",
|
|
226
|
+
"valueType": "number",
|
|
227
|
+
"isRequired": true
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"fieldName": "start_date",
|
|
231
|
+
"valueType": "date",
|
|
232
|
+
"inputType": "date",
|
|
233
|
+
"isRequired": true
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"fieldName": "subscriptionId",
|
|
237
|
+
"valueType": "number",
|
|
238
|
+
"inputType": "select",
|
|
239
|
+
"select": {
|
|
240
|
+
"items": "Subscriptions",
|
|
241
|
+
"itemKey": "id",
|
|
242
|
+
"showValues": [
|
|
243
|
+
"description"
|
|
244
|
+
]
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
"Subscriptions": [
|
|
249
|
+
{
|
|
250
|
+
"fieldName": "description",
|
|
251
|
+
"isRequired": true
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"fieldName": "price",
|
|
255
|
+
"valueType": "price",
|
|
256
|
+
"isRequired": true
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
},
|
|
260
|
+
"expandFields": {
|
|
261
|
+
"Users": "rol",
|
|
262
|
+
"Collections": "user,subscription"
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"name": "i18n",
|
|
268
|
+
"type": "app",
|
|
269
|
+
"data": {
|
|
270
|
+
"loginTexts": (isRegister) => ({
|
|
271
|
+
headerText: isRegister ? "REGISTRARSE" : "INICIAR SESIÓN",
|
|
272
|
+
footerText: isRegister ? "o iniciar sesión" : "o registrarse",
|
|
273
|
+
buttonText: isRegister ? "Crear" : "Ingresar",
|
|
274
|
+
formType: isRegister ? "register" : "login"
|
|
275
|
+
}),
|
|
276
|
+
"button": {
|
|
277
|
+
"confirm": "Confirmar"
|
|
278
|
+
},
|
|
279
|
+
"create": (entity) => `Crear ${entity}`,
|
|
280
|
+
"edit": (entity) => `Editar ${entity}`,
|
|
281
|
+
"mapping": {
|
|
282
|
+
"name": "Nombre",
|
|
283
|
+
"phone": "Teléfono",
|
|
284
|
+
"mail": "Mail",
|
|
285
|
+
"pending": "Pendiente",
|
|
286
|
+
"favor": "A favor",
|
|
287
|
+
"rolId": "Rol",
|
|
288
|
+
"rol.name": "Rol",
|
|
289
|
+
"status": "Estado",
|
|
290
|
+
"password": "Contraseña",
|
|
291
|
+
"confirmPassword": "Repetir contraseña",
|
|
292
|
+
"user.name": "Usuario",
|
|
293
|
+
"userId": "Usuario",
|
|
294
|
+
"price": "Precio",
|
|
295
|
+
"description": "Descripción",
|
|
296
|
+
"start_date": "Fecha de inicio",
|
|
297
|
+
"total_months": "Meses totales",
|
|
298
|
+
"subscription.description": "Subscripción",
|
|
299
|
+
"subscriptionId": "Subscripción",
|
|
300
|
+
"last_pay": "Último pago",
|
|
301
|
+
"first_month": "Mes de inicio",
|
|
302
|
+
"current_month": "Último mes pagado",
|
|
303
|
+
"payed_months": "Meses pagados",
|
|
304
|
+
"actions": "Acciones",
|
|
305
|
+
"created_at": "Creado",
|
|
306
|
+
"Users": "Usuarios",
|
|
307
|
+
"Collections": "Cuotas",
|
|
308
|
+
"Subscriptions": "Subscripciones",
|
|
309
|
+
"total": "TOTAL"
|
|
310
|
+
},
|
|
311
|
+
"months": {
|
|
312
|
+
"1": "Enero",
|
|
313
|
+
"2": "Febrero",
|
|
314
|
+
"3": "Marzo",
|
|
315
|
+
"4": "Abril",
|
|
316
|
+
"5": "Mayo",
|
|
317
|
+
"6": "Junio",
|
|
318
|
+
"7": "Julio",
|
|
319
|
+
"8": "Agosto",
|
|
320
|
+
"9": "Septiembre",
|
|
321
|
+
"10": "Octubre",
|
|
322
|
+
"11": "Noviembre",
|
|
323
|
+
"12": "Diciembre"
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from "./store/
|
|
2
|
-
export * from "./store/
|
|
1
|
+
export * from "./store/ApiStore";
|
|
2
|
+
export * from "./store/AppStore";
|
|
3
3
|
export * from "./store/StoreManager";
|
|
4
|
+
export * from "./store/RenderManager";
|
|
4
5
|
export * from "./ui/Controller";
|
|
5
6
|
export * from "./ui/createComponent";
|
|
6
7
|
export * from "./utils/QueryBuilder";
|
package/dist/index.js
CHANGED
|
@@ -13,12 +13,22 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
13
13
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
16
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
|
|
18
|
-
__exportStar(require("./store/
|
|
20
|
+
const StoreManager_1 = __importDefault(require("./store/StoreManager"));
|
|
21
|
+
__exportStar(require("./store/ApiStore"), exports);
|
|
22
|
+
__exportStar(require("./store/AppStore"), exports);
|
|
19
23
|
__exportStar(require("./store/StoreManager"), exports);
|
|
24
|
+
__exportStar(require("./store/RenderManager"), exports);
|
|
20
25
|
__exportStar(require("./ui/Controller"), exports);
|
|
21
26
|
__exportStar(require("./ui/createComponent"), exports);
|
|
22
27
|
__exportStar(require("./utils/QueryBuilder"), exports);
|
|
23
28
|
__exportStar(require("./utils/Toast"), exports);
|
|
24
29
|
__exportStar(require("./utils/TokenHelper"), exports);
|
|
30
|
+
// Inicializa los stores si existen
|
|
31
|
+
try {
|
|
32
|
+
StoreManager_1.default.init(require('./auto-register.mjs').default);
|
|
33
|
+
}
|
|
34
|
+
catch (e) { }
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { ApiResponse } from "@nano-app/backend";
|
|
2
|
-
import {
|
|
2
|
+
import { AppStore, StoreData } from "./AppStore";
|
|
3
3
|
export type ApiRequest = (query: string, body?: unknown) => Promise<ApiResponse>;
|
|
4
|
-
export declare class
|
|
4
|
+
export declare class ApiStore extends AppStore {
|
|
5
5
|
private baseUrl;
|
|
6
|
-
|
|
6
|
+
private busyCount;
|
|
7
|
+
constructor(initialData?: StoreData, storeName?: string, baseUrl?: string);
|
|
7
8
|
create: ApiRequest;
|
|
8
9
|
read: ApiRequest;
|
|
9
10
|
update: ApiRequest;
|
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
3
|
+
exports.ApiStore = void 0;
|
|
4
|
+
const AppStore_1 = require("./AppStore");
|
|
5
5
|
const QueryBuilder_1 = require("../utils/QueryBuilder");
|
|
6
6
|
const TokenHelper_1 = require("../utils/TokenHelper");
|
|
7
7
|
const Toast_1 = require("../utils/Toast");
|
|
8
|
-
class
|
|
8
|
+
class ApiStore extends AppStore_1.AppStore {
|
|
9
9
|
baseUrl;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
busyCount = 0;
|
|
11
|
+
constructor(initialData = {}, storeName = "", baseUrl = "/api") {
|
|
12
|
+
super({}, storeName);
|
|
12
13
|
this.baseUrl = baseUrl;
|
|
13
14
|
}
|
|
14
15
|
create = (entity, body) => this.request("POST", entity, body);
|
|
15
16
|
read = async (query, params = {}) => {
|
|
16
17
|
const path = query.split("?")[0];
|
|
17
18
|
const response = await this.request("GET", QueryBuilder_1.QueryBuilder.build(query, params));
|
|
18
|
-
this.set(
|
|
19
|
+
this.set(`${path}`, response.result);
|
|
19
20
|
return response;
|
|
20
21
|
};
|
|
21
22
|
update = (entity, body) => this.request("PUT", entity, body);
|
|
22
23
|
delete = (entity, id) => this.request("DELETE", entity, id);
|
|
23
24
|
async request(method, path, body) {
|
|
24
25
|
let oResponse = { result: null, success: false, message: "", warning: false };
|
|
25
|
-
this.
|
|
26
|
+
this.busyCount++;
|
|
26
27
|
this.set("/busy", true);
|
|
27
28
|
try {
|
|
28
29
|
oResponse = await fetch(`${this.baseUrl}${path}`, {
|
|
@@ -40,12 +41,11 @@ class ApiClient extends StoreClient_1.StoreClient {
|
|
|
40
41
|
console.error(error);
|
|
41
42
|
}
|
|
42
43
|
finally {
|
|
43
|
-
|
|
44
|
-
this.
|
|
45
|
-
if (remaining < 1)
|
|
44
|
+
this.busyCount--;
|
|
45
|
+
if (this.busyCount < 1)
|
|
46
46
|
this.set("/busy", false);
|
|
47
47
|
}
|
|
48
48
|
return oResponse;
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
exports.
|
|
51
|
+
exports.ApiStore = ApiStore;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type StoreData = Record<string, any>;
|
|
2
|
+
export declare class AppStore {
|
|
3
|
+
protected name: string;
|
|
4
|
+
private state;
|
|
5
|
+
constructor(initialData?: StoreData, name?: string);
|
|
6
|
+
/**
|
|
7
|
+
* Gestiona el estado de la store
|
|
8
|
+
* @param path - El path del estado
|
|
9
|
+
* @param value - El valor a asignar
|
|
10
|
+
* @returns El valor del estado
|
|
11
|
+
*/
|
|
12
|
+
private manageState;
|
|
13
|
+
/**
|
|
14
|
+
* Obtiene el valor del estado
|
|
15
|
+
* @param path - El path del estado
|
|
16
|
+
* @returns El valor del estado
|
|
17
|
+
*/
|
|
18
|
+
get(path: string): any;
|
|
19
|
+
/**
|
|
20
|
+
* Asigna un valor al estado
|
|
21
|
+
* @param path - El path del estado
|
|
22
|
+
* @param value - El valor a asignar
|
|
23
|
+
*/
|
|
24
|
+
set(path: string, value: any): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AppStore = void 0;
|
|
7
|
+
const RenderManager_1 = __importDefault(require("./RenderManager"));
|
|
8
|
+
class AppStore {
|
|
9
|
+
name;
|
|
10
|
+
state;
|
|
11
|
+
constructor(initialData = {}, name = "app") {
|
|
12
|
+
this.name = name;
|
|
13
|
+
this.state = initialData;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Gestiona el estado de la store
|
|
17
|
+
* @param path - El path del estado
|
|
18
|
+
* @param value - El valor a asignar
|
|
19
|
+
* @returns El valor del estado
|
|
20
|
+
*/
|
|
21
|
+
manageState(path, value) {
|
|
22
|
+
// Divide el path en segmentos y obtiene el ultimo segmento
|
|
23
|
+
const segments = path.split("/").filter(Boolean);
|
|
24
|
+
if (segments.length === 0)
|
|
25
|
+
return this.state;
|
|
26
|
+
const last = segments.pop();
|
|
27
|
+
// Recorre los segmentos y crea el objeto si no existe
|
|
28
|
+
let current = this.state;
|
|
29
|
+
for (const seg of segments) {
|
|
30
|
+
if (current[seg] == null)
|
|
31
|
+
current[seg] = {};
|
|
32
|
+
current = current[seg];
|
|
33
|
+
}
|
|
34
|
+
// Si se proporciona un valor, lo asigna al ultimo segmento
|
|
35
|
+
if (arguments.length >= 2) {
|
|
36
|
+
current[last] = value;
|
|
37
|
+
}
|
|
38
|
+
// Retorna el valor del ultimo segmento
|
|
39
|
+
return current[last];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Obtiene el valor del estado
|
|
43
|
+
* @param path - El path del estado
|
|
44
|
+
* @returns El valor del estado
|
|
45
|
+
*/
|
|
46
|
+
get(path) {
|
|
47
|
+
return this.manageState(path);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Asigna un valor al estado
|
|
51
|
+
* @param path - El path del estado
|
|
52
|
+
* @param value - El valor a asignar
|
|
53
|
+
*/
|
|
54
|
+
set(path, value) {
|
|
55
|
+
this.manageState(path, value);
|
|
56
|
+
RenderManager_1.default.refresh(path, this.name);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.AppStore = AppStore;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
type ComponentId = symbol;
|
|
2
|
+
/**
|
|
3
|
+
{
|
|
4
|
+
store1: {
|
|
5
|
+
path1: {
|
|
6
|
+
component1: true,
|
|
7
|
+
component2: true,
|
|
8
|
+
},
|
|
9
|
+
path2: {
|
|
10
|
+
component1: true,
|
|
11
|
+
},
|
|
12
|
+
path3: {
|
|
13
|
+
component1: true,
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
*/
|
|
18
|
+
export declare class RenderManager {
|
|
19
|
+
private dependenciesMap;
|
|
20
|
+
private hooksMap;
|
|
21
|
+
/**
|
|
22
|
+
* Registra un hook de re-render para un componente
|
|
23
|
+
* @param componentId - El id del componente
|
|
24
|
+
* @param hook - El hook de re-render
|
|
25
|
+
*/
|
|
26
|
+
register(componentId: ComponentId, hook: () => void): void;
|
|
27
|
+
/**
|
|
28
|
+
* Agrega una dependencia de path a un componente
|
|
29
|
+
* @param componentId - El id del componente
|
|
30
|
+
* @param path - El path del estado
|
|
31
|
+
* @param storeName - El nombre del store
|
|
32
|
+
*/
|
|
33
|
+
dependsOn(componentId: ComponentId, path: string, storeName: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Actualiza los componentes que dependen de este path
|
|
36
|
+
* @param path - El path del estado
|
|
37
|
+
* @param storeName - El nombre del store
|
|
38
|
+
*/
|
|
39
|
+
refresh(path: string, storeName: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Elimina un componente del manager
|
|
42
|
+
* @param componentId - El id del componente
|
|
43
|
+
*/
|
|
44
|
+
unregister(componentId: ComponentId): void;
|
|
45
|
+
}
|
|
46
|
+
declare const _default: RenderManager;
|
|
47
|
+
export default _default;
|