dphelper 3.7.1 → 3.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/README.md +385 -0
- package/docs/SUMMARY.md +83 -0
- package/docs/_config.yml +1 -0
- package/docs/markdown/ai.md +345 -0
- package/docs/markdown/anchor.md +156 -0
- package/docs/markdown/array.md +208 -0
- package/docs/markdown/audio.md +113 -0
- package/docs/markdown/avoid.md +53 -0
- package/docs/markdown/biometric.md +338 -0
- package/docs/markdown/browser.md +203 -0
- package/docs/markdown/check.md +65 -0
- package/docs/markdown/color.md +159 -0
- package/docs/markdown/compress.md +310 -0
- package/docs/markdown/cookie.md +115 -0
- package/docs/markdown/coords.md +127 -0
- package/docs/markdown/credits.md +56 -0
- package/docs/markdown/date.md +260 -0
- package/docs/markdown/disable.md +109 -0
- package/docs/markdown/dispatch.md +108 -0
- package/docs/markdown/element.md +53 -0
- package/docs/markdown/event.md +85 -0
- package/docs/markdown/fetch.md +122 -0
- package/docs/markdown/form.md +302 -0
- package/docs/markdown/format.md +122 -0
- package/docs/markdown/i18n.md +292 -0
- package/docs/markdown/image.md +298 -0
- package/docs/markdown/json.md +269 -0
- package/docs/markdown/load.md +133 -0
- package/docs/markdown/logging.md +99 -0
- package/docs/markdown/math.md +172 -0
- package/docs/markdown/memory.md +85 -0
- package/docs/markdown/navigation.md +152 -0
- package/docs/markdown/net.md +60 -0
- package/docs/markdown/obj.md +242 -0
- package/docs/markdown/path.md +46 -0
- package/docs/markdown/promise.md +94 -0
- package/docs/markdown/sanitize.md +118 -0
- package/docs/markdown/screen.md +78 -0
- package/docs/markdown/scrollbar.md +82 -0
- package/docs/markdown/security.md +289 -0
- package/docs/markdown/shortcut.md +100 -0
- package/docs/markdown/socket.md +134 -0
- package/docs/markdown/sse.md +120 -0
- package/docs/markdown/svg.md +167 -0
- package/docs/markdown/sync.md +147 -0
- package/docs/markdown/system.md +78 -0
- package/docs/markdown/terminal.md +73 -0
- package/docs/markdown/text.md +245 -0
- package/docs/markdown/timer.md +98 -0
- package/docs/markdown/tools.md +111 -0
- package/docs/markdown/translators.md +65 -0
- package/docs/markdown/trigger.md +99 -0
- package/docs/markdown/triggers.md +133 -0
- package/docs/markdown/type.md +109 -0
- package/docs/markdown/types.md +102 -0
- package/docs/markdown/ui.md +45 -0
- package/docs/markdown/window.md +211 -0
- package/docs/markdown/worker.md +223 -0
- package/index.cjs +1 -1
- package/index.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# ai
|
|
2
|
+
|
|
3
|
+
AI and LLM utilities for text processing, token estimation, data formatting, and integration tools.
|
|
4
|
+
|
|
5
|
+
## Functions
|
|
6
|
+
|
|
7
|
+
| Function | Description | Example |
|
|
8
|
+
|----------|-------------|---------|
|
|
9
|
+
| `tokenCount` | Estimates token count for LLM input | `dphelper.ai.tokenCount({ users: [1,2,3] })` |
|
|
10
|
+
| `smartSanitize` | Removes PII (emails, phones, etc.) from text | `dphelper.ai.smartSanitize(text)` |
|
|
11
|
+
| `toon` | Converts JSON to TOON format | `dphelper.ai.toon({ users: [{id: 1, name: 'Ada'}] })` |
|
|
12
|
+
| `toonToJson` | Converts TOON format back to JSON | `dphelper.ai.toonToJson('users[1]{id,name}:\n 1,Ada')` |
|
|
13
|
+
| `chunker` | Splits long text into chunks for RAG | `dphelper.ai.chunker(text, { size: 1000, overlap: 200 })` |
|
|
14
|
+
| `similarity` | Calculates cosine similarity between vectors | `dphelper.ai.similarity(vecA, vecB)` |
|
|
15
|
+
| `extractReasoning` | Extracts AI reasoning tags from response | `dphelper.ai.extractReasoning(aiResponse)` |
|
|
16
|
+
| `prompt` | Template engine for prompt variable injection | `dphelper.ai.prompt('Hello {{name}}', { name: 'Ada' })` |
|
|
17
|
+
| `schema` | Generates TOON-style schema definition | `dphelper.ai.schema({ id: 1, name: 'Ada' })` |
|
|
18
|
+
| `snapshot` | Captures app state snapshot for AI debugging | `dphelper.ai.snapshot()` |
|
|
19
|
+
|
|
20
|
+
## Description
|
|
21
|
+
|
|
22
|
+
Comprehensive AI/LLM integration utilities:
|
|
23
|
+
- **Token Estimation** - Estimate token counts for API limits
|
|
24
|
+
- **Data Format Conversion** - TOON (Token-Oriented Object Notation) format
|
|
25
|
+
- **Text Processing** - PII removal, text chunking for RAG
|
|
26
|
+
- **Vector Operations** - Cosine similarity for embeddings
|
|
27
|
+
- **Prompt Engineering** - Template variables, schema generation
|
|
28
|
+
- **AI Debugging** - Extract reasoning, capture app snapshots
|
|
29
|
+
|
|
30
|
+
## Usage Examples
|
|
31
|
+
|
|
32
|
+
### Token Count Estimation
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
// Estimate tokens for a string
|
|
36
|
+
const text = "Hello, how are you today?";
|
|
37
|
+
console.log(dphelper.ai.tokenCount(text)); // ~8 tokens
|
|
38
|
+
|
|
39
|
+
// Estimate tokens for an object (uses TOON format)
|
|
40
|
+
const data = {
|
|
41
|
+
users: [
|
|
42
|
+
{ id: 1, name: "John", email: "john@example.com" },
|
|
43
|
+
{ id: 2, name: "Jane", email: "jane@example.com" }
|
|
44
|
+
]
|
|
45
|
+
};
|
|
46
|
+
console.log(dphelper.ai.tokenCount(data)); // ~45 tokens
|
|
47
|
+
|
|
48
|
+
// Use for API rate limiting
|
|
49
|
+
const prompt = "Analyze the following data: " + JSON.stringify(data);
|
|
50
|
+
const tokens = dphelper.ai.tokenCount(prompt);
|
|
51
|
+
if (tokens > 4000) {
|
|
52
|
+
console.log("Warning: Approaching token limit");
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### PII Sanitization
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
// Remove personal information from text
|
|
60
|
+
const text = `
|
|
61
|
+
My name is John Smith and my email is john.smith@example.com.
|
|
62
|
+
You can call me at (555) 123-4567.
|
|
63
|
+
My credit card is 1234-5678-9012-3456.
|
|
64
|
+
SSN: 123-45-6789
|
|
65
|
+
`;
|
|
66
|
+
|
|
67
|
+
const sanitized = dphelper.ai.smartSanitize(text);
|
|
68
|
+
console.log(sanitized);
|
|
69
|
+
// My name is John Smith and my email is [EMAIL].
|
|
70
|
+
// You can call me at [PHONE].
|
|
71
|
+
// My credit card is [CREDIT_CARD].
|
|
72
|
+
// SSN: [SSN]
|
|
73
|
+
|
|
74
|
+
// Use before sending data to external AI APIs
|
|
75
|
+
async function sendToAI(data) {
|
|
76
|
+
const safeData = dphelper.ai.smartSanitize(JSON.stringify(data));
|
|
77
|
+
return await fetch('/api/ai/analyze', {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
body: JSON.stringify({ text: safeData })
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### TOON Format Conversion
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
// Convert JSON to TOON (compact, token-efficient format)
|
|
88
|
+
const data = {
|
|
89
|
+
users: [
|
|
90
|
+
{ id: 1, name: "Ada", age: 30 },
|
|
91
|
+
{ id: 2, name: "Bob", age: 25 }
|
|
92
|
+
]
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const toon = dphelper.ai.toon(data);
|
|
96
|
+
console.log(toon);
|
|
97
|
+
/*
|
|
98
|
+
users[2]{id,name,age}:
|
|
99
|
+
1,Ada,30
|
|
100
|
+
2,Bob,25
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
// Convert back from TOON to JSON
|
|
104
|
+
const json = dphelper.ai.toonToJson(toon);
|
|
105
|
+
console.log(json); // Original data restored
|
|
106
|
+
|
|
107
|
+
// Simple array
|
|
108
|
+
const arr = [1, 2, 3, 4, 5];
|
|
109
|
+
console.log(dphelper.ai.toon(arr));
|
|
110
|
+
// [5]: 1, 2, 3, 4, 5
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Text Chunking for RAG
|
|
114
|
+
|
|
115
|
+
```javascript
|
|
116
|
+
const longText = sit amet...`. `Lorem ipsum dolorrepeat(100);
|
|
117
|
+
|
|
118
|
+
// Split into chunks embedding for vector
|
|
119
|
+
const chunks = dphelper.ai.chunker(longText, { size: 1000, overlap: 200 });
|
|
120
|
+
console.log(chunks.length); // Number of chunks
|
|
121
|
+
console.log(chunks[0].length); // ~1000 characters
|
|
122
|
+
|
|
123
|
+
// Process each chunk for embedding
|
|
124
|
+
async function embedText(text) {
|
|
125
|
+
const chunks = dphelper.ai.chunker(text, { size: 500, overlap: 50 });
|
|
126
|
+
const embeddings = [];
|
|
127
|
+
|
|
128
|
+
for (const chunk of chunks) {
|
|
129
|
+
const embedding = await getEmbedding(chunk);
|
|
130
|
+
embeddings.push({ chunk, embedding });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return embeddings;
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Cosine Similarity
|
|
138
|
+
|
|
139
|
+
```javascript
|
|
140
|
+
// Calculate similarity between two embedding vectors
|
|
141
|
+
const vectorA = [1.0, 0.5, 0.3, 0.8];
|
|
142
|
+
const vectorB = [0.9, 0.6, 0.2, 0.7];
|
|
143
|
+
|
|
144
|
+
const similarity = dphelper.ai.similarity(vectorA, vectorB);
|
|
145
|
+
console.log(similarity); // ~0.98 (very similar)
|
|
146
|
+
|
|
147
|
+
// Find most similar document
|
|
148
|
+
const query = [1.0, 0.5, 0.3];
|
|
149
|
+
const documents = [
|
|
150
|
+
[0.9, 0.4, 0.2], // Similar
|
|
151
|
+
[0.1, 0.1, 0.1], // Different
|
|
152
|
+
[0.8, 0.6, 0.4] // Similar
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
let mostSimilar = 0;
|
|
156
|
+
let bestDoc = 0;
|
|
157
|
+
documents.forEach((doc, i) => {
|
|
158
|
+
const sim = dphelper.ai.similarity(query, doc);
|
|
159
|
+
if (sim > mostSimilar) {
|
|
160
|
+
mostSimilar = sim;
|
|
161
|
+
bestDoc = i;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
console.log(`Most similar: document ${bestDoc} (${mostSimilar})`);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Extract AI Reasoning
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
// Extract reasoning from AI response (e.g., Claude, OpenAI o1)
|
|
171
|
+
const aiResponse = `
|
|
172
|
+
<think>
|
|
173
|
+
The user is asking about the weather. Let me think about what data I have available.
|
|
174
|
+
I can provide current conditions based on the user's location.
|
|
175
|
+
</think>
|
|
176
|
+
The current weather in your area is sunny with a temperature of 72°F.
|
|
177
|
+
`;
|
|
178
|
+
|
|
179
|
+
const extracted = dphelper.ai.extractReasoning(aiResponse);
|
|
180
|
+
console.log(extracted.reasoning);
|
|
181
|
+
// "The user is asking about the weather. Let me think about what data I have available..."
|
|
182
|
+
|
|
183
|
+
console.log(extracted.content);
|
|
184
|
+
// "The current weather in your area is sunny with a temperature of 72°F."
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Prompt Template Engine
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
// Simple variable substitution
|
|
191
|
+
const template = "Hello {{name}}, welcome to {{place}}!";
|
|
192
|
+
const result = dphelper.ai.prompt(template, { name: "Ada", place: "our app" });
|
|
193
|
+
console.log(result); // "Hello Ada, welcome to our app!"
|
|
194
|
+
|
|
195
|
+
// With object variables (converts to TOON)
|
|
196
|
+
const template2 = `Analyze this user data:
|
|
197
|
+
{{user}}`;
|
|
198
|
+
|
|
199
|
+
const userData = {
|
|
200
|
+
id: 123,
|
|
201
|
+
name: "John",
|
|
202
|
+
preferences: { theme: "dark", lang: "en" }
|
|
203
|
+
};
|
|
204
|
+
console.log(dphelper.ai.prompt(template2, { user: userData }));
|
|
205
|
+
/*
|
|
206
|
+
Analyze this user data:
|
|
207
|
+
id: 123
|
|
208
|
+
name: John
|
|
209
|
+
preferences:
|
|
210
|
+
theme: dark
|
|
211
|
+
lang: en
|
|
212
|
+
*/
|
|
213
|
+
|
|
214
|
+
// Default values for missing variables
|
|
215
|
+
const t3 = "Welcome, {{name}}! Your role is {{role:guest}}.";
|
|
216
|
+
console.log(dphelper.ai.prompt(t3, { name: "Alice" }));
|
|
217
|
+
// "Welcome, Alice! Your role is guest."
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Schema Generation
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
// Generate TOON-style schema from data
|
|
224
|
+
const data = {
|
|
225
|
+
id: 1,
|
|
226
|
+
name: "John",
|
|
227
|
+
email: "john@example.com",
|
|
228
|
+
age: 30,
|
|
229
|
+
active: true
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const schema = dphelper.ai.schema(data);
|
|
233
|
+
console.log(schema);
|
|
234
|
+
/*
|
|
235
|
+
id: number
|
|
236
|
+
name: string
|
|
237
|
+
email: string
|
|
238
|
+
age: number
|
|
239
|
+
active: boolean
|
|
240
|
+
*/
|
|
241
|
+
|
|
242
|
+
// Array schema
|
|
243
|
+
const users = [
|
|
244
|
+
{ id: 1, name: "Ada" },
|
|
245
|
+
{ id: 2, name: "Bob" }
|
|
246
|
+
];
|
|
247
|
+
console.log(dphelper.ai.schema(users));
|
|
248
|
+
// users: Array<{id: number, name: string}>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### App State Snapshot
|
|
252
|
+
|
|
253
|
+
```javascript
|
|
254
|
+
// Capture current app state for AI debugging
|
|
255
|
+
const snapshot = dphelper.ai.snapshot();
|
|
256
|
+
console.log(snapshot);
|
|
257
|
+
|
|
258
|
+
/*
|
|
259
|
+
context:
|
|
260
|
+
env: browser
|
|
261
|
+
time: 2026-03-02T09:44:55.000Z
|
|
262
|
+
url: https://app.example.com/dashboard
|
|
263
|
+
title: My Dashboard
|
|
264
|
+
state: ...
|
|
265
|
+
logs: ...
|
|
266
|
+
system:
|
|
267
|
+
lang: en-US
|
|
268
|
+
screen: 1920x1080
|
|
269
|
+
zoom: 100
|
|
270
|
+
*/
|
|
271
|
+
|
|
272
|
+
// Useful for AI-assisted debugging
|
|
273
|
+
async function askAIForHelp(error) {
|
|
274
|
+
const snapshot = dphelper.ai.snapshot();
|
|
275
|
+
const prompt = `I'm seeing this error: ${error}\n\nCurrent state:\n${snapshot}`;
|
|
276
|
+
|
|
277
|
+
return await fetch('/api/ai/debug', {
|
|
278
|
+
method: 'POST',
|
|
279
|
+
body: JSON.stringify({ prompt, snapshot })
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Advanced Usage
|
|
285
|
+
|
|
286
|
+
### Complete RAG Pipeline
|
|
287
|
+
|
|
288
|
+
```javascript
|
|
289
|
+
class RAGPipeline {
|
|
290
|
+
constructor(chunkSize = 500, overlap = 50) {
|
|
291
|
+
this.chunkSize = chunkSize;
|
|
292
|
+
this.overlap = overlap;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async indexDocument(text, metadata = {}) {
|
|
296
|
+
// Chunk the text
|
|
297
|
+
const chunks = dphelper.ai.chunker(text, {
|
|
298
|
+
size: this.chunkSize,
|
|
299
|
+
overlap: this.overlap
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// Generate embeddings for each chunk
|
|
303
|
+
const documents = [];
|
|
304
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
305
|
+
const embedding = await this.getEmbedding(chunks[i]);
|
|
306
|
+
documents.push({
|
|
307
|
+
id: `doc_${i}`,
|
|
308
|
+
text: chunks[i],
|
|
309
|
+
embedding,
|
|
310
|
+
metadata,
|
|
311
|
+
tokenCount: dphelper.ai.tokenCount(chunks[i])
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return documents;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
async query(queryText, topK = 5) {
|
|
319
|
+
const queryEmbedding = await this.getEmbedding(queryText);
|
|
320
|
+
|
|
321
|
+
// Find most similar documents
|
|
322
|
+
const results = this.documents
|
|
323
|
+
.map(doc => ({
|
|
324
|
+
...doc,
|
|
325
|
+
similarity: dphelper.ai.similarity(queryEmbedding, doc.embedding)
|
|
326
|
+
}))
|
|
327
|
+
.sort((a, b) => b.similarity - a.similarity)
|
|
328
|
+
.slice(0, topK);
|
|
329
|
+
|
|
330
|
+
return results;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Details
|
|
336
|
+
|
|
337
|
+
- **Author:** Dario Passariello
|
|
338
|
+
- **Version:** 0.0.3
|
|
339
|
+
- **Creation Date:** 20260220
|
|
340
|
+
- **Last Modified:** 20260221
|
|
341
|
+
- **Environment:** Works in both client and server environments
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
*Automatically generated document*
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# anchor
|
|
2
|
+
|
|
3
|
+
Convert anchor tags to JavaScript onclick events for SPA (Single Page Application) navigation while maintaining compatibility with older browsers.
|
|
4
|
+
|
|
5
|
+
## Functions
|
|
6
|
+
|
|
7
|
+
| Function | Description | Example |
|
|
8
|
+
|----------|-------------|---------|
|
|
9
|
+
| `toOnClick` | Converts all anchor tags in an element to onclick events | `dphelper.anchor.toOnClick('#container')` |
|
|
10
|
+
|
|
11
|
+
## Description
|
|
12
|
+
|
|
13
|
+
This tool enables smooth SPA navigation by converting traditional `<a>` tags to JavaScript event handlers. It prevents full page reloads while maintaining browser history functionality. Useful for:
|
|
14
|
+
- Converting legacy HTML to SPA-compatible navigation
|
|
15
|
+
- Mixed environments (some pages SPA, some traditional)
|
|
16
|
+
- Progressive enhancement of existing sites
|
|
17
|
+
|
|
18
|
+
## Usage Examples
|
|
19
|
+
|
|
20
|
+
### Basic Usage
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
// Convert all links in a container to onclick events
|
|
24
|
+
dphelper.anchor.toOnClick('#main-content');
|
|
25
|
+
|
|
26
|
+
// Now all <a> tags in #main-content will use JavaScript navigation
|
|
27
|
+
// instead of traditional page reloads
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### HTML Structure
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<div id="content">
|
|
34
|
+
<nav>
|
|
35
|
+
<a href="/">Home</a>
|
|
36
|
+
<a href="/about">About</a>
|
|
37
|
+
<a href="/contact">Contact</a>
|
|
38
|
+
</nav>
|
|
39
|
+
|
|
40
|
+
<main>
|
|
41
|
+
<a href="/dashboard">Dashboard</a>
|
|
42
|
+
<a href="/settings">Settings</a>
|
|
43
|
+
</main>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<script>
|
|
47
|
+
// Convert all links in the content area
|
|
48
|
+
dphelper.anchor.toOnClick('#content');
|
|
49
|
+
</script>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### How It Works
|
|
53
|
+
|
|
54
|
+
When you call `toOnClick`:
|
|
55
|
+
|
|
56
|
+
1. **Selection** - Finds all `<a>` tags within the specified element
|
|
57
|
+
2. **PathRail Integration** - Adds path-based CSS classes for styling
|
|
58
|
+
3. **Event Conversion** - Removes `href` attribute and adds click handlers
|
|
59
|
+
4. **Navigation Handling**:
|
|
60
|
+
- Relative paths (`/dashboard`) → Uses SPA router via `history.pushState`
|
|
61
|
+
- External paths (`https://...`) → Uses `dphelper.browser.href()`
|
|
62
|
+
|
|
63
|
+
### Integration with PathRail
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
// PathRail must be configured for full functionality
|
|
67
|
+
// When used with dphelper.navigation, enables:
|
|
68
|
+
// - Dynamic page loading
|
|
69
|
+
// - CSS class targeting based on current path
|
|
70
|
+
// - History management
|
|
71
|
+
|
|
72
|
+
// Example: Current path is /dashboard/users
|
|
73
|
+
dphelper.anchor.toOnClick('#app');
|
|
74
|
+
|
|
75
|
+
// Adds class 'dashboardusers' to each anchor for path-based styling
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Advanced Usage
|
|
79
|
+
|
|
80
|
+
### SPA Router Integration
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
// Simple SPA router using anchor conversion
|
|
84
|
+
class SPARouter {
|
|
85
|
+
constructor(selector) {
|
|
86
|
+
this.selector = selector;
|
|
87
|
+
this.routes = {};
|
|
88
|
+
|
|
89
|
+
// Convert anchors when initialized
|
|
90
|
+
dphelper.anchor.toOnClick(selector);
|
|
91
|
+
|
|
92
|
+
// Handle browser back/forward
|
|
93
|
+
window.addEventListener('popstate', () => this.load(window.location.pathname));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
addRoute(path, handler) {
|
|
97
|
+
this.routes[path] = handler;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
load(path) {
|
|
101
|
+
const handler = this.routes[path];
|
|
102
|
+
if (handler) {
|
|
103
|
+
handler();
|
|
104
|
+
document.dispatchEvent(new CustomEvent('route:change', { detail: { path } }));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
navigate(path) {
|
|
109
|
+
history.pushState({}, '', path);
|
|
110
|
+
this.load(path);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Usage
|
|
115
|
+
const router = new SPARouter('#app');
|
|
116
|
+
router.addRoute('/', () => renderHome());
|
|
117
|
+
router.addRoute('/about', () => renderAbout());
|
|
118
|
+
router.addRoute('/dashboard', () => renderDashboard());
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Progressive Enhancement
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
// Convert anchors while preserving accessibility
|
|
125
|
+
function enhanceAnchors(containerSelector) {
|
|
126
|
+
const container = document.querySelector(containerSelector);
|
|
127
|
+
if (!container) return;
|
|
128
|
+
|
|
129
|
+
const anchors = container.querySelectorAll('a');
|
|
130
|
+
|
|
131
|
+
anchors.forEach(anchor => {
|
|
132
|
+
// Add aria-label if missing
|
|
133
|
+
if (!anchor.getAttribute('aria-label')) {
|
|
134
|
+
anchor.setAttribute('aria-label', anchor.textContent);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Ensure keyboard accessibility
|
|
138
|
+
anchor.setAttribute('tabindex', '0');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Convert to onclick
|
|
142
|
+
dphelper.anchor.toOnClick(containerSelector);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Details
|
|
147
|
+
|
|
148
|
+
- **Author:** Dario Passariello
|
|
149
|
+
- **Version:** 0.0.2
|
|
150
|
+
- **Creation Date:** 20210101
|
|
151
|
+
- **Last Modified:** 20260220
|
|
152
|
+
- **Environment:** Client-side only (browser)
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
*Automatically generated document*
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# array
|
|
2
|
+
|
|
3
|
+
Advanced utilities for JavaScript array manipulation with support for nested structures, merging, filtering, and more.
|
|
4
|
+
|
|
5
|
+
## Functions
|
|
6
|
+
|
|
7
|
+
| Function | Description | Example |
|
|
8
|
+
|----------|-------------|---------|
|
|
9
|
+
| `find` | Finds an element recursively in nested arrays | `dphelper.array.find(array, 'key')` |
|
|
10
|
+
| `delete` | Deletes an element recursively by key | `dphelper.array.delete(array, 'key')` |
|
|
11
|
+
| `merge` | Deep merges two objects/arrays (safe from prototype pollution) | `dphelper.array.merge(arrA, arrB)` |
|
|
12
|
+
| `mergeByKey` | Merges two arrays of objects via a specific key | `dphelper.array.mergeByKey(arrA, arrB, 'id')` |
|
|
13
|
+
| `unique` | Removes duplicate values from an array | `dphelper.array.unique(array)` |
|
|
14
|
+
| `asc` | Sorts array in ascending order | `dphelper.array.asc(array)` |
|
|
15
|
+
| `desc` | Sorts array in descending order | `dphelper.array.desc(array)` |
|
|
16
|
+
| `duplicates` | Finds duplicate elements in an array | `dphelper.array.duplicates(array)` |
|
|
17
|
+
| `even` | Filters even numbers from an array | `dphelper.array.even(array)` |
|
|
18
|
+
| `odd` | Filters odd numbers from an array | `dphelper.array.odd(array)` |
|
|
19
|
+
| `toObj` | Converts an array to an object | `dphelper.array.toObj(array)` |
|
|
20
|
+
| `sumColumn` | Sums values of a column in a multidimensional array | `dphelper.array.sumColumn(arr, 0)` |
|
|
21
|
+
| `shuffle` | Randomly shuffles elements (Fisher-Yates algorithm) | `dphelper.array.shuffle(array)` |
|
|
22
|
+
| `generate` | Generates an array of random numbers (1 to n) | `dphelper.array.generate(10)` |
|
|
23
|
+
| `testArrayInt` | Checks for missing numbers in a consecutive sequence | `dphelper.array.testArrayInt([1,2,4])` |
|
|
24
|
+
| `rand32` | Generates an array of random 32-bit unsigned integers | `dphelper.array.rand32(5)` |
|
|
25
|
+
| `findindex` | Finds the index of an element by key | `dphelper.array.findindex(array, 'name')` |
|
|
26
|
+
| `pathToJson` | Converts an array of paths into a JSON object | `dphelper.array.pathToJson(paths, '/')` |
|
|
27
|
+
| `deepClone` | Creates a deep clone using structuredClone | `dphelper.array.deepClone(array)` |
|
|
28
|
+
| `match` | Finds intersection between two arrays | `dphelper.array.match(arrA, arrB)` |
|
|
29
|
+
|
|
30
|
+
## Description
|
|
31
|
+
|
|
32
|
+
Comprehensive array manipulation library that provides utilities for:
|
|
33
|
+
- **Recursive operations** - Find, delete in nested structures
|
|
34
|
+
- **Merging** - Deep merge with prototype pollution protection
|
|
35
|
+
- **Filtering** - Even/odd numbers, duplicates
|
|
36
|
+
- **Sorting** - Ascending/descending order
|
|
37
|
+
- **Generation** - Random numbers, sequences
|
|
38
|
+
- **Conversion** - Array to object, paths to JSON
|
|
39
|
+
|
|
40
|
+
## Usage Examples
|
|
41
|
+
|
|
42
|
+
### Finding Elements in Nested Arrays
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
const data = [
|
|
46
|
+
{ id: 1, name: 'John', children: [{ id: 2, name: 'Jane' }] },
|
|
47
|
+
{ id: 3, name: 'Bob', children: [{ id: 4, name: 'Alice' }] }
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// Find element with id 2
|
|
51
|
+
const found = dphelper.array.find(data, 2);
|
|
52
|
+
console.log(found); // { id: 2, name: 'Jane' }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Deep Merging Objects
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
const obj1 = { a: 1, b: { c: 2 } };
|
|
59
|
+
const obj2 = { b: { d: 3 }, e: 4 };
|
|
60
|
+
|
|
61
|
+
const merged = dphelper.array.merge(obj1, obj2);
|
|
62
|
+
console.log(merged); // { a: 1, b: { c: 2, d: 3 }, e: 4 }
|
|
63
|
+
|
|
64
|
+
// Safe from prototype pollution
|
|
65
|
+
const dangerous = { '__proto__': { dangerous: true } };
|
|
66
|
+
const safe = dphelper.array.merge({}, dangerous);
|
|
67
|
+
console.log(safe); // { __proto__: { dangerous: true } } - safe!
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Merging Arrays by Key
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
const users = [
|
|
74
|
+
{ id: 1, name: 'John', age: 30 },
|
|
75
|
+
{ id: 2, name: 'Jane', age: 25 }
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
const details = [
|
|
79
|
+
{ id: 1, email: 'john@example.com' },
|
|
80
|
+
{ id: 2, email: 'jane@example.com' }
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
const merged = dphelper.array.mergeByKey(users, details, 'id');
|
|
84
|
+
// Result: [{ id: 1, name: 'John', age: 30, email: 'john@example.com' }, ...]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Finding Duplicates
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
const numbers = [1, 2, 3, 2, 4, 3, 5, 1];
|
|
91
|
+
const dups = dphelper.array.duplicates(numbers);
|
|
92
|
+
console.log(dups); // [2, 3, 1]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Filtering Even/Odd Numbers
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
99
|
+
|
|
100
|
+
console.log(dphelper.array.even(numbers)); // [2, 4, 6, 8, 10]
|
|
101
|
+
console.log(dphelper.array.odd(numbers)); // [1, 3, 5, 7, 9]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Sum Column in Multidimensional Array
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
const matrix = [
|
|
108
|
+
[1, 2, 3], // row 0
|
|
109
|
+
[4, 5, 6], // row 1
|
|
110
|
+
[7, 8, 9] // row 2
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
// Sum first column (index 0)
|
|
114
|
+
console.log(dphelper.array.sumColumn(matrix, 0)); // 12 (1+4+7)
|
|
115
|
+
|
|
116
|
+
// Sum second column (index 1)
|
|
117
|
+
console.log(dphelper.array.sumColumn(matrix, 1)); // 15 (2+5+8)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Shuffle Array (Fisher-Yates)
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
const cards = ['A', 'B', 'C', 'D', 'E'];
|
|
124
|
+
const shuffled = dphelper.array.shuffle([...cards]);
|
|
125
|
+
console.log(shuffled); // Random order, e.g., ['C', 'A', 'E', 'D', 'B']
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Generate Random Number Sequence
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
// Generate numbers 1-10 in random order
|
|
132
|
+
const sequence = dphelper.array.generate(10);
|
|
133
|
+
console.log(sequence); // e.g., [3, 1, 8, 5, 2, 9, 4, 7, 6, 10]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Test for Consecutive Integers
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
// Check for missing numbers in sequence [1, 2, 3, 4, 5]
|
|
140
|
+
console.log(dphelper.array.testArrayInt([1, 2, 3, 4, 5])); // [] (complete)
|
|
141
|
+
|
|
142
|
+
// Check for missing numbers in [1, 2, 4, 5]
|
|
143
|
+
console.log(dphelper.array.testArrayInt([1, 2, 4, 5])); // [3] (missing 3)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Generate Random 32-bit Integers
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
const randomNumbers = dphelper.array.rand32(5);
|
|
150
|
+
console.log(randomNumbers.nums); // [random1, random2, random3, random4, random5]
|
|
151
|
+
console.log(randomNumbers.time); // [execution time in ms]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Path to JSON Conversion
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
const paths = [
|
|
158
|
+
'/users/John',
|
|
159
|
+
'/users/John/profile',
|
|
160
|
+
'/users/John/settings',
|
|
161
|
+
'/users/Jane'
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
const json = dphelper.array.pathToJson(paths, '/');
|
|
165
|
+
// Result:
|
|
166
|
+
// {
|
|
167
|
+
// users: {
|
|
168
|
+
// John: {
|
|
169
|
+
// profile: null,
|
|
170
|
+
// settings: null
|
|
171
|
+
// },
|
|
172
|
+
// Jane: null
|
|
173
|
+
// }
|
|
174
|
+
// }
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Deep Clone Array
|
|
178
|
+
|
|
179
|
+
```javascript
|
|
180
|
+
const original = [{ a: 1 }, { b: 2 }];
|
|
181
|
+
const cloned = dphelper.array.deepClone(original);
|
|
182
|
+
|
|
183
|
+
cloned[0].a = 99;
|
|
184
|
+
console.log(original[0].a); // 1 (original unchanged)
|
|
185
|
+
console.log(cloned[0].a); // 99
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Find Array Intersection
|
|
189
|
+
|
|
190
|
+
```javascript
|
|
191
|
+
const words = ['apple', 'banana', 'cherry', 'date'];
|
|
192
|
+
const check = ['banana', 'date', 'elderberry'];
|
|
193
|
+
|
|
194
|
+
const matches = dphelper.array.match(words, check);
|
|
195
|
+
console.log(matches); // ['banana', 'date']
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Details
|
|
199
|
+
|
|
200
|
+
- **Author:** Dario Passariello
|
|
201
|
+
- **Version:** 0.0.2
|
|
202
|
+
- **Creation Date:** 20210101
|
|
203
|
+
- **Last Modified:** 20260220
|
|
204
|
+
- **Environment:** Works in both client and server environments
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
*Automatically generated document*
|