@humanspeak/svelte-markdown 0.8.13 → 0.8.14
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/dist/utils/cache.d.ts +3 -166
- package/dist/utils/cache.js +3 -261
- package/dist/utils/createFilterUtilities.d.ts +52 -0
- package/dist/utils/createFilterUtilities.js +126 -0
- package/dist/utils/parse-and-cache.js +3 -0
- package/dist/utils/rendererKeys.d.ts +1 -1
- package/dist/utils/unsupportedHtmlRenderers.d.ts +4 -4
- package/dist/utils/unsupportedHtmlRenderers.js +8 -43
- package/dist/utils/unsupportedRenderers.d.ts +8 -8
- package/dist/utils/unsupportedRenderers.js +11 -48
- package/package.json +30 -29
package/dist/utils/cache.d.ts
CHANGED
|
@@ -1,168 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* @interface CacheOptions
|
|
5
|
-
* @property {number} [maxSize] - Maximum number of entries the cache can hold before evicting oldest entries
|
|
6
|
-
* @property {number} [ttl] - Time-to-live in milliseconds for cache entries before they expire
|
|
2
|
+
* Re-export MemoryCache from @humanspeak/memory-cache package.
|
|
3
|
+
* This provides a generic in-memory cache implementation with TTL and size-based eviction.
|
|
7
4
|
*/
|
|
8
|
-
|
|
9
|
-
maxSize?: number;
|
|
10
|
-
ttl?: number;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Generic in-memory cache implementation with TTL and size-based eviction.
|
|
14
|
-
* Provides efficient caching for any type of data with automatic cleanup
|
|
15
|
-
* of expired or excess entries.
|
|
16
|
-
*
|
|
17
|
-
* @class MemoryCache
|
|
18
|
-
* @template T - The type of values being cached
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```typescript
|
|
22
|
-
* // Create a cache for string values
|
|
23
|
-
* const cache = new MemoryCache<string>({
|
|
24
|
-
* maxSize: 100,
|
|
25
|
-
* ttl: 5 * 60 * 1000 // 5 minutes
|
|
26
|
-
* });
|
|
27
|
-
*
|
|
28
|
-
* // Store and retrieve values
|
|
29
|
-
* cache.set('key', 'value');
|
|
30
|
-
* const value = cache.get('key');
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export declare class MemoryCache<T> {
|
|
34
|
-
private cache;
|
|
35
|
-
private maxSize;
|
|
36
|
-
private ttl;
|
|
37
|
-
/**
|
|
38
|
-
* Creates a new MemoryCache instance.
|
|
39
|
-
*
|
|
40
|
-
* @param {CacheOptions} options - Configuration options for the cache
|
|
41
|
-
* @param {number} [options.maxSize=100] - Maximum number of entries (default: 100)
|
|
42
|
-
* @param {number} [options.ttl=300000] - Time-to-live in milliseconds (default: 5 minutes)
|
|
43
|
-
*/
|
|
44
|
-
constructor(options?: CacheOptions);
|
|
45
|
-
/**
|
|
46
|
-
* Retrieves a value from the cache if it exists and hasn't expired.
|
|
47
|
-
*
|
|
48
|
-
* @param {string} key - The key to look up
|
|
49
|
-
* @returns {T | undefined} The cached value if found and valid, undefined otherwise
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```typescript
|
|
53
|
-
* const cache = new MemoryCache<number>();
|
|
54
|
-
* cache.set('counter', 42);
|
|
55
|
-
* const value = cache.get('counter'); // Returns 42
|
|
56
|
-
* const missing = cache.get('nonexistent'); // Returns undefined
|
|
57
|
-
* ```
|
|
58
|
-
*/
|
|
59
|
-
get(key: string): T | undefined;
|
|
60
|
-
/**
|
|
61
|
-
* Checks if a key exists in the cache (regardless of its value).
|
|
62
|
-
* This is useful for distinguishing between cache misses and cached undefined values.
|
|
63
|
-
*
|
|
64
|
-
* @param {string} key - The key to check
|
|
65
|
-
* @returns {boolean} True if the key exists in cache and hasn't expired, false otherwise
|
|
66
|
-
*/
|
|
67
|
-
has(key: string): boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Stores a value in the cache. If the cache is full, the oldest entry is removed.
|
|
70
|
-
*
|
|
71
|
-
* @param {string} key - The key under which to store the value
|
|
72
|
-
* @param {T} value - The value to cache
|
|
73
|
-
*
|
|
74
|
-
* @example
|
|
75
|
-
* ```typescript
|
|
76
|
-
* const cache = new MemoryCache<string>();
|
|
77
|
-
* cache.set('greeting', 'Hello, World!');
|
|
78
|
-
* ```
|
|
79
|
-
*/
|
|
80
|
-
set(key: string, value: T): void;
|
|
81
|
-
/**
|
|
82
|
-
* Removes a specific entry from the cache.
|
|
83
|
-
*
|
|
84
|
-
* @param {string} key - The key of the entry to remove
|
|
85
|
-
* @returns {boolean} True if an element was removed, false if the key wasn't found
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* const cache = new MemoryCache<string>();
|
|
90
|
-
* cache.set('key', 'value');
|
|
91
|
-
* cache.delete('key'); // Returns true
|
|
92
|
-
* cache.delete('nonexistent'); // Returns false
|
|
93
|
-
* ```
|
|
94
|
-
*/
|
|
95
|
-
delete(key: string): boolean;
|
|
96
|
-
deleteAsync(key: string): Promise<boolean>;
|
|
97
|
-
/**
|
|
98
|
-
* Removes all entries from the cache.
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* ```typescript
|
|
102
|
-
* const cache = new MemoryCache<string>();
|
|
103
|
-
* cache.set('key1', 'value1');
|
|
104
|
-
* cache.set('key2', 'value2');
|
|
105
|
-
* cache.clear(); // Removes all entries
|
|
106
|
-
* ```
|
|
107
|
-
*/
|
|
108
|
-
clear(): void;
|
|
109
|
-
/**
|
|
110
|
-
* Removes all entries from the cache whose keys start with the given prefix.
|
|
111
|
-
*
|
|
112
|
-
* @param {string} prefix - The prefix to match against cache keys
|
|
113
|
-
* @returns {number} Number of entries removed
|
|
114
|
-
*
|
|
115
|
-
* @example
|
|
116
|
-
* ```typescript
|
|
117
|
-
* const cache = new MemoryCache<string>();
|
|
118
|
-
* cache.set('user:123:name', 'John');
|
|
119
|
-
* cache.set('user:123:email', 'john@example.com');
|
|
120
|
-
* cache.set('post:456', 'Hello World');
|
|
121
|
-
*
|
|
122
|
-
* const removed = cache.deleteByPrefix('user:123:'); // Returns 2
|
|
123
|
-
* ```
|
|
124
|
-
*/
|
|
125
|
-
deleteByPrefix(prefix: string): number;
|
|
126
|
-
/**
|
|
127
|
-
* Removes all entries from the cache whose keys match the given wildcard pattern.
|
|
128
|
-
* Supports asterisk (*) wildcards for flexible pattern matching.
|
|
129
|
-
*
|
|
130
|
-
* @param {string} magicString - The wildcard pattern to match against cache keys (use * for wildcards)
|
|
131
|
-
* @returns {number} Number of entries removed
|
|
132
|
-
*
|
|
133
|
-
* @example
|
|
134
|
-
* ```typescript
|
|
135
|
-
* const cache = new MemoryCache<string>();
|
|
136
|
-
* cache.set('user:123:name', 'John');
|
|
137
|
-
* cache.set('user:123:email', 'john@example.com');
|
|
138
|
-
* cache.set('user:456:name', 'Jane');
|
|
139
|
-
* cache.set('post:789', 'Hello World');
|
|
140
|
-
*
|
|
141
|
-
* const removed1 = cache.deleteByMagicString('user:123:*'); // Returns 2 (matches name and email)
|
|
142
|
-
* const removed2 = cache.deleteByMagicString('user:*:name'); // Returns 1 (matches Jane's name)
|
|
143
|
-
* const removed3 = cache.deleteByMagicString('post:*'); // Returns 1 (matches the post)
|
|
144
|
-
* ```
|
|
145
|
-
*/
|
|
146
|
-
deleteByMagicString(magicString: string): number;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Cache decorator factory for method-level caching.
|
|
150
|
-
* Provides a way to cache method results based on their arguments.
|
|
151
|
-
*
|
|
152
|
-
* @template T - The return type of the decorated method
|
|
153
|
-
* @param {CacheOptions} options - Configuration options for the cache
|
|
154
|
-
* @returns A method decorator that caches the results
|
|
155
|
-
*
|
|
156
|
-
* @example
|
|
157
|
-
* ```typescript
|
|
158
|
-
* class UserService {
|
|
159
|
-
* @cached<User>({ ttl: 60000 })
|
|
160
|
-
* async getUser(id: string): Promise<User> {
|
|
161
|
-
* // Expensive operation
|
|
162
|
-
* return await fetchUser(id);
|
|
163
|
-
* }
|
|
164
|
-
* }
|
|
165
|
-
* ```
|
|
166
|
-
*/
|
|
167
|
-
export declare function cached<T>(options?: CacheOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
168
|
-
export {};
|
|
5
|
+
export { MemoryCache } from '@humanspeak/memory-cache';
|
package/dist/utils/cache.js
CHANGED
|
@@ -1,263 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* This
|
|
2
|
+
* Re-export MemoryCache from @humanspeak/memory-cache package.
|
|
3
|
+
* This provides a generic in-memory cache implementation with TTL and size-based eviction.
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
const CACHED_NULL = Symbol('CACHED_NULL');
|
|
7
|
-
/**
|
|
8
|
-
* Generic in-memory cache implementation with TTL and size-based eviction.
|
|
9
|
-
* Provides efficient caching for any type of data with automatic cleanup
|
|
10
|
-
* of expired or excess entries.
|
|
11
|
-
*
|
|
12
|
-
* @class MemoryCache
|
|
13
|
-
* @template T - The type of values being cached
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```typescript
|
|
17
|
-
* // Create a cache for string values
|
|
18
|
-
* const cache = new MemoryCache<string>({
|
|
19
|
-
* maxSize: 100,
|
|
20
|
-
* ttl: 5 * 60 * 1000 // 5 minutes
|
|
21
|
-
* });
|
|
22
|
-
*
|
|
23
|
-
* // Store and retrieve values
|
|
24
|
-
* cache.set('key', 'value');
|
|
25
|
-
* const value = cache.get('key');
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
export class MemoryCache {
|
|
29
|
-
cache = new Map();
|
|
30
|
-
maxSize;
|
|
31
|
-
ttl;
|
|
32
|
-
/**
|
|
33
|
-
* Creates a new MemoryCache instance.
|
|
34
|
-
*
|
|
35
|
-
* @param {CacheOptions} options - Configuration options for the cache
|
|
36
|
-
* @param {number} [options.maxSize=100] - Maximum number of entries (default: 100)
|
|
37
|
-
* @param {number} [options.ttl=300000] - Time-to-live in milliseconds (default: 5 minutes)
|
|
38
|
-
*/
|
|
39
|
-
constructor(options = {}) {
|
|
40
|
-
this.maxSize = options.maxSize ?? 100;
|
|
41
|
-
this.ttl = options.ttl ?? 5 * 60 * 1000; // 5 minutes default
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Retrieves a value from the cache if it exists and hasn't expired.
|
|
45
|
-
*
|
|
46
|
-
* @param {string} key - The key to look up
|
|
47
|
-
* @returns {T | undefined} The cached value if found and valid, undefined otherwise
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```typescript
|
|
51
|
-
* const cache = new MemoryCache<number>();
|
|
52
|
-
* cache.set('counter', 42);
|
|
53
|
-
* const value = cache.get('counter'); // Returns 42
|
|
54
|
-
* const missing = cache.get('nonexistent'); // Returns undefined
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
get(key) {
|
|
58
|
-
const entry = this.cache.get(key);
|
|
59
|
-
if (!entry)
|
|
60
|
-
return undefined;
|
|
61
|
-
// Check if entry has expired (skip check if TTL is 0 or negative)
|
|
62
|
-
if (this.ttl > 0 && Date.now() - entry.timestamp > this.ttl) {
|
|
63
|
-
this.cache.delete(key);
|
|
64
|
-
return undefined;
|
|
65
|
-
}
|
|
66
|
-
// Handle the special sentinel values for cached undefined/null
|
|
67
|
-
if (entry.value === CACHED_UNDEFINED) {
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
70
|
-
if (entry.value === CACHED_NULL) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
return entry.value;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Checks if a key exists in the cache (regardless of its value).
|
|
77
|
-
* This is useful for distinguishing between cache misses and cached undefined values.
|
|
78
|
-
*
|
|
79
|
-
* @param {string} key - The key to check
|
|
80
|
-
* @returns {boolean} True if the key exists in cache and hasn't expired, false otherwise
|
|
81
|
-
*/
|
|
82
|
-
has(key) {
|
|
83
|
-
const entry = this.cache.get(key);
|
|
84
|
-
if (!entry)
|
|
85
|
-
return false;
|
|
86
|
-
// Check if entry has expired (skip check if TTL is 0 or negative)
|
|
87
|
-
if (this.ttl > 0 && Date.now() - entry.timestamp > this.ttl) {
|
|
88
|
-
this.cache.delete(key);
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Stores a value in the cache. If the cache is full, the oldest entry is removed.
|
|
95
|
-
*
|
|
96
|
-
* @param {string} key - The key under which to store the value
|
|
97
|
-
* @param {T} value - The value to cache
|
|
98
|
-
*
|
|
99
|
-
* @example
|
|
100
|
-
* ```typescript
|
|
101
|
-
* const cache = new MemoryCache<string>();
|
|
102
|
-
* cache.set('greeting', 'Hello, World!');
|
|
103
|
-
* ```
|
|
104
|
-
*/
|
|
105
|
-
set(key, value) {
|
|
106
|
-
// Remove oldest entry if cache is full (skip if maxSize is 0 or negative)
|
|
107
|
-
if (this.maxSize > 0 && this.cache.size >= this.maxSize) {
|
|
108
|
-
const oldestKey = this.cache.keys().next().value;
|
|
109
|
-
if (oldestKey) {
|
|
110
|
-
this.cache.delete(oldestKey);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
// Store undefined/null values as sentinels to distinguish from cache misses
|
|
114
|
-
let valueToStore;
|
|
115
|
-
if (value === undefined) {
|
|
116
|
-
valueToStore = CACHED_UNDEFINED;
|
|
117
|
-
}
|
|
118
|
-
else if (value === null) {
|
|
119
|
-
valueToStore = CACHED_NULL;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
valueToStore = value;
|
|
123
|
-
}
|
|
124
|
-
this.cache.set(key, {
|
|
125
|
-
value: valueToStore,
|
|
126
|
-
timestamp: Date.now()
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Removes a specific entry from the cache.
|
|
131
|
-
*
|
|
132
|
-
* @param {string} key - The key of the entry to remove
|
|
133
|
-
* @returns {boolean} True if an element was removed, false if the key wasn't found
|
|
134
|
-
*
|
|
135
|
-
* @example
|
|
136
|
-
* ```typescript
|
|
137
|
-
* const cache = new MemoryCache<string>();
|
|
138
|
-
* cache.set('key', 'value');
|
|
139
|
-
* cache.delete('key'); // Returns true
|
|
140
|
-
* cache.delete('nonexistent'); // Returns false
|
|
141
|
-
* ```
|
|
142
|
-
*/
|
|
143
|
-
delete(key) {
|
|
144
|
-
return this.cache.delete(key);
|
|
145
|
-
}
|
|
146
|
-
async deleteAsync(key) {
|
|
147
|
-
return Promise.resolve(this.cache.delete(key));
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Removes all entries from the cache.
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```typescript
|
|
154
|
-
* const cache = new MemoryCache<string>();
|
|
155
|
-
* cache.set('key1', 'value1');
|
|
156
|
-
* cache.set('key2', 'value2');
|
|
157
|
-
* cache.clear(); // Removes all entries
|
|
158
|
-
* ```
|
|
159
|
-
*/
|
|
160
|
-
clear() {
|
|
161
|
-
this.cache.clear();
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Removes all entries from the cache whose keys start with the given prefix.
|
|
165
|
-
*
|
|
166
|
-
* @param {string} prefix - The prefix to match against cache keys
|
|
167
|
-
* @returns {number} Number of entries removed
|
|
168
|
-
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```typescript
|
|
171
|
-
* const cache = new MemoryCache<string>();
|
|
172
|
-
* cache.set('user:123:name', 'John');
|
|
173
|
-
* cache.set('user:123:email', 'john@example.com');
|
|
174
|
-
* cache.set('post:456', 'Hello World');
|
|
175
|
-
*
|
|
176
|
-
* const removed = cache.deleteByPrefix('user:123:'); // Returns 2
|
|
177
|
-
* ```
|
|
178
|
-
*/
|
|
179
|
-
deleteByPrefix(prefix) {
|
|
180
|
-
let count = 0;
|
|
181
|
-
for (const key of this.cache.keys()) {
|
|
182
|
-
if (key.startsWith(prefix)) {
|
|
183
|
-
this.cache.delete(key);
|
|
184
|
-
count++;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return count;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Removes all entries from the cache whose keys match the given wildcard pattern.
|
|
191
|
-
* Supports asterisk (*) wildcards for flexible pattern matching.
|
|
192
|
-
*
|
|
193
|
-
* @param {string} magicString - The wildcard pattern to match against cache keys (use * for wildcards)
|
|
194
|
-
* @returns {number} Number of entries removed
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* ```typescript
|
|
198
|
-
* const cache = new MemoryCache<string>();
|
|
199
|
-
* cache.set('user:123:name', 'John');
|
|
200
|
-
* cache.set('user:123:email', 'john@example.com');
|
|
201
|
-
* cache.set('user:456:name', 'Jane');
|
|
202
|
-
* cache.set('post:789', 'Hello World');
|
|
203
|
-
*
|
|
204
|
-
* const removed1 = cache.deleteByMagicString('user:123:*'); // Returns 2 (matches name and email)
|
|
205
|
-
* const removed2 = cache.deleteByMagicString('user:*:name'); // Returns 1 (matches Jane's name)
|
|
206
|
-
* const removed3 = cache.deleteByMagicString('post:*'); // Returns 1 (matches the post)
|
|
207
|
-
* ```
|
|
208
|
-
*/
|
|
209
|
-
deleteByMagicString(magicString) {
|
|
210
|
-
let count = 0;
|
|
211
|
-
// Convert wildcard pattern to regex
|
|
212
|
-
const escapedPattern = magicString
|
|
213
|
-
.replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape regex special chars except *
|
|
214
|
-
.replace(/\*/g, '.*'); // Convert * to .*
|
|
215
|
-
const regex = new RegExp(`^${escapedPattern}$`);
|
|
216
|
-
for (const key of this.cache.keys()) {
|
|
217
|
-
if (regex.test(key)) {
|
|
218
|
-
this.cache.delete(key);
|
|
219
|
-
count++;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return count;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Cache decorator factory for method-level caching.
|
|
227
|
-
* Provides a way to cache method results based on their arguments.
|
|
228
|
-
*
|
|
229
|
-
* @template T - The return type of the decorated method
|
|
230
|
-
* @param {CacheOptions} options - Configuration options for the cache
|
|
231
|
-
* @returns A method decorator that caches the results
|
|
232
|
-
*
|
|
233
|
-
* @example
|
|
234
|
-
* ```typescript
|
|
235
|
-
* class UserService {
|
|
236
|
-
* @cached<User>({ ttl: 60000 })
|
|
237
|
-
* async getUser(id: string): Promise<User> {
|
|
238
|
-
* // Expensive operation
|
|
239
|
-
* return await fetchUser(id);
|
|
240
|
-
* }
|
|
241
|
-
* }
|
|
242
|
-
* ```
|
|
243
|
-
*/
|
|
244
|
-
export function cached(options = {}) {
|
|
245
|
-
const cache = new MemoryCache(options);
|
|
246
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
247
|
-
return function (target, propertyKey, descriptor) {
|
|
248
|
-
const originalMethod = descriptor.value;
|
|
249
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
250
|
-
descriptor.value = function (...args) {
|
|
251
|
-
const key = `${propertyKey}:${JSON.stringify(args)}`;
|
|
252
|
-
// Use has() to check if key exists, then get() to retrieve value
|
|
253
|
-
// This allows us to distinguish between cache miss and cached undefined
|
|
254
|
-
if (cache.has(key)) {
|
|
255
|
-
return cache.get(key);
|
|
256
|
-
}
|
|
257
|
-
const result = originalMethod.apply(this, args);
|
|
258
|
-
cache.set(key, result);
|
|
259
|
-
return result;
|
|
260
|
-
};
|
|
261
|
-
return descriptor;
|
|
262
|
-
};
|
|
263
|
-
}
|
|
5
|
+
export { MemoryCache } from '@humanspeak/memory-cache';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Component } from 'svelte';
|
|
2
|
+
/**
|
|
3
|
+
* Generic component type for filter utilities.
|
|
4
|
+
* Allows Component, undefined, or null values.
|
|
5
|
+
*/
|
|
6
|
+
type FilterComponent = Component<any, any, any> | undefined | null;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a set of filter utility functions for renderer maps.
|
|
9
|
+
* This factory generates three functions: buildUnsupported, allowOnly, and excludeOnly.
|
|
10
|
+
*
|
|
11
|
+
* Used to eliminate code duplication between unsupportedRenderers.ts and unsupportedHtmlRenderers.ts.
|
|
12
|
+
*
|
|
13
|
+
* @template TKey - The string literal type for valid keys
|
|
14
|
+
* @template TResult - The result map type (e.g., Partial<Renderers> or HtmlRenderers)
|
|
15
|
+
*
|
|
16
|
+
* @param keys - Array of valid keys for this renderer type
|
|
17
|
+
* @param unsupportedComponent - The component to use for unsupported/disabled renderers
|
|
18
|
+
* @param defaultsMap - Map of keys to their default component implementations
|
|
19
|
+
*
|
|
20
|
+
* @returns Object containing buildUnsupported, allowOnly, and excludeOnly functions
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { createFilterUtilities } from './createFilterUtilities'
|
|
25
|
+
*
|
|
26
|
+
* type MyKey = 'foo' | 'bar' | 'baz'
|
|
27
|
+
* const keys: readonly MyKey[] = ['foo', 'bar', 'baz'] as const
|
|
28
|
+
* const UnsupportedComponent = () => null
|
|
29
|
+
* const defaults = { foo: FooComponent, bar: BarComponent, baz: BazComponent }
|
|
30
|
+
*
|
|
31
|
+
* const { buildUnsupported, allowOnly, excludeOnly } = createFilterUtilities<MyKey, Record<MyKey, Component>>(
|
|
32
|
+
* keys,
|
|
33
|
+
* UnsupportedComponent,
|
|
34
|
+
* defaults
|
|
35
|
+
* )
|
|
36
|
+
*
|
|
37
|
+
* // Block all renderers
|
|
38
|
+
* const allUnsupported = buildUnsupported()
|
|
39
|
+
*
|
|
40
|
+
* // Allow only 'foo' and 'bar', block 'baz'
|
|
41
|
+
* const allowList = allowOnly(['foo', 'bar'])
|
|
42
|
+
*
|
|
43
|
+
* // Block only 'baz', allow others with defaults
|
|
44
|
+
* const denyList = excludeOnly(['baz'])
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const createFilterUtilities: <TKey extends string, TResult extends Record<string, FilterComponent>>(keys: readonly TKey[], unsupportedComponent: FilterComponent, defaultsMap: Record<TKey, FilterComponent>) => {
|
|
48
|
+
buildUnsupported: () => TResult;
|
|
49
|
+
allowOnly: (_allowed: Array<TKey | [TKey, FilterComponent]>) => TResult;
|
|
50
|
+
excludeOnly: (_excluded: TKey[], _overrides?: Array<[TKey, FilterComponent]>) => TResult;
|
|
51
|
+
};
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a set of filter utility functions for renderer maps.
|
|
3
|
+
* This factory generates three functions: buildUnsupported, allowOnly, and excludeOnly.
|
|
4
|
+
*
|
|
5
|
+
* Used to eliminate code duplication between unsupportedRenderers.ts and unsupportedHtmlRenderers.ts.
|
|
6
|
+
*
|
|
7
|
+
* @template TKey - The string literal type for valid keys
|
|
8
|
+
* @template TResult - The result map type (e.g., Partial<Renderers> or HtmlRenderers)
|
|
9
|
+
*
|
|
10
|
+
* @param keys - Array of valid keys for this renderer type
|
|
11
|
+
* @param unsupportedComponent - The component to use for unsupported/disabled renderers
|
|
12
|
+
* @param defaultsMap - Map of keys to their default component implementations
|
|
13
|
+
*
|
|
14
|
+
* @returns Object containing buildUnsupported, allowOnly, and excludeOnly functions
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { createFilterUtilities } from './createFilterUtilities'
|
|
19
|
+
*
|
|
20
|
+
* type MyKey = 'foo' | 'bar' | 'baz'
|
|
21
|
+
* const keys: readonly MyKey[] = ['foo', 'bar', 'baz'] as const
|
|
22
|
+
* const UnsupportedComponent = () => null
|
|
23
|
+
* const defaults = { foo: FooComponent, bar: BarComponent, baz: BazComponent }
|
|
24
|
+
*
|
|
25
|
+
* const { buildUnsupported, allowOnly, excludeOnly } = createFilterUtilities<MyKey, Record<MyKey, Component>>(
|
|
26
|
+
* keys,
|
|
27
|
+
* UnsupportedComponent,
|
|
28
|
+
* defaults
|
|
29
|
+
* )
|
|
30
|
+
*
|
|
31
|
+
* // Block all renderers
|
|
32
|
+
* const allUnsupported = buildUnsupported()
|
|
33
|
+
*
|
|
34
|
+
* // Allow only 'foo' and 'bar', block 'baz'
|
|
35
|
+
* const allowList = allowOnly(['foo', 'bar'])
|
|
36
|
+
*
|
|
37
|
+
* // Block only 'baz', allow others with defaults
|
|
38
|
+
* const denyList = excludeOnly(['baz'])
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export const createFilterUtilities = (keys, unsupportedComponent, defaultsMap) => {
|
|
42
|
+
/**
|
|
43
|
+
* Checks if a key is valid for this renderer type.
|
|
44
|
+
*/
|
|
45
|
+
const hasKey = (key) => keys.includes(key);
|
|
46
|
+
/**
|
|
47
|
+
* Builds a map where every key is set to the unsupported component.
|
|
48
|
+
* Useful for starting with a "deny all" approach.
|
|
49
|
+
*/
|
|
50
|
+
const buildUnsupported = () => {
|
|
51
|
+
const result = {};
|
|
52
|
+
for (const key of keys) {
|
|
53
|
+
;
|
|
54
|
+
result[key] = unsupportedComponent;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Produces a renderer map that allows only the specified keys.
|
|
60
|
+
* All non-listed keys are set to the unsupported component.
|
|
61
|
+
*
|
|
62
|
+
* Each entry can be either:
|
|
63
|
+
* - A key string (to use the default component for that key)
|
|
64
|
+
* - A tuple [key, component] to specify a custom component
|
|
65
|
+
*/
|
|
66
|
+
const allowOnly = (allowed) => {
|
|
67
|
+
const result = buildUnsupported();
|
|
68
|
+
for (const entry of allowed) {
|
|
69
|
+
if (Array.isArray(entry)) {
|
|
70
|
+
const [key, component] = entry;
|
|
71
|
+
if (hasKey(key)) {
|
|
72
|
+
;
|
|
73
|
+
result[key] = component;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const key = entry;
|
|
78
|
+
if (hasKey(key)) {
|
|
79
|
+
;
|
|
80
|
+
result[key] = defaultsMap[key];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Produces a renderer map that excludes only the specified keys.
|
|
88
|
+
* Excluded keys are set to the unsupported component.
|
|
89
|
+
* All other keys use the default components.
|
|
90
|
+
*
|
|
91
|
+
* Optionally, specific non-excluded keys can be overridden with custom components.
|
|
92
|
+
* Exclusions take precedence over overrides.
|
|
93
|
+
*/
|
|
94
|
+
const excludeOnly = (excluded, overrides) => {
|
|
95
|
+
const result = {};
|
|
96
|
+
// Start with all defaults
|
|
97
|
+
for (const key of keys) {
|
|
98
|
+
;
|
|
99
|
+
result[key] = defaultsMap[key];
|
|
100
|
+
}
|
|
101
|
+
// Mark excluded keys as unsupported
|
|
102
|
+
for (const key of excluded) {
|
|
103
|
+
if (hasKey(key)) {
|
|
104
|
+
;
|
|
105
|
+
result[key] = unsupportedComponent;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Apply overrides (exclusions take precedence)
|
|
109
|
+
if (overrides) {
|
|
110
|
+
for (const [key, component] of overrides) {
|
|
111
|
+
if (excluded.includes(key))
|
|
112
|
+
continue;
|
|
113
|
+
if (hasKey(key)) {
|
|
114
|
+
;
|
|
115
|
+
result[key] = component;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
};
|
|
121
|
+
return {
|
|
122
|
+
buildUnsupported,
|
|
123
|
+
allowOnly,
|
|
124
|
+
excludeOnly
|
|
125
|
+
};
|
|
126
|
+
};
|
|
@@ -39,6 +39,9 @@ export function parseAndCacheTokens(source, options, isInline) {
|
|
|
39
39
|
const lexer = new Lexer(options);
|
|
40
40
|
const parsedTokens = isInline ? lexer.inlineTokens(source) : lexer.lex(source);
|
|
41
41
|
const cleanedTokens = shrinkHtmlTokens(parsedTokens);
|
|
42
|
+
if (typeof options.walkTokens === 'function') {
|
|
43
|
+
cleanedTokens.forEach(options.walkTokens);
|
|
44
|
+
}
|
|
42
45
|
// Cache the cleaned tokens for next time
|
|
43
46
|
tokenCache.setTokens(source, options, cleanedTokens);
|
|
44
47
|
return cleanedTokens;
|
|
@@ -2,5 +2,5 @@ import Html from '../renderers/html/index.js';
|
|
|
2
2
|
import { type Renderers } from './markdown-parser.js';
|
|
3
3
|
export type RendererKey = Exclude<keyof Renderers, 'html'>;
|
|
4
4
|
export declare const rendererKeysInternal: RendererKey[];
|
|
5
|
-
export type HtmlKey = keyof typeof Html;
|
|
5
|
+
export type HtmlKey = keyof typeof Html & string;
|
|
6
6
|
export declare const htmlRendererKeysInternal: HtmlKey[];
|
|
@@ -19,7 +19,7 @@ export declare const buildUnsupportedHTML: () => HtmlRenderers;
|
|
|
19
19
|
* Produces an HTML renderer map that allows only the specified tags.
|
|
20
20
|
* All non‑listed tags are set to `UnsupportedHTML`.
|
|
21
21
|
*
|
|
22
|
-
* Each entry can be either a tag name (to use the library
|
|
22
|
+
* Each entry can be either a tag name (to use the library's default component for that tag),
|
|
23
23
|
* or a tuple `[tag, component]` to specify a custom component for that tag.
|
|
24
24
|
*
|
|
25
25
|
* @function allowHtmlOnly
|
|
@@ -35,11 +35,11 @@ export declare const buildUnsupportedHTML: () => HtmlRenderers;
|
|
|
35
35
|
* // Allow a custom component for div while allowing the default for a
|
|
36
36
|
* const html = allowHtmlOnly([['div', MyDiv], 'a'])
|
|
37
37
|
*/
|
|
38
|
-
export declare const allowHtmlOnly: (
|
|
38
|
+
export declare const allowHtmlOnly: (_allowed: Array<HtmlKey | [HtmlKey, Component | null]>) => HtmlRenderers;
|
|
39
39
|
/**
|
|
40
40
|
* Produces an HTML renderer map that excludes only the specified tags.
|
|
41
41
|
* Excluded tags are mapped to `UnsupportedHTML`, while all other tags use the
|
|
42
|
-
* library
|
|
42
|
+
* library's default components. Optionally, you can override specific non‑excluded
|
|
43
43
|
* tags with custom components using `[tag, component]` tuples.
|
|
44
44
|
*
|
|
45
45
|
* Exclusions take precedence over overrides. If a tag is listed in `excluded`, an
|
|
@@ -59,4 +59,4 @@ export declare const allowHtmlOnly: (allowed: Array<HtmlKey | [HtmlKey, Componen
|
|
|
59
59
|
* // Disable span; override 'a' to CustomA component
|
|
60
60
|
* const html = excludeHtmlOnly(['span'], [['a', CustomA]])
|
|
61
61
|
*/
|
|
62
|
-
export declare const excludeHtmlOnly: (
|
|
62
|
+
export declare const excludeHtmlOnly: (_excluded: HtmlKey[], _overrides?: Array<[HtmlKey, Component | null]>) => HtmlRenderers;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import Html, { UnsupportedHTML } from '../renderers/html/index.js';
|
|
2
2
|
import { htmlRendererKeysInternal } from './rendererKeys.js';
|
|
3
|
+
import { createFilterUtilities } from './createFilterUtilities.js';
|
|
4
|
+
// Create filter utilities using the generic factory
|
|
5
|
+
const filterUtils = createFilterUtilities(htmlRendererKeysInternal, UnsupportedHTML, Html);
|
|
3
6
|
/**
|
|
4
7
|
* Builds a map of HTML renderers where every known HTML tag is mapped to `UnsupportedHTML`.
|
|
5
8
|
* This is useful when you want to disable all built‑in HTML rendering and provide
|
|
@@ -13,18 +16,12 @@ import { htmlRendererKeysInternal } from './rendererKeys.js';
|
|
|
13
16
|
* html: buildUnsupportedHTML()
|
|
14
17
|
* }
|
|
15
18
|
*/
|
|
16
|
-
export const buildUnsupportedHTML =
|
|
17
|
-
const result = {};
|
|
18
|
-
for (const key of htmlRendererKeysInternal) {
|
|
19
|
-
result[key] = UnsupportedHTML;
|
|
20
|
-
}
|
|
21
|
-
return result;
|
|
22
|
-
};
|
|
19
|
+
export const buildUnsupportedHTML = filterUtils.buildUnsupported;
|
|
23
20
|
/**
|
|
24
21
|
* Produces an HTML renderer map that allows only the specified tags.
|
|
25
22
|
* All non‑listed tags are set to `UnsupportedHTML`.
|
|
26
23
|
*
|
|
27
|
-
* Each entry can be either a tag name (to use the library
|
|
24
|
+
* Each entry can be either a tag name (to use the library's default component for that tag),
|
|
28
25
|
* or a tuple `[tag, component]` to specify a custom component for that tag.
|
|
29
26
|
*
|
|
30
27
|
* @function allowHtmlOnly
|
|
@@ -40,27 +37,11 @@ export const buildUnsupportedHTML = () => {
|
|
|
40
37
|
* // Allow a custom component for div while allowing the default for a
|
|
41
38
|
* const html = allowHtmlOnly([['div', MyDiv], 'a'])
|
|
42
39
|
*/
|
|
43
|
-
export const allowHtmlOnly =
|
|
44
|
-
const result = buildUnsupportedHTML();
|
|
45
|
-
for (const entry of allowed) {
|
|
46
|
-
if (Array.isArray(entry)) {
|
|
47
|
-
const [tag, component] = entry;
|
|
48
|
-
// Only set if the tag exists in our Html map
|
|
49
|
-
if (tag in Html)
|
|
50
|
-
result[tag] = component;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
const tag = entry;
|
|
54
|
-
if (tag in Html)
|
|
55
|
-
result[tag] = Html[tag];
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return result;
|
|
59
|
-
};
|
|
40
|
+
export const allowHtmlOnly = filterUtils.allowOnly;
|
|
60
41
|
/**
|
|
61
42
|
* Produces an HTML renderer map that excludes only the specified tags.
|
|
62
43
|
* Excluded tags are mapped to `UnsupportedHTML`, while all other tags use the
|
|
63
|
-
* library
|
|
44
|
+
* library's default components. Optionally, you can override specific non‑excluded
|
|
64
45
|
* tags with custom components using `[tag, component]` tuples.
|
|
65
46
|
*
|
|
66
47
|
* Exclusions take precedence over overrides. If a tag is listed in `excluded`, an
|
|
@@ -80,20 +61,4 @@ export const allowHtmlOnly = (allowed) => {
|
|
|
80
61
|
* // Disable span; override 'a' to CustomA component
|
|
81
62
|
* const html = excludeHtmlOnly(['span'], [['a', CustomA]])
|
|
82
63
|
*/
|
|
83
|
-
export const excludeHtmlOnly =
|
|
84
|
-
const result = { ...Html };
|
|
85
|
-
for (const tag of excluded) {
|
|
86
|
-
if (tag in Html)
|
|
87
|
-
result[tag] = UnsupportedHTML;
|
|
88
|
-
}
|
|
89
|
-
if (overrides) {
|
|
90
|
-
for (const [tag, component] of overrides) {
|
|
91
|
-
// Exclusions take precedence; do not override excluded tags
|
|
92
|
-
if (excluded.includes(tag))
|
|
93
|
-
continue;
|
|
94
|
-
if (tag in Html)
|
|
95
|
-
result[tag] = component;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return result;
|
|
99
|
-
};
|
|
64
|
+
export const excludeHtmlOnly = filterUtils.excludeOnly;
|
|
@@ -5,7 +5,7 @@ import { type RendererKey } from './rendererKeys.js';
|
|
|
5
5
|
* is set to the `Unsupported` component.
|
|
6
6
|
*
|
|
7
7
|
* @function buildUnsupportedRenderers
|
|
8
|
-
* @returns {
|
|
8
|
+
* @returns {Omit<Renderers, 'html'>} A map with all non‑HTML renderers set to `Unsupported`.
|
|
9
9
|
* @example
|
|
10
10
|
* import { buildUnsupportedRenderers } from '@humanspeak/svelte-markdown'
|
|
11
11
|
* const renderers = {
|
|
@@ -13,17 +13,17 @@ import { type RendererKey } from './rendererKeys.js';
|
|
|
13
13
|
* html: {} // customize HTML separately
|
|
14
14
|
* }
|
|
15
15
|
*/
|
|
16
|
-
export declare const buildUnsupportedRenderers: () =>
|
|
16
|
+
export declare const buildUnsupportedRenderers: () => Omit<Renderers, "html">;
|
|
17
17
|
/**
|
|
18
18
|
* Produces a renderer map that allows only the specified markdown renderers (excluding `html`).
|
|
19
19
|
* All non‑listed renderer keys are set to `Unsupported`.
|
|
20
|
-
* Each entry can be either a renderer key (to use the library
|
|
20
|
+
* Each entry can be either a renderer key (to use the library's default component),
|
|
21
21
|
* or a tuple `[key, component]` to specify a custom component for that key.
|
|
22
22
|
*
|
|
23
23
|
* @function allowRenderersOnly
|
|
24
24
|
* @param {Array<RendererKey | [RendererKey, RendererComponent]>} allowed
|
|
25
25
|
* Renderer keys to allow, or tuples for custom component overrides.
|
|
26
|
-
* @returns {
|
|
26
|
+
* @returns {Omit<Renderers, 'html'>} A renderer map with only the provided keys enabled.
|
|
27
27
|
* @example
|
|
28
28
|
* // Allow only paragraph and link with defaults
|
|
29
29
|
* const renderers = allowRenderersOnly(['paragraph', 'link'])
|
|
@@ -32,10 +32,10 @@ export declare const buildUnsupportedRenderers: () => Partial<Renderers>;
|
|
|
32
32
|
* // Allow paragraph with a custom component
|
|
33
33
|
* const renderers = allowRenderersOnly([['paragraph', MyParagraph]])
|
|
34
34
|
*/
|
|
35
|
-
export declare const allowRenderersOnly: (
|
|
35
|
+
export declare const allowRenderersOnly: (_allowed: Array<RendererKey | [RendererKey, RendererComponent]>) => Omit<Renderers, "html">;
|
|
36
36
|
/**
|
|
37
37
|
* Produces a renderer map that excludes only the specified markdown renderer keys (excluding `html`).
|
|
38
|
-
* Excluded keys are mapped to `Unsupported`, while all other keys use the library
|
|
38
|
+
* Excluded keys are mapped to `Unsupported`, while all other keys use the library's default components.
|
|
39
39
|
* Optionally override specific non‑excluded keys with custom components via `[key, component]` tuples.
|
|
40
40
|
*
|
|
41
41
|
* Exclusions take precedence over overrides.
|
|
@@ -45,7 +45,7 @@ export declare const allowRenderersOnly: (allowed: Array<RendererKey | [Renderer
|
|
|
45
45
|
* Renderer keys to exclude (set to `Unsupported`).
|
|
46
46
|
* @param {Array<[RendererKey, RendererComponent]>} [overrides]
|
|
47
47
|
* Optional tuples mapping non‑excluded keys to custom components.
|
|
48
|
-
* @returns {
|
|
48
|
+
* @returns {Omit<Renderers, 'html'>} A renderer map with only the provided keys excluded.
|
|
49
49
|
* @example
|
|
50
50
|
* // Disable just paragraph and link, keep others as defaults
|
|
51
51
|
* const renderers = excludeRenderersOnly(['paragraph', 'link'])
|
|
@@ -54,4 +54,4 @@ export declare const allowRenderersOnly: (allowed: Array<RendererKey | [Renderer
|
|
|
54
54
|
* // Disable link; override paragraph to a custom component
|
|
55
55
|
* const renderers = excludeRenderersOnly(['link'], [['paragraph', MyParagraph]])
|
|
56
56
|
*/
|
|
57
|
-
export declare const excludeRenderersOnly: (
|
|
57
|
+
export declare const excludeRenderersOnly: (_excluded: RendererKey[], _overrides?: Array<[RendererKey, RendererComponent]>) => Omit<Renderers, "html">;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Unsupported } from '../renderers/index.js';
|
|
2
2
|
import { defaultRenderers } from './markdown-parser.js';
|
|
3
3
|
import { rendererKeysInternal } from './rendererKeys.js';
|
|
4
|
-
|
|
4
|
+
import { createFilterUtilities } from './createFilterUtilities.js';
|
|
5
|
+
// Create filter utilities using the generic factory
|
|
6
|
+
const filterUtils = createFilterUtilities(rendererKeysInternal, Unsupported, defaultRenderers);
|
|
5
7
|
/**
|
|
6
8
|
* Builds a map where every markdown renderer (excluding the special `html` map)
|
|
7
9
|
* is set to the `Unsupported` component.
|
|
8
10
|
*
|
|
9
11
|
* @function buildUnsupportedRenderers
|
|
10
|
-
* @returns {
|
|
12
|
+
* @returns {Omit<Renderers, 'html'>} A map with all non‑HTML renderers set to `Unsupported`.
|
|
11
13
|
* @example
|
|
12
14
|
* import { buildUnsupportedRenderers } from '@humanspeak/svelte-markdown'
|
|
13
15
|
* const renderers = {
|
|
@@ -15,23 +17,17 @@ const allRendererKeys = rendererKeysInternal;
|
|
|
15
17
|
* html: {} // customize HTML separately
|
|
16
18
|
* }
|
|
17
19
|
*/
|
|
18
|
-
export const buildUnsupportedRenderers =
|
|
19
|
-
const result = {};
|
|
20
|
-
for (const key of allRendererKeys) {
|
|
21
|
-
result[key] = Unsupported;
|
|
22
|
-
}
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
20
|
+
export const buildUnsupportedRenderers = filterUtils.buildUnsupported;
|
|
25
21
|
/**
|
|
26
22
|
* Produces a renderer map that allows only the specified markdown renderers (excluding `html`).
|
|
27
23
|
* All non‑listed renderer keys are set to `Unsupported`.
|
|
28
|
-
* Each entry can be either a renderer key (to use the library
|
|
24
|
+
* Each entry can be either a renderer key (to use the library's default component),
|
|
29
25
|
* or a tuple `[key, component]` to specify a custom component for that key.
|
|
30
26
|
*
|
|
31
27
|
* @function allowRenderersOnly
|
|
32
28
|
* @param {Array<RendererKey | [RendererKey, RendererComponent]>} allowed
|
|
33
29
|
* Renderer keys to allow, or tuples for custom component overrides.
|
|
34
|
-
* @returns {
|
|
30
|
+
* @returns {Omit<Renderers, 'html'>} A renderer map with only the provided keys enabled.
|
|
35
31
|
* @example
|
|
36
32
|
* // Allow only paragraph and link with defaults
|
|
37
33
|
* const renderers = allowRenderersOnly(['paragraph', 'link'])
|
|
@@ -40,25 +36,10 @@ export const buildUnsupportedRenderers = () => {
|
|
|
40
36
|
* // Allow paragraph with a custom component
|
|
41
37
|
* const renderers = allowRenderersOnly([['paragraph', MyParagraph]])
|
|
42
38
|
*/
|
|
43
|
-
export const allowRenderersOnly =
|
|
44
|
-
const result = buildUnsupportedRenderers();
|
|
45
|
-
for (const entry of allowed) {
|
|
46
|
-
if (Array.isArray(entry)) {
|
|
47
|
-
const [key, component] = entry;
|
|
48
|
-
if (allRendererKeys.includes(key))
|
|
49
|
-
result[key] = component;
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
const key = entry;
|
|
53
|
-
if (allRendererKeys.includes(key))
|
|
54
|
-
result[key] = defaultRenderers[key];
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return result;
|
|
58
|
-
};
|
|
39
|
+
export const allowRenderersOnly = filterUtils.allowOnly;
|
|
59
40
|
/**
|
|
60
41
|
* Produces a renderer map that excludes only the specified markdown renderer keys (excluding `html`).
|
|
61
|
-
* Excluded keys are mapped to `Unsupported`, while all other keys use the library
|
|
42
|
+
* Excluded keys are mapped to `Unsupported`, while all other keys use the library's default components.
|
|
62
43
|
* Optionally override specific non‑excluded keys with custom components via `[key, component]` tuples.
|
|
63
44
|
*
|
|
64
45
|
* Exclusions take precedence over overrides.
|
|
@@ -68,7 +49,7 @@ export const allowRenderersOnly = (allowed) => {
|
|
|
68
49
|
* Renderer keys to exclude (set to `Unsupported`).
|
|
69
50
|
* @param {Array<[RendererKey, RendererComponent]>} [overrides]
|
|
70
51
|
* Optional tuples mapping non‑excluded keys to custom components.
|
|
71
|
-
* @returns {
|
|
52
|
+
* @returns {Omit<Renderers, 'html'>} A renderer map with only the provided keys excluded.
|
|
72
53
|
* @example
|
|
73
54
|
* // Disable just paragraph and link, keep others as defaults
|
|
74
55
|
* const renderers = excludeRenderersOnly(['paragraph', 'link'])
|
|
@@ -77,22 +58,4 @@ export const allowRenderersOnly = (allowed) => {
|
|
|
77
58
|
* // Disable link; override paragraph to a custom component
|
|
78
59
|
* const renderers = excludeRenderersOnly(['link'], [['paragraph', MyParagraph]])
|
|
79
60
|
*/
|
|
80
|
-
export const excludeRenderersOnly =
|
|
81
|
-
const result = {};
|
|
82
|
-
for (const key of allRendererKeys) {
|
|
83
|
-
result[key] = defaultRenderers[key];
|
|
84
|
-
}
|
|
85
|
-
for (const key of excluded) {
|
|
86
|
-
if (allRendererKeys.includes(key))
|
|
87
|
-
result[key] = Unsupported;
|
|
88
|
-
}
|
|
89
|
-
if (overrides) {
|
|
90
|
-
for (const [key, component] of overrides) {
|
|
91
|
-
if (excluded.includes(key))
|
|
92
|
-
continue;
|
|
93
|
-
if (allRendererKeys.includes(key))
|
|
94
|
-
result[key] = component;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return result;
|
|
98
|
-
};
|
|
61
|
+
export const excludeRenderersOnly = filterUtils.excludeOnly;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@humanspeak/svelte-markdown",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.14",
|
|
4
4
|
"description": "Fast, customizable markdown renderer for Svelte with built-in caching, TypeScript support, and Svelte 5 runes",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"svelte",
|
|
@@ -63,51 +63,52 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
+
"@humanspeak/memory-cache": "^1.0.2",
|
|
66
67
|
"github-slugger": "^2.0.0",
|
|
67
68
|
"htmlparser2": "^10.0.0",
|
|
68
|
-
"marked": "^
|
|
69
|
+
"marked": "^17.0.1"
|
|
69
70
|
},
|
|
70
71
|
"devDependencies": {
|
|
71
|
-
"@eslint/compat": "^
|
|
72
|
-
"@eslint/js": "^9.
|
|
73
|
-
"@playwright/test": "^1.
|
|
74
|
-
"@sveltejs/adapter-auto": "^
|
|
75
|
-
"@sveltejs/kit": "^2.
|
|
76
|
-
"@sveltejs/package": "^2.5.
|
|
77
|
-
"@sveltejs/vite-plugin-svelte": "^6.2.
|
|
72
|
+
"@eslint/compat": "^2.0.0",
|
|
73
|
+
"@eslint/js": "^9.39.2",
|
|
74
|
+
"@playwright/test": "^1.57.0",
|
|
75
|
+
"@sveltejs/adapter-auto": "^7.0.0",
|
|
76
|
+
"@sveltejs/kit": "^2.49.3",
|
|
77
|
+
"@sveltejs/package": "^2.5.7",
|
|
78
|
+
"@sveltejs/vite-plugin-svelte": "^6.2.2",
|
|
78
79
|
"@testing-library/jest-dom": "^6.9.1",
|
|
79
|
-
"@testing-library/svelte": "^5.
|
|
80
|
+
"@testing-library/svelte": "^5.3.1",
|
|
80
81
|
"@testing-library/user-event": "^14.6.1",
|
|
81
|
-
"@types/node": "^
|
|
82
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
83
|
-
"@typescript-eslint/parser": "^8.
|
|
84
|
-
"@vitest/coverage-v8": "^
|
|
82
|
+
"@types/node": "^25.0.3",
|
|
83
|
+
"@typescript-eslint/eslint-plugin": "^8.52.0",
|
|
84
|
+
"@typescript-eslint/parser": "^8.52.0",
|
|
85
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
85
86
|
"concurrently": "^9.2.1",
|
|
86
|
-
"eslint": "^9.
|
|
87
|
+
"eslint": "^9.39.2",
|
|
87
88
|
"eslint-config-prettier": "^10.1.8",
|
|
88
89
|
"eslint-plugin-import": "^2.32.0",
|
|
89
|
-
"eslint-plugin-svelte": "^3.
|
|
90
|
-
"eslint-plugin-unused-imports": "^4.
|
|
91
|
-
"globals": "^
|
|
90
|
+
"eslint-plugin-svelte": "^3.13.1",
|
|
91
|
+
"eslint-plugin-unused-imports": "^4.3.0",
|
|
92
|
+
"globals": "^17.0.0",
|
|
92
93
|
"husky": "^9.1.7",
|
|
93
|
-
"jsdom": "^27.
|
|
94
|
-
"prettier": "^3.
|
|
94
|
+
"jsdom": "^27.4.0",
|
|
95
|
+
"prettier": "^3.7.4",
|
|
95
96
|
"prettier-plugin-organize-imports": "^4.3.0",
|
|
96
|
-
"prettier-plugin-svelte": "^3.4.
|
|
97
|
-
"prettier-plugin-tailwindcss": "^0.
|
|
98
|
-
"publint": "^0.3.
|
|
99
|
-
"svelte": "^5.
|
|
100
|
-
"svelte-check": "^4.3.
|
|
97
|
+
"prettier-plugin-svelte": "^3.4.1",
|
|
98
|
+
"prettier-plugin-tailwindcss": "^0.7.2",
|
|
99
|
+
"publint": "^0.3.16",
|
|
100
|
+
"svelte": "^5.46.1",
|
|
101
|
+
"svelte-check": "^4.3.5",
|
|
101
102
|
"typescript": "^5.9.3",
|
|
102
|
-
"typescript-eslint": "^8.
|
|
103
|
-
"vite": "^7.1
|
|
104
|
-
"vitest": "^
|
|
103
|
+
"typescript-eslint": "^8.52.0",
|
|
104
|
+
"vite": "^7.3.1",
|
|
105
|
+
"vitest": "^4.0.16"
|
|
105
106
|
},
|
|
106
107
|
"peerDependencies": {
|
|
107
108
|
"svelte": "^5.0.0"
|
|
108
109
|
},
|
|
109
110
|
"volta": {
|
|
110
|
-
"node": "
|
|
111
|
+
"node": "24.12.0"
|
|
111
112
|
},
|
|
112
113
|
"publishConfig": {
|
|
113
114
|
"access": "public"
|