pawajs 2.3.6 → 2.4.0-beta.11
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/AGENT.md +163 -0
- package/CHANGELOG.md +3 -1
- package/LICENSE +1 -1
- package/README.md +218 -71
- package/examples/Text.js +5 -0
- package/examples/index.html +64 -0
- package/examples/index.js +31 -0
- package/examples/tools.js +89 -0
- package/index.d.ts +400 -358
- package/index.js +70 -1413
- package/package.json +6 -5
- package/src/builtIn/Active.js +67 -0
- package/src/builtIn/viewTransition.js +42 -0
- package/src/component/index.js +194 -0
- package/src/component/utils.js +358 -0
- package/src/control-flow/attribute.js +82 -0
- package/src/control-flow/await.js +77 -0
- package/src/control-flow/for.js +269 -0
- package/src/control-flow/if.js +127 -0
- package/src/control-flow/key.js +87 -0
- package/src/control-flow/ref.js +34 -0
- package/src/control-flow/state.js +26 -0
- package/src/control-flow/template.js +25 -0
- package/src/control-flow/text.js +58 -0
- package/src/control-flow/timers.js +26 -0
- package/src/control-flow/utils.js +42 -0
- package/src/dev/index.js +61 -0
- package/src/dev/plugin.js +24 -0
- package/src/event/index.js +211 -0
- package/src/global.js +93 -0
- package/src/graph/graph.js +180 -0
- package/src/graph/index.js +154 -0
- package/src/graph/setup.js +28 -0
- package/src/hooks/index.js +217 -0
- package/src/hooks/registerComponent.js +101 -0
- package/src/hooks/state.js +296 -0
- package/src/hooks/utils.js +35 -0
- package/src/pawaElement.js +159 -0
- package/src/reactive.js +251 -0
- package/{server.js → src/server/index.js} +6 -4
- package/src/store.js +3 -0
- package/src/utils.js +56 -0
- package/cdn/index.html +0 -25
- package/cdn/index.js +0 -23
- package/merger/for.js +0 -203
- package/merger/if.js +0 -135
- package/merger/key.js +0 -117
- package/merger/switch.js +0 -134
- package/normal/For.js +0 -30
- package/normal/If.js +0 -29
- package/normal/Key.js +0 -27
- package/normal/Switch.js +0 -29
- package/normal/component.js +0 -418
- package/normal/template.js +0 -33
- package/pawaComponent.js +0 -72
- package/pawaElement.js +0 -513
- package/power.js +0 -667
- package/reactive.js +0 -190
- package/resumer.js +0 -19
- package/server.d.ts +0 -13
- package/utils.js +0 -309
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Document</title>
|
|
7
|
+
<style>
|
|
8
|
+
.view{
|
|
9
|
+
width: 200px;
|
|
10
|
+
height: 200px;
|
|
11
|
+
background-color: aquamarine;
|
|
12
|
+
}
|
|
13
|
+
.views{
|
|
14
|
+
width: 150px;
|
|
15
|
+
height: 150px;
|
|
16
|
+
background-color: gold;
|
|
17
|
+
}
|
|
18
|
+
</style>
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
<div id="app">
|
|
22
|
+
<div>
|
|
23
|
+
<h1>Hello PawaJS</h1>
|
|
24
|
+
<text></text>
|
|
25
|
+
</div>
|
|
26
|
+
<transition
|
|
27
|
+
|
|
28
|
+
:duration="3000"
|
|
29
|
+
:enter="['transform:scale(0)','transform:scale(1)']"
|
|
30
|
+
:exit="['transform:scale(1)','transform:scale(0)']"
|
|
31
|
+
>
|
|
32
|
+
<div class="view" state-name="''">
|
|
33
|
+
<active :show="user.value">
|
|
34
|
+
<div #style.color="@{user.value?'red':'blue'}">@{name.value}</div>
|
|
35
|
+
</active>
|
|
36
|
+
<input @value="@{name.value}" on-input="name.value=e.target.value"/>
|
|
37
|
+
</div>
|
|
38
|
+
</transition>
|
|
39
|
+
|
|
40
|
+
<template for-each="item, i in items.value"
|
|
41
|
+
for-key="{{item.id}}"
|
|
42
|
+
>
|
|
43
|
+
<div #style.color="@{user.value?'red':'blue'}">@{item.name}</div>
|
|
44
|
+
<div on-click="remove(item.id)">Enter</div>
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<div on-click="set()">From template</div>
|
|
48
|
+
<div await="promise()">
|
|
49
|
+
<h4>This is Promise</h4>
|
|
50
|
+
</div>
|
|
51
|
+
<div as-fallback>
|
|
52
|
+
<span>Loading...</span>
|
|
53
|
+
</div>
|
|
54
|
+
<div as-catch>Error something wrong</div>
|
|
55
|
+
<counter user="user">
|
|
56
|
+
<div>
|
|
57
|
+
<span @inner-html="ALLWELL"></span>
|
|
58
|
+
<span>MY OWN Counter</span>
|
|
59
|
+
</div>
|
|
60
|
+
</counter>
|
|
61
|
+
</div>
|
|
62
|
+
<script type="module" src="./index.js"></script>
|
|
63
|
+
</body>
|
|
64
|
+
</html>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { pawaStartApp,$state, RegisterComponent, useValidateComponent, runEffect, useInnerContext, useInsert, forwardProps, Transition, Active } from "../index.js";
|
|
2
|
+
import { schedule, useStorage } from "../src/hooks/state.js";
|
|
3
|
+
const user=useStorage(()=>$state(false),'user')
|
|
4
|
+
const set=()=>{
|
|
5
|
+
schedule(()=>user.value=!user.value)
|
|
6
|
+
}
|
|
7
|
+
const items=$state([
|
|
8
|
+
{name:'james',id:938449},{name:'joy',id:736497},{name:'josh',id:997287}
|
|
9
|
+
])
|
|
10
|
+
const remove=(key)=>{
|
|
11
|
+
items.value=items.value.filter(n => n.id !== key)
|
|
12
|
+
}
|
|
13
|
+
const Counter=({...props})=>{
|
|
14
|
+
|
|
15
|
+
useInsert({data:'users'})
|
|
16
|
+
return `
|
|
17
|
+
<slot></slot>`
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const promise=()=>new Promise((r)=>{
|
|
21
|
+
setTimeout(() => {
|
|
22
|
+
r({
|
|
23
|
+
user:'Allwell',
|
|
24
|
+
age:24
|
|
25
|
+
})
|
|
26
|
+
}, 6000);
|
|
27
|
+
})
|
|
28
|
+
RegisterComponent(Counter,Transition,Active)
|
|
29
|
+
RegisterComponent.lazy('Text',()=>import('./Text.js'))
|
|
30
|
+
pawaStartApp(document.getElementById('app'),{user,set,items,remove,promise})
|
|
31
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const escapeHtml = (value) => String(value ?? '')
|
|
2
|
+
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
3
|
+
.replace(/"/g, '"').replace(/'/g, ''')
|
|
4
|
+
|
|
5
|
+
const formatTime = (time) => {
|
|
6
|
+
try { return new Date(time).toLocaleTimeString() } catch { return '' }
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const styles = `
|
|
10
|
+
:host { all: initial; }
|
|
11
|
+
* { box-sizing: border-box; }
|
|
12
|
+
button { font: inherit; border: 0; border-radius: 6px; padding: 5px 8px; color: #d1d5db; background: #374151; cursor: pointer; }
|
|
13
|
+
button:hover { color: white; background: #4b5563; }
|
|
14
|
+
.panel { position: fixed; z-index: 2147483647; right: 16px; bottom: 16px; width: min(440px, calc(100vw - 32px)); color: #e5e7eb; font: 13px/1.45 ui-monospace, monospace; background: #111827; border: 1px solid #374151; border-radius: 12px; box-shadow: 0 24px 70px #0008; overflow: hidden; }
|
|
15
|
+
.panel.minimized .body { display: none; }
|
|
16
|
+
.toolbar { display: flex; align-items: center; gap: 10px; padding: 11px 13px; background: #1f2937; border-bottom: 1px solid #374151; }
|
|
17
|
+
.brand { color: #f5d77b; font-weight: 700; flex: 1; }
|
|
18
|
+
.count { min-width: 22px; padding: 2px 6px; border-radius: 999px; text-align: center; color: #111827; background: #f87171; font-weight: 700; }
|
|
19
|
+
.body { max-height: min(540px, 65vh); overflow: auto; }
|
|
20
|
+
.empty { padding: 28px 16px; color: #9ca3af; text-align: center; }
|
|
21
|
+
.error { padding: 13px; border-bottom: 1px solid #374151; }
|
|
22
|
+
.error-head { display: flex; gap: 8px; align-items: center; color: #fca5a5; font-weight: 700; }
|
|
23
|
+
.error-time { margin-left: auto; color: #6b7280; font-size: 11px; font-weight: 400; }
|
|
24
|
+
.meta { margin-top: 6px; color: #d1d5db; white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
25
|
+
details { margin-top: 8px; color: #9ca3af; }
|
|
26
|
+
summary { cursor: pointer; }
|
|
27
|
+
pre { margin: 7px 0 0; padding: 8px; max-height: 170px; overflow: auto; color: #fca5a5; background: #030712; border-radius: 6px; white-space: pre-wrap; }
|
|
28
|
+
`
|
|
29
|
+
|
|
30
|
+
export const mountPawaDevtools = (options = {}) => {
|
|
31
|
+
if (typeof document === 'undefined') return () => {}
|
|
32
|
+
if (document.querySelector('[data-pawa-devtools]')) return () => {}
|
|
33
|
+
|
|
34
|
+
const host = document.createElement('div')
|
|
35
|
+
host.dataset.pawaDevtools = 'true'
|
|
36
|
+
const root = host.attachShadow?.({ mode: 'open' }) || host
|
|
37
|
+
root.innerHTML = `<style>${styles}</style><section class="panel"><div class="toolbar"><span class="brand">Pawa Devtools</span><span class="count">0</span><button data-action="clear" type="button">Clear</button><button data-action="minimize" type="button">_</button></div><div class="body"><div class="empty">No runtime errors</div></div></section>`
|
|
38
|
+
document.body.appendChild(host)
|
|
39
|
+
|
|
40
|
+
const panel = root.querySelector('.panel')
|
|
41
|
+
const count = root.querySelector('.count')
|
|
42
|
+
const body = root.querySelector('.body')
|
|
43
|
+
const errors = []
|
|
44
|
+
const dev = globalThis.__pawaDev
|
|
45
|
+
|
|
46
|
+
const render = () => {
|
|
47
|
+
count.textContent = String(errors.length)
|
|
48
|
+
if (!errors.length) {
|
|
49
|
+
body.innerHTML = '<div class="empty">No runtime errors</div>'
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
body.innerHTML = errors.slice().reverse().map((error) => `
|
|
53
|
+
<article class="error"><div class="error-head"><span>${escapeHtml(error.effect || 'runtime')}</span><span class="error-time">${escapeHtml(formatTime(error.time))}</span></div>
|
|
54
|
+
<div class="meta">${escapeHtml(error.msg || 'Unknown error')}</div>
|
|
55
|
+
${error.exp ? `<div class="meta">Expression: ${escapeHtml(error.exp)}</div>` : ''}
|
|
56
|
+
${error.stack || error.template ? `<details><summary>Details</summary>${error.template ? `<pre>${escapeHtml(error.template)}</pre>` : ''}${error.stack ? `<pre>${escapeHtml(error.stack)}</pre>` : ''}</details>` : ''}</article>
|
|
57
|
+
`).join('')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const unsubscribe = dev?.subscribe?.(({ type, data }) => {
|
|
61
|
+
if (type === 'clear') errors.length = 0
|
|
62
|
+
if (type === 'error' && data) errors.push(data)
|
|
63
|
+
render()
|
|
64
|
+
}) || (() => {})
|
|
65
|
+
errors.push(...(dev?.getSnapshot?.().errors || []))
|
|
66
|
+
render()
|
|
67
|
+
const article=root.querySelector('.panel')
|
|
68
|
+
let into=false
|
|
69
|
+
window.addEventListener('keydown', (e)=>{
|
|
70
|
+
if (e.ctrlKey && e.key === 'q') {
|
|
71
|
+
if(into)
|
|
72
|
+
article.setAttribute('hidden', '')
|
|
73
|
+
else
|
|
74
|
+
article.removeAttribute('hidden')
|
|
75
|
+
|
|
76
|
+
into=!into
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
})
|
|
80
|
+
root.querySelector('[data-action="clear"]').addEventListener('click', () => dev?.clearErrors?.())
|
|
81
|
+
root.querySelector('[data-action="minimize"]').addEventListener('click', () => panel.classList.toggle('minimized'))
|
|
82
|
+
if (options.open === false) panel.classList.add('minimized')
|
|
83
|
+
|
|
84
|
+
return () => { unsubscribe(); host.remove() }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const unmountPawaDevtools = () => {
|
|
88
|
+
document.querySelector('[data-pawa-devtools]')?.remove()
|
|
89
|
+
}
|