pawajs 2.0.2 → 2.0.3
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/CHANGELOG.md +3 -1
- package/README.md +49 -11
- package/index.d.ts +2 -3
- package/index.js +31 -27
- package/normal/component.js +13 -6
- package/package.json +2 -2
- package/pawaElement.js +4 -1
- package/power.js +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -19,4 +19,6 @@ CHANGELOG.md
|
|
|
19
19
|
+ version 1.4.33 - added registerComponent.lazy
|
|
20
20
|
+ version 1.4.33 -1.4.42 fixing lazy registration component
|
|
21
21
|
+ version 1.5.1 stable
|
|
22
|
-
+ version 1.5.2 - added function dependencies
|
|
22
|
+
+ version 1.5.2 - added function dependencies
|
|
23
|
+
+ version 2.0.1 -2.0.2 made runEffect to be global or component capability
|
|
24
|
+
+ version 2.0.3 integrating HMR system
|
package/README.md
CHANGED
|
@@ -35,15 +35,53 @@ npm install pawajs
|
|
|
35
35
|
CDN
|
|
36
36
|
|
|
37
37
|
```html
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
<!doctype html>
|
|
39
|
+
<html lang="en">
|
|
40
|
+
<head>
|
|
41
|
+
<meta charset="UTF-8" />
|
|
42
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
43
|
+
<title>PawaJS CDN Demo</title>
|
|
44
|
+
</head>
|
|
45
|
+
<body>
|
|
46
|
+
<div id="app">
|
|
47
|
+
<counter></counter>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<!-- PawaJS CDN -->
|
|
51
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/pawajs-cdn@latest/dist/pawajs.iife.min.js"></script>
|
|
52
|
+
|
|
53
|
+
<script type="module">
|
|
54
|
+
const { pawaStartApp, $state, RegisterComponent, useInsert, html } = Pawa;
|
|
55
|
+
|
|
56
|
+
// 1. Define the component
|
|
57
|
+
const Counter = () => {
|
|
58
|
+
const count = $state(0);
|
|
59
|
+
useInsert({ count });
|
|
60
|
+
|
|
61
|
+
return html`
|
|
62
|
+
<div class="p-8 border rounded-lg shadow-md flex flex-col items-center">
|
|
63
|
+
<h1 class="text-2xl font-bold">Count: @{count.value}</h1>
|
|
64
|
+
<button
|
|
65
|
+
on-click="count.value++"
|
|
66
|
+
class="mt-4 px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
|
|
67
|
+
>
|
|
68
|
+
Increment
|
|
69
|
+
</button>
|
|
70
|
+
</div>
|
|
71
|
+
`;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// 2. Register it as a custom element
|
|
75
|
+
RegisterComponent(Counter);
|
|
76
|
+
|
|
77
|
+
// 3. Start the app
|
|
78
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
79
|
+
const app = document.getElementById('app');
|
|
80
|
+
pawaStartApp(app);
|
|
81
|
+
});
|
|
82
|
+
</script>
|
|
83
|
+
</body>
|
|
84
|
+
</html>
|
|
47
85
|
```
|
|
48
86
|
|
|
49
87
|
OR
|
|
@@ -202,7 +240,7 @@ PawaJS uses a simple `@{...}` syntax to embed dynamic JavaScript expressions dir
|
|
|
202
240
|
|
|
203
241
|
<!-- Bind to attributes -->
|
|
204
242
|
<div class="user-card @{user.value.isActive ? 'active' : 'inactive'}">
|
|
205
|
-
<input value="@{user.value.name}" on-input="user.value.name = e.target.value">
|
|
243
|
+
<input @value="@{user.value.name}" on-input="user.value.name = e.target.value">
|
|
206
244
|
</div>
|
|
207
245
|
```
|
|
208
246
|
|
|
@@ -304,7 +342,7 @@ const message = $state('This is a message from the parent!');
|
|
|
304
342
|
useInsert({ message });
|
|
305
343
|
|
|
306
344
|
return html`
|
|
307
|
-
<todo-list
|
|
345
|
+
<todo-list title="My Todo List" :message="message.value" class="to the rest prop">Children in here</todo-list>
|
|
308
346
|
`;
|
|
309
347
|
```
|
|
310
348
|
|
package/index.d.ts
CHANGED
|
@@ -265,11 +265,10 @@ export function RegisterComponent(...args: (string | Function)[]): void;
|
|
|
265
265
|
export namespace RegisterComponent {
|
|
266
266
|
/**
|
|
267
267
|
* Registers components lazily. The component's bundle is only fetched during runime encounter.
|
|
268
|
-
* (
|
|
268
|
+
* (name,import) or ([names,...],import)
|
|
269
269
|
*/
|
|
270
|
-
export function lazy(...
|
|
270
|
+
export function lazy(...arg:Array<string|Function|Array<string>>): Promise<void>;
|
|
271
271
|
}
|
|
272
|
-
|
|
273
272
|
/**
|
|
274
273
|
* Runs a side effect or lifecycle hook.
|
|
275
274
|
* @param {(comment:PawaComment) => void | (() => void)} callback - Effect function,comment for component hacking and optionally returning cleanup .
|
package/index.js
CHANGED
|
@@ -903,7 +903,7 @@ const component = (el, resume = false, attr, notRender, stopResume) => {
|
|
|
903
903
|
|
|
904
904
|
if (!resume) {
|
|
905
905
|
if (el._lazy) {
|
|
906
|
-
//
|
|
906
|
+
// passes the normal component to lazy handler
|
|
907
907
|
el.style.opacity=0
|
|
908
908
|
addLazyComponentElement(el,()=>normal_component(el, stateContext, setStateContext, mapsPlugins, formerStateContext, pawaContext, stateWatch))
|
|
909
909
|
return
|
|
@@ -1205,9 +1205,11 @@ export const render = (el, contexts = {}, notRender, isName) => {
|
|
|
1205
1205
|
startsWithSet.forEach(starts => {
|
|
1206
1206
|
|
|
1207
1207
|
el._attributes.forEach(attr => {
|
|
1208
|
-
|
|
1208
|
+
let attrName=attr.name.replace(/^-+/, '');
|
|
1209
|
+
attrName=attrName.trim()
|
|
1210
|
+
if (attrName.startsWith(starts)) {
|
|
1209
1211
|
startAttribute = true
|
|
1210
|
-
startObject[
|
|
1212
|
+
startObject[attrName] = starts
|
|
1211
1213
|
}
|
|
1212
1214
|
})
|
|
1213
1215
|
})
|
|
@@ -1215,51 +1217,52 @@ export const render = (el, contexts = {}, notRender, isName) => {
|
|
|
1215
1217
|
const isAcomponent=el._componentName?true:false
|
|
1216
1218
|
|
|
1217
1219
|
el._attributes.forEach(attr => {
|
|
1218
|
-
|
|
1220
|
+
let attrName=attr.name.replace(/^-+/, '');
|
|
1221
|
+
attrName=attrName.trim()
|
|
1219
1222
|
if (stopResume.stop || el._hasRun) return
|
|
1220
|
-
if (directives[
|
|
1221
|
-
directives[
|
|
1222
|
-
} else if (
|
|
1223
|
+
if (directives[attrName]) {
|
|
1224
|
+
directives[attrName](el, attr, stateContext)
|
|
1225
|
+
} else if (attrName.startsWith('on-') && !isAcomponent) {
|
|
1223
1226
|
event(el, attr, stateContext)
|
|
1224
|
-
} else if ((attr.value.includes('@{') ||
|
|
1227
|
+
} else if ((attr.value.includes('@{') || attrName.startsWith('@')) && !attrName.startsWith('c-at-')) {
|
|
1225
1228
|
mainAttribute(el, attr, isName)
|
|
1226
|
-
} else if (
|
|
1229
|
+
} else if (attrName.startsWith('state-')) {
|
|
1227
1230
|
States(el, attr, getCurrentContext())
|
|
1228
|
-
} else if (
|
|
1231
|
+
} else if (attrName.startsWith('out-') && !isAcomponent) {
|
|
1229
1232
|
documentEvent(el, attr)
|
|
1230
|
-
} else if (
|
|
1233
|
+
} else if (attrNamestartsWith('after-[') && attrName.endsWith(']') && !isAcomponent) {
|
|
1231
1234
|
After(el, attr)
|
|
1232
1235
|
}
|
|
1233
|
-
else if (
|
|
1236
|
+
else if (attrName.startsWith('every-[') && attrName.endsWith(']') && !isAcomponent) {
|
|
1234
1237
|
Every(el, attr)
|
|
1235
1238
|
}
|
|
1236
|
-
else if (
|
|
1239
|
+
else if (attrName.startsWith('c-c-')) {
|
|
1237
1240
|
stopResume.stop = true
|
|
1238
1241
|
|
|
1239
1242
|
|
|
1240
1243
|
component(el, true, attr, notRender, stopResume)// component continuity
|
|
1241
|
-
} else if (
|
|
1244
|
+
} else if (attrName.startsWith('c-at-')) {
|
|
1242
1245
|
resumer.resume_attribute?.(el, attr, notRender) //attribute continuity
|
|
1243
|
-
} else if (
|
|
1246
|
+
} else if (attrName.startsWith('c-$-')) {
|
|
1244
1247
|
resumer.resume_state?.(el, attr, notRender) //state continuity
|
|
1245
|
-
} else if (
|
|
1248
|
+
} else if (attrName.startsWith('c-t')) {//text continuity
|
|
1246
1249
|
resumer.resume_text(el, attr, isName)
|
|
1247
|
-
} else if (
|
|
1250
|
+
} else if (attrName.startsWith('c-if-')) {
|
|
1248
1251
|
directives['if'](el, attr, stateContext, true, notRender, stopResume)
|
|
1249
|
-
} else if (
|
|
1252
|
+
} else if (attrName === 'c-for') {
|
|
1250
1253
|
directives['for-each'](el, attr, stateContext, true, notRender, stopResume)
|
|
1251
|
-
}else if (
|
|
1254
|
+
}else if (attrName.startsWith('c-key-')) {
|
|
1252
1255
|
directives['key'](el, attr, stateContext, true, notRender, stopResume)
|
|
1253
1256
|
}
|
|
1254
|
-
else if (
|
|
1257
|
+
else if (attrName.startsWith('c-sw-')) {
|
|
1255
1258
|
directives['switch'](el, attr, stateContext, true, notRender, stopResume)// switch continuity
|
|
1256
|
-
} else if (fullNamePlugin.has(
|
|
1257
|
-
if (externalPlugin[
|
|
1258
|
-
if (el._componentName && !
|
|
1259
|
-
const plugin = externalPlugin[
|
|
1259
|
+
} else if (fullNamePlugin.has(attrName)) {
|
|
1260
|
+
if (externalPlugin[attrName]) {
|
|
1261
|
+
if (el._componentName && !attrName.startsWith('c-'))return
|
|
1262
|
+
const plugin = externalPlugin[attrName]
|
|
1260
1263
|
try {
|
|
1261
1264
|
if (typeof plugin !== 'function') {
|
|
1262
|
-
console.warn(`${
|
|
1265
|
+
console.warn(`${attrName} plugin must be a function`)
|
|
1263
1266
|
return
|
|
1264
1267
|
}
|
|
1265
1268
|
plugin(el, attr, stateContext, notRender, stopResume)
|
|
@@ -1268,9 +1271,9 @@ export const render = (el, contexts = {}, notRender, isName) => {
|
|
|
1268
1271
|
}
|
|
1269
1272
|
}
|
|
1270
1273
|
} else if (startAttribute) {
|
|
1271
|
-
const name = startObject[
|
|
1274
|
+
const name = startObject[attrName]
|
|
1272
1275
|
if (externalPlugin[name]) {
|
|
1273
|
-
if (el._componentName && !
|
|
1276
|
+
if (el._componentName && !attrName.startsWith('c-'))return
|
|
1274
1277
|
const plugin = externalPlugin[name]
|
|
1275
1278
|
try {
|
|
1276
1279
|
if (typeof plugin !== 'function') {
|
|
@@ -1393,6 +1396,7 @@ const Pawa = {
|
|
|
1393
1396
|
RegisterComponent,
|
|
1394
1397
|
runEffect,
|
|
1395
1398
|
html,
|
|
1399
|
+
accessChild,
|
|
1396
1400
|
PawaCustomEvent
|
|
1397
1401
|
}
|
|
1398
1402
|
|
package/normal/component.js
CHANGED
|
@@ -83,19 +83,26 @@ export const normal_component=(el,stateContext,setStateContext,mapsPlugin,former
|
|
|
83
83
|
let compo
|
|
84
84
|
let awaits=false
|
|
85
85
|
let suspense=''
|
|
86
|
-
|
|
86
|
+
let elementContext=el._context
|
|
87
87
|
if (__pawaDev.tool) {
|
|
88
|
-
|
|
89
|
-
if (HmrComponentMap.has(
|
|
90
|
-
HmrComponentMap.get(
|
|
88
|
+
const id=Date.now() + Math.random()
|
|
89
|
+
if (HmrComponentMap.has(el._componentName)) {
|
|
90
|
+
HmrComponentMap.get(el._componentName).push({id:id,template:el._template,el:el,stateContext:stateContexts,remove:()=>{
|
|
91
|
+
return pawaWayRemover(comment,endComment)
|
|
92
|
+
},context:elementContext,comment:comment
|
|
93
|
+
})
|
|
91
94
|
}else{
|
|
92
|
-
HmrComponentMap.set(
|
|
95
|
+
HmrComponentMap.set(el._componentName,[{id:id,template:el._template,el:el,stateContext:stateContexts,remove:()=>{
|
|
96
|
+
return pawaWayRemover(comment,endComment)
|
|
97
|
+
},context:elementContext,comment:comment}])
|
|
93
98
|
}
|
|
94
99
|
el._setUnMount(()=>{
|
|
95
|
-
const array=HmrComponentMap.get(
|
|
100
|
+
const array=HmrComponentMap.get(el._componentName)
|
|
96
101
|
if(array){
|
|
97
102
|
const index=array.findIndex(item => item.id === id)
|
|
98
103
|
if(index !== -1) array.splice(index,1)
|
|
104
|
+
}else{
|
|
105
|
+
HmrComponentMap.delete(el._componentName)
|
|
99
106
|
}
|
|
100
107
|
})
|
|
101
108
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pawajs",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"type":"module",
|
|
5
|
-
"description": "pawajs library (reactive web runtime) for easily building web ui, enhancing html element, micro frontend etc ",
|
|
5
|
+
"description": "pawajs library (reactive web runtime) for easily building web ui, enhancing html element, micro frontend, spa etc ",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"test": "echo \"Error: no test specified\" && exit 1"
|
package/pawaElement.js
CHANGED
|
@@ -75,6 +75,8 @@ export class PawaElement {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
}catch(error){
|
|
78
|
+
throw new Error(`Error evaluating expression: ${expression}\n${error.message}`);
|
|
79
|
+
|
|
78
80
|
__pawaDev.setError({
|
|
79
81
|
el:this?._el,
|
|
80
82
|
msg:`from ${expression}`,
|
|
@@ -319,6 +321,7 @@ export class PawaElement {
|
|
|
319
321
|
name=attr.name
|
|
320
322
|
}
|
|
321
323
|
const context=this._context
|
|
324
|
+
const main={...context}
|
|
322
325
|
const setProps=()=>{
|
|
323
326
|
delete this._restProps[name]
|
|
324
327
|
let value=attr.value
|
|
@@ -328,7 +331,7 @@ export class PawaElement {
|
|
|
328
331
|
if (checkKeywordsExistence(this._staticContext, expression)) {
|
|
329
332
|
return value
|
|
330
333
|
} else {
|
|
331
|
-
const res = this.safeEval(
|
|
334
|
+
const res = this.safeEval({...main}, expression, 'props', true)
|
|
332
335
|
return res
|
|
333
336
|
}
|
|
334
337
|
});
|
package/power.js
CHANGED
|
@@ -104,7 +104,8 @@ const processEventExecution = (el, attrName, modifiers, callback, eventType, dir
|
|
|
104
104
|
const execute = () => {
|
|
105
105
|
try { callback(); }
|
|
106
106
|
catch (error) {
|
|
107
|
-
|
|
107
|
+
throw new Error(error,`at ${attrName} from ${el._template}`);
|
|
108
|
+
|
|
108
109
|
setPawaDevError({ message: `Error from ${directiveName}-${eventType} directive ${error.message}`, error, template: el._template }); }
|
|
109
110
|
};
|
|
110
111
|
if (!el._eventTimers) el._eventTimers = {};
|
|
@@ -352,8 +353,9 @@ const createBoundCallback = (el, code,context) => {
|
|
|
352
353
|
const keys = Object.keys(context);
|
|
353
354
|
const resolvePath = (path, obj) => path.split('.').reduce((acc, key) => acc?.[key], obj);
|
|
354
355
|
const values = keys.map((key) => resolvePath(key, context));
|
|
355
|
-
const func = new Function(
|
|
356
|
-
|
|
356
|
+
const func = new Function('$el',...keys, code);
|
|
357
|
+
const $el=el
|
|
358
|
+
return () => func($el,...values);
|
|
357
359
|
};
|
|
358
360
|
|
|
359
361
|
export const mountElement = (el, attr) => {
|