vaderjs 1.3.3-alpha-41 → 1.3.3-alpha-43
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 +2 -0
- package/client/index.js +243 -455
- package/package.json +10 -1
- package/runtime/router.js +23 -22
- package/runtime/vader.js +106 -382
- package/vader.js +334 -359
package/client/index.js
CHANGED
|
@@ -1,153 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
window.params = {};
|
|
3
1
|
window.Vader = {
|
|
4
|
-
version: "1.3.3",
|
|
2
|
+
version: "1.3.3",
|
|
5
3
|
};
|
|
6
4
|
|
|
7
5
|
let errors = {
|
|
8
6
|
"SyntaxError: Unexpected token '<'": "You forgot to enclose tags in a fragment <></>",
|
|
9
7
|
}
|
|
10
|
-
|
|
11
|
-
const path = {
|
|
12
|
-
basename: (path) => {
|
|
13
|
-
return path.split("/").pop();
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
window.queryRef = (ref) => {
|
|
19
|
-
return document.querySelector(`[data-ref="${ref}"]`)
|
|
20
|
-
}
|
|
21
|
-
window.reinvoke = (eventtype, element) => {
|
|
22
|
-
const eventListener = (e) => {
|
|
23
|
-
return e
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
// Check if the event listener has not been added before adding it
|
|
27
|
-
if (!element._eventListenerAdded) {
|
|
28
|
-
element.addEventListener(eventtype, eventListener);
|
|
29
|
-
|
|
30
|
-
// Set the flag to indicate that the event listener has been added
|
|
31
|
-
element._eventListenerAdded = true;
|
|
32
|
-
|
|
33
|
-
// Trigger the event without overwriting existing data or listeners
|
|
34
|
-
element.dispatchEvent(new Event(eventtype));
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
|
|
39
8
|
|
|
40
|
-
|
|
41
|
-
let invokes = []
|
|
42
|
-
let hasran = [];
|
|
43
|
-
let states = {};
|
|
44
9
|
let mounts = [];
|
|
10
|
+
/**
|
|
11
|
+
* @method strictMount
|
|
12
|
+
* @description This method allows you to await until the component is mounted before running a callback
|
|
13
|
+
* @param {*} key
|
|
14
|
+
* @param {*} callback
|
|
15
|
+
*/
|
|
45
16
|
export const strictMount = (key, callback) => {
|
|
46
17
|
let timer = setInterval(() => {
|
|
47
|
-
if (
|
|
48
|
-
console.log('mounted')
|
|
18
|
+
if (mounts.find((m) => m.key === key)) {
|
|
49
19
|
clearInterval(timer);
|
|
50
20
|
callback();
|
|
51
21
|
}
|
|
52
22
|
}, 120);
|
|
53
23
|
};
|
|
54
24
|
|
|
55
|
-
window.delegate = (event) => {
|
|
56
|
-
return event.detail.target
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
let components = {};
|
|
60
|
-
|
|
61
|
-
let style = document.createElement("style");
|
|
62
|
-
document.head.appendChild(style);
|
|
63
|
-
|
|
64
|
-
const parseStyles = async (styles, className = '') => {
|
|
65
|
-
let css = await fetch(styles).then((res) => res.text());
|
|
66
|
-
let classes = css.split("}");
|
|
67
|
-
let parsedClasses = {};
|
|
68
|
-
classes.forEach((cls) => {
|
|
69
|
-
|
|
70
|
-
let name = cls.split(".")[1];
|
|
71
|
-
let value = cls.split("{")[1]
|
|
72
|
-
let keys = value.split(";");
|
|
73
|
-
let newKeys = [];
|
|
74
|
-
keys.forEach((key) => {
|
|
75
|
-
if (key.includes(":")) {
|
|
76
|
-
let newKey = key.split(":")[0].trim();
|
|
77
|
-
let newValue = key.split(":")[1].trim();
|
|
78
|
-
newKeys.push(`${newKey}: "${newValue}"`);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
value = `{${newKeys.join(",")}}`;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
parsedClasses[name] = JSON.stringify(value);
|
|
85
|
-
});
|
|
86
|
-
return parsedClasses;
|
|
87
|
-
};
|
|
88
25
|
|
|
89
26
|
|
|
90
|
-
export const stylis = {
|
|
91
|
-
/**
|
|
92
|
-
* @method create
|
|
93
|
-
* @param {*} styles
|
|
94
|
-
* @returns {Object} classes
|
|
95
|
-
* @description This method allows you to create css classes from an object
|
|
96
|
-
*/
|
|
97
|
-
create: async (/**@type {string} */ styles) => {
|
|
98
|
-
|
|
99
|
-
return await parseStyles(styles);
|
|
100
|
-
},
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* @method mem
|
|
105
|
-
* @param {Component} component
|
|
106
|
-
* @returns {Component} Stateless Component
|
|
107
|
-
* @description This method allows you to memoize a component - this means it will be intialized only once and can be reused multiple times baased on a static key
|
|
108
|
-
*/
|
|
109
|
-
export const mem = (/**@type {Component}**/ component) => {
|
|
110
|
-
// ensure component is instance of Component
|
|
111
|
-
switch (true) {
|
|
112
|
-
case !(component instanceof Component):
|
|
113
|
-
throw new Error("component must be an instance of Component");
|
|
114
|
-
case !component.key:
|
|
115
|
-
throw new Error("component must have a static key");
|
|
116
|
-
// check if key was randomly generated
|
|
117
|
-
}
|
|
118
|
-
let key = component.key;
|
|
119
|
-
if (!components[key]) {
|
|
120
|
-
components[key] = component;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return components[key];
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* @method invoke
|
|
128
|
-
* @description This method allows you to invoke a function from its id
|
|
129
|
-
* @param {*} name
|
|
130
|
-
* @param {*} params
|
|
131
|
-
* @returns
|
|
132
|
-
* @example
|
|
133
|
-
* invoke(this.functions['test'], 'hello') // this will invoke the function test with the params hello
|
|
134
|
-
*/
|
|
135
|
-
|
|
136
|
-
let functions = {};
|
|
137
|
-
|
|
138
|
-
export const invoke = (func, params) => {
|
|
139
|
-
let name = func.name;
|
|
140
|
-
|
|
141
|
-
window[name] = function (params) {
|
|
142
|
-
return func(params);
|
|
143
|
-
}
|
|
144
|
-
window[name] = window[name].bind(this);
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return `${name}(${params})`;
|
|
148
|
-
|
|
149
|
-
};
|
|
150
|
-
|
|
151
27
|
/**
|
|
152
28
|
* Represents a component in the Vader framework.
|
|
153
29
|
*/
|
|
@@ -159,55 +35,50 @@ export class Component {
|
|
|
159
35
|
this.state = {};
|
|
160
36
|
this.key = null;
|
|
161
37
|
this.components = {};
|
|
162
|
-
this.mounted = false;
|
|
163
|
-
this.currenthtml = null;
|
|
164
|
-
window.listeners = [];
|
|
165
|
-
this.functionMap = new Map();
|
|
166
|
-
this.freeMemoryFromFunctions();
|
|
38
|
+
this.mounted = false;
|
|
167
39
|
this.checkIFMounted();
|
|
168
40
|
this.memoizes = []
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
41
|
+
this.functions = []
|
|
42
|
+
|
|
172
43
|
this.children = []
|
|
173
|
-
|
|
174
|
-
|
|
44
|
+
|
|
45
|
+
|
|
175
46
|
/**
|
|
176
47
|
* Parent of the current component.
|
|
177
48
|
* @type {Component}
|
|
178
49
|
*/
|
|
179
|
-
this.parentNode =
|
|
180
|
-
|
|
50
|
+
this.parentNode = {}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Request object.
|
|
54
|
+
*/
|
|
55
|
+
this.request = {
|
|
181
56
|
/**
|
|
182
|
-
*
|
|
57
|
+
* @type {string}
|
|
58
|
+
* @description The headers for the current route
|
|
183
59
|
*/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
* @type {string}
|
|
207
|
-
* @description query: query object for the current route ?name=hello -> {name: 'hello'}
|
|
208
|
-
*/
|
|
209
|
-
query: {},
|
|
210
|
-
},
|
|
60
|
+
headers: {},
|
|
61
|
+
/**
|
|
62
|
+
* @type {string}
|
|
63
|
+
* @description The method for the current route
|
|
64
|
+
*/
|
|
65
|
+
method: "GET",
|
|
66
|
+
/**
|
|
67
|
+
* @type {string}
|
|
68
|
+
* @description params for the given route /:id/:name etc
|
|
69
|
+
*/
|
|
70
|
+
params: {},
|
|
71
|
+
/**
|
|
72
|
+
* @type {string}
|
|
73
|
+
* @description path: current route path
|
|
74
|
+
*/
|
|
75
|
+
path: "",
|
|
76
|
+
/**
|
|
77
|
+
* @type {string}
|
|
78
|
+
* @description query: query object for the current route ?name=hello -> {name: 'hello'}
|
|
79
|
+
*/
|
|
80
|
+
query: {},
|
|
81
|
+
},
|
|
211
82
|
/**
|
|
212
83
|
* @type {string}
|
|
213
84
|
* @description The response object for the current route
|
|
@@ -218,83 +89,123 @@ export class Component {
|
|
|
218
89
|
* @description This method allows you to send json data to the client
|
|
219
90
|
* @param {*} data
|
|
220
91
|
*/
|
|
221
|
-
json: (data) => {},
|
|
92
|
+
json: (data) => { },
|
|
222
93
|
/**
|
|
223
94
|
* @method send
|
|
224
95
|
* @description This method allows you to send text data to the client
|
|
225
96
|
* @param {*} data
|
|
226
97
|
*/
|
|
227
|
-
send: (data) => {},
|
|
98
|
+
send: (data) => { },
|
|
228
99
|
/**
|
|
229
100
|
* @method redirect
|
|
230
101
|
* @description This method allows you to redirect the client to a new route
|
|
231
102
|
* @param {*} path
|
|
232
103
|
*/
|
|
233
|
-
redirect: (path) => {},
|
|
104
|
+
redirect: (path) => { },
|
|
234
105
|
/**
|
|
235
106
|
* @method render
|
|
236
107
|
* @description render a new component to the client
|
|
237
108
|
* @param {*} Component
|
|
238
109
|
*/
|
|
239
|
-
render: async (Component) => {},
|
|
110
|
+
render: async (Component) => { },
|
|
111
|
+
/**
|
|
112
|
+
* @method log
|
|
113
|
+
* @description This method is used to log the request and response
|
|
114
|
+
* @param {String} type
|
|
115
|
+
*/
|
|
116
|
+
log: (type) => { },
|
|
117
|
+
/**
|
|
118
|
+
* @method setQuery
|
|
119
|
+
* @description This method is used to set the query object for the current route
|
|
120
|
+
*/
|
|
121
|
+
setQuery: (query) => { },
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* @method router
|
|
126
|
+
* @description use router methods directly from the parent component
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
this.router = {
|
|
130
|
+
/**
|
|
131
|
+
* @method use
|
|
132
|
+
* @description add a middleware to the current route
|
|
133
|
+
* @param {Function} middleware
|
|
134
|
+
* @returns {void}
|
|
135
|
+
*/
|
|
136
|
+
use: (/**@type {Function} */ middleware) => { },
|
|
137
|
+
}
|
|
240
138
|
}
|
|
241
|
-
}
|
|
242
139
|
|
|
243
140
|
createComponent(/**@type {Component}**/component, props, children) {
|
|
244
|
-
|
|
141
|
+
|
|
245
142
|
if (!component) {
|
|
246
143
|
throw new Error("Component must be defined");
|
|
247
144
|
}
|
|
248
|
-
if(!props.key){
|
|
145
|
+
if (!props.key) {
|
|
249
146
|
throw new Error('new components must have a key')
|
|
250
|
-
}
|
|
147
|
+
}
|
|
251
148
|
let comp = new component(props);
|
|
252
|
-
|
|
149
|
+
|
|
253
150
|
comp['props'] = props;
|
|
254
|
-
comp.children = children;
|
|
151
|
+
comp.children = children;
|
|
255
152
|
comp.props.children = children.join('')
|
|
256
|
-
comp.parentNode
|
|
153
|
+
comp.parentNode = this;
|
|
257
154
|
comp.request = this.request;
|
|
258
155
|
comp.response = this.response;
|
|
259
156
|
comp.key = props.key || null;
|
|
260
|
-
|
|
261
|
-
this.components[props.key]
|
|
157
|
+
|
|
158
|
+
if (!this.components[props.key]) {
|
|
159
|
+
this.components[props.key] = comp;
|
|
160
|
+
}
|
|
262
161
|
this.children.push(comp)
|
|
263
|
-
return this.components[props.key]
|
|
162
|
+
return this.components[props.key]
|
|
163
|
+
}
|
|
164
|
+
reset() {
|
|
165
|
+
console.log('reset')
|
|
166
|
+
Object.keys(this.components).forEach((key) => {
|
|
167
|
+
this.components[key].onUnmount()
|
|
168
|
+
delete this.components[key]
|
|
169
|
+
})
|
|
170
|
+
this.state = {}
|
|
171
|
+
this.children = []
|
|
264
172
|
}
|
|
265
|
-
memoize(/**@type {Component}**/component){
|
|
266
|
-
if(!component.key){
|
|
173
|
+
memoize(/**@type {Component}**/component) {
|
|
174
|
+
if (!component.key) {
|
|
267
175
|
throw new Error('Component must have a static key')
|
|
268
176
|
}
|
|
269
|
-
switch(true){
|
|
177
|
+
switch (true) {
|
|
270
178
|
case !this.memoizes.includes(component.key):
|
|
271
179
|
this.memoizes.push(component.key)
|
|
272
180
|
this.components[component.key] = component;
|
|
273
181
|
break;
|
|
274
182
|
}
|
|
275
|
-
|
|
183
|
+
|
|
276
184
|
let comp = this.components[component.key];
|
|
277
|
-
|
|
185
|
+
comp.bindMount();
|
|
186
|
+
comp.parentNode = this;
|
|
278
187
|
comp.props = component.props;
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
188
|
+
comp.request = this.request;
|
|
189
|
+
comp.response = this.response;
|
|
190
|
+
let h = comp.render()
|
|
191
|
+
|
|
192
|
+
if (h && h.split('>,').length > 1) {
|
|
282
193
|
h = h.replaceAll('>,', '>')
|
|
283
194
|
}
|
|
284
195
|
|
|
285
196
|
return `<div key="${component.key}">${h}</div>`
|
|
286
197
|
}
|
|
287
|
-
parseStyle(styles){
|
|
198
|
+
parseStyle(styles) {
|
|
288
199
|
let css = ''
|
|
289
|
-
Object.keys(styles).forEach((key) => {
|
|
200
|
+
Object.keys(styles).forEach((key) => {
|
|
290
201
|
let value = styles[key]
|
|
291
|
-
|
|
292
|
-
|
|
202
|
+
key = key.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase()
|
|
203
|
+
css += `${key}:${value};`
|
|
293
204
|
})
|
|
294
205
|
return css
|
|
295
206
|
}
|
|
296
|
-
bindMount(){
|
|
297
|
-
mounts.push(this)
|
|
207
|
+
bindMount() {
|
|
208
|
+
mounts.push(this)
|
|
298
209
|
}
|
|
299
210
|
|
|
300
211
|
/**
|
|
@@ -302,13 +213,13 @@ export class Component {
|
|
|
302
213
|
* @private
|
|
303
214
|
*/
|
|
304
215
|
|
|
305
|
-
|
|
216
|
+
domDifference(oldDom, newDom) {
|
|
306
217
|
let diff = [];
|
|
307
|
-
|
|
218
|
+
|
|
308
219
|
for (let i = 0; i < oldDom.length; i++) {
|
|
309
220
|
let oldEl = oldDom[i];
|
|
310
221
|
let newEl = newDom[i];
|
|
311
|
-
|
|
222
|
+
|
|
312
223
|
if (oldEl && newEl && !oldEl.isEqualNode(newEl)) {
|
|
313
224
|
diff.push({
|
|
314
225
|
type: 'replace',
|
|
@@ -317,11 +228,11 @@ export class Component {
|
|
|
317
228
|
});
|
|
318
229
|
}
|
|
319
230
|
}
|
|
320
|
-
|
|
231
|
+
|
|
321
232
|
return diff;
|
|
322
233
|
}
|
|
323
|
-
|
|
324
|
-
|
|
234
|
+
|
|
235
|
+
updateChangedElements(diff) {
|
|
325
236
|
diff.forEach((change) => {
|
|
326
237
|
switch (change.type) {
|
|
327
238
|
case 'replace':
|
|
@@ -338,12 +249,12 @@ export class Component {
|
|
|
338
249
|
}
|
|
339
250
|
});
|
|
340
251
|
}
|
|
341
|
-
|
|
342
|
-
|
|
252
|
+
|
|
253
|
+
hydrate(hook) {
|
|
343
254
|
if (this.key) {
|
|
344
255
|
if (hook) {
|
|
345
256
|
let newDom = new DOMParser().parseFromString(this.render(), 'text/html').body.firstChild;
|
|
346
|
-
|
|
257
|
+
|
|
347
258
|
let oldElements = document.body.querySelectorAll(`[ref="${hook}"]`);
|
|
348
259
|
let newElements = newDom.querySelectorAll(`[ref="${hook}"]`);
|
|
349
260
|
let diff = this.domDifference(oldElements, newElements);
|
|
@@ -351,25 +262,25 @@ export class Component {
|
|
|
351
262
|
} else {
|
|
352
263
|
const targetElement = document.querySelector(`[key="${this.key}"]`);
|
|
353
264
|
if (targetElement) {
|
|
354
|
-
targetElement.
|
|
265
|
+
targetElement.outerHTML = this.render();
|
|
355
266
|
} else {
|
|
356
267
|
console.error('Target element not found.');
|
|
357
268
|
}
|
|
358
269
|
}
|
|
359
270
|
}
|
|
360
271
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
364
275
|
patch(oldElements, newElements) {
|
|
365
276
|
const diff = this.domDifference(oldElements, newElements);
|
|
366
|
-
|
|
277
|
+
|
|
367
278
|
this.updateChangedElements(diff);
|
|
368
279
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
|
|
373
284
|
|
|
374
285
|
/**
|
|
375
286
|
* Handles an object by parsing it as JSON and evaluating it.
|
|
@@ -386,19 +297,7 @@ export class Component {
|
|
|
386
297
|
return eval(obj);
|
|
387
298
|
}
|
|
388
299
|
|
|
389
|
-
|
|
390
|
-
* Frees memory from functions that have not been used for a certain period of time.c
|
|
391
|
-
* @private
|
|
392
|
-
*/
|
|
393
|
-
freeMemoryFromFunctions() {
|
|
394
|
-
setInterval(() => {
|
|
395
|
-
for (var [key, value] in this.functionMap) {
|
|
396
|
-
if (Date.now() - value.lastUsed > 1000) {
|
|
397
|
-
this.functionMap.delete(key);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
}, 1000);
|
|
401
|
-
}
|
|
300
|
+
|
|
402
301
|
|
|
403
302
|
/**
|
|
404
303
|
* Binds a function to the component.
|
|
@@ -407,128 +306,65 @@ export class Component {
|
|
|
407
306
|
* @param {string} ref - The reference.
|
|
408
307
|
* @returns {string} - A valid inline JS function call.
|
|
409
308
|
*/
|
|
410
|
-
bind(
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
const name = `func_${crypto ? crypto.getRandomValues(new Uint32Array(1))[0] : Math.random()}`;
|
|
414
|
-
|
|
415
|
-
var dynamicFunction = async (...params) => {
|
|
416
|
-
|
|
417
|
-
// Replace double commas with a single comma
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
// Turn params into a destructured object
|
|
421
|
-
let paramObject = {};
|
|
422
|
-
params = params[0]
|
|
423
|
-
|
|
424
|
-
paramNames = paramNames.replace(/,,/g, ',');
|
|
425
|
-
let newparamnames = paramNames.replaceAll(',,', ',')
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
for(var i in params){
|
|
429
|
-
paramObject[newparamnames.split(',')[i]] = params[i]
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
paramNames = paramNames.replace(',,', ',');
|
|
435
|
-
let func = new Function(`${paramNames}`, `
|
|
436
|
-
return (async (${paramNames}) => {
|
|
437
|
-
${funcData}
|
|
438
|
-
})(${Object.keys(paramObject).join(',')})
|
|
439
|
-
`);
|
|
440
|
-
await func.bind(this)(...Object.values(paramObject));
|
|
441
|
-
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
dynamicFunction = dynamicFunction.bind(this);
|
|
446
|
-
if (!this.functionMap.has(name)) {
|
|
447
|
-
document.addEventListener(`call_${name}`, (e) => {
|
|
448
|
-
|
|
449
|
-
dynamicFunction(params)
|
|
450
|
-
this.functionMap.set(e.detail.name, {
|
|
451
|
-
lastUsed: Date.now(),
|
|
452
|
-
});
|
|
453
|
-
});
|
|
454
|
-
}
|
|
309
|
+
bind(funcTion, isTerny, jsx, ref, paramNames, ...params) {
|
|
310
|
+
ref = ref + this.key;
|
|
455
311
|
|
|
456
|
-
|
|
457
|
-
lastUsed: Date.now(),
|
|
458
|
-
});
|
|
312
|
+
let paramObject = {};
|
|
459
313
|
|
|
460
|
-
window.call = (name, eventdata, params) => {
|
|
461
|
-
document.dispatchEvent(
|
|
462
|
-
new CustomEvent(`call_${name}`, {
|
|
463
|
-
detail: { name: `call_${name}`, target: eventdata },
|
|
464
|
-
})
|
|
465
|
-
);
|
|
466
|
-
};
|
|
467
314
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
((event) => {
|
|
471
|
-
event.target.setAttribute('data-ref', '${ref}');
|
|
472
|
-
let reference = event.target.getAttribute('data-ref');
|
|
473
|
-
event.target.eventData = event;
|
|
474
|
-
event.target.data = event
|
|
475
|
-
call('${name}', {event:event.target.data}, '${paramNames}')
|
|
476
|
-
})(event)
|
|
477
|
-
`;
|
|
478
|
-
}
|
|
315
|
+
paramNames = paramNames.replace(/,,/g, ',');
|
|
316
|
+
let newparamnames = paramNames.replaceAll(',,', ',')
|
|
479
317
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
callFunction(func, isInlineJsx, ...params) {
|
|
486
|
-
if(!isInlineJsx && params[0] && params[0].detail){
|
|
487
|
-
let el = params[0].detail.target.event.target
|
|
488
|
-
params[0].data = el.value;
|
|
489
|
-
params[0] = params[0].detail.target.event
|
|
490
|
-
}
|
|
491
|
-
func = func.replace(/'/g, '');
|
|
492
|
-
document.dispatchEvent(new CustomEvent(func, { detail: { name: func, params: params } }));
|
|
493
|
-
}
|
|
318
|
+
for (var i in params) {
|
|
319
|
+
let param = params[i]
|
|
320
|
+
let paramname = newparamnames.split(',')[i]
|
|
321
|
+
paramObject[paramname] = param
|
|
322
|
+
}
|
|
494
323
|
|
|
495
|
-
/**
|
|
496
|
-
* Uses a function with the specified parameters.
|
|
497
|
-
* @param {Function} func - The function to use.
|
|
498
|
-
* @param {string} params - The function parameters.
|
|
499
|
-
* @param {boolean} [isInlineJsx=false] - Indicates if the function is an inline JSX.
|
|
500
|
-
* @returns {string} - The function call.
|
|
501
|
-
*/
|
|
502
|
-
useFunction(func, params, isInlineJsx = false) {
|
|
503
|
-
const sanitizedFuncName = func.name.trim().replace(/\s+/g, '_');
|
|
504
324
|
|
|
505
|
-
if (!invokes.includes(`'${sanitizedFuncName}'${this.key}`)) {
|
|
506
|
-
invokes.push(`'${sanitizedFuncName}'${this.key}`);
|
|
507
|
-
document.addEventListener(`call_${sanitizedFuncName}_${this.key}`, (e) => {
|
|
508
|
-
let { name, params } = e.detail;
|
|
509
|
-
if (name === `call_${sanitizedFuncName}_${this.key}`) {
|
|
510
|
-
let isarray = Array.isArray(params);
|
|
511
325
|
|
|
512
|
-
|
|
326
|
+
let ranfunctionanme = Math.random().toString(36).substring(7).slice(0, 5).replace(/[^a-z0-9]+/g, '')
|
|
327
|
+
// no numbers
|
|
328
|
+
ranfunctionanme = ranfunctionanme.replace(/[0-9]/g, '')
|
|
329
|
+
let tfunc = funcTion.toString().replace('async', '').replace('function', `function ${ranfunctionanme}`)
|
|
330
|
+
|
|
331
|
+
paramNames = paramNames.replace(',,', ',');
|
|
332
|
+
|
|
333
|
+
let func = new Function(`${paramNames}`, `
|
|
334
|
+
return (async (${paramNames}) => {
|
|
335
|
+
${tfunc}
|
|
336
|
+
})(${Object.keys(paramObject).join(',')})
|
|
337
|
+
`);
|
|
338
|
+
func = func.bind(this)
|
|
339
|
+
|
|
340
|
+
if (!this.functions.find((f) => f.ref === ref)) {
|
|
341
|
+
document.addEventListener(`$dispatch_#id=${ref}`, (e) => {
|
|
342
|
+
let { name, event } = e.detail;
|
|
343
|
+
if (name === ref) {
|
|
344
|
+
let params = this.functions.find((f) => f.ref === ref).params
|
|
345
|
+
Object.keys(params).forEach((key) => {
|
|
346
|
+
if (params[key] instanceof CustomEvent) {
|
|
347
|
+
delete params[key]
|
|
348
|
+
}
|
|
349
|
+
params[key] === undefined ? delete params[key] : params[key]
|
|
350
|
+
})
|
|
351
|
+
isTerny ? funcTion(event, ...Object.values(params)) : func(...Object.values(params))
|
|
513
352
|
}
|
|
514
353
|
});
|
|
515
354
|
|
|
516
|
-
func = func.bind(this);
|
|
517
355
|
}
|
|
518
356
|
|
|
519
|
-
|
|
520
|
-
params
|
|
521
|
-
} catch (error) {
|
|
522
|
-
// Handle JSON parsing error if needed
|
|
357
|
+
window.callFunction = (name, event) => {
|
|
358
|
+
document.dispatchEvent(new CustomEvent(`$dispatch_#id=${name}`, { detail: { name: name, params: null, event: event } }));
|
|
523
359
|
}
|
|
360
|
+
!this.functions.find((f) => f.ref === ref) ? this.functions.push({ ref: ref, params: paramObject }) : !isTerny ? this.functions.find((f) => f.ref === ref).params = paramObject : null
|
|
524
361
|
|
|
525
|
-
const returnString = isInlineJsx
|
|
526
|
-
? `'call_${sanitizedFuncName}_${this.key}'`
|
|
527
|
-
: `document.dispatchEvent(new CustomEvent('call_${sanitizedFuncName}_${this.key}', { detail: { name: 'call_${sanitizedFuncName}_${this.key}', params: ${JSON.stringify(params)} } }))`;
|
|
528
362
|
|
|
529
|
-
return
|
|
363
|
+
return jsx ? funcTion : `((event)=>{event.target.ev = event; callFunction('${ref}', event.target.ev)})(event)`;
|
|
530
364
|
}
|
|
531
365
|
|
|
366
|
+
|
|
367
|
+
|
|
532
368
|
/**
|
|
533
369
|
* useState hook.
|
|
534
370
|
*
|
|
@@ -537,145 +373,111 @@ export class Component {
|
|
|
537
373
|
* @param {T} initialState - The initial state value.
|
|
538
374
|
* @returns {[() => T, (newValue: T, hook: Function) => void]} - A tuple with getter and setter functions.
|
|
539
375
|
*/
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
376
|
+
useState(key, initialState) {
|
|
377
|
+
if (!this.state[key]) {
|
|
378
|
+
this.state[key] = initialState;
|
|
379
|
+
}
|
|
544
380
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
381
|
+
/**
|
|
382
|
+
* Get the current state value.
|
|
383
|
+
*
|
|
384
|
+
* @returns {T} The current state value.
|
|
385
|
+
*/
|
|
386
|
+
let updatedValue = () => this.state[key];
|
|
551
387
|
|
|
552
|
-
|
|
388
|
+
const getValue = updatedValue();
|
|
553
389
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
390
|
+
/**
|
|
391
|
+
* Set a new value for the state.
|
|
392
|
+
*
|
|
393
|
+
* @param {T} newValue - The new value to set.
|
|
394
|
+
* @param {Function} hook - The hook to hydrate after setting the value.
|
|
395
|
+
*/
|
|
396
|
+
const set = (newValue, hook) => {
|
|
397
|
+
this.state[key] = newValue;
|
|
398
|
+
this.hydrate(hook);
|
|
399
|
+
};
|
|
564
400
|
|
|
565
|
-
|
|
566
401
|
|
|
567
|
-
return [this.state[key], set];
|
|
568
|
-
}
|
|
569
402
|
|
|
570
|
-
|
|
403
|
+
return [getValue, set];
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
|
|
571
407
|
|
|
572
408
|
useRef(key = null, initialState) {
|
|
573
409
|
if (!this.state[key]) {
|
|
574
410
|
this.state[key] = initialState;
|
|
575
411
|
}
|
|
576
|
-
const getValue = () =>
|
|
412
|
+
const getValue = () => document.querySelector(`[ref="${key + this.key}"]`) || initialState;
|
|
577
413
|
const set = (newValue) => {
|
|
578
414
|
this.state[key] = newValue;
|
|
579
415
|
this.hydrate();
|
|
580
416
|
};
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
return
|
|
584
|
-
|
|
585
|
-
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
return {
|
|
420
|
+
bind: key + this.key,
|
|
421
|
+
current: getValue(),
|
|
586
422
|
}
|
|
587
423
|
}
|
|
588
424
|
|
|
589
425
|
useReducer(key = null, initialState, func = null) {
|
|
590
426
|
const getValue = () => this.state[key];
|
|
427
|
+
const value = getValue();
|
|
591
428
|
const set = (newValue) => {
|
|
592
|
-
|
|
593
|
-
this.
|
|
429
|
+
const nextState = func ? func(this.state[key], newValue) : newValue;
|
|
430
|
+
this.state[key] = nextState;
|
|
594
431
|
};
|
|
595
|
-
return [
|
|
432
|
+
return [value, set];
|
|
596
433
|
}
|
|
597
434
|
|
|
435
|
+
|
|
598
436
|
/**
|
|
599
437
|
* Placeholder for content to be rendered.
|
|
600
438
|
* @method render
|
|
601
439
|
*/
|
|
602
|
-
render() {}
|
|
440
|
+
render() { }
|
|
603
441
|
|
|
604
442
|
/**
|
|
605
443
|
* Checks if the component is mounted and triggers the onMount method.
|
|
606
444
|
* @private
|
|
607
445
|
*/
|
|
608
446
|
checkIFMounted() {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
447
|
+
let observer = new MutationObserver((mutations) => {
|
|
448
|
+
mutations.forEach((mutation) => {
|
|
449
|
+
|
|
450
|
+
if (mutation.target.querySelector(`[key="${this.key}"]`) && !this.mounted) {
|
|
451
|
+
this.onMount();
|
|
452
|
+
this.mounted = true;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (Array.from(mutation.removedNodes).find((node) => node.attributes && node.attributes.key && node.attributes.key.value === this.key)) {
|
|
456
|
+
this.onUnmount();
|
|
457
|
+
this.reset();
|
|
458
|
+
}
|
|
459
|
+
})
|
|
460
|
+
})
|
|
461
|
+
observer.observe(document.body, {
|
|
462
|
+
childList: true,
|
|
463
|
+
subtree: true,
|
|
464
|
+
});
|
|
617
465
|
}
|
|
618
466
|
|
|
619
467
|
/**
|
|
620
468
|
* Method that is called when the component is mounted.
|
|
621
469
|
* @method onMount
|
|
622
470
|
*/
|
|
623
|
-
onMount() {}
|
|
471
|
+
onMount() { }
|
|
472
|
+
/**
|
|
473
|
+
* Method that is called when the component is unmounted.
|
|
474
|
+
* @method onUnmount
|
|
475
|
+
*/
|
|
476
|
+
onUnmount() { }
|
|
624
477
|
}
|
|
625
478
|
|
|
626
479
|
|
|
627
480
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
let cache = {};
|
|
631
|
-
/**
|
|
632
|
-
* @method require
|
|
633
|
-
* @description Import CommonJS modules like Node.js for the browser
|
|
634
|
-
* @param {string} path
|
|
635
|
-
* @param {Boolean} noresolve - used to tell if the path should be automatically handled or manually handled - this is false by default
|
|
636
|
-
* @returns
|
|
637
|
-
*/
|
|
638
|
-
export const require = async (path, noresolve = false) => {
|
|
639
|
-
|
|
640
|
-
if (cache[path]) {
|
|
641
|
-
return cache[path];
|
|
642
|
-
}
|
|
643
|
-
let file = ''
|
|
644
|
-
try {
|
|
645
|
-
file = await fetch(path).then((res) => res.text());
|
|
646
|
-
} catch (error) {
|
|
647
|
-
console.error(error)
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
file = file + `\n//# sourceURL=${path}\n`;
|
|
651
|
-
|
|
652
|
-
let filetype = path.split(".").pop();
|
|
653
|
-
switch (true) {
|
|
654
|
-
case filetype === "js":
|
|
655
|
-
let exports = file.match(/module.exports\s*=\s*{.*}/gs) || file.match(/exports\s*=\s*{.*}/gs);
|
|
656
|
-
exports = exports ? exports[0] : null;
|
|
657
|
-
|
|
658
|
-
if (exports) {
|
|
659
|
-
let keys = exports.split("{")[1].split("}")[0].split(",");
|
|
660
|
-
let returnstring = "";
|
|
661
|
-
keys.forEach((key) => {
|
|
662
|
-
key = key.trim();
|
|
663
|
-
returnstring += `${key},`;
|
|
664
|
-
});
|
|
665
|
-
returnstring = `return {${returnstring}}`;
|
|
666
|
-
file = file += returnstring;
|
|
667
|
-
file = file.replaceAll(exports, "");
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
return new Function(`return (async () => { ${file} })()`)();
|
|
671
|
-
case filetype === "jsx":
|
|
672
|
-
return new Function(`return (async () => { ${file} })()`)()
|
|
673
|
-
|
|
674
|
-
}
|
|
675
|
-
};
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
window.require = require;
|
|
679
481
|
/**
|
|
680
482
|
* useState hook.
|
|
681
483
|
*
|
|
@@ -709,7 +511,7 @@ export const useState = (key, initialState) => {
|
|
|
709
511
|
return [states[key], set];
|
|
710
512
|
};
|
|
711
513
|
|
|
712
|
-
|
|
514
|
+
|
|
713
515
|
|
|
714
516
|
/**
|
|
715
517
|
* @method useReducer
|
|
@@ -718,35 +520,26 @@ export const useState = (key, initialState) => {
|
|
|
718
520
|
* @returns {Array} [value, set]
|
|
719
521
|
*/
|
|
720
522
|
export const useReducer = (/**@type {*}**/initialState, /**@type {function}**/reducer) => {
|
|
721
|
-
return [initialState, (newValue) => {}];
|
|
523
|
+
return [initialState, (newValue) => { }];
|
|
722
524
|
};
|
|
723
525
|
|
|
724
|
-
const constants = {};
|
|
725
|
-
let constantCounter = 0;
|
|
726
526
|
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
};
|
|
734
|
-
|
|
735
|
-
/**
|
|
736
|
-
* useRef hook.
|
|
737
|
-
*
|
|
738
|
-
* @param {*} initialState - The initial state value for the ref.
|
|
739
|
-
* @returns {{ current: *, bind: string }} - An object containing the current value and a bind string.
|
|
740
|
-
*/
|
|
527
|
+
/**
|
|
528
|
+
* useRef hook.
|
|
529
|
+
*
|
|
530
|
+
* @param {*} initialState - The initial state value for the ref.
|
|
531
|
+
* @returns {{ current: *, bind: string }} - An object containing the current value and a bind string.
|
|
532
|
+
*/
|
|
741
533
|
export const useRef = (initialState) => {
|
|
742
534
|
return {
|
|
743
535
|
/**
|
|
744
536
|
* @description The current value of the ref.
|
|
745
|
-
|
|
537
|
+
@type {*}
|
|
746
538
|
*/
|
|
747
539
|
current: initialState,
|
|
748
540
|
/**
|
|
749
541
|
* @description A unique string that can be used to bind the ref to an element.
|
|
542
|
+
* @type {HTMLElement|string}
|
|
750
543
|
*/
|
|
751
544
|
bind: '',
|
|
752
545
|
};
|
|
@@ -754,13 +547,8 @@ export const useRef = (initialState) => {
|
|
|
754
547
|
|
|
755
548
|
export default {
|
|
756
549
|
Component,
|
|
757
|
-
require,
|
|
758
|
-
invoke,
|
|
759
|
-
mem,
|
|
760
|
-
constant,
|
|
761
550
|
useRef,
|
|
762
551
|
useReducer,
|
|
763
552
|
useState,
|
|
764
553
|
strictMount,
|
|
765
|
-
stylis,
|
|
766
554
|
}
|