tiny-essentials 1.28.16 โ 1.28.18
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/changelog/1/28/17.md +11 -0
- package/changelog/1/28/18.md +14 -0
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyMediaPlayer.min.js +1 -1
- package/dist/v1/TinyRadioFm.min.js +1 -1
- package/dist/v1/basics/index.cjs +4 -0
- package/dist/v1/basics/index.d.mts +2 -1
- package/dist/v1/basics/index.d.mts.map +1 -1
- package/dist/v1/basics/index.mjs +2 -1
- package/dist/v1/basics/jsonFilter.cjs +267 -0
- package/dist/v1/basics/jsonFilter.d.mts +91 -0
- package/dist/v1/basics/jsonFilter.d.mts.map +1 -0
- package/dist/v1/basics/jsonFilter.mjs +237 -0
- package/dist/v1/basics/mediaContent.cjs +96 -104
- package/dist/v1/basics/mediaContent.d.mts.map +1 -1
- package/dist/v1/basics/mediaContent.mjs +94 -102
- package/dist/v1/index.cjs +4 -0
- package/dist/v1/index.d.mts +2 -1
- package/dist/v1/index.d.mts.map +1 -1
- package/dist/v1/index.mjs +2 -1
- package/dist/v1/libs/media/TinyRadioFm.cjs +83 -40
- package/dist/v1/libs/media/TinyRadioFm.d.mts +7 -2
- package/dist/v1/libs/media/TinyRadioFm.d.mts.map +1 -1
- package/dist/v1/libs/media/TinyRadioFm.mjs +77 -38
- package/docs/v1/Exports.md +3 -2
- package/docs/v1/README.md +2 -1
- package/docs/v1/basics/jsonFilter.md +194 -0
- package/docs/v1/libs/media/TinyRadioFm.md +40 -11
- package/package.json +5 -1
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# ๐ ๏ธ Object Filtering Utilities Documentation
|
|
2
|
+
|
|
3
|
+
A collection of powerful, high-precision JavaScript utilities designed to filter objects based on keys, values, or complex nested conditions.
|
|
4
|
+
|
|
5
|
+
## ๐ Table of Contents
|
|
6
|
+
1. [`jsonFilter`](#jsonfilter) โ Shallow filtering.
|
|
7
|
+
2. [`jsonFilterRecursive`](#jsonfilterrecursive) โ Deep/Recursive filtering.
|
|
8
|
+
3. [`jsonFilterByKeys`](#jsonfilterbykeys) โ Selective key/value extraction.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## ๐ `jsonFilter`
|
|
13
|
+
|
|
14
|
+
`jsonFilter` is a shallow filtering function. It creates a new object containing only the entries that satisfy a specific predicate function.
|
|
15
|
+
|
|
16
|
+
### โ๏ธ Syntax
|
|
17
|
+
```javascript
|
|
18
|
+
jsonFilter(value, filterContent);
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### ๐ฅ Parameters
|
|
22
|
+
| Parameter | Type | Description |
|
|
23
|
+
| :--- | :--- | :--- |
|
|
24
|
+
| `value` | `Object` | The source object to be filtered. |
|
|
25
|
+
| `filterContent` | `Function` | A callback: `(entry, index, array) => boolean`. |
|
|
26
|
+
|
|
27
|
+
### ๐ Example
|
|
28
|
+
Filtering an object to only keep entries where the value is a number greater than 10.
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
import { jsonFilter } from 'tiny-essentials/basics/jsonFilter';
|
|
32
|
+
|
|
33
|
+
const data = { a: 5, b: 15, c: 20, d: 'hello' };
|
|
34
|
+
|
|
35
|
+
const result = jsonFilter(data, ([key, value]) => typeof value === 'number' && value > 10);
|
|
36
|
+
|
|
37
|
+
console.log(result);
|
|
38
|
+
// Output: { b: 15, c: 20 }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## ๐ณ `jsonFilterRecursive`
|
|
44
|
+
|
|
45
|
+
`jsonFilterRecursive` performs a deep traversal of a data structure. It allows you to apply specific filtering rules depending on whether the current item is a **primitive**, an **array**, or a **complex container** (Object, Map, or Set).
|
|
46
|
+
|
|
47
|
+
### โ๏ธ Syntax
|
|
48
|
+
```javascript
|
|
49
|
+
jsonFilterRecursive(value, filter);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### ๐ฅ Parameters
|
|
53
|
+
| Parameter | Type | Description |
|
|
54
|
+
| :--- | :--- | :--- |
|
|
55
|
+
| `value` | `Object \| Map \| Set` | The source structure to be filtered. |
|
|
56
|
+
| `filter` | `Object` | An object containing predicate functions: |
|
|
57
|
+
| `filter.value` | `Function` | Applied to **primitive** values. |
|
|
58
|
+
| `filter.obj` | `Function` | Applied to **nested objects, Maps, or Sets** (used for pruning). |
|
|
59
|
+
| `filter.array` | `Function` | Applied to **arrays**. |
|
|
60
|
+
|
|
61
|
+
> **Note:** `WeakMap` and `WeakSet` are supported but, due to their non-iterable nature, will return a new empty instance of the same type when processed.
|
|
62
|
+
|
|
63
|
+
### ๐ Example
|
|
64
|
+
Filtering a complex structure containing `Map` and `Set` objects.
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
import { jsonFilterRecursive } from 'tiny-essentials/basics/jsonFilter';
|
|
68
|
+
|
|
69
|
+
const complexData = {
|
|
70
|
+
id: 'Yasmin',
|
|
71
|
+
food: ['pudding'],
|
|
72
|
+
tags: new Set(['premium', 'beta-tester']),
|
|
73
|
+
empty: new Set(),
|
|
74
|
+
metadata: new Map([
|
|
75
|
+
['last_login', '2023-10-27'],
|
|
76
|
+
['login_count', 42]
|
|
77
|
+
]),
|
|
78
|
+
settings: {
|
|
79
|
+
theme: 'dark',
|
|
80
|
+
notifications: true
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const filterConfig = {
|
|
85
|
+
value: ([key, val]) => typeof val === 'string', // Keep strings
|
|
86
|
+
|
|
87
|
+
// Prune Maps or Sets if they become empty after filtering
|
|
88
|
+
obj: (container) => {
|
|
89
|
+
if (container instanceof Map || container instanceof Set) {
|
|
90
|
+
return container.size > 0;
|
|
91
|
+
}
|
|
92
|
+
return container.id !== undefined; // Prune objects that don't have an 'id'
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
array: () => true // Keep all arrays
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const result = jsonFilterRecursive(complexData, filterConfig);
|
|
99
|
+
|
|
100
|
+
console.log(result);
|
|
101
|
+
/*
|
|
102
|
+
Output:
|
|
103
|
+
{
|
|
104
|
+
food: ['pudding'],
|
|
105
|
+
id: 'Yasmin',
|
|
106
|
+
tags: Set { 'premium', 'beta-tester' },
|
|
107
|
+
metadata: Map { 'last_login' => '2023-10-27' }
|
|
108
|
+
}
|
|
109
|
+
*/
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## ๐ `jsonFilterByKeys`
|
|
115
|
+
|
|
116
|
+
`jsonFilterByKeys` is a highly specialized selector. It allows you to extract specific keys or key-value pairs using simple strings, tuples, or validation functions.
|
|
117
|
+
|
|
118
|
+
### โ๏ธ Syntax
|
|
119
|
+
```javascript
|
|
120
|
+
jsonFilterByKeys(item, keys, values);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### ๐ฅ Parameters
|
|
124
|
+
| Parameter | Type | Description |
|
|
125
|
+
| :--- | :--- | :--- |
|
|
126
|
+
| `item` | `Object` | The source object. |
|
|
127
|
+
| `keys` | `Array` | An array of `string` keys OR `[key, validator/value]` tuples. |
|
|
128
|
+
| `values` | `Array` (opt) | A list of allowed values or validators to apply to the keys. |
|
|
129
|
+
|
|
130
|
+
### ๐ก Usage Modes
|
|
131
|
+
|
|
132
|
+
#### 1. Using Simple Keys + Value Whitelist
|
|
133
|
+
If you provide a list of keys and a list of allowed values.
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
import { jsonFilterByKeys } from 'tiny-essentials/basics/jsonFilter';
|
|
137
|
+
|
|
138
|
+
const data = { status: 'active', type: 'user', age: 25 };
|
|
139
|
+
// Keep only 'status' if it is 'active'
|
|
140
|
+
const result = jsonFilterByKeys(data, ['status'], ['active']);
|
|
141
|
+
// Output: { status: 'active' }
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### 2. Using Key-Value Tuples (Highly Precise)
|
|
145
|
+
You can pass a tuple `[key, condition]` where the condition is a value or a function.
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
import { jsonFilterByKeys } from 'tiny-essentials/basics/jsonFilter';
|
|
149
|
+
|
|
150
|
+
const data = {
|
|
151
|
+
id: 101,
|
|
152
|
+
role: 'admin',
|
|
153
|
+
score: 95,
|
|
154
|
+
enabled: true
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Keep 'id', 'score', and 'role'.
|
|
158
|
+
const result = jsonFilterByKeys(data, [
|
|
159
|
+
'id',
|
|
160
|
+
['role', 'admin'],
|
|
161
|
+
['score', (value) => value > 90]
|
|
162
|
+
]);
|
|
163
|
+
|
|
164
|
+
console.log(result);
|
|
165
|
+
// Output: { id: 101, role: 'admin', score: 95 }
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### 3. Using Validators
|
|
169
|
+
You can pass functions to perform complex validation during selection.
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
import { jsonFilterByKeys } from 'tiny-essentials/basics/jsonFilter';
|
|
173
|
+
|
|
174
|
+
const data = {
|
|
175
|
+
name: 'Isabela',
|
|
176
|
+
age: 30,
|
|
177
|
+
score: 9.5
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Keep keys where the value is a number greater than 10
|
|
181
|
+
const result = jsonFilterByKeys(data, ['age', 'score'], [(v) => typeof v === 'number' && v > 10]);
|
|
182
|
+
|
|
183
|
+
console.log(result);
|
|
184
|
+
// Output: { age: 30 }
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## โ ๏ธ Error Handling
|
|
190
|
+
|
|
191
|
+
All functions implement strict runtime validation and will throw a `TypeError` if:
|
|
192
|
+
- The input `value` is not a valid object.
|
|
193
|
+
- The `filterContent` or `filter` predicates are not functions.
|
|
194
|
+
- The `keys` or `values` arguments are not arrays when required.
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* **๐ต Dual-Stream Logic:** Manages separate playlists for `music` and `voice`, with configurable interaction rules (e.g., playing voices after music).
|
|
13
13
|
* **๐
Scheduled Mutations:** Schedule tasks to `add`, `remove`, or `move` items in the playlist at specific future timestamps.
|
|
14
14
|
* **โก Custom Injections:** Inject "Custom Positions" into the timeline that interrupt the standard cycle.
|
|
15
|
-
* **๐ง Smart Queuing:** Intelligent logic to prevent audio overlaps by automatically adjusting timestamps to the end of currently playing content.
|
|
15
|
+
* **๐ง Smart Queuing:** Intelligent logic to prevent audio overlaps by automatically adjusting timestamps to the end of the currently playing content.
|
|
16
16
|
* **๐พ State Persistence:** Full export/import capabilities, including automatic conversion of Blob URLs to Base64 for easy storage.
|
|
17
|
-
* **๐งน Memory Management:** Proactive cleanup of Blob URLs and event listeners to prevent memory leaks.
|
|
17
|
+
* **๐งน Memory Management:** Proactive cleanup of Blob URLs and event listeners to prevent memory leaks, with configurable optimization for media and pictures.
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
@@ -31,6 +31,7 @@ The behavior of the engine is controlled via the `RadioConfig` object.
|
|
|
31
31
|
| `voiceAfterMusic` | `boolean` | `true` | If `true`, voice messages play after music tracks. |
|
|
32
32
|
| `voiceMin` | `number` | `0` | Minimum number of voice messages to play in a cycle. |
|
|
33
33
|
| `voiceMax` | `number` | `1` | Maximum number of voice messages to play in a cycle. |
|
|
34
|
+
| `voiceWeight` | `number` | `1` | Weight used to calculate the probability of a voice block occurring ($P = W / (W + 1)$). |
|
|
34
35
|
| `musicMinConsecutive`| `number` | `0` | Min times a music track must repeat consecutively. |
|
|
35
36
|
| `musicMaxConsecutive`| `number` | `0` | Max consecutive music repeats (`-1` = unlimited, `0` = no repeats). |
|
|
36
37
|
| `voiceMinConsecutive`| `number` | `0` | Min times a voice track must repeat consecutively. |
|
|
@@ -50,11 +51,41 @@ Prepares a `MediaContent` object by extracting metadata from an audio source.
|
|
|
50
51
|
* `metadata`: Optional manual overrides.
|
|
51
52
|
* `parseFile`: Internal helper for file parsing.
|
|
52
53
|
* `callbacks`: Object containing `onProgress` and `onError` handlers.
|
|
53
|
-
* `convertBase64toBlob`: If true, the image content will be converted directly into a high-performance Blob URL
|
|
54
|
+
* `convertBase64toBlob`: If true, the image content will be converted directly into a high-performance Blob URL.
|
|
54
55
|
* **Returns:** `Promise<MediaContent>`
|
|
55
56
|
* **Throws:** `MediaLoadingError`
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
#### `static get/set unknownArtist(value)`
|
|
59
|
+
Gets or sets the identifier used when an artist cannot be determined.
|
|
60
|
+
* **Value:** A `string` or a `function` that returns a `string`.
|
|
61
|
+
* **Throws:** `TypeError` if the value is not a string or a function.
|
|
62
|
+
|
|
63
|
+
### ๐ Properties (Getters & Setters)
|
|
64
|
+
|
|
65
|
+
#### **System State & Lifecycle**
|
|
66
|
+
* `destroyed`: Returns `true` if the instance has been destroyed.
|
|
67
|
+
* `size`: Total count of all content items (music + voice).
|
|
68
|
+
* `seed`: Gets/Sets the core randomness seed.
|
|
69
|
+
* `anchorDate`: Gets the absolute timestamp used as the timeline anchor.
|
|
70
|
+
* `cycleCacheSize`: Returns the number of items currently stored in the cycle cache.
|
|
71
|
+
|
|
72
|
+
#### **Playlist Access (Returns Deep Clones)**
|
|
73
|
+
* `musicList`: Returns a deep clone of the music playlist.
|
|
74
|
+
* `voiceList`: Returns a deep clone of the voice playlist.
|
|
75
|
+
* `allList`: Returns a deep clone of the combined music and voice playlists.
|
|
76
|
+
* `customPositions`: Returns a deep clone of the custom position injections.
|
|
77
|
+
* `scheduledTasks`: Returns a deep clone of the pending scheduled tasks.
|
|
78
|
+
|
|
79
|
+
#### **Counters**
|
|
80
|
+
* `musicSize`: Total number of items in the music playlist.
|
|
81
|
+
* `voiceSize`: Total number of items in the voice playlist.
|
|
82
|
+
* `customPosSize`: Number of active custom position injections.
|
|
83
|
+
* `tasksSize`: Number of pending scheduled tasks.
|
|
84
|
+
|
|
85
|
+
#### **Configuration & Optimization**
|
|
86
|
+
* `config`: Gets/Sets the current `RadioConfig` object.
|
|
87
|
+
* `optimizeMediaMemory`: Gets/Sets whether Blob URLs for media should be converted to Base64 during export.
|
|
88
|
+
* `optimizePictureMemory`: Gets/Sets whether Blob URLs for pictures should be converted to Base64 during export.
|
|
58
89
|
|
|
59
90
|
### ๐ฅ Content Management
|
|
60
91
|
|
|
@@ -67,12 +98,10 @@ Adds new content to the engine immediately.
|
|
|
67
98
|
* **Emits:** `contentAdded`
|
|
68
99
|
|
|
69
100
|
#### `remove(id)`
|
|
70
|
-
Instantly removes content by its unique ID across all lists, custom positions, and pending tasks. It also revokes associated Blob URLs.
|
|
101
|
+
Instantly removes content by its unique ID across all lists, custom positions, and pending tasks. It also revokes associated Blob URLs to free memory.
|
|
71
102
|
* **Parameters:** `id` (string)
|
|
72
103
|
* **Emits:** `contentRemoved`
|
|
73
104
|
|
|
74
|
-
---
|
|
75
|
-
|
|
76
105
|
### ๐
Task & Config Management
|
|
77
106
|
|
|
78
107
|
#### `scheduleTask(timestamp, action, type, payload, smartQueue = true)`
|
|
@@ -90,8 +119,6 @@ Performs a partial or full update of the engine configuration.
|
|
|
90
119
|
* **Parameters:** `config` (Partial or full `RadioConfig` object).
|
|
91
120
|
* **Emits:** `configChanged`
|
|
92
121
|
|
|
93
|
-
---
|
|
94
|
-
|
|
95
122
|
### ๐ Timeline & Querying
|
|
96
123
|
|
|
97
124
|
#### `getCurrentEvent()`
|
|
@@ -106,7 +133,9 @@ Predicts upcoming events from a specific date forward using a virtual sandbox to
|
|
|
106
133
|
* **Returns:** `RadioEvent[]`
|
|
107
134
|
* **Throws:** `TypeError` or `RangeError` if limit is invalid.
|
|
108
135
|
|
|
109
|
-
|
|
136
|
+
#### `searchCustomPositions()`
|
|
137
|
+
Returns a shallow copy of all active custom positions currently injected into the timeline.
|
|
138
|
+
* **Returns:** `CustomPosition[]`
|
|
110
139
|
|
|
111
140
|
### ๐พ Persistence & Lifecycle
|
|
112
141
|
|
|
@@ -161,4 +190,4 @@ A structural block representing a single full iteration of the radio sequence.
|
|
|
161
190
|
* `lastMusicId`: ID of the last music played in this block.
|
|
162
191
|
* `musicConsecutiveCount`: Current consecutive count for music.
|
|
163
192
|
* `lastVoiceId`: ID of the last voice played in this block.
|
|
164
|
-
* `voiceConsecutiveCount`: Current consecutive count for voice.
|
|
193
|
+
* `voiceConsecutiveCount`: Current consecutive count for voice.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiny-essentials",
|
|
3
|
-
"version": "1.28.
|
|
3
|
+
"version": "1.28.18",
|
|
4
4
|
"description": "Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"tiny-essentials-fork": "./TinyFork.mjs"
|
|
@@ -114,6 +114,10 @@
|
|
|
114
114
|
"require": "./dist/v1/basics/browserDetector.cjs",
|
|
115
115
|
"import": "./dist/v1/basics/browserDetector.mjs"
|
|
116
116
|
},
|
|
117
|
+
"./basics/jsonFilter": {
|
|
118
|
+
"require": "./dist/v1/basics/jsonFilter.cjs",
|
|
119
|
+
"import": "./dist/v1/basics/jsonFilter.mjs"
|
|
120
|
+
},
|
|
117
121
|
"./fileManager": {
|
|
118
122
|
"require": "./dist/v1/fileManager/index.cjs",
|
|
119
123
|
"import": "./dist/v1/fileManager/index.mjs"
|