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.
Files changed (61) hide show
  1. package/AGENT.md +163 -0
  2. package/CHANGELOG.md +3 -1
  3. package/LICENSE +1 -1
  4. package/README.md +218 -71
  5. package/examples/Text.js +5 -0
  6. package/examples/index.html +64 -0
  7. package/examples/index.js +31 -0
  8. package/examples/tools.js +89 -0
  9. package/index.d.ts +400 -358
  10. package/index.js +70 -1413
  11. package/package.json +6 -5
  12. package/src/builtIn/Active.js +67 -0
  13. package/src/builtIn/viewTransition.js +42 -0
  14. package/src/component/index.js +194 -0
  15. package/src/component/utils.js +358 -0
  16. package/src/control-flow/attribute.js +82 -0
  17. package/src/control-flow/await.js +77 -0
  18. package/src/control-flow/for.js +269 -0
  19. package/src/control-flow/if.js +127 -0
  20. package/src/control-flow/key.js +87 -0
  21. package/src/control-flow/ref.js +34 -0
  22. package/src/control-flow/state.js +26 -0
  23. package/src/control-flow/template.js +25 -0
  24. package/src/control-flow/text.js +58 -0
  25. package/src/control-flow/timers.js +26 -0
  26. package/src/control-flow/utils.js +42 -0
  27. package/src/dev/index.js +61 -0
  28. package/src/dev/plugin.js +24 -0
  29. package/src/event/index.js +211 -0
  30. package/src/global.js +93 -0
  31. package/src/graph/graph.js +180 -0
  32. package/src/graph/index.js +154 -0
  33. package/src/graph/setup.js +28 -0
  34. package/src/hooks/index.js +217 -0
  35. package/src/hooks/registerComponent.js +101 -0
  36. package/src/hooks/state.js +296 -0
  37. package/src/hooks/utils.js +35 -0
  38. package/src/pawaElement.js +159 -0
  39. package/src/reactive.js +251 -0
  40. package/{server.js → src/server/index.js} +6 -4
  41. package/src/store.js +3 -0
  42. package/src/utils.js +56 -0
  43. package/cdn/index.html +0 -25
  44. package/cdn/index.js +0 -23
  45. package/merger/for.js +0 -203
  46. package/merger/if.js +0 -135
  47. package/merger/key.js +0 -117
  48. package/merger/switch.js +0 -134
  49. package/normal/For.js +0 -30
  50. package/normal/If.js +0 -29
  51. package/normal/Key.js +0 -27
  52. package/normal/Switch.js +0 -29
  53. package/normal/component.js +0 -418
  54. package/normal/template.js +0 -33
  55. package/pawaComponent.js +0 -72
  56. package/pawaElement.js +0 -513
  57. package/power.js +0 -667
  58. package/reactive.js +0 -190
  59. package/resumer.js +0 -19
  60. package/server.d.ts +0 -13
  61. 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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
3
+ .replace(/"/g, '&quot;').replace(/'/g, '&#039;')
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
+ }