microui-wc 0.1.0 → 0.1.2
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/AGENTS.md +71 -71
- package/CHANGELOG.md +1 -1
- package/README.md +14 -9
- package/dist/AGENTS.md +116 -116
- package/dist/README.md +21 -16
- package/dist/components.css +1 -1
- package/dist/microui.css +1 -1
- package/dist/microui.esm.js.map +1 -1
- package/dist/microui.min.js.map +1 -1
- package/dist/styles/components/switch.css +1 -1
- package/docs/getting-started.md +3 -3
- package/package.json +38 -10
- package/src/components/mu-schema-form.js +1 -1
- package/src/styles/components/switch.css +7 -8
- package/src/styles/components.css +6 -6
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -33
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
- package/.github/workflows/ci.yml +0 -42
- package/.github/workflows/deploy-pages.yml +0 -112
- package/CODE_OF_CONDUCT.md +0 -59
- package/CONTRIBUTING.md +0 -156
- package/SECURITY.md +0 -58
- package/app/.generated/routes/alerts.js +0 -8
- package/app/.generated/routes/avatars.js +0 -8
- package/app/.generated/routes/badges.js +0 -8
- package/app/.generated/routes/buttons.js +0 -10
- package/app/.generated/routes/cards.js +0 -10
- package/app/.generated/routes/checkboxes.js +0 -9
- package/app/.generated/routes/chips.js +0 -8
- package/app/.generated/routes/dropdowns.js +0 -9
- package/app/.generated/routes/home.js +0 -7
- package/app/.generated/routes/icons.js +0 -9
- package/app/.generated/routes/inputs.js +0 -10
- package/app/.generated/routes/installation.js +0 -7
- package/app/.generated/routes/layout.js +0 -9
- package/app/.generated/routes/modals.js +0 -9
- package/app/.generated/routes/navbar.js +0 -7
- package/app/.generated/routes/progress.js +0 -9
- package/app/.generated/routes/radios.js +0 -9
- package/app/.generated/routes/switches.js +0 -9
- package/app/.generated/routes/tabs.js +0 -8
- package/app/.generated/routes/toasts.js +0 -9
- package/app/index.html +0 -67
- package/app/pages/alerts.html +0 -23
- package/app/pages/avatars.html +0 -22
- package/app/pages/badges.html +0 -22
- package/app/pages/buttons.html +0 -71
- package/app/pages/cards.html +0 -54
- package/app/pages/checkboxes.html +0 -39
- package/app/pages/chips.html +0 -23
- package/app/pages/dropdowns.html +0 -41
- package/app/pages/home.html +0 -59
- package/app/pages/icons.html +0 -29
- package/app/pages/inputs.html +0 -66
- package/app/pages/installation.html +0 -34
- package/app/pages/layout.html +0 -30
- package/app/pages/modals.html +0 -21
- package/app/pages/navbar.html +0 -22
- package/app/pages/progress.html +0 -35
- package/app/pages/radios.html +0 -40
- package/app/pages/switches.html +0 -39
- package/app/pages/tabs.html +0 -30
- package/app/pages/toasts.html +0 -22
- package/app-dist/index.html +0 -67
- package/app-dist/pages/alerts.html +0 -23
- package/app-dist/pages/avatars.html +0 -22
- package/app-dist/pages/badges.html +0 -22
- package/app-dist/pages/buttons.html +0 -71
- package/app-dist/pages/cards.html +0 -54
- package/app-dist/pages/checkboxes.html +0 -39
- package/app-dist/pages/chips.html +0 -23
- package/app-dist/pages/dropdowns.html +0 -41
- package/app-dist/pages/home.html +0 -59
- package/app-dist/pages/icons.html +0 -29
- package/app-dist/pages/inputs.html +0 -66
- package/app-dist/pages/installation.html +0 -34
- package/app-dist/pages/layout.html +0 -30
- package/app-dist/pages/modals.html +0 -21
- package/app-dist/pages/navbar.html +0 -22
- package/app-dist/pages/progress.html +0 -35
- package/app-dist/pages/radios.html +0 -40
- package/app-dist/pages/switches.html +0 -39
- package/app-dist/pages/tabs.html +0 -30
- package/app-dist/pages/toasts.html +0 -22
- package/app-dist/pages.json +0 -217
- package/app-dist/routes/alerts.js +0 -5
- package/app-dist/routes/avatars.js +0 -1
- package/app-dist/routes/badges.js +0 -1
- package/app-dist/routes/buttons.js +0 -1
- package/app-dist/routes/cards.js +0 -1
- package/app-dist/routes/checkboxes.js +0 -9
- package/app-dist/routes/chips.js +0 -4
- package/app-dist/routes/chunk-019e5e2f.js +0 -5
- package/app-dist/routes/chunk-0m4j19yd.js +0 -2
- package/app-dist/routes/chunk-0tmmp5q0.js +0 -1
- package/app-dist/routes/chunk-10xn709r.js +0 -1
- package/app-dist/routes/chunk-15m2qcda.js +0 -2
- package/app-dist/routes/chunk-1bh8g23n.js +0 -1
- package/app-dist/routes/chunk-1vg0v937.js +0 -1
- package/app-dist/routes/chunk-1zvcgy3j.js +0 -1
- package/app-dist/routes/chunk-2afb0861.js +0 -1
- package/app-dist/routes/chunk-2c6ttpzt.js +0 -5
- package/app-dist/routes/chunk-3dy30fhs.js +0 -1
- package/app-dist/routes/chunk-426dnces.js +0 -13
- package/app-dist/routes/chunk-44kgxery.js +0 -1
- package/app-dist/routes/chunk-47fdnejd.js +0 -33
- package/app-dist/routes/chunk-49a6t2vq.js +0 -1
- package/app-dist/routes/chunk-4fe1rm5b.js +0 -1
- package/app-dist/routes/chunk-4ggmvkta.js +0 -33
- package/app-dist/routes/chunk-4vkz81q7.js +0 -33
- package/app-dist/routes/chunk-4w4tmj8f.js +0 -31
- package/app-dist/routes/chunk-532s62kr.js +0 -31
- package/app-dist/routes/chunk-5hm3bssy.js +0 -33
- package/app-dist/routes/chunk-5vrh24hc.js +0 -1
- package/app-dist/routes/chunk-61pcg25a.js +0 -1
- package/app-dist/routes/chunk-6nfhygvf.js +0 -1
- package/app-dist/routes/chunk-700e7je6.js +0 -33
- package/app-dist/routes/chunk-7fsn17kg.js +0 -1
- package/app-dist/routes/chunk-7k789b32.js +0 -1
- package/app-dist/routes/chunk-7r46q0ys.js +0 -36
- package/app-dist/routes/chunk-86fmc1fr.js +0 -5
- package/app-dist/routes/chunk-8qth37vw.js +0 -1
- package/app-dist/routes/chunk-924wv8n0.js +0 -1
- package/app-dist/routes/chunk-9mbhgxk9.js +0 -1
- package/app-dist/routes/chunk-a216hyd9.js +0 -1
- package/app-dist/routes/chunk-akzxykh9.js +0 -33
- package/app-dist/routes/chunk-b3dcvy8c.js +0 -1
- package/app-dist/routes/chunk-b74zahz5.js +0 -31
- package/app-dist/routes/chunk-bftj53p2.js +0 -5
- package/app-dist/routes/chunk-c01hnz3e.js +0 -1
- package/app-dist/routes/chunk-d8pvv5km.js +0 -1
- package/app-dist/routes/chunk-dev0aezr.js +0 -2
- package/app-dist/routes/chunk-dh6vnv0e.js +0 -1
- package/app-dist/routes/chunk-dn2cbpva.js +0 -36
- package/app-dist/routes/chunk-dvn0my90.js +0 -1
- package/app-dist/routes/chunk-dvq8mnve.js +0 -36
- package/app-dist/routes/chunk-e8c2gc4d.js +0 -5
- package/app-dist/routes/chunk-ejf9ak2x.js +0 -1
- package/app-dist/routes/chunk-f083m55s.js +0 -1
- package/app-dist/routes/chunk-fnrj28s1.js +0 -31
- package/app-dist/routes/chunk-fvg3yjdp.js +0 -31
- package/app-dist/routes/chunk-g7k381n1.js +0 -1
- package/app-dist/routes/chunk-h01kq2ae.js +0 -13
- package/app-dist/routes/chunk-h4dk761v.js +0 -5
- package/app-dist/routes/chunk-hmx91z2x.js +0 -5
- package/app-dist/routes/chunk-hxbg4m42.js +0 -36
- package/app-dist/routes/chunk-jbjnfp2b.js +0 -2
- package/app-dist/routes/chunk-jxtz5vv6.js +0 -36
- package/app-dist/routes/chunk-jxzcs0ey.js +0 -36
- package/app-dist/routes/chunk-kt7wwhcx.js +0 -1
- package/app-dist/routes/chunk-kzptszyc.js +0 -33
- package/app-dist/routes/chunk-mhgca4w4.js +0 -2
- package/app-dist/routes/chunk-mhswxa20.js +0 -1
- package/app-dist/routes/chunk-n8zfeex6.js +0 -1
- package/app-dist/routes/chunk-pee47b2r.js +0 -1
- package/app-dist/routes/chunk-pesmw829.js +0 -1
- package/app-dist/routes/chunk-pgc4c6f3.js +0 -36
- package/app-dist/routes/chunk-q8egegm1.js +0 -1
- package/app-dist/routes/chunk-q9mn2qyq.js +0 -36
- package/app-dist/routes/chunk-qh0rtaf3.js +0 -5
- package/app-dist/routes/chunk-qqhmk6ye.js +0 -2
- package/app-dist/routes/chunk-qrxygmf7.js +0 -33
- package/app-dist/routes/chunk-r46yzksx.js +0 -36
- package/app-dist/routes/chunk-rgpbw2w0.js +0 -5
- package/app-dist/routes/chunk-rnpzv3d8.js +0 -2
- package/app-dist/routes/chunk-s5v8cv05.js +0 -2
- package/app-dist/routes/chunk-sbwn5bpc.js +0 -1
- package/app-dist/routes/chunk-sqbg8jbt.js +0 -33
- package/app-dist/routes/chunk-sv8dqnf7.js +0 -1
- package/app-dist/routes/chunk-t67sw3za.js +0 -1
- package/app-dist/routes/chunk-tjdpqwdf.js +0 -31
- package/app-dist/routes/chunk-tq2mfghg.js +0 -1
- package/app-dist/routes/chunk-ttn10vt6.js +0 -1
- package/app-dist/routes/chunk-v2hzpjxr.js +0 -1
- package/app-dist/routes/chunk-wfjjkw9y.js +0 -1
- package/app-dist/routes/chunk-wt8cxzmf.js +0 -31
- package/app-dist/routes/chunk-x45d372k.js +0 -5
- package/app-dist/routes/chunk-y3wsazkt.js +0 -1
- package/app-dist/routes/chunk-y7pmgc7t.js +0 -33
- package/app-dist/routes/chunk-zefdt2q3.js +0 -31
- package/app-dist/routes/dropdowns.js +0 -6
- package/app-dist/routes/home.js +0 -1
- package/app-dist/routes/icons.js +0 -1
- package/app-dist/routes/inputs.js +0 -12
- package/app-dist/routes/installation.js +0 -1
- package/app-dist/routes/layout.js +0 -1
- package/app-dist/routes/modals.js +0 -7
- package/app-dist/routes/navbar.js +0 -1
- package/app-dist/routes/progress.js +0 -1
- package/app-dist/routes/radios.js +0 -6
- package/app-dist/routes/switches.js +0 -6
- package/app-dist/routes/tabs.js +0 -1
- package/app-dist/routes/toasts.js +0 -16
- package/assets/fonts/material-symbols-mini.woff2 +0 -0
- package/assets/fonts/material-symbols.woff2 +0 -0
- package/assets/fonts/roboto-400.woff2 +0 -0
- package/assets/fonts/roboto-500.woff2 +0 -0
- package/assets/fonts/roboto-700.woff2 +0 -0
- package/assets/logo-banner-400.jpg +0 -0
- package/assets/logo-banner-400.webp +0 -0
- package/assets/logo-banner-800.webp +0 -0
- package/assets/logo-banner.jpg +0 -0
- package/assets/logo-icon-64.jpg +0 -0
- package/assets/logo-icon-64.webp +0 -0
- package/assets/logo-icon.jpg +0 -0
- package/assets/logo-square.jpg +0 -0
- package/bun.lock +0 -312
- package/bunfig.toml +0 -4
- package/custom-elements.json +0 -1916
- package/demo/api/sample-data.json +0 -38
- package/demo/content/alerts.html +0 -115
- package/demo/content/avatars.html +0 -70
- package/demo/content/badges.html +0 -65
- package/demo/content/buttons.html +0 -188
- package/demo/content/callouts.html +0 -91
- package/demo/content/cards.html +0 -121
- package/demo/content/checkboxes.html +0 -178
- package/demo/content/chips.html +0 -67
- package/demo/content/codeblocks.html +0 -101
- package/demo/content/confirms.html +0 -115
- package/demo/content/datatables.html +0 -149
- package/demo/content/dividers.html +0 -119
- package/demo/content/dropdowns.html +0 -89
- package/demo/content/enterprise.html +0 -252
- package/demo/content/home.html +0 -149
- package/demo/content/icons.html +0 -89
- package/demo/content/inputs.html +0 -135
- package/demo/content/installation.html +0 -16
- package/demo/content/layout.html +0 -136
- package/demo/content/modals.html +0 -141
- package/demo/content/navbar.html +0 -70
- package/demo/content/progress.html +0 -119
- package/demo/content/radios.html +0 -88
- package/demo/content/skeletons.html +0 -109
- package/demo/content/spinners.html +0 -96
- package/demo/content/switches.html +0 -84
- package/demo/content/tables.html +0 -124
- package/demo/content/tabs.html +0 -85
- package/demo/content/toasts.html +0 -116
- package/demo/content/tooltips.html +0 -107
- package/demo/content/virtual-lists.html +0 -233
- package/demo/favicon.ico +0 -0
- package/demo/favicon.png +0 -0
- package/demo/full.html +0 -52
- package/demo/iife.html +0 -46
- package/demo/manifest.json +0 -34
- package/demo/pages/datatable-demo.html +0 -237
- package/demo/pages/prompt-ui-demo.html +0 -218
- package/demo/pages/responsive-demo.html +0 -122
- package/demo/pages/schema-form-demo.html +0 -270
- package/demo/robots.txt +0 -6
- package/demo/shell.html +0 -712
- package/demo/sw.js +0 -387
- package/lighthouse-audit.mjs +0 -113
- package/scripts/analyze-components.js +0 -105
- package/scripts/build-app.js +0 -193
- package/scripts/build-framework.js +0 -444
- package/scripts/build-utils.js +0 -101
- package/scripts/test-isolated.js +0 -151
- package/server.js +0 -256
- package/tests/agents/agent-integration.test.js +0 -76
- package/tests/benchmark.html +0 -296
- package/tests/build/scan-components.test.js +0 -173
- package/tests/components/all-components.test.js +0 -245
- package/tests/components/all-missing-components.test.js +0 -574
- package/tests/components/mu-alert.test.js +0 -113
- package/tests/components/mu-avatar.test.js +0 -148
- package/tests/components/mu-badge.test.js +0 -92
- package/tests/components/mu-button.test.js +0 -112
- package/tests/components/mu-card.test.js +0 -89
- package/tests/components/mu-checkbox.test.js +0 -158
- package/tests/components/mu-chip.test.js +0 -118
- package/tests/components/mu-container.test.js +0 -120
- package/tests/components/mu-divider.test.js +0 -98
- package/tests/components/mu-drawer-item.test.js +0 -199
- package/tests/components/mu-drawer.test.js +0 -96
- package/tests/components/mu-dropdown.test.js +0 -125
- package/tests/components/mu-form.test.js +0 -138
- package/tests/components/mu-grid.test.js +0 -135
- package/tests/components/mu-icon.test.js +0 -110
- package/tests/components/mu-input.test.js +0 -131
- package/tests/components/mu-lazy.test.js +0 -103
- package/tests/components/mu-modal.test.js +0 -275
- package/tests/components/mu-navbar.test.js +0 -101
- package/tests/components/mu-progress.test.js +0 -115
- package/tests/components/mu-radio.test.js +0 -114
- package/tests/components/mu-repeat.test.js +0 -106
- package/tests/components/mu-sidebar.test.js +0 -126
- package/tests/components/mu-skeleton.test.js +0 -162
- package/tests/components/mu-stack.test.js +0 -143
- package/tests/components/mu-switch.test.js +0 -292
- package/tests/components/mu-table.test.js +0 -124
- package/tests/components/mu-tabs.test.js +0 -104
- package/tests/components/mu-textarea.test.js +0 -115
- package/tests/components/mu-toast.test.js +0 -321
- package/tests/components/mu-tooltip.test.js +0 -133
- package/tests/components/mu-virtual-list.test.js +0 -109
- package/tests/core/MuElement.test.js +0 -120
- package/tests/core/agent-api.test.js +0 -125
- package/tests/core/all-core-modules.test.js +0 -442
- package/tests/core/bus.test.js +0 -364
- package/tests/core/component-schema.test.js +0 -160
- package/tests/core/feature-registry.test.js +0 -198
- package/tests/core/form-state.test.js +0 -167
- package/tests/core/http.test.js +0 -119
- package/tests/core/keyboard.test.js +0 -319
- package/tests/core/layers.test.js +0 -129
- package/tests/core/namespaced-stores.test.js +0 -114
- package/tests/core/render.test.js +0 -121
- package/tests/core/ripple.test.js +0 -131
- package/tests/core/router.test.js +0 -89
- package/tests/core/scheduler.test.js +0 -121
- package/tests/core/signals.test.js +0 -128
- package/tests/core/store.test.js +0 -171
- package/tests/core/transitions.test.js +0 -82
- package/tests/e2e/accessibility-harness.html +0 -58
- package/tests/e2e/accessibility.test.js +0 -401
- package/tests/e2e/agent-features.test.js +0 -372
- package/tests/e2e/card-spacing.test.js +0 -287
- package/tests/e2e/components.test.js +0 -439
- package/tests/e2e/demo-routes.test.js +0 -478
- package/tests/e2e/layout-css-fallback.test.js +0 -334
- package/tests/e2e/mu-alert.e2e.test.js +0 -111
- package/tests/e2e/mu-checkbox.test.js +0 -489
- package/tests/e2e/mu-chip.test.js +0 -347
- package/tests/e2e/mu-form.test.js +0 -499
- package/tests/e2e/mu-icon.test.js +0 -114
- package/tests/e2e/mu-radio.test.js +0 -113
- package/tests/e2e/mu-skeleton.test.js +0 -140
- package/tests/e2e/mu-switch.test.js +0 -415
- package/tests/e2e/mu-tabs.test.js +0 -494
- package/tests/e2e/mu-textarea.test.js +0 -242
- package/tests/e2e/mu-virtual-list.test.js +0 -427
- package/tests/e2e/perf-memory.test.js +0 -161
- package/tests/e2e/puppeteer-helper.js +0 -137
- package/tests/e2e/puppeteer.test.js +0 -226
- package/tests/e2e/pwa.test.js +0 -261
- package/tests/e2e/test-harness.html +0 -319
- package/tests/manual/test-components.html +0 -120
- package/tests/memory-test.html +0 -309
- package/tests/setup-dom.js +0 -93
- package/tests/visual-test.html +0 -301
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>Per-Component Loading Test</title>
|
|
8
|
-
<link rel="stylesheet" href="dist/microui.css">
|
|
9
|
-
<style>
|
|
10
|
-
body {
|
|
11
|
-
font-family: system-ui;
|
|
12
|
-
padding: 40px;
|
|
13
|
-
max-width: 800px;
|
|
14
|
-
margin: 0 auto;
|
|
15
|
-
background: var(--md-sys-color-background, #fffbfe);
|
|
16
|
-
color: var(--md-sys-color-on-background, #1d1b20);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
h1 {
|
|
20
|
-
margin-bottom: 8px;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.subtitle {
|
|
24
|
-
color: #666;
|
|
25
|
-
margin-bottom: 32px;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.test-section {
|
|
29
|
-
margin: 24px 0;
|
|
30
|
-
padding: 20px;
|
|
31
|
-
background: var(--md-sys-color-surface-container, #f3edf7);
|
|
32
|
-
border-radius: 12px;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.log {
|
|
36
|
-
font-family: monospace;
|
|
37
|
-
font-size: 13px;
|
|
38
|
-
padding: 12px;
|
|
39
|
-
background: #1d1b20;
|
|
40
|
-
color: #c6ffc1;
|
|
41
|
-
border-radius: 8px;
|
|
42
|
-
margin-top: 16px;
|
|
43
|
-
}
|
|
44
|
-
</style>
|
|
45
|
-
</head>
|
|
46
|
-
|
|
47
|
-
<body>
|
|
48
|
-
<h1>🧪 Per-Component Loading Test</h1>
|
|
49
|
-
<p class="subtitle">Testing individual component imports from dist/components/</p>
|
|
50
|
-
|
|
51
|
-
<div class="test-section">
|
|
52
|
-
<h2>Test 1: Button Component</h2>
|
|
53
|
-
<mu-button variant="filled">Loaded Button</mu-button>
|
|
54
|
-
<mu-button variant="tonal">Tonal</mu-button>
|
|
55
|
-
<mu-button variant="outlined">Outlined</mu-button>
|
|
56
|
-
</div>
|
|
57
|
-
|
|
58
|
-
<div class="test-section">
|
|
59
|
-
<h2>Test 2: Card Component</h2>
|
|
60
|
-
<mu-card style="padding: 20px;">
|
|
61
|
-
<h3>Card Title</h3>
|
|
62
|
-
<p>This card was loaded via per-component import.</p>
|
|
63
|
-
</mu-card>
|
|
64
|
-
</div>
|
|
65
|
-
|
|
66
|
-
<div class="test-section">
|
|
67
|
-
<h2>Test 3: Modal Component</h2>
|
|
68
|
-
<mu-button variant="filled" id="open-modal">Open Modal</mu-button>
|
|
69
|
-
<mu-modal id="test-modal">
|
|
70
|
-
<h2>Modal Test</h2>
|
|
71
|
-
<p>Modal loaded via per-component import!</p>
|
|
72
|
-
<mu-button variant="filled" onclick="document.getElementById('test-modal').close()">Close</mu-button>
|
|
73
|
-
</mu-modal>
|
|
74
|
-
</div>
|
|
75
|
-
|
|
76
|
-
<div class="log" id="log">Loading components...</div>
|
|
77
|
-
|
|
78
|
-
<script type="module">
|
|
79
|
-
const log = document.getElementById('log');
|
|
80
|
-
const logs = [];
|
|
81
|
-
|
|
82
|
-
function addLog(msg) {
|
|
83
|
-
logs.push(msg);
|
|
84
|
-
log.innerHTML = logs.join('<br>');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const perfStart = performance.now();
|
|
88
|
-
addLog('⏱️ Starting per-component load test...');
|
|
89
|
-
|
|
90
|
-
// Load only the components we need
|
|
91
|
-
const componentsToLoad = [
|
|
92
|
-
'mu-button',
|
|
93
|
-
'mu-card',
|
|
94
|
-
'mu-modal',
|
|
95
|
-
'mu-stack'
|
|
96
|
-
];
|
|
97
|
-
|
|
98
|
-
for (const comp of componentsToLoad) {
|
|
99
|
-
const start = performance.now();
|
|
100
|
-
try {
|
|
101
|
-
await import('./dist/components/' + comp + '.js');
|
|
102
|
-
const time = (performance.now() - start).toFixed(0);
|
|
103
|
-
addLog('✅ ' + comp + '.js loaded in ' + time + 'ms');
|
|
104
|
-
} catch (e) {
|
|
105
|
-
addLog('❌ ' + comp + '.js failed: ' + e.message);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const totalTime = (performance.now() - perfStart).toFixed(0);
|
|
110
|
-
addLog('');
|
|
111
|
-
addLog('📦 Total: 4 components loaded in ' + totalTime + 'ms');
|
|
112
|
-
|
|
113
|
-
// Setup modal button
|
|
114
|
-
document.getElementById('open-modal').onclick = () => {
|
|
115
|
-
document.getElementById('test-modal').open();
|
|
116
|
-
};
|
|
117
|
-
</script>
|
|
118
|
-
</body>
|
|
119
|
-
|
|
120
|
-
</html>
|
package/tests/memory-test.html
DELETED
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8">
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>microUI v0.1.0 - Memory Leak Test</title>
|
|
8
|
-
<link rel="stylesheet" href="../src/styles/tokens.css">
|
|
9
|
-
<link rel="stylesheet" href="../src/styles/components.css">
|
|
10
|
-
<style>
|
|
11
|
-
body {
|
|
12
|
-
font-family: var(--md-sys-typescale-font);
|
|
13
|
-
background: var(--md-sys-color-surface);
|
|
14
|
-
color: var(--md-sys-color-on-surface);
|
|
15
|
-
padding: 24px;
|
|
16
|
-
max-width: 800px;
|
|
17
|
-
margin: 0 auto;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.card {
|
|
21
|
-
background: var(--md-sys-color-surface-container);
|
|
22
|
-
border-radius: 12px;
|
|
23
|
-
padding: 20px;
|
|
24
|
-
margin-bottom: 16px;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.result {
|
|
28
|
-
font-family: monospace;
|
|
29
|
-
background: var(--md-sys-color-surface-container-highest);
|
|
30
|
-
padding: 12px;
|
|
31
|
-
border-radius: 8px;
|
|
32
|
-
white-space: pre-wrap;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
button {
|
|
36
|
-
background: var(--md-sys-color-primary);
|
|
37
|
-
color: var(--md-sys-color-on-primary);
|
|
38
|
-
border: none;
|
|
39
|
-
padding: 12px 24px;
|
|
40
|
-
border-radius: 8px;
|
|
41
|
-
cursor: pointer;
|
|
42
|
-
font-size: 16px;
|
|
43
|
-
margin: 4px;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.pass {
|
|
47
|
-
color: var(--md-sys-color-primary);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.fail {
|
|
51
|
-
color: var(--md-sys-color-error);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
#container {
|
|
55
|
-
display: none;
|
|
56
|
-
}
|
|
57
|
-
</style>
|
|
58
|
-
</head>
|
|
59
|
-
|
|
60
|
-
<body>
|
|
61
|
-
<h1>🔬 Memory Leak Test Suite</h1>
|
|
62
|
-
|
|
63
|
-
<div class="card">
|
|
64
|
-
<h2>Test 1: Component Lifecycle</h2>
|
|
65
|
-
<p>Creates and destroys 1000 components, checks for proper cleanup.</p>
|
|
66
|
-
<button onclick="testLifecycle()">Run Test</button>
|
|
67
|
-
<div id="lifecycle-result" class="result">Click to run...</div>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
<div class="card">
|
|
71
|
-
<h2>Test 2: Event Listener Cleanup</h2>
|
|
72
|
-
<p>Tests that event listeners are properly removed on disconnect.</p>
|
|
73
|
-
<button onclick="testEventListeners()">Run Test</button>
|
|
74
|
-
<div id="events-result" class="result">Click to run...</div>
|
|
75
|
-
</div>
|
|
76
|
-
|
|
77
|
-
<div class="card">
|
|
78
|
-
<h2>Test 3: Timer/Interval Cleanup</h2>
|
|
79
|
-
<p>Tests that timers and intervals are cleared on disconnect.</p>
|
|
80
|
-
<button onclick="testTimers()">Run Test</button>
|
|
81
|
-
<div id="timers-result" class="result">Click to run...</div>
|
|
82
|
-
</div>
|
|
83
|
-
|
|
84
|
-
<div class="card">
|
|
85
|
-
<h2>Test 4: WeakRef EventBus</h2>
|
|
86
|
-
<p>Tests that WeakRef listeners are garbage collected.</p>
|
|
87
|
-
<button onclick="testWeakRef()">Run Test</button>
|
|
88
|
-
<div id="weakref-result" class="result">Click to run...</div>
|
|
89
|
-
</div>
|
|
90
|
-
|
|
91
|
-
<div class="card">
|
|
92
|
-
<h2>Test 5: Stress Test</h2>
|
|
93
|
-
<p>Creates 10000 components rapidly to detect memory growth.</p>
|
|
94
|
-
<button onclick="testStress()">Run Stress Test</button>
|
|
95
|
-
<div id="stress-result" class="result">Click to run...</div>
|
|
96
|
-
</div>
|
|
97
|
-
|
|
98
|
-
<div id="container"></div>
|
|
99
|
-
|
|
100
|
-
<script type="module">
|
|
101
|
-
import { MuButton, bus } from '../src/index.js';
|
|
102
|
-
|
|
103
|
-
const container = document.getElementById('container');
|
|
104
|
-
|
|
105
|
-
// Test 1: Component Lifecycle
|
|
106
|
-
window.testLifecycle = async () => {
|
|
107
|
-
const result = document.getElementById('lifecycle-result');
|
|
108
|
-
result.textContent = 'Running...';
|
|
109
|
-
|
|
110
|
-
const initialMemory = performance.memory?.usedJSHeapSize;
|
|
111
|
-
|
|
112
|
-
// Create and destroy 1000 components
|
|
113
|
-
for (let i = 0; i < 1000; i++) {
|
|
114
|
-
const btn = document.createElement('mu-button');
|
|
115
|
-
btn.textContent = `Button ${i}`;
|
|
116
|
-
container.appendChild(btn);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const afterCreate = performance.memory?.usedJSHeapSize;
|
|
120
|
-
|
|
121
|
-
// Remove all
|
|
122
|
-
container.innerHTML = '';
|
|
123
|
-
|
|
124
|
-
// Force GC if available
|
|
125
|
-
if (window.gc) window.gc();
|
|
126
|
-
|
|
127
|
-
await new Promise(r => setTimeout(r, 500));
|
|
128
|
-
|
|
129
|
-
const afterDestroy = performance.memory?.usedJSHeapSize;
|
|
130
|
-
|
|
131
|
-
if (performance.memory) {
|
|
132
|
-
const createdMB = ((afterCreate - initialMemory) / 1024 / 1024).toFixed(2);
|
|
133
|
-
const retainedMB = ((afterDestroy - initialMemory) / 1024 / 1024).toFixed(2);
|
|
134
|
-
const freedMB = ((afterCreate - afterDestroy) / 1024 / 1024).toFixed(2);
|
|
135
|
-
|
|
136
|
-
const isGood = parseFloat(retainedMB) < parseFloat(createdMB) * 0.2;
|
|
137
|
-
|
|
138
|
-
result.innerHTML = `
|
|
139
|
-
<span class="${isGood ? 'pass' : 'fail'}">${isGood ? '✓ PASS' : '✗ POTENTIAL LEAK'}</span>
|
|
140
|
-
|
|
141
|
-
Memory allocated: ${createdMB} MB
|
|
142
|
-
Memory after cleanup: ${retainedMB} MB
|
|
143
|
-
Memory freed: ${freedMB} MB
|
|
144
|
-
|
|
145
|
-
${isGood ? 'Components properly cleaned up!' : 'Warning: Memory not fully released'}`;
|
|
146
|
-
} else {
|
|
147
|
-
result.textContent = '⚠️ Memory API not available. Run with --enable-precise-memory-info';
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// Test 2: Event Listener Cleanup
|
|
152
|
-
window.testEventListeners = () => {
|
|
153
|
-
const result = document.getElementById('events-result');
|
|
154
|
-
let listenerCalled = false;
|
|
155
|
-
|
|
156
|
-
// Create component that adds global listener
|
|
157
|
-
const btn = document.createElement('mu-button');
|
|
158
|
-
|
|
159
|
-
// Manually add listener using component's listen method
|
|
160
|
-
const handler = () => { listenerCalled = true; };
|
|
161
|
-
|
|
162
|
-
container.appendChild(btn);
|
|
163
|
-
|
|
164
|
-
// Use the new listen() method
|
|
165
|
-
btn.listen(window, 'test-event', handler);
|
|
166
|
-
|
|
167
|
-
// Dispatch to confirm it works
|
|
168
|
-
window.dispatchEvent(new Event('test-event'));
|
|
169
|
-
const calledBefore = listenerCalled;
|
|
170
|
-
|
|
171
|
-
// Remove component
|
|
172
|
-
container.removeChild(btn);
|
|
173
|
-
|
|
174
|
-
// Reset and try again
|
|
175
|
-
listenerCalled = false;
|
|
176
|
-
window.dispatchEvent(new Event('test-event'));
|
|
177
|
-
const calledAfter = listenerCalled;
|
|
178
|
-
|
|
179
|
-
if (calledBefore && !calledAfter) {
|
|
180
|
-
result.innerHTML = '<span class="pass">✓ PASS</span>\n\nListener active before disconnect: ✓\nListener cleaned up after disconnect: ✓';
|
|
181
|
-
} else if (!calledBefore) {
|
|
182
|
-
result.innerHTML = '<span class="fail">✗ FAIL</span>\n\nListener was not active before disconnect';
|
|
183
|
-
} else {
|
|
184
|
-
result.innerHTML = '<span class="fail">✗ FAIL - MEMORY LEAK</span>\n\nListener still active after disconnect!\nThis indicates a memory leak.';
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
// Test 3: Timer/Interval Cleanup
|
|
189
|
-
window.testTimers = async () => {
|
|
190
|
-
const result = document.getElementById('timers-result');
|
|
191
|
-
let timerFired = false;
|
|
192
|
-
let intervalCount = 0;
|
|
193
|
-
|
|
194
|
-
// Create component with timers
|
|
195
|
-
const btn = document.createElement('mu-button');
|
|
196
|
-
container.appendChild(btn);
|
|
197
|
-
|
|
198
|
-
// Use component's safe setTimeout/setInterval
|
|
199
|
-
btn.setTimeout(() => { timerFired = true; }, 200);
|
|
200
|
-
btn.setInterval(() => { intervalCount++; }, 100);
|
|
201
|
-
|
|
202
|
-
// Remove immediately
|
|
203
|
-
container.removeChild(btn);
|
|
204
|
-
|
|
205
|
-
// Wait for timers
|
|
206
|
-
await new Promise(r => setTimeout(r, 500));
|
|
207
|
-
|
|
208
|
-
const isGood = !timerFired && intervalCount === 0;
|
|
209
|
-
|
|
210
|
-
result.innerHTML = `
|
|
211
|
-
<span class="${isGood ? 'pass' : 'fail'}">${isGood ? '✓ PASS' : '✗ FAIL'}</span>
|
|
212
|
-
|
|
213
|
-
Timer fired after disconnect: ${timerFired ? 'YES (leak!)' : 'NO ✓'}
|
|
214
|
-
Interval count after disconnect: ${intervalCount} ${intervalCount === 0 ? '✓' : '(should be 0)'}
|
|
215
|
-
|
|
216
|
-
${isGood ? 'Timers properly cleaned up!' : 'Warning: Timers still running after component removed!'}`;
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
// Test 4: WeakRef EventBus
|
|
220
|
-
window.testWeakRef = async () => {
|
|
221
|
-
const result = document.getElementById('weakref-result');
|
|
222
|
-
|
|
223
|
-
const counts = bus.listenerCount('test:weak');
|
|
224
|
-
const initialCount = counts.total;
|
|
225
|
-
|
|
226
|
-
// Add a weak listener
|
|
227
|
-
let callback = (data) => console.log('weak callback');
|
|
228
|
-
bus.on('test:weak', callback, { weak: true });
|
|
229
|
-
|
|
230
|
-
const afterAdd = bus.listenerCount('test:weak');
|
|
231
|
-
|
|
232
|
-
// Remove reference
|
|
233
|
-
callback = null;
|
|
234
|
-
|
|
235
|
-
// Force GC if available
|
|
236
|
-
if (window.gc) window.gc();
|
|
237
|
-
|
|
238
|
-
// Emit to trigger cleanup
|
|
239
|
-
await new Promise(r => setTimeout(r, 100));
|
|
240
|
-
bus.emit('test:weak', {});
|
|
241
|
-
|
|
242
|
-
const afterEmit = bus.listenerCount('test:weak');
|
|
243
|
-
|
|
244
|
-
result.innerHTML = `
|
|
245
|
-
<span class="pass">✓ WeakRef Support Active</span>
|
|
246
|
-
|
|
247
|
-
Listeners before: ${initialCount}
|
|
248
|
-
After adding weak: ${afterAdd.weak} weak, ${afterAdd.strong} strong
|
|
249
|
-
After emit (cleanup): ${afterEmit.weak} weak, ${afterEmit.strong} strong
|
|
250
|
-
|
|
251
|
-
Note: Actual GC timing is unpredictable.
|
|
252
|
-
Use --expose-gc flag and window.gc() for deterministic testing.`;
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
// Test 5: Stress Test
|
|
256
|
-
window.testStress = async () => {
|
|
257
|
-
const result = document.getElementById('stress-result');
|
|
258
|
-
result.textContent = 'Running stress test (10000 components)...';
|
|
259
|
-
|
|
260
|
-
const before = performance.memory?.usedJSHeapSize || 0;
|
|
261
|
-
const start = performance.now();
|
|
262
|
-
|
|
263
|
-
// Create 10000 components
|
|
264
|
-
for (let i = 0; i < 10000; i++) {
|
|
265
|
-
const btn = document.createElement('mu-button');
|
|
266
|
-
btn.textContent = `B${i}`;
|
|
267
|
-
container.appendChild(btn);
|
|
268
|
-
|
|
269
|
-
// Report progress
|
|
270
|
-
if (i % 1000 === 0) {
|
|
271
|
-
result.textContent = `Creating: ${i}/10000...`;
|
|
272
|
-
await new Promise(r => setTimeout(r, 0));
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const afterCreate = performance.now();
|
|
277
|
-
const memAfterCreate = performance.memory?.usedJSHeapSize || 0;
|
|
278
|
-
|
|
279
|
-
// Destroy all
|
|
280
|
-
container.innerHTML = '';
|
|
281
|
-
|
|
282
|
-
if (window.gc) window.gc();
|
|
283
|
-
await new Promise(r => setTimeout(r, 500));
|
|
284
|
-
|
|
285
|
-
const afterDestroy = performance.now();
|
|
286
|
-
const memAfterDestroy = performance.memory?.usedJSHeapSize || 0;
|
|
287
|
-
|
|
288
|
-
const createTime = (afterCreate - start).toFixed(0);
|
|
289
|
-
const destroyTime = (afterDestroy - afterCreate).toFixed(0);
|
|
290
|
-
const memUsed = ((memAfterCreate - before) / 1024 / 1024).toFixed(2);
|
|
291
|
-
const memRetained = ((memAfterDestroy - before) / 1024 / 1024).toFixed(2);
|
|
292
|
-
|
|
293
|
-
result.innerHTML = `
|
|
294
|
-
<span class="pass">✓ Stress Test Complete</span>
|
|
295
|
-
|
|
296
|
-
Components: 10,000
|
|
297
|
-
Create time: ${createTime}ms (${(10000 / (createTime / 1000)).toFixed(0)} components/sec)
|
|
298
|
-
Destroy time: ${destroyTime}ms
|
|
299
|
-
|
|
300
|
-
Memory used: ${memUsed} MB
|
|
301
|
-
Memory after cleanup: ${memRetained} MB
|
|
302
|
-
Per-component: ~${(memAfterCreate - before) / 10000} bytes`;
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
console.log('🔬 Memory Leak Test Suite Ready');
|
|
306
|
-
</script>
|
|
307
|
-
</body>
|
|
308
|
-
|
|
309
|
-
</html>
|
package/tests/setup-dom.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Shared test setup for linkedom DOM environment
|
|
3
|
-
*
|
|
4
|
-
* This file provides a shared linkedom DOM instance for all tests.
|
|
5
|
-
* It must be imported before any component imports to ensure consistent
|
|
6
|
-
* globalThis state across all test files.
|
|
7
|
-
*
|
|
8
|
-
* Usage in test files:
|
|
9
|
-
* import '../setup-dom.js'; // First import!
|
|
10
|
-
* import { MuButton } from '../../src/components/mu-button.js';
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { parseHTML } from 'linkedom';
|
|
14
|
-
|
|
15
|
-
// Create shared DOM instance
|
|
16
|
-
const dom = parseHTML(`<!DOCTYPE html>
|
|
17
|
-
<html lang="en">
|
|
18
|
-
<head>
|
|
19
|
-
<meta charset="UTF-8">
|
|
20
|
-
<title>Test</title>
|
|
21
|
-
</head>
|
|
22
|
-
<body></body>
|
|
23
|
-
</html>`);
|
|
24
|
-
|
|
25
|
-
// Set up globals only once
|
|
26
|
-
if (!globalThis.__testDomInitialized) {
|
|
27
|
-
globalThis.__testDomInitialized = true;
|
|
28
|
-
|
|
29
|
-
globalThis.window = dom.window;
|
|
30
|
-
globalThis.document = dom.document;
|
|
31
|
-
globalThis.customElements = dom.customElements;
|
|
32
|
-
globalThis.HTMLElement = dom.HTMLElement;
|
|
33
|
-
globalThis.Node = dom.Node || globalThis.Node;
|
|
34
|
-
globalThis.Element = dom.Element || globalThis.Element;
|
|
35
|
-
globalThis.DocumentFragment = dom.DocumentFragment || globalThis.DocumentFragment;
|
|
36
|
-
|
|
37
|
-
// Mock requestAnimationFrame
|
|
38
|
-
globalThis.requestAnimationFrame = (cb) => {
|
|
39
|
-
cb(Date.now());
|
|
40
|
-
return 0;
|
|
41
|
-
};
|
|
42
|
-
globalThis.cancelAnimationFrame = () => { };
|
|
43
|
-
|
|
44
|
-
// Mock getComputedStyle
|
|
45
|
-
globalThis.getComputedStyle = () => ({
|
|
46
|
-
position: 'static',
|
|
47
|
-
overflow: 'visible',
|
|
48
|
-
getPropertyValue: () => ''
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
// Mock Web Animations API
|
|
52
|
-
if (!dom.HTMLElement.prototype.animate) {
|
|
53
|
-
dom.HTMLElement.prototype.animate = function (keyframes, options) {
|
|
54
|
-
return {
|
|
55
|
-
finished: Promise.resolve(),
|
|
56
|
-
cancel: () => { },
|
|
57
|
-
play: () => { },
|
|
58
|
-
pause: () => { },
|
|
59
|
-
onfinish: null
|
|
60
|
-
};
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Mock IntersectionObserver
|
|
65
|
-
globalThis.IntersectionObserver = class {
|
|
66
|
-
constructor(callback) {
|
|
67
|
-
this.callback = callback;
|
|
68
|
-
}
|
|
69
|
-
observe() { }
|
|
70
|
-
unobserve() { }
|
|
71
|
-
disconnect() { }
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
// Mock ResizeObserver
|
|
75
|
-
globalThis.ResizeObserver = class {
|
|
76
|
-
constructor(callback) {
|
|
77
|
-
this.callback = callback;
|
|
78
|
-
}
|
|
79
|
-
observe() { }
|
|
80
|
-
unobserve() { }
|
|
81
|
-
disconnect() { }
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Export for tests that need direct access
|
|
86
|
-
export const testDocument = dom.document;
|
|
87
|
-
export const testBody = dom.document.body;
|
|
88
|
-
export const testCustomElements = dom.customElements;
|
|
89
|
-
|
|
90
|
-
// Helper to reset body between tests
|
|
91
|
-
export function resetBody() {
|
|
92
|
-
dom.document.body.innerHTML = '';
|
|
93
|
-
}
|