pawajs 1.3.0
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/LICENSE +21 -0
- package/README.md +354 -0
- package/cdn/index.js +5 -0
- package/index.d.ts +291 -0
- package/index.js +1180 -0
- package/merger/for.js +218 -0
- package/merger/if.js +125 -0
- package/merger/key.js +101 -0
- package/merger/switch.js +127 -0
- package/normal/For.js +30 -0
- package/normal/If.js +29 -0
- package/normal/Key.js +27 -0
- package/normal/Switch.js +29 -0
- package/normal/component.js +211 -0
- package/normal/template.js +24 -0
- package/package.json +27 -0
- package/pawaComponent.js +68 -0
- package/pawaElement.js +455 -0
- package/power.js +468 -0
- package/reactive.js +174 -0
- package/resumer.js +21 -0
- package/server.js +21 -0
- package/utils.js +328 -0
package/normal/Switch.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createEffect } from '../reactive.js';
|
|
2
|
+
import { render, $state, keepContext,restoreContext} from '../index.js';
|
|
3
|
+
import { PawaComment, PawaElement } from '../pawaElement.js';
|
|
4
|
+
import { processNode, pawaWayRemover, safeEval, getEvalValues, setPawaDevError, checkKeywordsExistence } from '../utils.js';
|
|
5
|
+
import { merger_switch } from '../merger/switch.js';
|
|
6
|
+
export const normal_Switch=(el, attr, stateContext,endComment,chainMap,chained)=>{
|
|
7
|
+
|
|
8
|
+
const comment = document.createComment(`switch`)
|
|
9
|
+
el._out = true
|
|
10
|
+
const parent = endComment.parentElement
|
|
11
|
+
el._deCompositionElement = true
|
|
12
|
+
el._isKill = true
|
|
13
|
+
el._kill = () => {
|
|
14
|
+
pawaWayRemover(comment, endComment)
|
|
15
|
+
comment.remove(), endComment.remove();
|
|
16
|
+
}
|
|
17
|
+
PawaComment.Element(comment)
|
|
18
|
+
comment._setCoveringElement(el)
|
|
19
|
+
parent.insertBefore(comment, endComment)
|
|
20
|
+
el._underControl = comment
|
|
21
|
+
const context = el._context
|
|
22
|
+
let firstEnter = false
|
|
23
|
+
comment._controlComponent = true
|
|
24
|
+
const evaluate=merger_switch(el,attr,stateContext,false,
|
|
25
|
+
{comment,endComment,chained,chainMap})
|
|
26
|
+
createEffect(() => {
|
|
27
|
+
evaluate()
|
|
28
|
+
}, el)
|
|
29
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import {propsValidator, setPawaDevError, pawaWayRemover, checkKeywordsExistence, sanitizeTemplate } from '../utils.js';
|
|
2
|
+
import {PawaElement,PawaComment} from '../pawaElement.js';
|
|
3
|
+
import {keepContext,render} from '../index.js'
|
|
4
|
+
export const normal_component=(el,stateContext,setStateContext,mapsPlugin,formerStateContext,pawaContext,stateWatch)=>{
|
|
5
|
+
const compoBeforeCall=mapsPlugin.compoBeforeCall
|
|
6
|
+
const compoAfterCall=mapsPlugin.compoAfterCall
|
|
7
|
+
const endComment = document.createComment(`end ${el.tagName}`)
|
|
8
|
+
const comment = document.createComment(` ${el.tagName}`)
|
|
9
|
+
PawaComment.Element(comment)
|
|
10
|
+
el.replaceWith(endComment)
|
|
11
|
+
endComment.parentElement.insertBefore(comment,endComment)
|
|
12
|
+
el._underControl=comment
|
|
13
|
+
comment._componentElement=el
|
|
14
|
+
comment._controlComponent=true
|
|
15
|
+
const props={}
|
|
16
|
+
const children=el._componentChildren
|
|
17
|
+
/**
|
|
18
|
+
* @type {DocumentFragment}
|
|
19
|
+
*/
|
|
20
|
+
const slot=el._slots
|
|
21
|
+
const mount=[]
|
|
22
|
+
const unmount=[]
|
|
23
|
+
const slots={}
|
|
24
|
+
const reactiveProps={}
|
|
25
|
+
Array.from(slot.children).forEach(prop =>{
|
|
26
|
+
if (prop.hasAttribute('prop')) {
|
|
27
|
+
slots[prop.getAttribute('prop')]=()=>prop.innerHTML
|
|
28
|
+
}else{
|
|
29
|
+
console.warn('sloting props must have prop attribute')
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
//kill the template element
|
|
33
|
+
el._isKill=true
|
|
34
|
+
el._kill=()=>{
|
|
35
|
+
pawaWayRemover(comment,endComment)
|
|
36
|
+
comment.remove(),endComment.remove();
|
|
37
|
+
}
|
|
38
|
+
if (el._reactiveProps) {
|
|
39
|
+
for (const [key,value] of Object.entries(el._reactiveProps)) {
|
|
40
|
+
el._props[key]=value()
|
|
41
|
+
reactiveProps[key]=value
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const validprops=el._component.validPropRule
|
|
45
|
+
let done=true
|
|
46
|
+
if(validprops && Object.entries(validprops).length > 0){
|
|
47
|
+
done= propsValidator(validprops,{...el._props,...slots},el._componentName,el._template,el)
|
|
48
|
+
}
|
|
49
|
+
const app = {
|
|
50
|
+
children,
|
|
51
|
+
...slots,
|
|
52
|
+
...el._props
|
|
53
|
+
}
|
|
54
|
+
for (const fn of compoBeforeCall) {
|
|
55
|
+
try {
|
|
56
|
+
fn(stateContext,app)
|
|
57
|
+
} catch (error) {
|
|
58
|
+
__pawaDev.setError({el:el,msg:error.message})
|
|
59
|
+
console.error(error.message)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const div = document.createElement('div')
|
|
63
|
+
el._componentTerminate=() => {
|
|
64
|
+
comment._terminateByComponent(endComment)
|
|
65
|
+
}
|
|
66
|
+
const component =el._component
|
|
67
|
+
const stateContexts=setStateContext(component)
|
|
68
|
+
stateContexts._prop={children,...el._props,...slots}
|
|
69
|
+
stateContexts._elementContext={...el._context}
|
|
70
|
+
stateContexts._name=el._componentName
|
|
71
|
+
stateContexts._reactiveProps=reactiveProps
|
|
72
|
+
stateContexts._template=el._template
|
|
73
|
+
stateContexts._recallEffect=()=>{
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
const storeContext=stateContexts
|
|
77
|
+
let compo
|
|
78
|
+
try {
|
|
79
|
+
if(done){
|
|
80
|
+
const compoCall=component.component(app)
|
|
81
|
+
if( compoCall instanceof Promise){
|
|
82
|
+
compoCall.then((res)=>{
|
|
83
|
+
div.innerHTML=res
|
|
84
|
+
propsSetter()
|
|
85
|
+
if (storeContext._hasRun) {
|
|
86
|
+
storeContext._hasRun = false
|
|
87
|
+
keepContext(storeContext)
|
|
88
|
+
}if (storeContext?._insert) {
|
|
89
|
+
Object.assign(el._context,storeContext._insert)
|
|
90
|
+
}
|
|
91
|
+
childInsert()
|
|
92
|
+
lifeCircle()
|
|
93
|
+
storeContext._hasRun=true
|
|
94
|
+
stateContext=null
|
|
95
|
+
})
|
|
96
|
+
}else if (compoCall !== undefined){
|
|
97
|
+
compo= sanitizeTemplate(compoCall)
|
|
98
|
+
}
|
|
99
|
+
}else{
|
|
100
|
+
compo=""
|
|
101
|
+
}
|
|
102
|
+
} catch (error) {
|
|
103
|
+
setPawaDevError({
|
|
104
|
+
message:`error from ${el._componentName} component ${error.message}`,
|
|
105
|
+
error:error,
|
|
106
|
+
template:el._template
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// stateContext._hasRun=true
|
|
111
|
+
div.innerHTML = compo;
|
|
112
|
+
if (component?._insert) {
|
|
113
|
+
Object.assign(el._context,component._insert)
|
|
114
|
+
}
|
|
115
|
+
const propsSetter=()=>{
|
|
116
|
+
if(Object.entries(el._restProps).length > 0){
|
|
117
|
+
const findElement=div.querySelector('[--]') || div.querySelector('[rest]')
|
|
118
|
+
if (findElement) {
|
|
119
|
+
for (const [key,value] of Object.entries(el._restProps)) {
|
|
120
|
+
findElement.setAttribute(value.name,value.value)
|
|
121
|
+
findElement.removeAttribute('--')
|
|
122
|
+
findElement.removeAttribute('rest')
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
propsSetter()
|
|
128
|
+
for (const fn of compoAfterCall) {
|
|
129
|
+
try {
|
|
130
|
+
fn(stateContexts,div?.firstElementChild,el)
|
|
131
|
+
} catch (error) {
|
|
132
|
+
__pawaDev.setError({el:el,msg:error.message})
|
|
133
|
+
console.error(error.message)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const childInsert=()=>{
|
|
137
|
+
el._component?._hook?.beforeMount?.forEach((bfm) => {
|
|
138
|
+
const result= bfm()
|
|
139
|
+
if (typeof result === 'function') {
|
|
140
|
+
el._unMountFunctions.push(result)
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
el._component?._hook?.isMount.forEach((hook) => {
|
|
145
|
+
el._MountFunctions.push(hook)
|
|
146
|
+
})
|
|
147
|
+
el._component?._hook?.isUnMount.forEach((hook) => {
|
|
148
|
+
el._unMountFunctions.push(hook)
|
|
149
|
+
})
|
|
150
|
+
const child=div.children[0]
|
|
151
|
+
|
|
152
|
+
if (child !== null ) {
|
|
153
|
+
if (child) {
|
|
154
|
+
endComment.parentElement.insertBefore(child, endComment)
|
|
155
|
+
|
|
156
|
+
stateContexts?._error?.forEach((error) => {
|
|
157
|
+
throw Error(error)
|
|
158
|
+
})
|
|
159
|
+
render(child, el._context)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
childInsert()
|
|
164
|
+
const lifeCircle=()=>{
|
|
165
|
+
Promise.resolve().then(()=>{
|
|
166
|
+
el._component?._hook?.effect.forEach((hook) => {
|
|
167
|
+
if(hook?.done) return
|
|
168
|
+
hook.done=true
|
|
169
|
+
const result=stateWatch(hook.effect,hook.deps)
|
|
170
|
+
if (typeof result === 'function') {
|
|
171
|
+
el._unMountFunctions.push(result)
|
|
172
|
+
}
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
if (el._component?._hook?.reactiveEffect) {
|
|
176
|
+
el._component?._hook?.reactiveEffect.forEach((hook) => {
|
|
177
|
+
if(hook?.done) return
|
|
178
|
+
hook.done=true
|
|
179
|
+
const effect=hook.effect()
|
|
180
|
+
if (hook.deps?.component) {
|
|
181
|
+
createEffect(() => {
|
|
182
|
+
return effect()
|
|
183
|
+
},el)
|
|
184
|
+
} else {
|
|
185
|
+
createEffect(() => {
|
|
186
|
+
return effect()
|
|
187
|
+
},hook.deps.value)
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
el._MountFunctions.forEach((func) => {
|
|
192
|
+
func.done=true
|
|
193
|
+
const result=func()
|
|
194
|
+
if (typeof result === 'function') {
|
|
195
|
+
el._unMountFunctions.push(result)
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
})
|
|
200
|
+
}
|
|
201
|
+
lifeCircle()
|
|
202
|
+
stateContexts._hasRun=true
|
|
203
|
+
keepContext(stateContexts._formerContext)
|
|
204
|
+
if (stateContexts._transportContext) {
|
|
205
|
+
let contextId = stateContexts._transportContext
|
|
206
|
+
delete pawaContext[contextId]
|
|
207
|
+
}
|
|
208
|
+
stateContext=formerStateContext
|
|
209
|
+
__pawaDev.totalComponent++
|
|
210
|
+
|
|
211
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {render} from '../index.js'
|
|
2
|
+
export const templates=(el)=>{
|
|
3
|
+
const comment=document.createComment('<template>')
|
|
4
|
+
const endComment=document.createComment('</template>')
|
|
5
|
+
el.replaceWith(endComment)
|
|
6
|
+
//kill the template element
|
|
7
|
+
el._isKill=true
|
|
8
|
+
el._kill=()=>{
|
|
9
|
+
pawaWayRemover(comment,endComment)
|
|
10
|
+
comment.remove(),endComment.remove();
|
|
11
|
+
}
|
|
12
|
+
endComment.parentElement.insertBefore(comment,endComment)
|
|
13
|
+
el._underControl=comment
|
|
14
|
+
let element=[]
|
|
15
|
+
Array.from(el.content.children).forEach((child) => {
|
|
16
|
+
endComment.parentElement.insertBefore(child,endComment)
|
|
17
|
+
element.push(child)
|
|
18
|
+
})
|
|
19
|
+
const number={notRender:null,index:null}
|
|
20
|
+
element.forEach(child=>{
|
|
21
|
+
if(number.notRender)return
|
|
22
|
+
render(child,el._context,number)
|
|
23
|
+
})
|
|
24
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pawajs",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "pawajs library (html runtime) for easily building web ui, enhancing html element, micro frontend etc ",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Allisboy/pawajs.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"pawajs",
|
|
15
|
+
"js",
|
|
16
|
+
"html",
|
|
17
|
+
"css",
|
|
18
|
+
"web development",
|
|
19
|
+
"ui"
|
|
20
|
+
],
|
|
21
|
+
"author": "Allwell Oriso-owubo Owupele",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/Allisboy/pawajs/issues"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/Allisboy/pawajs#readme"
|
|
27
|
+
}
|
package/pawaComponent.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a Pawa component instance.
|
|
3
|
+
* @class
|
|
4
|
+
*/
|
|
5
|
+
class PawaComponent {
|
|
6
|
+
/**
|
|
7
|
+
* @param {Function} func - The component function that defines rendering logic.
|
|
8
|
+
*/
|
|
9
|
+
constructor(func) {
|
|
10
|
+
/**
|
|
11
|
+
* Default props for the component (currently unused).
|
|
12
|
+
* @type {Object}
|
|
13
|
+
*/
|
|
14
|
+
this.prop = {};
|
|
15
|
+
/**
|
|
16
|
+
* Props Validation rules set for the component (when called)
|
|
17
|
+
* @type {Object{[any]:{strict:boolean,err:string,default:any,type:any}}>}
|
|
18
|
+
*/
|
|
19
|
+
this.validPropRule=func?.validateProps || {};
|
|
20
|
+
/**
|
|
21
|
+
* The component function.
|
|
22
|
+
* @type {Function}
|
|
23
|
+
*/
|
|
24
|
+
this.component = func;
|
|
25
|
+
/**
|
|
26
|
+
* Tracks whether the component has been rendered.
|
|
27
|
+
* @type {boolean}
|
|
28
|
+
*/
|
|
29
|
+
this._hasRun = false;
|
|
30
|
+
/**
|
|
31
|
+
* Data to inject into the rendering context.
|
|
32
|
+
* @type {Object}
|
|
33
|
+
*/
|
|
34
|
+
this._insert = {};
|
|
35
|
+
/**
|
|
36
|
+
* Lifecycle hooks for mount, unmount, and effects.
|
|
37
|
+
* @type {{effect: Array, isMount: Array, isUnMount: Array}}
|
|
38
|
+
*/
|
|
39
|
+
this._hook = {
|
|
40
|
+
effect: [],
|
|
41
|
+
isMount: [],
|
|
42
|
+
isUnMount: [],
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Map for non-reactive internal state (currently unused).
|
|
46
|
+
* @type {Map}
|
|
47
|
+
*/
|
|
48
|
+
this._innerState = new Map();
|
|
49
|
+
/**
|
|
50
|
+
* Map for reactive state created via $state.
|
|
51
|
+
* @type {Map}
|
|
52
|
+
*/
|
|
53
|
+
this._stateMap = new Map();
|
|
54
|
+
/**
|
|
55
|
+
* Stores the previous context for scoping.
|
|
56
|
+
* @type {Object|null}
|
|
57
|
+
*/
|
|
58
|
+
this._formerContext = null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Returns the component function.
|
|
62
|
+
* @returns {Function}
|
|
63
|
+
*/
|
|
64
|
+
getComponent() {
|
|
65
|
+
return this.component;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export default PawaComponent
|