@vicaniddouglas/js_aide 1.11.0 → 1.13.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/README.md +69 -3
- package/declarations.d.ts +28 -1
- package/demo/index.html +1243 -0
- package/demo/main.js +368 -0
- package/demo/style.css +541 -0
- package/dist/js_aide.cjs.js +337 -314
- package/dist/js_aide.cjs.js.map +4 -4
- package/dist/js_aide.esm.js +337 -314
- package/dist/js_aide.esm.js.map +4 -4
- package/dist/js_aide.min.js +337 -314
- package/dist/js_aide.min.js.map +4 -4
- package/package.json +4 -2
package/demo/index.html
ADDED
|
@@ -0,0 +1,1243 @@
|
|
|
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>JS Aide | Official Documentation</title>
|
|
7
|
+
<link rel="stylesheet" href="style.css">
|
|
8
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
9
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
10
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<div class="app-container">
|
|
14
|
+
<!-- Sidebar -->
|
|
15
|
+
<aside class="sidebar">
|
|
16
|
+
<div class="sidebar-header">
|
|
17
|
+
<div class="brand-group">
|
|
18
|
+
<div class="logo">JS Aide</div>
|
|
19
|
+
<span class="version">v1.12.0</span>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="sidebar-divider"></div>
|
|
23
|
+
|
|
24
|
+
<nav class="sidebar-nav">
|
|
25
|
+
<!-- Group 1: Basics -->
|
|
26
|
+
<div class="nav-group">
|
|
27
|
+
<a href="#about" class="nav-item active" data-view="about">
|
|
28
|
+
<span class="icon" id="icon-about"></span> About
|
|
29
|
+
</a>
|
|
30
|
+
<a href="#features" class="nav-item" data-view="features">
|
|
31
|
+
<span class="icon" id="icon-features"></span> Features
|
|
32
|
+
</a>
|
|
33
|
+
<a href="#demo" class="nav-item" data-view="demo">
|
|
34
|
+
<span class="icon" id="icon-demo"></span> Interactive Demo
|
|
35
|
+
</a>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<!-- Group 2: Documentation Modules -->
|
|
39
|
+
<div class="nav-group">
|
|
40
|
+
<div class="nav-group-header">Documentation <span class="arrow">▾</span></div>
|
|
41
|
+
<div class="nav-group-content">
|
|
42
|
+
<a href="#docs-requests" class="sub-nav-item" data-view="docs-requests">HTTP Requests</a>
|
|
43
|
+
<a href="#docs-websockets" class="sub-nav-item" data-view="docs-websockets">WebSockets</a>
|
|
44
|
+
<a href="#docs-dates" class="sub-nav-item" data-view="docs-dates">Dates & Timing</a>
|
|
45
|
+
<a href="#docs-router" class="sub-nav-item" data-view="docs-router">Router & Navigation</a>
|
|
46
|
+
<a href="#docs-observers" class="sub-nav-item" data-view="docs-observers">Intersection Observers</a>
|
|
47
|
+
<a href="#docs-validation" class="sub-nav-item" data-view="docs-validation">Validations</a>
|
|
48
|
+
<a href="#docs-files" class="sub-nav-item" data-view="docs-files">Files & Exports</a>
|
|
49
|
+
<a href="#docs-icons" class="sub-nav-item" data-view="docs-icons">Icons Library</a>
|
|
50
|
+
<a href="#docs-figures" class="sub-nav-item" data-view="docs-figures">Figures (Formatting)</a>
|
|
51
|
+
<a href="#docs-media" class="sub-nav-item" data-view="docs-media">Media (Camera)</a>
|
|
52
|
+
<a href="#docs-loaders" class="sub-nav-item" data-view="docs-loaders">View Loaders</a>
|
|
53
|
+
<a href="#docs-popups" class="sub-nav-item" data-view="docs-popups">Popups (Alerts)</a>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</nav>
|
|
57
|
+
|
|
58
|
+
<div class="sidebar-footer">
|
|
59
|
+
<p>Professional web application development.</p>
|
|
60
|
+
</div>
|
|
61
|
+
</aside>
|
|
62
|
+
|
|
63
|
+
<!-- Main Content -->
|
|
64
|
+
<div class="main-wrapper">
|
|
65
|
+
<div id="top-loading-bar" class="loading-bar"></div>
|
|
66
|
+
<header class="main-header">
|
|
67
|
+
<div class="breadcrumb">Package / <span id="current-view-title">About</span></div>
|
|
68
|
+
<div class="header-actions">
|
|
69
|
+
<a href="https://gitlab.com/vicaniddouglas/js_aide" target="_blank" class="github-link">GitLab</a>
|
|
70
|
+
</div>
|
|
71
|
+
</header>
|
|
72
|
+
|
|
73
|
+
<main class="content-area">
|
|
74
|
+
<!-- VIEW: ABOUT -->
|
|
75
|
+
<section id="view-about" class="content-view active">
|
|
76
|
+
<h1>Comprehensive Utilities for Modern Web Applications</h1>
|
|
77
|
+
<p class="lead">JS Aide is a high-performance utility library designed for both <strong>Single-Page (SPA)</strong> and <strong>Multi-Page (MPA)</strong> architectures. While it offers a localized router for SPAs, its core modules—from HTTP and WebSockets to DOM handling and Validation—bring enterprise-grade stability to any web project.</p>
|
|
78
|
+
|
|
79
|
+
<div class="grid">
|
|
80
|
+
<div class="info-card">
|
|
81
|
+
<div class="info-icon" id="info-icon-light"></div>
|
|
82
|
+
<h3>Vanilla JS & Zero Dependencies</h3>
|
|
83
|
+
<p>Written in pure <strong>Vanilla JavaScript</strong> using standard browser APIs. Whether you're using React, Vue, or a traditional Django/Laravel MPA, JS Aide integrates with zero friction.</p>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="info-card">
|
|
86
|
+
<div class="info-icon" id="info-icon-modular"></div>
|
|
87
|
+
<h3>Enterprise-Ready</h3>
|
|
88
|
+
<p>Standardized network responses, strict TypeScript declarations, and robust error handling ensure consistency across large development teams.</p>
|
|
89
|
+
</div>
|
|
90
|
+
<div class="info-card">
|
|
91
|
+
<div class="info-icon" id="info-icon-proactive"></div>
|
|
92
|
+
<h3>Proactive Intelligence</h3>
|
|
93
|
+
<p>Automate UI feedback with "Proactive Logic"—interceptors that handle loading states, auto-error popups, and sequential async flows automatically.</p>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</section>
|
|
97
|
+
|
|
98
|
+
<!-- VIEW: FEATURES -->
|
|
99
|
+
<section id="view-features" class="content-view">
|
|
100
|
+
<h1>Core Modules</h1>
|
|
101
|
+
<p class="lead">Explore the modular building blocks of JS Aide. Click each module to dive into its specific capabilities.</p>
|
|
102
|
+
|
|
103
|
+
<div class="accordion-container">
|
|
104
|
+
<!-- HTTP -->
|
|
105
|
+
<div class="accordion-item active">
|
|
106
|
+
<div class="accordion-header">
|
|
107
|
+
<div class="brand-info">
|
|
108
|
+
<div class="info-icon" id="feat-icon-http"></div>
|
|
109
|
+
<div class="header-text">
|
|
110
|
+
<h3>Standardized HTTP</h3>
|
|
111
|
+
<span class="badge badge-popular">Popular</span>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
<span class="accordion-arrow">▾</span>
|
|
115
|
+
</div>
|
|
116
|
+
<div class="accordion-content">
|
|
117
|
+
<p>Automated request queueing, proactive error handling, and standardized response objects for every API call. It implements the "Always Resolve" pattern, removing the need for nested try-catch blocks in your frontend logic.</p>
|
|
118
|
+
<ul class="spec-list">
|
|
119
|
+
<li>Sequential Async Middleware</li>
|
|
120
|
+
<li>Global Interceptors</li>
|
|
121
|
+
<li>Priority Queue Tuning</li>
|
|
122
|
+
</ul>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<!-- WebSockets -->
|
|
127
|
+
<div class="accordion-item">
|
|
128
|
+
<div class="accordion-header">
|
|
129
|
+
<div class="brand-info">
|
|
130
|
+
<div class="info-icon" id="feat-icon-ws"></div>
|
|
131
|
+
<div class="header-text">
|
|
132
|
+
<h3>WebSocket Client</h3>
|
|
133
|
+
<span class="badge badge-core">Core</span>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
<span class="accordion-arrow">▸</span>
|
|
137
|
+
</div>
|
|
138
|
+
<div class="accordion-content">
|
|
139
|
+
<p>A full-featured real-time engine built for scale. Supports multiple namespaces, private/public rooms, and robust connection management with automated heartbeats.</p>
|
|
140
|
+
<ul class="spec-list">
|
|
141
|
+
<li>Automatic Reconnection</li>
|
|
142
|
+
<li>Event Buffering (Offline Support)</li>
|
|
143
|
+
<li>Binary Data Handling</li>
|
|
144
|
+
</ul>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<!-- Validations -->
|
|
149
|
+
<div class="accordion-item">
|
|
150
|
+
<div class="accordion-header">
|
|
151
|
+
<div class="brand-info">
|
|
152
|
+
<div class="info-icon" id="feat-icon-val"></div>
|
|
153
|
+
<div class="header-text">
|
|
154
|
+
<h3>Smart Validations</h3>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
<span class="accordion-arrow">▸</span>
|
|
158
|
+
</div>
|
|
159
|
+
<div class="accordion-content">
|
|
160
|
+
<p>Advanced field validation for dynamic forms. Includes specialized logic for name uniqueness, phone number parsing, and mandatory field enforcement with custom error hooks.</p>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
|
|
164
|
+
<!-- Observers -->
|
|
165
|
+
<div class="accordion-item">
|
|
166
|
+
<div class="accordion-header">
|
|
167
|
+
<div class="brand-info">
|
|
168
|
+
<div class="info-icon" id="feat-icon-obs"></div>
|
|
169
|
+
<div class="header-text">
|
|
170
|
+
<h3>DOM Observers</h3>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
<span class="accordion-arrow">▸</span>
|
|
174
|
+
</div>
|
|
175
|
+
<div class="accordion-content">
|
|
176
|
+
<p>Intelligent element watchers that track visibility, size changes, and lifecycle events using high-performance Intersection and Resize APIs.</p>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
|
|
180
|
+
<!-- Popups -->
|
|
181
|
+
<div class="accordion-item">
|
|
182
|
+
<div class="accordion-header">
|
|
183
|
+
<div class="brand-info">
|
|
184
|
+
<div class="info-icon" id="feat-icon-pop"></div>
|
|
185
|
+
<div class="header-text">
|
|
186
|
+
<h3>Async Popups</h3>
|
|
187
|
+
<span class="badge badge-new">New</span>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
<span class="accordion-arrow">▸</span>
|
|
191
|
+
</div>
|
|
192
|
+
<div class="accordion-content">
|
|
193
|
+
<p>Professional, blocking feedback system with full ARIA accessibility. Supports custom icons, duration timers, and "blocking" async flows that wait for user confirmation.</p>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</section>
|
|
198
|
+
|
|
199
|
+
<!-- VIEW: DEMO -->
|
|
200
|
+
<section id="view-demo" class="content-view">
|
|
201
|
+
<h1>Interactive Engine Playground</h1>
|
|
202
|
+
<p>Fine-tune the library's proactive logic before executing requests. See how <strong>JS Aide</strong> adapts to different network conditions.</p>
|
|
203
|
+
|
|
204
|
+
<!-- Configuration Panel -->
|
|
205
|
+
<div class="demo-card config-panel">
|
|
206
|
+
<div class="panel-header">
|
|
207
|
+
<span class="icon" id="icon-config"></span>
|
|
208
|
+
<h3>Engine Configuration</h3>
|
|
209
|
+
</div>
|
|
210
|
+
<div class="config-grid">
|
|
211
|
+
<div class="input-group">
|
|
212
|
+
<label for="cfg-retries">Retry Count</label>
|
|
213
|
+
<input type="number" id="cfg-retries" value="3" min="0" max="10">
|
|
214
|
+
<small>Attempts before failing</small>
|
|
215
|
+
</div>
|
|
216
|
+
<div class="input-group">
|
|
217
|
+
<label for="cfg-delay">Retry Delay (ms)</label>
|
|
218
|
+
<input type="number" id="cfg-delay" value="1000" step="500">
|
|
219
|
+
<small>Wait time between retries</small>
|
|
220
|
+
</div>
|
|
221
|
+
<div class="input-group">
|
|
222
|
+
<label for="cfg-latency">Mock Latency (ms)</label>
|
|
223
|
+
<input type="number" id="cfg-latency" value="1200" step="100">
|
|
224
|
+
<small>Simulated server response time</small>
|
|
225
|
+
</div>
|
|
226
|
+
<div class="input-group toggle-group">
|
|
227
|
+
<label for="cfg-silent">Silent Mode</label>
|
|
228
|
+
<input type="checkbox" id="cfg-silent">
|
|
229
|
+
<small>Suppress all UI feedback</small>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
<div class="demo-grid">
|
|
235
|
+
<div class="demo-card">
|
|
236
|
+
<h3>Sequential Success Flow</h3>
|
|
237
|
+
<p>Loading → Success Callback → <strong>Blocking Popup</strong> → Complete.</p>
|
|
238
|
+
<div class="demo-actions">
|
|
239
|
+
<button id="btn-success" class="btn-primary">Execute Request</button>
|
|
240
|
+
<span id="log-success" class="status-pill status-idle">Ready</span>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
|
|
244
|
+
<div class="demo-card">
|
|
245
|
+
<h3>Automatic Error Handling</h3>
|
|
246
|
+
<p>Simulates a 500 error. Watch how the library manages your configured retries before showing the alert.</p>
|
|
247
|
+
<div class="demo-actions">
|
|
248
|
+
<button id="btn-error" class="btn-danger">Force Error</button>
|
|
249
|
+
<span id="log-error" class="status-pill status-idle">Ready</span>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<!-- Priority Queuing -->
|
|
254
|
+
<div class="demo-card">
|
|
255
|
+
<h3>Priority Request Queueing</h3>
|
|
256
|
+
<p>Send multiple requests at once with different priorities. The engine will process the <strong>High Priority</strong> items first.</p>
|
|
257
|
+
<div class="demo-actions" style="gap: 12px;">
|
|
258
|
+
<button id="btn-queue-low" class="btn-secondary">Add Low Priority</button>
|
|
259
|
+
<button id="btn-queue-high" class="btn-primary">Add High Priority</button>
|
|
260
|
+
<div id="queue-display" class="queue-monitor">
|
|
261
|
+
<span class="active-count">Active: 0</span>
|
|
262
|
+
<span class="pending-count">Pending: 0</span>
|
|
263
|
+
</div>
|
|
264
|
+
</div>
|
|
265
|
+
<div id="queue-log" class="queue-log-area"></div>
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
<!-- Smart Inputs Demo -->
|
|
269
|
+
<div class="demo-card">
|
|
270
|
+
<div class="panel-header">
|
|
271
|
+
<span class="icon" id="icon-smart"></span>
|
|
272
|
+
<h3>Smart Component Showcase</h3>
|
|
273
|
+
</div>
|
|
274
|
+
<p>Below are <strong>SmartInput</strong> components generated dynamically by the library. They handle their own state, validation, and formatting.</p>
|
|
275
|
+
<div id="smart-input-showcase" class="smart-showcase-grid"></div>
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
<!-- Popup Sandbox -->
|
|
279
|
+
<div class="demo-card" style="grid-column: span 2;">
|
|
280
|
+
<div class="panel-header">
|
|
281
|
+
<span class="icon" id="icon-popup-sandbox"></span>
|
|
282
|
+
<h3>Asynchronous Popup Sandbox</h3>
|
|
283
|
+
</div>
|
|
284
|
+
<p>Configure and trigger a live modal to test the asynchronous response logic. Choose a message and an input type to see how the library handles the handshake.</p>
|
|
285
|
+
|
|
286
|
+
<div class="playground-config" style="margin: 20px 0; padding: 24px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 12px;">
|
|
287
|
+
<div class="input-group" style="margin-bottom: 20px;">
|
|
288
|
+
<label style="display: block; margin-bottom: 8px; font-weight: 700; color: #1e293b;">Question / Message</label>
|
|
289
|
+
<input type="text" id="playground-message" value="How much is the investment?" style="width: 100%; padding: 12px 16px; border: 1px solid #cbd5e1; border-radius: 8px; font-size: 0.95rem;">
|
|
290
|
+
</div>
|
|
291
|
+
|
|
292
|
+
<div style="margin-bottom: 24px;">
|
|
293
|
+
<label style="display: block; margin-bottom: 12px; font-weight: 700; color: #1e293b;">Select Action & Input Type</label>
|
|
294
|
+
<div style="display: flex; gap: 16px; flex-wrap: wrap;">
|
|
295
|
+
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.9rem; color: #475569;">
|
|
296
|
+
<input type="radio" name="playground-type" value="text" checked> Text
|
|
297
|
+
</label>
|
|
298
|
+
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.9rem; color: #475569;">
|
|
299
|
+
<input type="radio" name="playground-type" value="number"> Number
|
|
300
|
+
</label>
|
|
301
|
+
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.9rem; color: #475569;">
|
|
302
|
+
<input type="radio" name="playground-type" value="currency"> Currency Comma
|
|
303
|
+
</label>
|
|
304
|
+
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.9rem; color: #475569;">
|
|
305
|
+
<input type="radio" name="playground-type" value="password"> Password
|
|
306
|
+
</label>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
<div class="demo-actions">
|
|
311
|
+
<button id="btn-run-prompt" class="btn-primary" style="flex: 1;">Run Dynamic Prompt</button>
|
|
312
|
+
<button id="btn-run-confirm" class="btn-secondary" style="flex: 1;">Run Confirm Check</button>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
<div id="popup-playground-result" style="padding: 12px 16px; background: #0f172a; border-radius: 8px; color: #38bdf8; font-family: 'Fira Code', monospace; font-size: 0.85rem; border-left: 4px solid #7c3aed;">
|
|
317
|
+
» Log: Awaiting interaction...
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
</section>
|
|
322
|
+
|
|
323
|
+
<!-- VIEW: DOCS - HTTP REQUESTS -->
|
|
324
|
+
<section id="view-docs-requests" class="content-view">
|
|
325
|
+
<div class="docs-header">
|
|
326
|
+
<span class="badge badge-popular">Popular</span>
|
|
327
|
+
<h1>Standardized HTTP Engine</h1>
|
|
328
|
+
<p class="lead">Universal network client featuring automated request queueing, proactive error handling, and multi-pattern usage for both modern and legacy architectures.</p>
|
|
329
|
+
</div>
|
|
330
|
+
|
|
331
|
+
<!-- Usage Patterns -->
|
|
332
|
+
<div class="docs-section">
|
|
333
|
+
<h3>1. Modern Async/Await</h3>
|
|
334
|
+
<p>The standard way to use <code>sendRequest</code> in modern JS apps. By default, it returns a <strong>Standardized Response Object</strong>.</p>
|
|
335
|
+
<div class="code-block">
|
|
336
|
+
<pre><code><span class="token-keyword">import</span> { sendRequest } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
337
|
+
|
|
338
|
+
<span class="token-keyword">const</span> <span class="token-function">fetchProfile</span> = <span class="token-keyword">async</span> () => {
|
|
339
|
+
<span class="token-keyword">const</span> result = <span class="token-keyword">await</span> <span class="token-function">sendRequest</span>({ endpoint: <span class="token-string">'/profile'</span> });
|
|
340
|
+
|
|
341
|
+
<span class="token-keyword">if</span> (result.status) {
|
|
342
|
+
<span class="token-comment">// result.data is the raw backend payload</span>
|
|
343
|
+
console.<span class="token-function">log</span>(result.data);
|
|
344
|
+
}
|
|
345
|
+
};</code></pre>
|
|
346
|
+
</div>
|
|
347
|
+
</div>
|
|
348
|
+
|
|
349
|
+
<div class="docs-section">
|
|
350
|
+
<h3>2. Callback Hooks (Proactive)</h3>
|
|
351
|
+
<p>Use <code>onSuccess</code> and <code>onError</code> hooks to trigger reactive UI logic directly within the request configuration.</p>
|
|
352
|
+
<div class="code-block">
|
|
353
|
+
<pre><code><span class="token-function">sendRequest</span>({
|
|
354
|
+
endpoint: <span class="token-string">'/auth/login'</span>,
|
|
355
|
+
payload: { user, pass },
|
|
356
|
+
<span class="token-function">onSuccess</span>: <span class="token-keyword">async</span> (data) => {
|
|
357
|
+
<span class="token-comment">// Blocks execution until user clicks OK on popup</span>
|
|
358
|
+
<span class="token-keyword">await</span> popup.<span class="token-function">success</span>(<span class="token-string">"Login successful!"</span>);
|
|
359
|
+
window.location.<span class="token-function">replace</span>(<span class="token-string">'/nexus'</span>);
|
|
360
|
+
},
|
|
361
|
+
<span class="token-function">onError</span>: (errMsg) => {
|
|
362
|
+
<span class="token-comment">// Custom logging logic for analytics</span>
|
|
363
|
+
analytics.<span class="token-function">logError</span>(errMsg);
|
|
364
|
+
}
|
|
365
|
+
});</code></pre>
|
|
366
|
+
</div>
|
|
367
|
+
</div>
|
|
368
|
+
|
|
369
|
+
<div class="docs-section">
|
|
370
|
+
<h3>3. Chained Sequential Requests</h3>
|
|
371
|
+
<p>Perfect for scenarios where one request depends on the result of another (e.g., getting a user ID to fetch their posts).</p>
|
|
372
|
+
<div class="code-block">
|
|
373
|
+
<pre><code><span class="token-keyword">const</span> result = <span class="token-keyword">await</span> <span class="token-function">sendRequest</span>({ endpoint: <span class="token-string">'/get-session'</span> });
|
|
374
|
+
|
|
375
|
+
<span class="token-keyword">if</span> (result.status) {
|
|
376
|
+
<span class="token-comment">// Pass data from first request to the second</span>
|
|
377
|
+
<span class="token-keyword">const</span> posts = <span class="token-keyword">await</span> <span class="token-function">sendRequest</span>({
|
|
378
|
+
endpoint: <span class="token-string">'/posts'</span>,
|
|
379
|
+
payload: { userId: result.data.id }
|
|
380
|
+
});
|
|
381
|
+
console.<span class="token-function">log</span>(posts.data);
|
|
382
|
+
}</code></pre>
|
|
383
|
+
</div>
|
|
384
|
+
</div>
|
|
385
|
+
|
|
386
|
+
<div class="docs-section">
|
|
387
|
+
<h3>4. Legacy Promise Chaining</h3>
|
|
388
|
+
<p>If you prefer a <code>.then()/.catch()</code> style or aren't using an <code>async</code> context, <code>sendRequest</code> holds full support.</p>
|
|
389
|
+
<div class="code-block">
|
|
390
|
+
<pre><code><span class="token-function">sendRequest</span>({ endpoint: <span class="token-string">'/status'</span> })
|
|
391
|
+
.<span class="token-function">then</span>(result => {
|
|
392
|
+
<span class="token-keyword">if</span> (result.status) {
|
|
393
|
+
console.<span class="token-function">log</span>(<span class="token-string">"Server Healthy"</span>);
|
|
394
|
+
}
|
|
395
|
+
})
|
|
396
|
+
.<span class="token-function">catch</span>(err => {
|
|
397
|
+
<span class="token-comment">// Used for critical engine crashes (rare)</span>
|
|
398
|
+
console.<span class="token-function">error</span>(err);
|
|
399
|
+
});</code></pre>
|
|
400
|
+
</div>
|
|
401
|
+
</div>
|
|
402
|
+
|
|
403
|
+
<!-- Configuration -->
|
|
404
|
+
<div class="docs-section">
|
|
405
|
+
<h3>5. Global Configuration & Key Mapping</h3>
|
|
406
|
+
<p>Configure the library at the entry point of your application. The <code>keys</code> configuration allows you to tell the engine exactly where to look for session data without hardcoding dependencies.</p>
|
|
407
|
+
<div class="code-block">
|
|
408
|
+
<pre><code><span class="token-keyword">import</span> { initRequestHandler } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
409
|
+
|
|
410
|
+
<span class="token-function">initRequestHandler</span>({
|
|
411
|
+
apiUrl: <span class="token-string">'https://api.myapp.com'</span>,
|
|
412
|
+
keys: {
|
|
413
|
+
<span class="token-comment">// 1. Looks for window.APP_CONFIG.apiUrl to override defaults</span>
|
|
414
|
+
globalConfig: <span class="token-string">'APP_CONFIG'</span>,
|
|
415
|
+
|
|
416
|
+
<span class="token-comment">// 2. Checks localStorage/sessionStorage['token'] for Bearer auth</span>
|
|
417
|
+
authToken: <span class="token-string">'token'</span>,
|
|
418
|
+
|
|
419
|
+
<span class="token-comment">// 3. Looks for <meta name="csrf-token"> contents</span>
|
|
420
|
+
csrfToken: <span class="token-string">'csrf-token'</span>,
|
|
421
|
+
|
|
422
|
+
<span class="token-comment">// 4. Searches document.cookie for 'XSRF-TOKEN' as fallback</span>
|
|
423
|
+
csrfCookie: <span class="token-string">'XSRF-TOKEN'</span>
|
|
424
|
+
}
|
|
425
|
+
});</code></pre>
|
|
426
|
+
</div>
|
|
427
|
+
</div>
|
|
428
|
+
|
|
429
|
+
<!-- Interceptors -->
|
|
430
|
+
<div class="docs-section">
|
|
431
|
+
<h3>6. Network Interceptors</h3>
|
|
432
|
+
<p>Interceptors allow you to transform requests/responses globally. Use them for logging, adding dynamic security headers, or handling global redirects.</p>
|
|
433
|
+
<div class="code-block">
|
|
434
|
+
<pre><code><span class="token-keyword">import</span> { interceptors } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
435
|
+
|
|
436
|
+
<span class="token-comment">// Outgoing Request: Add a unique correlation ID before send</span>
|
|
437
|
+
interceptors.<span class="token-function">request</span>((config) => {
|
|
438
|
+
config.headers[<span class="token-string">'X-App-Version'</span>] = <span class="token-string">'2.4.0'</span>;
|
|
439
|
+
<span class="token-keyword">return</span> config;
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
<span class="token-comment">// Incoming Response: Process or sanitize every successful result</span>
|
|
443
|
+
interceptors.<span class="token-function">response</span>((response) => {
|
|
444
|
+
<span class="token-keyword">if</span> (response.status === <span class="token-number">200</span>) {
|
|
445
|
+
console.<span class="token-function">log</span>(<span class="token-string">"System: Healthy"</span>);
|
|
446
|
+
}
|
|
447
|
+
<span class="token-keyword">return</span> response;
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
<span class="token-comment">// Global Error: Handle unauthorized status globally</span>
|
|
451
|
+
interceptors.<span class="token-function">error</span>((error) => {
|
|
452
|
+
<span class="token-keyword">if</span> (error.status === <span class="token-number">401</span>) {
|
|
453
|
+
<span class="token-comment">// Automated logout or session expiration logic</span>
|
|
454
|
+
window.location.<span class="token-function">replace</span>(<span class="token-string">'/logout'</span>);
|
|
455
|
+
}
|
|
456
|
+
});</code></pre>
|
|
457
|
+
</div>
|
|
458
|
+
</div>
|
|
459
|
+
</section>
|
|
460
|
+
|
|
461
|
+
<!-- VIEW: DOCS - WEBSOCKETS -->
|
|
462
|
+
<section id="view-docs-websockets" class="content-view">
|
|
463
|
+
<div class="docs-header">
|
|
464
|
+
<span class="badge badge-core">Core</span>
|
|
465
|
+
<h1>Real-Time Engine (WebSockets)</h1>
|
|
466
|
+
<p class="lead">A highly scalable, multi-protocol WebSocket client designed for massive real-time applications. Features built-in support for namespaces, private rooms, and automated presence tracking.</p>
|
|
467
|
+
</div>
|
|
468
|
+
|
|
469
|
+
<!-- 1. Initialization -->
|
|
470
|
+
<div class="docs-section">
|
|
471
|
+
<h3>1. Initialization & Handshake</h3>
|
|
472
|
+
<p>Establish a persistent connection with automated authentication. The engine automatically pulls the Bearer token from your global HTTP configuration.</p>
|
|
473
|
+
<div class="code-block">
|
|
474
|
+
<pre><code><span class="token-keyword">import</span> { WebSocketClient } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
475
|
+
|
|
476
|
+
<span class="token-comment">// Connect to the gateway with rich configuration</span>
|
|
477
|
+
<span class="token-keyword">const</span> socket = <span class="token-keyword">new</span> <span class="token-class">WebSocketClient</span>(<span class="token-string">'wss://api.myapp.com/gateway'</span>, {
|
|
478
|
+
autoConnect: <span class="token-boolean">true</span>, <span class="token-comment">// Start connection immediately</span>
|
|
479
|
+
reconnectInterval: <span class="token-number">5000</span>, <span class="token-comment">// Wait 5s before trying to reconnect</span>
|
|
480
|
+
maxReconnectAttempts: <span class="token-number">10</span>, <span class="token-comment">// Total attempts before giving up</span>
|
|
481
|
+
heartbeat: <span class="token-boolean">true</span>, <span class="token-comment">// Send "ping" packets regularly</span>
|
|
482
|
+
heartbeatInterval: <span class="token-number">30000</span>, <span class="token-comment">// Ping every 30 seconds</span>
|
|
483
|
+
timeout: <span class="token-number">5000</span> <span class="token-comment">// Default timeout for Acknowledged messages</span>
|
|
484
|
+
});</code></pre>
|
|
485
|
+
</div>
|
|
486
|
+
</div>
|
|
487
|
+
|
|
488
|
+
<!-- 2. Namespaces & Rooms -->
|
|
489
|
+
<div class="docs-section">
|
|
490
|
+
<h3>2. Namespaces & Dynamic Rooms</h3>
|
|
491
|
+
<p>Partition your logic into namespaces (e.g., /chat, /notifications) and manage group-based communication using rooms.</p>
|
|
492
|
+
<div class="code-block">
|
|
493
|
+
<pre><code><span class="token-comment">// Create a dedicated namespace</span>
|
|
494
|
+
<span class="token-keyword">const</span> chat = socket.<span class="token-function">namespace</span>(<span class="token-string">'/chat'</span>);
|
|
495
|
+
|
|
496
|
+
<span class="token-comment">// Join a private room (e.g., specific user or group)</span>
|
|
497
|
+
chat.<span class="token-function">join</span>(<span class="token-string">'lobby-101'</span>);
|
|
498
|
+
|
|
499
|
+
<span class="token-comment">// Leave a room gracefully</span>
|
|
500
|
+
chat.<span class="token-function">leave</span>(<span class="token-string">'lobby-101'</span>);</code></pre>
|
|
501
|
+
</div>
|
|
502
|
+
</div>
|
|
503
|
+
|
|
504
|
+
<!-- 3. Lifecycle & Error Handling -->
|
|
505
|
+
<div class="docs-section">
|
|
506
|
+
<h3>3. Lifecycle & Event Listeners</h3>
|
|
507
|
+
<p>Monitor connection health using standardized events. We recommend using the internal <strong>ConnectionEvent</strong> enum to avoid common string typos.</p>
|
|
508
|
+
<div class="code-block">
|
|
509
|
+
<pre><code><span class="token-keyword">import</span> { ConnectionEvent } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
510
|
+
|
|
511
|
+
<span class="token-comment">// Listen for global connection changes</span>
|
|
512
|
+
socket.<span class="token-function">on</span>(ConnectionEvent.CONNECTED, () => {
|
|
513
|
+
console.<span class="token-function">log</span>(<span class="token-string">"System: Online"</span>);
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
<span class="token-comment">// Listen for raw incoming data</span>
|
|
517
|
+
socket.<span class="token-function">on</span>(<span class="token-string">'message'</span>, (raw) => {
|
|
518
|
+
console.<span class="token-function">log</span>(<span class="token-string">"Raw Traffic:"</span>, raw);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
<span class="token-comment">// Permanent cleanup (Unsubscribes and closes)</span>
|
|
522
|
+
socket.<span class="token-function">destroy</span>();</code></pre>
|
|
523
|
+
</div>
|
|
524
|
+
</div>
|
|
525
|
+
|
|
526
|
+
<!-- 4. Defensive Programming with Enums -->
|
|
527
|
+
<div class="docs-section">
|
|
528
|
+
<h3>4. Defensive Programming (Enums)</h3>
|
|
529
|
+
<p>JS Aide exports internal constants for every message type and priority. Using these ensures your code is robust and IDE-friendly.</p>
|
|
530
|
+
<div class="code-block">
|
|
531
|
+
<pre><code><span class="token-keyword">import</span> { Type, Priority } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
532
|
+
|
|
533
|
+
<span class="token-comment">// Use Enums instead of raw strings</span>
|
|
534
|
+
socket.<span class="token-function">send</span>({
|
|
535
|
+
event: Type.MESSAGE,
|
|
536
|
+
priority: Priority.HIGH,
|
|
537
|
+
data: { text: <span class="token-string">"Urgent Alert"</span> }
|
|
538
|
+
});</code></pre>
|
|
539
|
+
</div>
|
|
540
|
+
</div>
|
|
541
|
+
|
|
542
|
+
<!-- 5. Advanced: Targeted Message Handlers -->
|
|
543
|
+
<div class="docs-section">
|
|
544
|
+
<h3>5. Targeted Message Handlers</h3>
|
|
545
|
+
<p>Instead of a global listener, you can attach handlers for specific "event" names. This keeps your message-routing logic clean and modular.</p>
|
|
546
|
+
<div class="code-block">
|
|
547
|
+
<pre><code><span class="token-comment">// Only fires when { event: 'chat_msg' } is received</span>
|
|
548
|
+
socket.<span class="token-function">onMessage</span>(<span class="token-string">'chat_msg'</span>, (data) => {
|
|
549
|
+
console.<span class="token-function">log</span>(<span class="token-string">"New Message:"</span>, data.text);
|
|
550
|
+
});</code></pre>
|
|
551
|
+
</div>
|
|
552
|
+
</div>
|
|
553
|
+
|
|
554
|
+
<!-- 6. Reliable Messaging -->
|
|
555
|
+
<div class="docs-section">
|
|
556
|
+
<h3>6. The sendWithAck Backend Contract</h3>
|
|
557
|
+
<p>When using <code>sendWithAck</code>, the client attaches a unique <strong>id</strong>. The server <strong>must</strong> respond with a specific acknowledgement packet for the promise to resolve.</p>
|
|
558
|
+
<div class="code-block">
|
|
559
|
+
<pre><code><span class="token-comment">// --- CLIENT-SIDE ---</span>
|
|
560
|
+
<span class="token-keyword">const</span> ack = <span class="token-keyword">await</span> socket.<span class="token-function">sendWithAck</span>(<span class="token-string">'save'</span>, { name: <span class="token-string">'Douglas'</span> });
|
|
561
|
+
|
|
562
|
+
<span class="token-comment">// --- SERVER-SIDE RESPONSE CONTRACT ---</span>
|
|
563
|
+
<span class="token-comment">// The backend MUST return this exact structure:</span>
|
|
564
|
+
<span class="token-comment">// { </span>
|
|
565
|
+
<span class="token-comment">// "event": "ack", </span>
|
|
566
|
+
<span class="token-comment">// "id": "SAME_ID_FROM_CLIENT", </span>
|
|
567
|
+
<span class="token-comment">// "success": true, </span>
|
|
568
|
+
<span class="token-comment">// "result": { "stored": true } </span>
|
|
569
|
+
<span class="token-comment">// }</span></code></pre>
|
|
570
|
+
</div>
|
|
571
|
+
</div>
|
|
572
|
+
</section>
|
|
573
|
+
|
|
574
|
+
<!-- VIEW: DOCS - ROUTER -->
|
|
575
|
+
<section id="view-docs-router" class="content-view">
|
|
576
|
+
<div class="docs-header">
|
|
577
|
+
<span class="badge badge-feature">SPA</span>
|
|
578
|
+
<h1>Router & Navigation</h1>
|
|
579
|
+
<p class="lead">A professional History API router for large-scale Single-Page Applications (SPA). Features dynamic route matching, asynchronous guards, and automated link interception.</p>
|
|
580
|
+
</div>
|
|
581
|
+
|
|
582
|
+
<!-- 1. Initialization -->
|
|
583
|
+
<div class="docs-section">
|
|
584
|
+
<h3>1. Basic Configuration</h3>
|
|
585
|
+
<p>Initialize the router by mapping paths to DOM element IDs. The engine automatically manages the visibility of these elements based on the current URL.</p>
|
|
586
|
+
<div class="code-block">
|
|
587
|
+
<pre><code><span class="token-keyword">import</span> { Router } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
588
|
+
|
|
589
|
+
<span class="token-comment">// Define route mapping ( Path -> Element ID )</span>
|
|
590
|
+
<span class="token-keyword">const</span> routes = {
|
|
591
|
+
<span class="token-string">'/'</span>: <span class="token-string">'view-home'</span>,
|
|
592
|
+
<span class="token-string">'/profile'</span>: <span class="token-string">'view-profile'</span>,
|
|
593
|
+
<span class="token-string">'/settings'</span>: <span class="token-string">'view-settings'</span>
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
<span class="token-keyword">const</span> router = <span class="token-keyword">new</span> <span class="token-class">Router</span>(routes, <span class="token-string">'/'</span>);
|
|
597
|
+
|
|
598
|
+
<span class="token-comment">// Optional: Clear view content on leave for memory efficiency</span>
|
|
599
|
+
router.<span class="token-function">config</span>({ clearOnLeave: <span class="token-boolean">true</span> });</code></pre>
|
|
600
|
+
</div>
|
|
601
|
+
</div>
|
|
602
|
+
|
|
603
|
+
<!-- 2. Dynamic Routes -->
|
|
604
|
+
<div class="docs-section">
|
|
605
|
+
<h3>2. Dynamic Parameters</h3>
|
|
606
|
+
<p>Support for dynamic segments using the <code>:param</code> syntax. Extracted values are passed to navigation events and guards.</p>
|
|
607
|
+
<div class="code-block">
|
|
608
|
+
<pre><code><span class="token-comment">// Define a route with parameters</span>
|
|
609
|
+
<span class="token-keyword">const</span> routes = {
|
|
610
|
+
<span class="token-string">'/user/:id'</span>: <span class="token-string">'view-user-profile'</span>
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
<span class="token-comment">// Navigate programmatically</span>
|
|
614
|
+
router.<span class="token-function">navigate</span>(<span class="token-string">'/user/123'</span>);</code></pre>
|
|
615
|
+
</div>
|
|
616
|
+
</div>
|
|
617
|
+
|
|
618
|
+
<!-- 3. Navigation Guards -->
|
|
619
|
+
<div class="docs-section">
|
|
620
|
+
<h3>3. Lifecycle Guards (beforeNavigate)</h3>
|
|
621
|
+
<p>The <code>beforeNavigate</code> hook is an asynchronous gate that allows you to block navigation (auth checks) or redirect users globally.</p>
|
|
622
|
+
<div class="code-block">
|
|
623
|
+
<pre><code>router.beforeNavigate = <span class="token-keyword">async</span> (to, from) => {
|
|
624
|
+
<span class="token-keyword">if</span> (to === <span class="token-string">'/admin'</span> && !user.isAdmin) {
|
|
625
|
+
<span class="token-comment">// Block navigation and stay on the current page</span>
|
|
626
|
+
<span class="token-keyword">return</span> <span class="token-boolean">false</span>;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
<span class="token-keyword">if</span> (to === <span class="token-string">'/old-path'</span>) {
|
|
630
|
+
<span class="token-comment">// Perform a graceful redirect</span>
|
|
631
|
+
<span class="token-keyword">return</span> <span class="token-string">'/new-path'</span>;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
<span class="token-keyword">return</span> <span class="token-boolean">true</span>; <span class="token-comment">// Allow navigation</span>
|
|
635
|
+
};</code></pre>
|
|
636
|
+
</div>
|
|
637
|
+
</div>
|
|
638
|
+
|
|
639
|
+
<!-- 4. Interplay with AppLoader (Pro-Tip) -->
|
|
640
|
+
<div class="docs-section">
|
|
641
|
+
<h3>4. Pro-Tip: Sequential SPA Engine</h3>
|
|
642
|
+
<p>Combine the Router with <strong>AppLoader</strong> to build massive SPAs that only load what the user is looking at. Sync them via the global <code>navigated</code> event.</p>
|
|
643
|
+
<div class="code-block">
|
|
644
|
+
<pre><code>window.<span class="token-function">addEventListener</span>(<span class="token-string">'router:navigated'</span>, <span class="token-keyword">async</span> (e) => {
|
|
645
|
+
<span class="token-keyword">const</span> { pathname } = e.detail;
|
|
646
|
+
<span class="token-comment">// Trigger dynamic load when path changes</span>
|
|
647
|
+
<span class="token-keyword">await</span> loader.<span class="token-function">loadView</span>(pathname.<span class="token-function">replace</span>(<span class="token-string">'/'</span>, <span class="token-string">''</span>));
|
|
648
|
+
});</code></pre>
|
|
649
|
+
</div>
|
|
650
|
+
</div>
|
|
651
|
+
</section>
|
|
652
|
+
|
|
653
|
+
<!-- VIEW: DOCS - VIEW LOADERS -->
|
|
654
|
+
<section id="view-docs-loaders" class="content-view">
|
|
655
|
+
<div class="docs-header">
|
|
656
|
+
<span class="badge badge-modular">Modular</span>
|
|
657
|
+
<h1>View Loader (AppLoader)</h1>
|
|
658
|
+
<p class="lead">A professional resource loader that dynamically injects HTML, CSS, and JS modules. Designed for high-performance SPAs where memory management and lazy-loading are critical.</p>
|
|
659
|
+
</div>
|
|
660
|
+
|
|
661
|
+
<!-- 1. Initialization -->
|
|
662
|
+
<div class="docs-section">
|
|
663
|
+
<h3>1. Dynamic Resource Mapping</h3>
|
|
664
|
+
<p>Map your view names to external file paths. The loader will only fetch these files when you explicitly request them.</p>
|
|
665
|
+
<div class="code-block">
|
|
666
|
+
<pre><code><span class="token-keyword">import</span> { AppLoader } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
667
|
+
|
|
668
|
+
<span class="token-keyword">const</span> loader = <span class="token-keyword">new</span> <span class="token-class">AppLoader</span>({
|
|
669
|
+
home: {
|
|
670
|
+
html: <span class="token-string">'/views/home.html'</span>,
|
|
671
|
+
css: <span class="token-string">'/views/home.css'</span>,
|
|
672
|
+
js: <span class="token-string">'/views/home.js'</span>
|
|
673
|
+
},
|
|
674
|
+
profile: {
|
|
675
|
+
html: <span class="token-string">'/views/profile.html'</span>,
|
|
676
|
+
js: <span class="token-string">'/views/profile.js'</span> <span class="token-comment">// CSS is optional</span>
|
|
677
|
+
}
|
|
678
|
+
});</code></pre>
|
|
679
|
+
</div>
|
|
680
|
+
</div>
|
|
681
|
+
|
|
682
|
+
<!-- 2. View Lifecycle -->
|
|
683
|
+
<div class="docs-section">
|
|
684
|
+
<h3>2. Professional Lifecycle (init/cleanup)</h3>
|
|
685
|
+
<p>The loader looks for specifically exported functions in your JS modules to manage memory and event listeners gracefully.</p>
|
|
686
|
+
<div class="code-block">
|
|
687
|
+
<pre><code><span class="token-comment">// Example /views/profile.js</span>
|
|
688
|
+
<span class="token-keyword">export function</span> <span class="token-function">init</span>() {
|
|
689
|
+
console.<span class="token-function">log</span>(<span class="token-string">"Profile Initialized: Listeners added"</span>);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
<span class="token-keyword">export function</span> <span class="token-function">cleanup</span>() {
|
|
693
|
+
console.<span class="token-function">log</span>(<span class="token-string">"Profile Unloaded: Listeners removed"</span>);
|
|
694
|
+
}</code></pre>
|
|
695
|
+
</div>
|
|
696
|
+
</div>
|
|
697
|
+
|
|
698
|
+
<!-- 3. Interplay with Router -->
|
|
699
|
+
<div class="docs-section">
|
|
700
|
+
<h3>3. Interplay: Creating the SPA Bridge</h3>
|
|
701
|
+
<p>This is the standard pattern for building JS Aide SPAs. Use the Router to handle history, and the AppLoader to handle content.</p>
|
|
702
|
+
<div class="code-block">
|
|
703
|
+
<pre><code><span class="token-comment">// Global entry point</span>
|
|
704
|
+
<span class="token-keyword">const</span> router = <span class="token-keyword">new</span> <span class="token-class">Router</span>(routes);
|
|
705
|
+
<span class="token-keyword">const</span> loader = <span class="token-keyword">new</span> <span class="token-class">AppLoader</span>(viewConfigs);
|
|
706
|
+
|
|
707
|
+
<span class="token-comment">// The Bridge: Load view content when navigation occurs</span>
|
|
708
|
+
window.<span class="token-function">addEventListener</span>(<span class="token-string">'router:navigated'</span>, <span class="token-keyword">async</span> (e) => {
|
|
709
|
+
<span class="token-comment">// Load the HTML/JS for the new view</span>
|
|
710
|
+
<span class="token-keyword">await</span> loader.<span class="token-function">loadView</span>(e.detail.viewId);
|
|
711
|
+
});</code></pre>
|
|
712
|
+
</div>
|
|
713
|
+
</div>
|
|
714
|
+
</section>
|
|
715
|
+
|
|
716
|
+
<!-- VIEW: DOCS - DATES & TIMING -->
|
|
717
|
+
<section id="view-docs-dates" class="content-view">
|
|
718
|
+
<div class="docs-header">
|
|
719
|
+
<span class="badge badge-feature">Logic</span>
|
|
720
|
+
<h1>Dates & Timing</h1>
|
|
721
|
+
<p class="lead">A complete ecosystem for enterprise-grade date management. Built for strict validation, complex business math, and the native Intl humanization API.</p>
|
|
722
|
+
</div>
|
|
723
|
+
|
|
724
|
+
<!-- 1. Validation & State -->
|
|
725
|
+
<div class="docs-section">
|
|
726
|
+
<h3>1. Strict Validation & Analysis</h3>
|
|
727
|
+
<p>Before any processing, ensure your date strings are valid <code>YYYY-MM-DD</code> compliant. Check if dates reside in the past or future relative to the system clock.</p>
|
|
728
|
+
<div class="code-block">
|
|
729
|
+
<pre><code><span class="token-keyword">import</span> { validateDate, isFutureDate, isPastDate } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
730
|
+
|
|
731
|
+
<span class="token-comment">// Strict format check (YYYY-MM-DD)</span>
|
|
732
|
+
<span class="token-function">validateDate</span>(<span class="token-string">'2024-13-45'</span>); <span class="token-comment">// false</span>
|
|
733
|
+
|
|
734
|
+
<span class="token-comment">// Temporal checks</span>
|
|
735
|
+
<span class="token-function">isFutureDate</span>(<span class="token-string">'2030-01-01'</span>); <span class="token-comment">// true</span>
|
|
736
|
+
<span class="token-function">isPastDate</span>(<span class="token-string">'1990-12-31'</span>); <span class="token-comment">// true</span></code></pre>
|
|
737
|
+
</div>
|
|
738
|
+
</div>
|
|
739
|
+
|
|
740
|
+
<!-- 2. Formatting -->
|
|
741
|
+
<div class="docs-section">
|
|
742
|
+
<h3>2. Humanization (Relative & Precise)</h3>
|
|
743
|
+
<p>Convert ISO-like strings into meaningful text. Optimized for small-form factors and social-media style updates.</p>
|
|
744
|
+
<div class="code-block">
|
|
745
|
+
<pre><code><span class="token-keyword">import</span> { humanizeDate, getRelativeTime, timeAgo } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
746
|
+
|
|
747
|
+
<span class="token-comment">// Configurable formatting</span>
|
|
748
|
+
<span class="token-function">humanizeDate</span>(<span class="token-string">'2025-12-25'</span>, { format: <span class="token-string">'weekday'</span> }); <span class="token-comment">// "Thu, Dec 25, 2025"</span>
|
|
749
|
+
|
|
750
|
+
<span class="token-comment">// Semantic mapping</span>
|
|
751
|
+
<span class="token-function">getRelativeTime</span>(<span class="token-string">'2024-01-01'</span>); <span class="token-comment">// "2 days ago"</span>
|
|
752
|
+
<span class="token-function">timeAgo</span>(<span class="token-keyword">new</span> <span class="token-class">Date</span>()); <span class="token-comment">// "now"</span></code></pre>
|
|
753
|
+
</div>
|
|
754
|
+
</div>
|
|
755
|
+
|
|
756
|
+
<!-- 3. Precise Math -->
|
|
757
|
+
<div class="docs-section">
|
|
758
|
+
<h3>3. Date Math & Advanced Ranges</h3>
|
|
759
|
+
<p>Handle durations, specific offsets, and predefined dynamic windows (last week, next month, etc).</p>
|
|
760
|
+
<div class="code-block">
|
|
761
|
+
<pre><code><span class="token-keyword">import</span> { getEndDate, getDaysBetween, getDateRange, getFutureDateRange } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
762
|
+
|
|
763
|
+
<span class="token-comment">// Calculate precise distance</span>
|
|
764
|
+
<span class="token-function">getDaysBetween</span>(<span class="token-string">'2024-01-01'</span>, <span class="token-string">'2024-01-31'</span>, { inclusiveEndDate: <span class="token-boolean">true</span> }); <span class="token-comment">// 31</span>
|
|
765
|
+
|
|
766
|
+
<span class="token-comment">// Offset math (Duration)</span>
|
|
767
|
+
<span class="token-function">getEndDate</span>(<span class="token-string">'2024-01-15'</span>, <span class="token-number">1</span>, <span class="token-string">'months'</span>); <span class="token-comment">// "2024-02-15"</span>
|
|
768
|
+
|
|
769
|
+
<span class="token-comment">// Predefined windows (Historical vs Future)</span>
|
|
770
|
+
<span class="token-function">getDateRange</span>(<span class="token-string">'lastWeek'</span>); <span class="token-comment">// [from, to] (Historical)</span>
|
|
771
|
+
<span class="token-function">getFutureDateRange</span>(<span class="token-string">'nextYear'</span>); <span class="token-comment">// [from, to] (Future)</span></code></pre>
|
|
772
|
+
</div>
|
|
773
|
+
</div>
|
|
774
|
+
|
|
775
|
+
<!-- 4. Modern Shorthands -->
|
|
776
|
+
<div class="docs-section">
|
|
777
|
+
<h3>4. Navigation & Shortcuts</h3>
|
|
778
|
+
<p>Quick access to common temporal milestones without manual <code>new Date()</code> manipulation.</p>
|
|
779
|
+
<div class="code-block">
|
|
780
|
+
<pre><code><span class="token-keyword">import</span> { getCurrentDate, getDateYesterday, getDateTomorrow, getDateAgo } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
781
|
+
|
|
782
|
+
<span class="token-function">getCurrentDate</span>(); <span class="token-comment">// "2024-01-15" (Today)</span>
|
|
783
|
+
<span class="token-function">getDateYesterday</span>(); <span class="token-comment">// "2024-01-14"</span>
|
|
784
|
+
<span class="token-function">getDateTomorrow</span>(); <span class="token-comment">// "2024-01-16"</span>
|
|
785
|
+
|
|
786
|
+
<span class="token-comment">// Semantic offsets</span>
|
|
787
|
+
<span class="token-function">getDateAgo</span>(<span class="token-number">3</span>, <span class="token-string">'weeks'</span>); <span class="token-comment">// Date exactly 3 weeks ago</span></code></pre>
|
|
788
|
+
</div>
|
|
789
|
+
</div>
|
|
790
|
+
</section>
|
|
791
|
+
|
|
792
|
+
<!-- VIEW: DOCS - POPUPS -->
|
|
793
|
+
<section id="view-docs-popups" class="content-view">
|
|
794
|
+
<div class="docs-header">
|
|
795
|
+
<span class="badge badge-ui">UI</span>
|
|
796
|
+
<h1>Popups & Alerts</h1>
|
|
797
|
+
<p class="lead">An enterprise-grade modal system designed for high-end web applications. Features asynchronous logic, total thematic control, and deep accessibility (a11y) support.</p>
|
|
798
|
+
</div>
|
|
799
|
+
|
|
800
|
+
<!-- 1. Thematic Control -->
|
|
801
|
+
<div class="docs-section">
|
|
802
|
+
<h3>1. Custom Visual overrides</h3>
|
|
803
|
+
<p>While the library has gorgeous defaults, you can override the icon set and color palette to match your product's specific branding.</p>
|
|
804
|
+
<div class="code-block">
|
|
805
|
+
<pre><code><span class="token-keyword">import</span> { popup } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
806
|
+
|
|
807
|
+
<span class="token-keyword">await</span> popup.<span class="token-function">info</span>(<span class="token-string">'Syncing Database...'</span>, {
|
|
808
|
+
color: <span class="token-string">'#3b82f6'</span>, <span class="token-comment">// Pro-grade Custom HEX color</span>
|
|
809
|
+
icon: <span class="token-string">'<svg>...</svg>'</span>, <span class="token-comment">// Custom SVG injection</span>
|
|
810
|
+
duration: <span class="token-number">5000</span> <span class="token-comment">// Visible for 5 seconds</span>
|
|
811
|
+
});</code></pre>
|
|
812
|
+
</div>
|
|
813
|
+
</div>
|
|
814
|
+
|
|
815
|
+
<!-- 2. Logic & Persistence -->
|
|
816
|
+
<div class="docs-section">
|
|
817
|
+
<h3>2. Persistence & Blocking</h3>
|
|
818
|
+
<p>Control the modal's persistence and the ability for the user to dismiss it using the cross button or the overlay background.</p>
|
|
819
|
+
<div class="code-block">
|
|
820
|
+
<pre><code><span class="token-keyword">await</span> popup.<span class="token-function">error</span>(<span class="token-string">'Critical Error: Retrying...'</span>, {
|
|
821
|
+
persistent: <span class="token-boolean">true</span>, <span class="token-comment">// Stay until closed programmatically</span>
|
|
822
|
+
closable: <span class="token-boolean">false</span> <span class="token-comment">// Hide close button (Force attention)</span>
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
<span class="token-comment">// Dismiss the active popup programmatically later</span>
|
|
826
|
+
popup.<span class="token-function">close</span>();</code></pre>
|
|
827
|
+
</div>
|
|
828
|
+
</div>
|
|
829
|
+
|
|
830
|
+
<!-- 3. Lifecycle -->
|
|
831
|
+
<div class="docs-section">
|
|
832
|
+
<h3>3. Asynchronous Execution</h3>
|
|
833
|
+
<p>Every popup is a Promise. Use <code>await</code> to pause your application flow until the visual feedback is complete or dismissed.</p>
|
|
834
|
+
<div class="code-block">
|
|
835
|
+
<pre><code><span class="token-keyword">await</span> popup.<span class="token-function">success</span>(<span class="token-string">'Operation Complete'</span>);
|
|
836
|
+
window.location.<span class="token-function">reload</span>(); <span class="token-comment">// Wait for popup first!</span></code></pre>
|
|
837
|
+
</div>
|
|
838
|
+
</div>
|
|
839
|
+
|
|
840
|
+
<!-- 4. Async Confirm -->
|
|
841
|
+
<div class="docs-section">
|
|
842
|
+
<h3>4. Asynchronous Handshaking (Confirm Modal)</h3>
|
|
843
|
+
<p>Ditch the native <code>confirm()</code> for a professional, design-consistent modal. Returns a Promise that resolves to <code>true</code> or <code>false</code>.</p>
|
|
844
|
+
<div class="code-block">
|
|
845
|
+
<pre><code><span class="token-keyword">const</span> proceed = <span class="token-keyword">await</span> popup.<span class="token-function">confirm</span>(<span class="token-string">'Are you sure?'</span>);
|
|
846
|
+
<span class="token-keyword">if</span> (proceed) { <span class="token-comment">/* ... */</span> }</code></pre>
|
|
847
|
+
</div>
|
|
848
|
+
</div>
|
|
849
|
+
|
|
850
|
+
<!-- 5. Smart Prompts -->
|
|
851
|
+
<div class="docs-section">
|
|
852
|
+
<h3>5. Smart Data Prompts (Prompt Modal)</h3>
|
|
853
|
+
<p>Capture complex user input with real-time formatting. Supports <code>text</code>, <code>password</code>, <code>number</code>, and <code>currency</code> (auto-comma separation).</p>
|
|
854
|
+
<div class="code-block">
|
|
855
|
+
<pre><code><span class="token-keyword">import</span> { popup } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
856
|
+
|
|
857
|
+
<span class="token-comment">// 1. Capture Financial Data</span>
|
|
858
|
+
<span class="token-keyword">const</span> amount = <span class="token-keyword">await</span> popup.<span class="token-function">prompt</span>(<span class="token-string">'Enter Transfer Amount:'</span>, {
|
|
859
|
+
inputType: <span class="token-string">'currency'</span>,
|
|
860
|
+
placeholder: <span class="token-string">'0.00'</span>,
|
|
861
|
+
submitText: <span class="token-string">'Send'</span>
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
<span class="token-comment">// 2. Capture Private Keys</span>
|
|
865
|
+
<span class="token-keyword">const</span> pin = <span class="token-keyword">await</span> popup.<span class="token-function">prompt</span>(<span class="token-string">'Enter Security PIN:'</span>, {
|
|
866
|
+
inputType: <span class="token-string">'password'</span>,
|
|
867
|
+
placeholder: <span class="token-string">'****'</span>
|
|
868
|
+
});
|
|
869
|
+
|
|
870
|
+
<span class="token-keyword">if</span> (amount) console.<span class="token-function">log</span>(<span class="token-string">`Transferring: ${amount}`</span>);</code></pre>
|
|
871
|
+
</div>
|
|
872
|
+
</div>
|
|
873
|
+
|
|
874
|
+
</section>
|
|
875
|
+
|
|
876
|
+
<!-- VIEW: DOCS - OBSERVERS -->
|
|
877
|
+
<section id="view-docs-observers" class="content-view">
|
|
878
|
+
<div class="docs-header">
|
|
879
|
+
<span class="badge badge-ui">Visibility</span>
|
|
880
|
+
<h1>Intersection Watcher</h1>
|
|
881
|
+
<p class="lead">A high-performance wrapper for the Intersection Observer API. Features an intelligent <strong>Pooling System</strong> that groups watchers by configuration to reduce browser overhead.</p>
|
|
882
|
+
</div>
|
|
883
|
+
|
|
884
|
+
<!-- 1. Pooling Architecture -->
|
|
885
|
+
<div class="docs-section">
|
|
886
|
+
<h3>1. Intelligent Observer Pooling</h3>
|
|
887
|
+
<p>Unlike standard observers, JS Aide automatically groups watchers that share the same <code>root</code> and <code>rootMargin</code>. This keeps your application performant even with hundreds of active watchers.</p>
|
|
888
|
+
<div class="code-block">
|
|
889
|
+
<pre><code><span class="token-keyword">import</span> { watchElement, watchAll } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
890
|
+
|
|
891
|
+
<span class="token-comment">// Watch a single element</span>
|
|
892
|
+
<span class="token-keyword">const</span> cleanup = <span class="token-function">watchElement</span>(<span class="token-string">'#hero'</span>, {
|
|
893
|
+
onEnter: (el) => el.classList.<span class="token-function">add</span>(<span class="token-string">'fade-in'</span>),
|
|
894
|
+
threshold: <span class="token-number">0.5</span>, <span class="token-comment">// 50% visible</span>
|
|
895
|
+
triggerOnce: <span class="token-boolean">true</span> <span class="token-comment">// Auto-cleanup after first trigger</span>
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
<span class="token-comment">// Stop watching manually</span>
|
|
899
|
+
<span class="token-function">cleanup</span>();</code></pre>
|
|
900
|
+
</div>
|
|
901
|
+
</div>
|
|
902
|
+
|
|
903
|
+
<!-- 2. Utility API -->
|
|
904
|
+
<div class="docs-section">
|
|
905
|
+
<h3>2. Batch Watching (watchAll)</h3>
|
|
906
|
+
<p>Perfect for lazy-loading images or triggering animations across entire lists with a single call.</p>
|
|
907
|
+
<div class="code-block">
|
|
908
|
+
<pre><code><span class="token-comment">// Lazy load all images with 200px pre-trigger buffer</span>
|
|
909
|
+
<span class="token-function">watchAll</span>(<span class="token-string">'img.lazy'</span>, {
|
|
910
|
+
onEnter: (img) => { img.src = img.dataset.src; },
|
|
911
|
+
rootMargin: <span class="token-string">'200px'</span>,
|
|
912
|
+
triggerOnce: <span class="token-boolean">true</span>
|
|
913
|
+
});</code></pre>
|
|
914
|
+
</div>
|
|
915
|
+
</div>
|
|
916
|
+
|
|
917
|
+
<!-- 3. Infinite Scroll -->
|
|
918
|
+
<div class="docs-section">
|
|
919
|
+
<h3>3. Infinite Scroll Pattern</h3>
|
|
920
|
+
<p>Easily implement infinite scrolling by watching a "sentinel" element at the bottom of your feed.</p>
|
|
921
|
+
<div class="code-block">
|
|
922
|
+
<pre><code><span class="token-function">watchElement</span>(<span class="token-string">'#load-more-trigger'</span>, {
|
|
923
|
+
onEnter: <span class="token-keyword">async</span> () => {
|
|
924
|
+
<span class="token-keyword">await</span> <span class="token-function">loadNextPage</span>();
|
|
925
|
+
},
|
|
926
|
+
rootMargin: <span class="token-string">'400px'</span> <span class="token-comment">// Trigger 400px before reaching bottom</span>
|
|
927
|
+
});</code></pre>
|
|
928
|
+
</div>
|
|
929
|
+
</div>
|
|
930
|
+
</section>
|
|
931
|
+
|
|
932
|
+
<!-- VIEW: DOCS - VALIDATION -->
|
|
933
|
+
<section id="view-docs-validation" class="content-view">
|
|
934
|
+
<div class="docs-header">
|
|
935
|
+
<span class="badge badge-feature">Security</span>
|
|
936
|
+
<h1>Smart Validations</h1>
|
|
937
|
+
<p class="lead">A localized validation engine that handles everything from simple mandatory checks to complex phone number prefix validation and name sanitization.</p>
|
|
938
|
+
</div>
|
|
939
|
+
|
|
940
|
+
<!-- 1. Mandatory Fields -->
|
|
941
|
+
<div class="docs-section">
|
|
942
|
+
<h3>1. Automated UI Feedback</h3>
|
|
943
|
+
<p>The <code>validateMandatoryFields</code> utility automatically scans a set of fields, injects <strong>.error-border</strong> classes, and appends <strong><small class="error-message"></strong> elements to the DOM.</p>
|
|
944
|
+
<div class="code-block">
|
|
945
|
+
<pre><code><span class="token-keyword">import</span> { validateMandatoryFields } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
946
|
+
|
|
947
|
+
<span class="token-keyword">const</span> fields = document.<span class="token-function">querySelectorAll</span>(<span class="token-string">'.required-input'</span>);
|
|
948
|
+
<span class="token-keyword">if</span> (!<span class="token-function">validateMandatoryFields</span>(fields)) {
|
|
949
|
+
<span class="token-comment">// UI is already updated with error messages!</span>
|
|
950
|
+
<span class="token-keyword">return</span>;
|
|
951
|
+
}</code></pre>
|
|
952
|
+
</div>
|
|
953
|
+
</div>
|
|
954
|
+
|
|
955
|
+
<!-- 2. Localized Rules -->
|
|
956
|
+
<div class="docs-section">
|
|
957
|
+
<h3>2. Specialized Numeric Rules</h3>
|
|
958
|
+
<p>Built-in support for localized phone number validation, checking for specific carrier prefixes and strict digits-only formatting.</p>
|
|
959
|
+
<div class="code-block">
|
|
960
|
+
<pre><code><span class="token-keyword">import</span> { validatePhoneNumber } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
961
|
+
|
|
962
|
+
<span class="token-keyword">const</span> res = <span class="token-function">validatePhoneNumber</span>(<span class="token-string">'0772 123 456'</span>, { strict: <span class="token-boolean">false</span> });
|
|
963
|
+
|
|
964
|
+
<span class="token-comment">// { isValid: true, cleanedNumber: '0772123456', prefix: '077' }</span></code></pre>
|
|
965
|
+
</div>
|
|
966
|
+
</div>
|
|
967
|
+
|
|
968
|
+
<!-- 3. Sanitized Names -->
|
|
969
|
+
<div class="docs-section">
|
|
970
|
+
<h3>3. Name & Identity Sanitization</h3>
|
|
971
|
+
<p>Strict name validation that blocks non-alphabetical characters, prevents consecutive special chars, and returns a trimmed, sanitized string.</p>
|
|
972
|
+
<div class="code-block">
|
|
973
|
+
<pre><code><span class="token-keyword">import</span> { validateName } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
974
|
+
|
|
975
|
+
<span class="token-keyword">const</span> { isValid, cleanedName } = <span class="token-function">validateName</span>(<span class="token-string">' John--Doe '</span>);
|
|
976
|
+
<span class="token-comment">// isValid: false (Blocks consecutive hyphens)</span></code></pre>
|
|
977
|
+
</div>
|
|
978
|
+
</div>
|
|
979
|
+
</section>
|
|
980
|
+
|
|
981
|
+
<!-- VIEW: DOCS - ICONS -->
|
|
982
|
+
<section id="view-docs-icons" class="content-view">
|
|
983
|
+
<div class="docs-header">
|
|
984
|
+
<span class="badge badge-ui">Assets</span>
|
|
985
|
+
<h1>Internal Icon Library</h1>
|
|
986
|
+
<p class="lead">A curated collection of over 60+ high-fidelity SVG icons optimized for performance and ease of use. Every icon is built to inherit Styles from your CSS automatically.</p>
|
|
987
|
+
</div>
|
|
988
|
+
|
|
989
|
+
<!-- 1. Usage -->
|
|
990
|
+
<div class="docs-section">
|
|
991
|
+
<h3>1. Direct Injection & Coloring</h3>
|
|
992
|
+
<p>Icons are returned as raw SVG strings. Because they use <code>fill="currentColor"</code>, they will match the font color of their parent container automatically.</p>
|
|
993
|
+
<div class="code-block">
|
|
994
|
+
<pre><code><span class="token-keyword">import</span> { icons } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
995
|
+
|
|
996
|
+
<span class="token-comment">// Inject into any element</span>
|
|
997
|
+
document.<span class="token-function">getElementById</span>(<span class="token-string">'btn'</span>).innerHTML = icons.<span class="token-function">saveIcon</span>();
|
|
998
|
+
|
|
999
|
+
<span class="token-comment">// CSS Integration</span>
|
|
1000
|
+
<span class="token-selector">.btn-primary</span> { <span class="token-property">color</span>: <span class="token-string">#3b82f6</span>; }
|
|
1001
|
+
<span class="token-comment">/* The icon inside will automatically turn Blue! */</span></code></pre>
|
|
1002
|
+
</div>
|
|
1003
|
+
</div>
|
|
1004
|
+
|
|
1005
|
+
<!-- 2. Variants -->
|
|
1006
|
+
<div class="docs-section">
|
|
1007
|
+
<h3>2. Professional Variants</h3>
|
|
1008
|
+
<p>Most core icons come in multiple stylistic variants (Solid, Outline, or Specialized) to suit different UI contexts.</p>
|
|
1009
|
+
<div class="code-block">
|
|
1010
|
+
<pre><code><span class="token-function">homeIcon</span>(); <span class="token-comment">// Classic Outline</span>
|
|
1011
|
+
<span class="token-function">homeIcon2</span>(); <span class="token-comment">// Modern Flat</span>
|
|
1012
|
+
<span class="token-function">logoutIcon3</span>(); <span class="token-comment">// Specialized Action</span></code></pre>
|
|
1013
|
+
</div>
|
|
1014
|
+
</div>
|
|
1015
|
+
|
|
1016
|
+
<!-- 3. Specialized Categories -->
|
|
1017
|
+
<div class="docs-section">
|
|
1018
|
+
<h3>3. Domain-Specific Icons</h3>
|
|
1019
|
+
<p>Includes specialized assets for File Types (PDF, Excel, CSV), Commerce, Navigation, and Social interactions.</p>
|
|
1020
|
+
<div class="code-block">
|
|
1021
|
+
<pre><code><span class="token-function">pdfIcon</span>(); <span class="token-comment">// Document processing</span>
|
|
1022
|
+
<span class="token-function">graduateIcon</span>(); <span class="token-comment">// Educational tracking</span>
|
|
1023
|
+
<span class="token-function">heartsIcon3</span>(); <span class="token-comment">// Social interactions</span></code></pre>
|
|
1024
|
+
</div>
|
|
1025
|
+
</div>
|
|
1026
|
+
</section>
|
|
1027
|
+
|
|
1028
|
+
<!-- VIEW: DOCS - FIGURES -->
|
|
1029
|
+
<section id="view-docs-figures" class="content-view">
|
|
1030
|
+
<div class="docs-header">
|
|
1031
|
+
<span class="badge badge-feature">Logic</span>
|
|
1032
|
+
<h1>Figures & Formatting</h1>
|
|
1033
|
+
<p class="lead">A robust engine for number formatting, currency localization, and intelligent input synchronization. Built to handle the heavy lifting of financial and data-heavy UIs.</p>
|
|
1034
|
+
</div>
|
|
1035
|
+
|
|
1036
|
+
<!-- 1. Basic Formatting -->
|
|
1037
|
+
<div class="docs-section">
|
|
1038
|
+
<h3>1. Pro-Grade Formatting</h3>
|
|
1039
|
+
<p>Format raw numbers into localized currency, percentages, or abbreviated strings for dashboards.</p>
|
|
1040
|
+
<div class="code-block">
|
|
1041
|
+
<pre><code><span class="token-keyword">import</span> { formatCurrency, abbreviateNumber, formatPercentage } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
1042
|
+
|
|
1043
|
+
<span class="token-comment">// Currency (Defaults to UGX)</span>
|
|
1044
|
+
<span class="token-function">formatCurrency</span>(<span class="token-number">50000</span>); <span class="token-comment">// "UGX 50,000.00"</span>
|
|
1045
|
+
|
|
1046
|
+
<span class="token-comment">// Abbreviation for Dashboards</span>
|
|
1047
|
+
<span class="token-function">abbreviateNumber</span>(<span class="token-number">1250000</span>); <span class="token-comment">// "1.3M"</span>
|
|
1048
|
+
|
|
1049
|
+
<span class="token-comment">// Percentages</span>
|
|
1050
|
+
<span class="token-function">formatPercentage</span>(<span class="token-number">0.85</span>); <span class="token-comment">// "85.0%"</span></code></pre>
|
|
1051
|
+
</div>
|
|
1052
|
+
</div>
|
|
1053
|
+
|
|
1054
|
+
<!-- 2. Rounding Logic -->
|
|
1055
|
+
<div class="docs-section">
|
|
1056
|
+
<h3>2. Rounding & Precision</h3>
|
|
1057
|
+
<p>Support for custom increments and directional rounding (Floor, Ceil, NearestUpper).</p>
|
|
1058
|
+
<div class="code-block">
|
|
1059
|
+
<pre><code><span class="token-keyword">import</span> { roundToNearest } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
1060
|
+
|
|
1061
|
+
<span class="token-function">roundToNearest</span>(<span class="token-number">123.45</span>, <span class="token-number">10</span>); <span class="token-comment">// 120</span>
|
|
1062
|
+
<span class="token-function">roundToNearest</span>(<span class="token-number">123.45</span>, <span class="token-number">0.5</span>, <span class="token-string">'ceil'</span>); <span class="token-comment">// 123.5</span></code></pre>
|
|
1063
|
+
</div>
|
|
1064
|
+
</div>
|
|
1065
|
+
|
|
1066
|
+
<!-- 3. Advanced Input Sync -->
|
|
1067
|
+
<div class="docs-section">
|
|
1068
|
+
<h3>3. Advanced Input Synchronization</h3>
|
|
1069
|
+
<p>Transform standard inputs into smart formatting fields. Shows raw digits on focus for editing, and localized formatting on blur for display.</p>
|
|
1070
|
+
<div class="code-block">
|
|
1071
|
+
<pre><code><span class="token-keyword">import</span> { formatNumberInput, getNumericValue } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
1072
|
+
|
|
1073
|
+
<span class="token-keyword">const</span> input = document.<span class="token-function">querySelector</span>(<span class="token-string">'#salary'</span>);
|
|
1074
|
+
<span class="token-function">formatNumberInput</span>(input, {
|
|
1075
|
+
maxDecimalPlaces: <span class="token-number">2</span>,
|
|
1076
|
+
allowNegative: <span class="token-boolean">false</span>
|
|
1077
|
+
});
|
|
1078
|
+
|
|
1079
|
+
<span class="token-comment">// Get the real number, not the formatted string!</span>
|
|
1080
|
+
<span class="token-keyword">const</span> raw = <span class="token-function">getNumericValue</span>(input); <span class="token-comment">// 50000 (Number)</span></code></pre>
|
|
1081
|
+
</div>
|
|
1082
|
+
</div>
|
|
1083
|
+
</section>
|
|
1084
|
+
|
|
1085
|
+
<!-- VIEW: DOCS - MEDIA -->
|
|
1086
|
+
<section id="view-docs-media" class="content-view">
|
|
1087
|
+
<div class="docs-header">
|
|
1088
|
+
<span class="badge badge-feature">Hardware</span>
|
|
1089
|
+
<h1>Media & Camera</h1>
|
|
1090
|
+
<p class="lead">A Pro-grade camera integration system for the browser. Featuring real-time video streaming, intelligent cropping, and dual-camera support (Environment vs User).</p>
|
|
1091
|
+
</div>
|
|
1092
|
+
|
|
1093
|
+
<!-- 1. Basic Lifecycle -->
|
|
1094
|
+
<div class="docs-section">
|
|
1095
|
+
<h3>1. Camera Lifecycle</h3>
|
|
1096
|
+
<p>Initialize the <code>CameraModal</code> with either a preview container or a callback. The library handles all hardware permissions and stream cleanups automatically.</p>
|
|
1097
|
+
<div class="code-block">
|
|
1098
|
+
<pre><code><span class="token-keyword">import</span> { CameraModal } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
1099
|
+
|
|
1100
|
+
<span class="token-keyword">const</span> camera = <span class="token-keyword">new</span> <span class="token-class">CameraModal</span>({
|
|
1101
|
+
previewContainer: <span class="token-string">'#photo-preview'</span>, <span class="token-comment">// Auto-render capture</span>
|
|
1102
|
+
onPictureTaken: (base64) => {
|
|
1103
|
+
console.<span class="token-function">log</span>(<span class="token-string">'Captured:'</span>, base64); <span class="token-comment">// Raw Image Data</span>
|
|
1104
|
+
}
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1107
|
+
<span class="token-comment">// Open hardware-accelerated modal</span>
|
|
1108
|
+
camera.<span class="token-function">open</span>();</code></pre>
|
|
1109
|
+
</div>
|
|
1110
|
+
</div>
|
|
1111
|
+
|
|
1112
|
+
<!-- 2. Integrated Tooling -->
|
|
1113
|
+
<div class="docs-section">
|
|
1114
|
+
<h3>2. Advanced Capture Tools</h3>
|
|
1115
|
+
<p>The modal includes built-in tools for switching between Front/Back cameras and a high-fidelity 4-point draggable cropping utility.</p>
|
|
1116
|
+
<div class="code-block">
|
|
1117
|
+
<pre><code><span class="token-comment">// Programmatic Camera Toggling</span>
|
|
1118
|
+
camera.<span class="token-function">switchCamera</span>(); <span class="token-comment">// Toggles front/back stream</span>
|
|
1119
|
+
|
|
1120
|
+
<span class="token-comment">// Draggable Cropping (Internal Logic)</span>
|
|
1121
|
+
<span class="token-comment">// 1. Click "Crop" once image is captured.</span>
|
|
1122
|
+
<span class="token-comment">// 2. Drag the 4 corner points to select area.</span>
|
|
1123
|
+
<span class="token-comment">// 3. Library uses offscreen <canvas> for pixel-perfect results.</span></code></pre>
|
|
1124
|
+
</div>
|
|
1125
|
+
</div>
|
|
1126
|
+
|
|
1127
|
+
<!-- 3. Post-Processing -->
|
|
1128
|
+
<div class="docs-section">
|
|
1129
|
+
<h3>3. Upload & Processing</h3>
|
|
1130
|
+
<p>Captured images are returned as Base64. For server-side processing, convert them to Blobs or Files.</p>
|
|
1131
|
+
<div class="code-block">
|
|
1132
|
+
<pre><code><span class="token-keyword">const</span> camera = <span class="token-keyword">new</span> <span class="token-class">CameraModal</span>({
|
|
1133
|
+
onPictureTaken: <span class="token-keyword">async</span> (base64) => {
|
|
1134
|
+
<span class="token-comment">// Convert to binary Blob for FormData</span>
|
|
1135
|
+
<span class="token-keyword">const</span> blob = <span class="token-function">base64ToBlob</span>(base64);
|
|
1136
|
+
|
|
1137
|
+
<span class="token-keyword">const</span> form = <span class="token-keyword">new</span> <span class="token-class">FormData</span>();
|
|
1138
|
+
form.<span class="token-function">append</span>(<span class="token-string">'avatar'</span>, blob, <span class="token-string">'user.png'</span>);
|
|
1139
|
+
|
|
1140
|
+
<span class="token-keyword">await</span> <span class="token-function">sendRequest</span>({ endpoint: <span class="token-string">'/upload'</span>, payload: form });
|
|
1141
|
+
}
|
|
1142
|
+
});</code></pre>
|
|
1143
|
+
</div>
|
|
1144
|
+
</div>
|
|
1145
|
+
</section>
|
|
1146
|
+
<!-- VIEW: DOCS - FILES -->
|
|
1147
|
+
<section id="view-docs-files" class="content-view">
|
|
1148
|
+
<div class="docs-header">
|
|
1149
|
+
<span class="badge badge-feature">Data</span>
|
|
1150
|
+
<h1>Files & Handling</h1>
|
|
1151
|
+
<p class="lead">A complete subsystem for handling local files, generating professional reports, and managing high-performance uploads with real-time progress feedback.</p>
|
|
1152
|
+
</div>
|
|
1153
|
+
|
|
1154
|
+
<!-- 1. Secure Uploads -->
|
|
1155
|
+
<div class="docs-section">
|
|
1156
|
+
<h3>1. Pro-Grade File Uploads</h3>
|
|
1157
|
+
<p>Seamlessly handle single or multiple file uploads (Images, Excel, PDF) with built-in progress tracking and automatic <code>FormData</code> construction.</p>
|
|
1158
|
+
<div class="code-block">
|
|
1159
|
+
<pre><code><span class="token-keyword">import</span> { uploadFile, popup } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
1160
|
+
|
|
1161
|
+
<span class="token-keyword">const</span> result = <span class="token-keyword">await</span> <span class="token-function">uploadFile</span>({
|
|
1162
|
+
files: document.<span class="token-function">getElementById</span>(<span class="token-string">'input'</span>).files[<span class="token-number">0</span>],
|
|
1163
|
+
endpoint: <span class="token-string">'/upload/avatar'</span>,
|
|
1164
|
+
fieldName: <span class="token-string">'image'</span>,
|
|
1165
|
+
allowedTypes: [<span class="token-string">'image'</span>, <span class="token-string">'pdf'</span>],
|
|
1166
|
+
onProgress: (percent) => {
|
|
1167
|
+
<span class="token-function">updateProgressBar</span>(percent);
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
|
|
1171
|
+
<span class="token-keyword">if</span> (result.status) {
|
|
1172
|
+
<span class="token-keyword">await</span> popup.<span class="token-function">success</span>(<span class="token-string">'File stored on server!'</span>);
|
|
1173
|
+
}</code></pre>
|
|
1174
|
+
</div>
|
|
1175
|
+
</div>
|
|
1176
|
+
|
|
1177
|
+
<!-- 2. Zero-Latency Previews -->
|
|
1178
|
+
<div class="docs-section">
|
|
1179
|
+
<h3>2. Pro Pattern: Zero-Latency UI</h3>
|
|
1180
|
+
<p>Don't wait for the network. Show the user their file instantly using a local ObjectURL while the upload happens in the background.</p>
|
|
1181
|
+
<div class="code-block">
|
|
1182
|
+
<pre><code><span class="token-comment">// 1. Generate Instant Local Preview</span>
|
|
1183
|
+
<span class="token-keyword">const</span> localUrl = URL.<span class="token-function">createObjectURL</span>(selectedFile);
|
|
1184
|
+
document.<span class="token-function">getElementById</span>(<span class="token-string">'preview-img'</span>).src = localUrl;
|
|
1185
|
+
|
|
1186
|
+
<span class="token-comment">// 2. Start Uploader in background</span>
|
|
1187
|
+
<span class="token-function">uploadFile</span>({ files: selectedFile, ... });</code></pre>
|
|
1188
|
+
</div>
|
|
1189
|
+
</div>
|
|
1190
|
+
|
|
1191
|
+
<!-- 3. Camera Integration -->
|
|
1192
|
+
<div class="docs-section">
|
|
1193
|
+
<h3>3. Camera & Binary Handshaking</h3>
|
|
1194
|
+
<p>Upload results from the <code>CameraModal</code> crop utility directly to your server using <code>uploadDataUrl</code>.</p>
|
|
1195
|
+
<div class="code-block">
|
|
1196
|
+
<pre><code><span class="token-keyword">import</span> { CameraModal, uploadDataUrl } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
1197
|
+
|
|
1198
|
+
<span class="token-keyword">const</span> camera = <span class="token-keyword">new</span> <span class="token-class">CameraModal</span>({
|
|
1199
|
+
onPictureTaken: <span class="token-keyword">async</span> (base64) => {
|
|
1200
|
+
<span class="token-keyword">const</span> result = <span class="token-keyword">await</span> <span class="token-function">uploadDataUrl</span>(base64, <span class="token-string">'capture.png'</span>, {
|
|
1201
|
+
endpoint: <span class="token-string">'/api/storage'</span>,
|
|
1202
|
+
fieldName: <span class="token-string">'avatar'</span>
|
|
1203
|
+
});
|
|
1204
|
+
<span class="token-comment">// result.data.url contains the permanent server link!</span>
|
|
1205
|
+
}
|
|
1206
|
+
});</code></pre>
|
|
1207
|
+
</div>
|
|
1208
|
+
</div>
|
|
1209
|
+
|
|
1210
|
+
<!-- 4. Exporting -->
|
|
1211
|
+
<div class="docs-section">
|
|
1212
|
+
<h3>4. Data Export (Reporting)</h3>
|
|
1213
|
+
<p>Generate professional Excel, CSV, or PDF reports directly from HTML tables or raw JS objects. Automatically handles dependency injection for <code>SheetJS</code> and <code>jsPDF</code>.</p>
|
|
1214
|
+
<div class="code-block">
|
|
1215
|
+
<pre><code><span class="token-keyword">import</span> { DataExporter } <span class="token-keyword">from</span> <span class="token-string">'js_aide'</span>;
|
|
1216
|
+
|
|
1217
|
+
<span class="token-keyword">const</span> exporter = <span class="token-keyword">new</span> <span class="token-class">DataExporter</span>();
|
|
1218
|
+
<span class="token-keyword">const</span> table = document.<span class="token-function">querySelector</span>(<span class="token-string">'table'</span>);
|
|
1219
|
+
|
|
1220
|
+
<span class="token-comment">// Native conversion from DOM to Excel</span>
|
|
1221
|
+
<span class="token-keyword">await</span> exporter.<span class="token-function">exportToExcel</span>(table, { filename: <span class="token-string">'Reports_2024'</span> });</code></pre>
|
|
1222
|
+
</div>
|
|
1223
|
+
</div>
|
|
1224
|
+
</section>
|
|
1225
|
+
|
|
1226
|
+
<!-- VIEW: DOCS - FALLBACK (Simplified for others) -->
|
|
1227
|
+
<section id="view-docs-generic" class="content-view">
|
|
1228
|
+
<h1>Coming Soon</h1>
|
|
1229
|
+
<p>We are currently migrating this section to the new documentation portal. Check back shortly for extensive code snippets and interactive demos.</p>
|
|
1230
|
+
<div class="info-card">
|
|
1231
|
+
<h3>Developer Notice</h3>
|
|
1232
|
+
<p>All core modules are fully functional in the library source. This is a documentation-only update.</p>
|
|
1233
|
+
</div>
|
|
1234
|
+
</section>
|
|
1235
|
+
</main>
|
|
1236
|
+
</div>
|
|
1237
|
+
|
|
1238
|
+
</div>
|
|
1239
|
+
|
|
1240
|
+
<!-- Load Library -->
|
|
1241
|
+
<script type="module" src="main.js"></script>
|
|
1242
|
+
</body>
|
|
1243
|
+
</html>
|