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 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
- <head>
39
- </head>
40
- <body>
41
- <div id="app"></div>
42
- <script type="module" src="https://cdn.jsdelivr.net/npm/pawajs@latestVersion/index.js"></script>
43
- <script type="module">
44
- window.$pawa.pawaStartApp(document.getElementById('app'));
45
- </script>
46
- </body>
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 :title="'My Todo List'" :message="message.value" class="to the rest prop">Children in here</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
- * (nam,import) or ([names,...],import)
268
+ * (name,import) or ([names,...],import)
269
269
  */
270
- export function lazy(...args: (string | Array<string> | Function)[]): Promise<void>;
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
- // pas the normal component to lazy handler
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
- if (attr.name.startsWith(starts)) {
1208
+ let attrName=attr.name.replace(/^-+/, '');
1209
+ attrName=attrName.trim()
1210
+ if (attrName.startsWith(starts)) {
1209
1211
  startAttribute = true
1210
- startObject[attr.name] = starts
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[attr.name]) {
1221
- directives[attr.name](el, attr, stateContext)
1222
- } else if (attr.name.startsWith('on-') && !isAcomponent) {
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('@{') || attr.name.startsWith('@')) && !attr.name.startsWith('c-at-')) {
1227
+ } else if ((attr.value.includes('@{') || attrName.startsWith('@')) && !attrName.startsWith('c-at-')) {
1225
1228
  mainAttribute(el, attr, isName)
1226
- } else if (attr.name.startsWith('state-')) {
1229
+ } else if (attrName.startsWith('state-')) {
1227
1230
  States(el, attr, getCurrentContext())
1228
- } else if (attr.name.startsWith('out-') && !isAcomponent) {
1231
+ } else if (attrName.startsWith('out-') && !isAcomponent) {
1229
1232
  documentEvent(el, attr)
1230
- } else if (attr.name.startsWith('after-[') && attr.name.endsWith(']') && !isAcomponent) {
1233
+ } else if (attrNamestartsWith('after-[') && attrName.endsWith(']') && !isAcomponent) {
1231
1234
  After(el, attr)
1232
1235
  }
1233
- else if (attr.name.startsWith('every-[') && attr.name.endsWith(']') && !isAcomponent) {
1236
+ else if (attrName.startsWith('every-[') && attrName.endsWith(']') && !isAcomponent) {
1234
1237
  Every(el, attr)
1235
1238
  }
1236
- else if (attr.name.startsWith('c-c-')) {
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 (attr.name.startsWith('c-at-')) {
1244
+ } else if (attrName.startsWith('c-at-')) {
1242
1245
  resumer.resume_attribute?.(el, attr, notRender) //attribute continuity
1243
- } else if (attr.name.startsWith('c-$-')) {
1246
+ } else if (attrName.startsWith('c-$-')) {
1244
1247
  resumer.resume_state?.(el, attr, notRender) //state continuity
1245
- } else if (attr.name.startsWith('c-t')) {//text continuity
1248
+ } else if (attrName.startsWith('c-t')) {//text continuity
1246
1249
  resumer.resume_text(el, attr, isName)
1247
- } else if (attr.name.startsWith('c-if-')) {
1250
+ } else if (attrName.startsWith('c-if-')) {
1248
1251
  directives['if'](el, attr, stateContext, true, notRender, stopResume)
1249
- } else if (attr.name === 'c-for') {
1252
+ } else if (attrName === 'c-for') {
1250
1253
  directives['for-each'](el, attr, stateContext, true, notRender, stopResume)
1251
- }else if (attr.name.startsWith('c-key-')) {
1254
+ }else if (attrName.startsWith('c-key-')) {
1252
1255
  directives['key'](el, attr, stateContext, true, notRender, stopResume)
1253
1256
  }
1254
- else if (attr.name.startsWith('c-sw-')) {
1257
+ else if (attrName.startsWith('c-sw-')) {
1255
1258
  directives['switch'](el, attr, stateContext, true, notRender, stopResume)// switch continuity
1256
- } else if (fullNamePlugin.has(attr.name)) {
1257
- if (externalPlugin[attr.name]) {
1258
- if (el._componentName && !attr.name.startsWith('c-'))return
1259
- const plugin = externalPlugin[attr.name]
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(`${attr.name} plugin must be a function`)
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[attr.name]
1274
+ const name = startObject[attrName]
1272
1275
  if (externalPlugin[name]) {
1273
- if (el._componentName && !attr.name.startsWith('c-'))return
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
 
@@ -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
- const id= crypto.randomUUID()
89
- if (HmrComponentMap.has(stateContexts.component._filePath) && stateContexts.component._filePath) {
90
- HmrComponentMap.get(stateContexts.component._filePath).push({id:id,template:el._template,el:el,stateContext:stateContexts})
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(stateContexts.component._filePath,[{id:id,template:el._template,el:el,stateContext:stateContexts}])
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(stateContexts.component._filePath)
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.2",
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(context, expression, 'props', true)
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
- console.log(error,'at event')
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(...keys, code);
356
- return () => func(...values);
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) => {