sigpro 1.0.14 → 1.2.40

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 (112) hide show
  1. package/Readme.md +164 -1008
  2. package/dist/sigpro.db.js +1 -0
  3. package/dist/sigpro.editor.js +1 -0
  4. package/dist/sigpro.grid.js +78 -0
  5. package/dist/sigpro.js +1 -0
  6. package/dist/sigpro.locale.js +1 -0
  7. package/dist/sigpro.router.js +1 -0
  8. package/dist/sigpro.ui.css +2 -0
  9. package/dist/sigpro.ui.js +1 -0
  10. package/dist/sigpro.vite.js +4 -0
  11. package/package.json +94 -13
  12. package/sigpro.d.ts +395 -0
  13. package/sigpro.ui.d.ts +308 -0
  14. package/.github/workflows/publish.yml +0 -25
  15. package/bun.lock +0 -385
  16. package/docs/404.html +0 -22
  17. package/docs/api/components.html +0 -595
  18. package/docs/api/effects.html +0 -787
  19. package/docs/api/fetch.html +0 -873
  20. package/docs/api/pages.html +0 -405
  21. package/docs/api/quick.html +0 -217
  22. package/docs/api/routing.html +0 -628
  23. package/docs/api/signals.html +0 -683
  24. package/docs/api/storage.html +0 -820
  25. package/docs/assets/api_components.md.BlFwj17l.js +0 -571
  26. package/docs/assets/api_components.md.BlFwj17l.lean.js +0 -1
  27. package/docs/assets/api_effects.md.Br_yStBS.js +0 -763
  28. package/docs/assets/api_effects.md.Br_yStBS.lean.js +0 -1
  29. package/docs/assets/api_fetch.md.DQLBJSoq.js +0 -849
  30. package/docs/assets/api_fetch.md.DQLBJSoq.lean.js +0 -1
  31. package/docs/assets/api_pages.md.BP19nHXw.js +0 -381
  32. package/docs/assets/api_pages.md.BP19nHXw.lean.js +0 -1
  33. package/docs/assets/api_quick.md.BDS3ttnt.js +0 -193
  34. package/docs/assets/api_quick.md.BDS3ttnt.lean.js +0 -1
  35. package/docs/assets/api_routing.md.7SNAZXtp.js +0 -604
  36. package/docs/assets/api_routing.md.7SNAZXtp.lean.js +0 -1
  37. package/docs/assets/api_signals.md.CrW68-BA.js +0 -659
  38. package/docs/assets/api_signals.md.CrW68-BA.lean.js +0 -1
  39. package/docs/assets/api_storage.md.COEWBXHk.js +0 -796
  40. package/docs/assets/api_storage.md.COEWBXHk.lean.js +0 -1
  41. package/docs/assets/app.DtmzNmNl.js +0 -1
  42. package/docs/assets/chunks/framework.C8AWLET_.js +0 -19
  43. package/docs/assets/chunks/theme.yfWKMLQM.js +0 -1
  44. package/docs/assets/guide_getting-started.md.BeQpK3vd.js +0 -172
  45. package/docs/assets/guide_getting-started.md.BeQpK3vd.lean.js +0 -1
  46. package/docs/assets/guide_why.md.DXchYMN-.js +0 -23
  47. package/docs/assets/guide_why.md.DXchYMN-.lean.js +0 -1
  48. package/docs/assets/index.md.uvMJmU4o.js +0 -1
  49. package/docs/assets/index.md.uvMJmU4o.lean.js +0 -1
  50. package/docs/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
  51. package/docs/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
  52. package/docs/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
  53. package/docs/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
  54. package/docs/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
  55. package/docs/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
  56. package/docs/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
  57. package/docs/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
  58. package/docs/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
  59. package/docs/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
  60. package/docs/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
  61. package/docs/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
  62. package/docs/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
  63. package/docs/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
  64. package/docs/assets/style.DJRheFKp.css +0 -1
  65. package/docs/assets/ui_intro.md.gZ21GFqo.js +0 -1
  66. package/docs/assets/ui_intro.md.gZ21GFqo.lean.js +0 -1
  67. package/docs/assets/vite_plugin.md.gDWEi8f0.js +0 -225
  68. package/docs/assets/vite_plugin.md.gDWEi8f0.lean.js +0 -1
  69. package/docs/guide/getting-started.html +0 -196
  70. package/docs/guide/why.html +0 -47
  71. package/docs/hashmap.json +0 -1
  72. package/docs/index.html +0 -25
  73. package/docs/logo.svg +0 -118
  74. package/docs/ui/intro.html +0 -25
  75. package/docs/vite/plugin.html +0 -249
  76. package/docs/vp-icons.css +0 -1
  77. package/index.js +0 -3
  78. package/packages/docs/.vitepress/cache/deps/@theme_index.js +0 -275
  79. package/packages/docs/.vitepress/cache/deps/@theme_index.js.map +0 -7
  80. package/packages/docs/.vitepress/cache/deps/_metadata.json +0 -40
  81. package/packages/docs/.vitepress/cache/deps/chunk-3S55Y3P7.js +0 -12951
  82. package/packages/docs/.vitepress/cache/deps/chunk-3S55Y3P7.js.map +0 -7
  83. package/packages/docs/.vitepress/cache/deps/chunk-RLEUDPPB.js +0 -9719
  84. package/packages/docs/.vitepress/cache/deps/chunk-RLEUDPPB.js.map +0 -7
  85. package/packages/docs/.vitepress/cache/deps/package.json +0 -3
  86. package/packages/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +0 -4505
  87. package/packages/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +0 -7
  88. package/packages/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +0 -583
  89. package/packages/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +0 -7
  90. package/packages/docs/.vitepress/cache/deps/vue.js +0 -347
  91. package/packages/docs/.vitepress/cache/deps/vue.js.map +0 -7
  92. package/packages/docs/.vitepress/config.js +0 -68
  93. package/packages/docs/api/components.md +0 -760
  94. package/packages/docs/api/effects.md +0 -1039
  95. package/packages/docs/api/fetch.md +0 -998
  96. package/packages/docs/api/pages.md +0 -497
  97. package/packages/docs/api/quick.md +0 -436
  98. package/packages/docs/api/routing.md +0 -784
  99. package/packages/docs/api/signals.md +0 -899
  100. package/packages/docs/api/storage.md +0 -952
  101. package/packages/docs/guide/getting-started.md +0 -308
  102. package/packages/docs/guide/why.md +0 -135
  103. package/packages/docs/index.md +0 -84
  104. package/packages/docs/logo.svg +0 -118
  105. package/packages/docs/public/logo.svg +0 -118
  106. package/packages/docs/ui/intro.md +0 -16
  107. package/packages/docs/vite/plugin.md +0 -423
  108. package/packages/sigpro/plugin.js +0 -91
  109. package/packages/sigpro/plugin.min.js +0 -1
  110. package/packages/sigpro/sigpro.js +0 -631
  111. package/packages/sigpro/sigpro.min.js +0 -1
  112. package/vite.config.js +0 -24
@@ -1,497 +0,0 @@
1
- # Pages API 📄
2
-
3
- Pages in SigPro are special components designed for route-based navigation with **automatic cleanup**. When you navigate away from a page, all signals, effects, and event listeners created within that page are automatically cleaned up - no memory leaks, no manual cleanup needed.
4
-
5
- ## `$.page(setupFunction)`
6
-
7
- Creates a page with automatic cleanup of all signals and effects when navigated away.
8
-
9
- ```javascript
10
- import { $, html } from 'sigpro';
11
-
12
- export default $.page(() => {
13
- // All signals and effects created here
14
- // will be automatically cleaned up on navigation
15
- const count = $(0);
16
-
17
- $.effect(() => {
18
- console.log(`Count: ${count()}`);
19
- });
20
-
21
- return html`
22
- <div>
23
- <h1>My Page</h1>
24
- <p>Count: ${count}</p>
25
- <button @click=${() => count(c => c + 1)}>+</button>
26
- </div>
27
- `;
28
- });
29
- ```
30
-
31
- ## 📋 API Reference
32
-
33
- | Parameter | Type | Description |
34
- |-----------|------|-------------|
35
- | `setupFunction` | `Function` | Function that returns the page content. Receives context object with `params` and `onUnmount` |
36
-
37
- ### Context Object Properties
38
-
39
- | Property | Type | Description |
40
- |----------|------|-------------|
41
- | `params` | `Object` | Route parameters passed to the page |
42
- | `onUnmount` | `Function` | Register cleanup callbacks (alternative to automatic cleanup) |
43
-
44
- ## 🎯 Basic Usage
45
-
46
- ### Simple Page
47
-
48
- ```javascript
49
- // pages/home.js
50
- import { $, html } from 'sigpro';
51
-
52
- export default $.page(() => {
53
- const title = $('Welcome to SigPro');
54
-
55
- return html`
56
- <div class="home-page">
57
- <h1>${title}</h1>
58
- <p>This page will clean itself up when you navigate away.</p>
59
- </div>
60
- `;
61
- });
62
- ```
63
-
64
- ### Page with Route Parameters
65
-
66
- ```javascript
67
- // pages/user.js
68
- import { $, html } from 'sigpro';
69
-
70
- export default $.page(({ params }) => {
71
- // Access route parameters
72
- const userId = params.id;
73
- const userData = $(null);
74
- const loading = $(false);
75
-
76
- // Auto-cleaned effect
77
- $.effect(() => {
78
- loading(true);
79
- $.fetch(`/api/users/${userId}`, null, loading)
80
- .then(data => userData(data));
81
- });
82
-
83
- return html`
84
- <div>
85
- ${() => loading() ? html`
86
- <div class="spinner">Loading...</div>
87
- ` : html`
88
- <h1>User Profile: ${userData()?.name}</h1>
89
- <p>Email: ${userData()?.email}</p>
90
- `}
91
- </div>
92
- `;
93
- });
94
- ```
95
-
96
- ## 🧹 Automatic Cleanup
97
-
98
- The magic of `$.page` is automatic cleanup. Everything created inside the page is tracked and cleaned up:
99
-
100
- ```javascript
101
- export default $.page(() => {
102
- // ✅ Signals are auto-cleaned
103
- const count = $(0);
104
- const user = $(null);
105
-
106
- // ✅ Effects are auto-cleaned
107
- $.effect(() => {
108
- document.title = `Count: ${count()}`;
109
- });
110
-
111
- // ✅ Event listeners are auto-cleaned
112
- window.addEventListener('resize', handleResize);
113
-
114
- // ✅ Intervals and timeouts are auto-cleaned
115
- const interval = setInterval(() => {
116
- refreshData();
117
- }, 5000);
118
-
119
- return html`<div>Page content</div>`;
120
- });
121
- // When navigating away: all signals, effects, listeners, intervals STOP
122
- ```
123
-
124
- ## 📝 Manual Cleanup with `onUnmount`
125
-
126
- Sometimes you need custom cleanup logic. Use `onUnmount` for that:
127
-
128
- ```javascript
129
- export default $.page(({ onUnmount }) => {
130
- // WebSocket connection
131
- const socket = new WebSocket('wss://api.example.com');
132
-
133
- socket.onmessage = (event) => {
134
- updateData(JSON.parse(event.data));
135
- };
136
-
137
- // Manual cleanup
138
- onUnmount(() => {
139
- socket.close();
140
- console.log('WebSocket closed');
141
- });
142
-
143
- return html`<div>Real-time updates</div>`;
144
- });
145
- ```
146
-
147
- ## 🔄 Integration with Router
148
-
149
- Pages are designed to work seamlessly with `$.router`:
150
-
151
- ```javascript
152
- import { $, html } from 'sigpro';
153
- import HomePage from './pages/Home.js';
154
- import UserPage from './pages/User.js';
155
- import SettingsPage from './pages/Settings.js';
156
-
157
- const routes = [
158
- { path: '/', component: HomePage },
159
- { path: '/user/:id', component: UserPage },
160
- { path: '/settings', component: SettingsPage },
161
- ];
162
-
163
- // Mount router
164
- document.body.appendChild($.router(routes));
165
- ```
166
-
167
- ## 💡 Practical Examples
168
-
169
- ### Example 1: Data Fetching Page
170
-
171
- ```javascript
172
- // pages/posts.js
173
- export default $.page(({ params }) => {
174
- const posts = $([]);
175
- const loading = $(true);
176
- const error = $(null);
177
-
178
- $.effect(() => {
179
- fetch('/api/posts')
180
- .then(res => res.json())
181
- .then(data => {
182
- posts(data);
183
- loading(false);
184
- })
185
- .catch(err => {
186
- error(err.message);
187
- loading(false);
188
- });
189
- });
190
-
191
- return html`
192
- <div class="posts-page">
193
- <h1>Blog Posts</h1>
194
-
195
- ${() => loading() ? html`
196
- <div class="loading">Loading posts...</div>
197
- ` : error() ? html`
198
- <div class="error">Error: ${error()}</div>
199
- ` : html`
200
- <div class="posts-grid">
201
- ${posts().map(post => html`
202
- <article class="post-card">
203
- <h2>${post.title}</h2>
204
- <p>${post.excerpt}</p>
205
- <a href="#/post/${post.id}">Read more</a>
206
- </article>
207
- `)}
208
- </div>
209
- `}
210
- </div>
211
- `;
212
- });
213
- ```
214
-
215
- ### Example 2: Real-time Dashboard
216
-
217
- ```javascript
218
- // pages/dashboard.js
219
- export default $.page(({ onUnmount }) => {
220
- const metrics = $({
221
- cpu: 0,
222
- memory: 0,
223
- requests: 0
224
- });
225
-
226
- // Auto-refresh data
227
- const refreshInterval = setInterval(async () => {
228
- const data = await $.fetch('/api/metrics');
229
- if (data) metrics(data);
230
- }, 5000);
231
-
232
- // Manual cleanup for interval
233
- onUnmount(() => clearInterval(refreshInterval));
234
-
235
- // Live clock
236
- const currentTime = $(new Date());
237
- const clockInterval = setInterval(() => {
238
- currentTime(new Date());
239
- }, 1000);
240
-
241
- onUnmount(() => clearInterval(clockInterval));
242
-
243
- return html`
244
- <div class="dashboard">
245
- <h1>System Dashboard</h1>
246
-
247
- <div class="time">
248
- Last updated: ${() => currentTime().toLocaleTimeString()}
249
- </div>
250
-
251
- <div class="metrics-grid">
252
- <div class="metric-card">
253
- <h3>CPU Usage</h3>
254
- <p class="metric-value">${() => metrics().cpu}%</p>
255
- </div>
256
- <div class="metric-card">
257
- <h3>Memory Usage</h3>
258
- <p class="metric-value">${() => metrics().memory}%</p>
259
- </div>
260
- <div class="metric-card">
261
- <h3>Requests/min</h3>
262
- <p class="metric-value">${() => metrics().requests}</p>
263
- </div>
264
- </div>
265
- </div>
266
- `;
267
- });
268
- ```
269
-
270
- ### Example 3: Multi-step Form
271
-
272
- ```javascript
273
- // pages/checkout.js
274
- export default $.page(({ onUnmount }) => {
275
- const step = $(1);
276
- const formData = $({
277
- email: '',
278
- address: '',
279
- payment: ''
280
- });
281
-
282
- // Warn user before leaving
283
- const handleBeforeUnload = (e) => {
284
- if (step() < 3) {
285
- e.preventDefault();
286
- e.returnValue = '';
287
- }
288
- };
289
-
290
- window.addEventListener('beforeunload', handleBeforeUnload);
291
- onUnmount(() => {
292
- window.removeEventListener('beforeunload', handleBeforeUnload);
293
- });
294
-
295
- const nextStep = () => step(s => Math.min(s + 1, 3));
296
- const prevStep = () => step(s => Math.max(s - 1, 1));
297
-
298
- return html`
299
- <div class="checkout">
300
- <h1>Checkout - Step ${step} of 3</h1>
301
-
302
- ${() => {
303
- switch(step()) {
304
- case 1:
305
- return html`
306
- <div class="step">
307
- <h2>Email</h2>
308
- <input
309
- type="email"
310
- :value=${() => formData().email}
311
- @input=${(e) => formData({...formData(), email: e.target.value})}
312
- />
313
- </div>
314
- `;
315
- case 2:
316
- return html`
317
- <div class="step">
318
- <h2>Address</h2>
319
- <textarea
320
- :value=${() => formData().address}
321
- @input=${(e) => formData({...formData(), address: e.target.value})}
322
- ></textarea>
323
- </div>
324
- `;
325
- case 3:
326
- return html`
327
- <div class="step">
328
- <h2>Payment</h2>
329
- <input
330
- type="text"
331
- placeholder="Card number"
332
- :value=${() => formData().payment}
333
- @input=${(e) => formData({...formData(), payment: e.target.value})}
334
- />
335
- </div>
336
- `;
337
- }
338
- }}
339
-
340
- <div class="buttons">
341
- ${() => step() > 1 ? html`
342
- <button @click=${prevStep}>Previous</button>
343
- ` : ''}
344
-
345
- ${() => step() < 3 ? html`
346
- <button @click=${nextStep}>Next</button>
347
- ` : html`
348
- <button @click=${submitOrder}>Place Order</button>
349
- `}
350
- </div>
351
- </div>
352
- `;
353
- });
354
- ```
355
-
356
- ### Example 4: Page with Tabs
357
-
358
- ```javascript
359
- // pages/profile.js
360
- export default $.page(({ params }) => {
361
- const activeTab = $('overview');
362
- const userData = $(null);
363
-
364
- // Load user data
365
- $.effect(() => {
366
- $.fetch(`/api/users/${params.id}`)
367
- .then(data => userData(data));
368
- });
369
-
370
- const tabs = {
371
- overview: () => html`
372
- <div>
373
- <h3>Overview</h3>
374
- <p>Username: ${userData()?.username}</p>
375
- <p>Member since: ${userData()?.joined}</p>
376
- </div>
377
- `,
378
- posts: () => html`
379
- <div>
380
- <h3>Posts</h3>
381
- ${userData()?.posts.map(post => html`
382
- <div class="post">${post.title}</div>
383
- `)}
384
- </div>
385
- `,
386
- settings: () => html`
387
- <div>
388
- <h3>Settings</h3>
389
- <label>
390
- <input type="checkbox" :checked=${userData()?.emailNotifications} />
391
- Email notifications
392
- </label>
393
- </div>
394
- `
395
- };
396
-
397
- return html`
398
- <div class="profile-page">
399
- <h1>${() => userData()?.name}</h1>
400
-
401
- <div class="tabs">
402
- ${Object.keys(tabs).map(tab => html`
403
- <button
404
- class:active=${() => activeTab() === tab}
405
- @click=${() => activeTab(tab)}
406
- >
407
- ${tab.charAt(0).toUpperCase() + tab.slice(1)}
408
- </button>
409
- `)}
410
- </div>
411
-
412
- <div class="tab-content">
413
- ${() => tabs[activeTab()]()}
414
- </div>
415
- </div>
416
- `;
417
- });
418
- ```
419
-
420
- ## 🎯 Advanced Patterns
421
-
422
- ### Page with Nested Routes
423
-
424
- ```javascript
425
- // pages/settings/index.js
426
- export default $.page(({ params }) => {
427
- const section = params.section || 'general';
428
-
429
- const sections = {
430
- general: () => import('./general.js').then(m => m.default),
431
- security: () => import('./security.js').then(m => m.default),
432
- notifications: () => import('./notifications.js').then(m => m.default)
433
- };
434
-
435
- const currentSection = $(null);
436
-
437
- $.effect(() => {
438
- sections[section]().then(comp => currentSection(comp));
439
- });
440
-
441
- return html`
442
- <div class="settings">
443
- <nav>
444
- <a href="#/settings/general">General</a>
445
- <a href="#/settings/security">Security</a>
446
- <a href="#/settings/notifications">Notifications</a>
447
- </nav>
448
-
449
- <div class="content">
450
- ${currentSection}
451
- </div>
452
- </div>
453
- `;
454
- });
455
- ```
456
-
457
- ### Page with Authentication
458
-
459
- ```javascript
460
- // pages/dashboard.js
461
- export default $.page(({ onUnmount }) => {
462
- const isAuthenticated = $(false);
463
- const authCheck = $.effect(() => {
464
- const token = localStorage.getItem('token');
465
- isAuthenticated(!!token);
466
- });
467
-
468
- // Redirect if not authenticated
469
- $.effect(() => {
470
- if (!isAuthenticated()) {
471
- $.router.go('/login');
472
- }
473
- });
474
-
475
- return html`
476
- <div class="dashboard">
477
- <h1>Protected Dashboard</h1>
478
- <!-- Protected content -->
479
- </div>
480
- `;
481
- });
482
- ```
483
-
484
- ## 📊 Summary
485
-
486
- | Feature | Description |
487
- |---------|-------------|
488
- | **Automatic Cleanup** | All signals, effects, and resources auto-cleaned on navigation |
489
- | **Memory Safe** | No memory leaks, even with complex nested effects |
490
- | **Router Integration** | Designed to work perfectly with `$.router` |
491
- | **Parameters** | Access route parameters via `params` object |
492
- | **Manual Cleanup** | `onUnmount` for custom cleanup needs |
493
- | **Zero Configuration** | Just wrap your page in `$.page()` and it works |
494
-
495
- ---
496
-
497
- > **Pro Tip:** Always wrap route-based views in `$.page()` to ensure proper cleanup. This prevents memory leaks and ensures your app stays performant even after many navigation changes.