@fuzdev/fuz_util 0.50.1 → 0.52.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/dist/async.d.ts +21 -15
- package/dist/async.d.ts.map +1 -1
- package/dist/async.js +134 -75
- package/dist/path.d.ts +8 -2
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +8 -2
- package/dist/process.d.ts +4 -1
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +4 -1
- package/dist/source_json.d.ts +106 -6
- package/dist/source_json.d.ts.map +1 -1
- package/dist/source_json.js +27 -2
- package/package.json +10 -6
- package/src/lib/async.ts +146 -83
- package/src/lib/path.ts +8 -2
- package/src/lib/process.ts +4 -1
- package/src/lib/source_json.ts +27 -2
package/src/lib/async.ts
CHANGED
|
@@ -13,7 +13,7 @@ export const is_promise = (value: unknown): value is Promise<unknown> =>
|
|
|
13
13
|
value != null && typeof (value as Promise<unknown>).then === 'function';
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* A deferred object with a promise and its resolve/reject handlers.
|
|
17
17
|
*/
|
|
18
18
|
export interface Deferred<T> {
|
|
19
19
|
promise: Promise<T>;
|
|
@@ -22,7 +22,7 @@ export interface Deferred<T> {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* Creates
|
|
25
|
+
* Creates an object with a `promise` and its `resolve`/`reject` handlers.
|
|
26
26
|
*/
|
|
27
27
|
export const create_deferred = <T>(): Deferred<T> => {
|
|
28
28
|
let resolve!: (value: T) => void;
|
|
@@ -35,72 +35,87 @@ export const create_deferred = <T>(): Deferred<T> => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
* Runs
|
|
38
|
+
* Runs a function on each item with controlled concurrency.
|
|
39
39
|
* Like `map_concurrent` but doesn't collect results (more efficient for side effects).
|
|
40
40
|
*
|
|
41
|
-
* @param items
|
|
42
|
-
* @param fn async function to apply to each item
|
|
41
|
+
* @param items items to process
|
|
43
42
|
* @param concurrency maximum number of concurrent operations
|
|
43
|
+
* @param fn function to apply to each item
|
|
44
|
+
* @param signal optional `AbortSignal` to cancel processing
|
|
44
45
|
*
|
|
45
46
|
* @example
|
|
46
47
|
* ```ts
|
|
47
48
|
* await each_concurrent(
|
|
48
49
|
* file_paths,
|
|
49
|
-
* async (path) => { await unlink(path); },
|
|
50
50
|
* 5, // max 5 concurrent deletions
|
|
51
|
+
* async (path) => { await unlink(path); },
|
|
51
52
|
* );
|
|
52
53
|
* ```
|
|
53
54
|
*/
|
|
54
55
|
export const each_concurrent = async <T>(
|
|
55
|
-
items:
|
|
56
|
-
fn: (item: T, index: number) => Promise<void>,
|
|
56
|
+
items: Iterable<T>,
|
|
57
57
|
concurrency: number,
|
|
58
|
+
fn: (item: T, index: number) => Promise<void> | void,
|
|
59
|
+
signal?: AbortSignal,
|
|
58
60
|
): Promise<void> => {
|
|
59
|
-
if (concurrency
|
|
61
|
+
if (!(concurrency >= 1)) {
|
|
60
62
|
throw new Error('concurrency must be at least 1');
|
|
61
63
|
}
|
|
62
64
|
|
|
65
|
+
const iterator = items[Symbol.iterator]();
|
|
63
66
|
let next_index = 0;
|
|
64
67
|
let active_count = 0;
|
|
65
68
|
let rejected = false;
|
|
66
69
|
|
|
67
70
|
return new Promise((resolve, reject) => {
|
|
68
|
-
const
|
|
69
|
-
|
|
71
|
+
const cleanup = signal ? () => signal.removeEventListener('abort', on_abort) : undefined;
|
|
72
|
+
|
|
73
|
+
const done = (): void => {
|
|
74
|
+
cleanup?.();
|
|
75
|
+
resolve();
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const fail = (error: unknown): void => {
|
|
70
79
|
if (rejected) return;
|
|
80
|
+
rejected = true;
|
|
81
|
+
cleanup?.();
|
|
82
|
+
reject(error); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
|
|
83
|
+
};
|
|
71
84
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
85
|
+
function on_abort(): void {
|
|
86
|
+
fail(signal!.reason);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (signal?.aborted) {
|
|
90
|
+
fail(signal.reason);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
signal?.addEventListener('abort', on_abort);
|
|
94
|
+
|
|
95
|
+
const run_next = (): void => {
|
|
96
|
+
if (rejected) return;
|
|
77
97
|
|
|
78
98
|
// Spawn workers up to concurrency limit
|
|
79
|
-
while (active_count < concurrency
|
|
99
|
+
while (active_count < concurrency) {
|
|
100
|
+
const next = iterator.next();
|
|
101
|
+
if (next.done) {
|
|
102
|
+
if (active_count === 0) done();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
80
105
|
const index = next_index++;
|
|
81
|
-
const item =
|
|
106
|
+
const item = next.value;
|
|
82
107
|
active_count++;
|
|
83
108
|
|
|
84
|
-
fn(item, index)
|
|
109
|
+
new Promise<void>((r) => r(fn(item, index)))
|
|
85
110
|
.then(() => {
|
|
86
111
|
if (rejected) return;
|
|
87
112
|
active_count--;
|
|
88
113
|
run_next();
|
|
89
114
|
})
|
|
90
|
-
.catch(
|
|
91
|
-
if (rejected) return;
|
|
92
|
-
rejected = true;
|
|
93
|
-
reject(error); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
|
|
94
|
-
});
|
|
115
|
+
.catch(fail);
|
|
95
116
|
}
|
|
96
117
|
};
|
|
97
118
|
|
|
98
|
-
// Handle empty array
|
|
99
|
-
if (items.length === 0) {
|
|
100
|
-
resolve();
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
119
|
run_next();
|
|
105
120
|
});
|
|
106
121
|
};
|
|
@@ -108,72 +123,87 @@ export const each_concurrent = async <T>(
|
|
|
108
123
|
/**
|
|
109
124
|
* Maps over items with controlled concurrency, preserving input order.
|
|
110
125
|
*
|
|
111
|
-
* @param items
|
|
112
|
-
* @param fn async function to apply to each item
|
|
126
|
+
* @param items items to process
|
|
113
127
|
* @param concurrency maximum number of concurrent operations
|
|
128
|
+
* @param fn function to apply to each item
|
|
129
|
+
* @param signal optional `AbortSignal` to cancel processing
|
|
114
130
|
* @returns promise resolving to array of results in same order as input
|
|
115
131
|
*
|
|
116
132
|
* @example
|
|
117
133
|
* ```ts
|
|
118
134
|
* const results = await map_concurrent(
|
|
119
135
|
* file_paths,
|
|
120
|
-
* async (path) => readFile(path, 'utf8'),
|
|
121
136
|
* 5, // max 5 concurrent reads
|
|
137
|
+
* async (path) => readFile(path, 'utf8'),
|
|
122
138
|
* );
|
|
123
139
|
* ```
|
|
124
140
|
*/
|
|
125
141
|
export const map_concurrent = async <T, R>(
|
|
126
|
-
items:
|
|
127
|
-
fn: (item: T, index: number) => Promise<R>,
|
|
142
|
+
items: Iterable<T>,
|
|
128
143
|
concurrency: number,
|
|
144
|
+
fn: (item: T, index: number) => Promise<R> | R,
|
|
145
|
+
signal?: AbortSignal,
|
|
129
146
|
): Promise<Array<R>> => {
|
|
130
|
-
if (concurrency
|
|
147
|
+
if (!(concurrency >= 1)) {
|
|
131
148
|
throw new Error('concurrency must be at least 1');
|
|
132
149
|
}
|
|
133
150
|
|
|
134
|
-
const results: Array<R> =
|
|
151
|
+
const results: Array<R> = [];
|
|
152
|
+
const iterator = items[Symbol.iterator]();
|
|
135
153
|
let next_index = 0;
|
|
136
154
|
let active_count = 0;
|
|
137
155
|
let rejected = false;
|
|
138
156
|
|
|
139
157
|
return new Promise((resolve, reject) => {
|
|
140
|
-
const
|
|
141
|
-
|
|
158
|
+
const cleanup = signal ? () => signal.removeEventListener('abort', on_abort) : undefined;
|
|
159
|
+
|
|
160
|
+
const done = (): void => {
|
|
161
|
+
cleanup?.();
|
|
162
|
+
resolve(results);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const fail = (error: unknown): void => {
|
|
142
166
|
if (rejected) return;
|
|
167
|
+
rejected = true;
|
|
168
|
+
cleanup?.();
|
|
169
|
+
reject(error); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
|
|
170
|
+
};
|
|
143
171
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
172
|
+
function on_abort(): void {
|
|
173
|
+
fail(signal!.reason);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (signal?.aborted) {
|
|
177
|
+
fail(signal.reason);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
signal?.addEventListener('abort', on_abort);
|
|
181
|
+
|
|
182
|
+
const run_next = (): void => {
|
|
183
|
+
if (rejected) return;
|
|
149
184
|
|
|
150
185
|
// Spawn workers up to concurrency limit
|
|
151
|
-
while (active_count < concurrency
|
|
186
|
+
while (active_count < concurrency) {
|
|
187
|
+
const next = iterator.next();
|
|
188
|
+
if (next.done) {
|
|
189
|
+
if (active_count === 0) done();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
152
192
|
const index = next_index++;
|
|
153
|
-
const item =
|
|
193
|
+
const item = next.value;
|
|
154
194
|
active_count++;
|
|
155
195
|
|
|
156
|
-
fn(item, index)
|
|
196
|
+
new Promise<R>((r) => r(fn(item, index)))
|
|
157
197
|
.then((result) => {
|
|
158
198
|
if (rejected) return;
|
|
159
199
|
results[index] = result;
|
|
160
200
|
active_count--;
|
|
161
201
|
run_next();
|
|
162
202
|
})
|
|
163
|
-
.catch(
|
|
164
|
-
if (rejected) return;
|
|
165
|
-
rejected = true;
|
|
166
|
-
reject(error); // eslint-disable-line @typescript-eslint/prefer-promise-reject-errors
|
|
167
|
-
});
|
|
203
|
+
.catch(fail);
|
|
168
204
|
}
|
|
169
205
|
};
|
|
170
206
|
|
|
171
|
-
// Handle empty array
|
|
172
|
-
if (items.length === 0) {
|
|
173
|
-
resolve(results);
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
207
|
run_next();
|
|
178
208
|
});
|
|
179
209
|
};
|
|
@@ -182,14 +212,18 @@ export const map_concurrent = async <T, R>(
|
|
|
182
212
|
* Like `map_concurrent` but collects all results/errors instead of failing fast.
|
|
183
213
|
* Returns an array of settlement objects matching the `Promise.allSettled` pattern.
|
|
184
214
|
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
215
|
+
* On abort, resolves with partial results: completed items keep their real settlements,
|
|
216
|
+
* in-flight and un-started items are settled as rejected with the abort reason.
|
|
217
|
+
*
|
|
218
|
+
* @param items items to process
|
|
187
219
|
* @param concurrency maximum number of concurrent operations
|
|
220
|
+
* @param fn function to apply to each item
|
|
221
|
+
* @param signal optional `AbortSignal` to cancel processing
|
|
188
222
|
* @returns promise resolving to array of `PromiseSettledResult` objects in input order
|
|
189
223
|
*
|
|
190
224
|
* @example
|
|
191
225
|
* ```ts
|
|
192
|
-
* const results = await map_concurrent_settled(urls,
|
|
226
|
+
* const results = await map_concurrent_settled(urls, 5, fetch);
|
|
193
227
|
* for (const [i, result] of results.entries()) {
|
|
194
228
|
* if (result.status === 'fulfilled') {
|
|
195
229
|
* console.log(`${urls[i]}: ${result.value.status}`);
|
|
@@ -200,52 +234,78 @@ export const map_concurrent = async <T, R>(
|
|
|
200
234
|
* ```
|
|
201
235
|
*/
|
|
202
236
|
export const map_concurrent_settled = async <T, R>(
|
|
203
|
-
items:
|
|
204
|
-
fn: (item: T, index: number) => Promise<R>,
|
|
237
|
+
items: Iterable<T>,
|
|
205
238
|
concurrency: number,
|
|
239
|
+
fn: (item: T, index: number) => Promise<R> | R,
|
|
240
|
+
signal?: AbortSignal,
|
|
206
241
|
): Promise<Array<PromiseSettledResult<R>>> => {
|
|
207
|
-
if (concurrency
|
|
242
|
+
if (!(concurrency >= 1)) {
|
|
208
243
|
throw new Error('concurrency must be at least 1');
|
|
209
244
|
}
|
|
210
245
|
|
|
211
|
-
const results: Array<PromiseSettledResult<R>> =
|
|
246
|
+
const results: Array<PromiseSettledResult<R>> = [];
|
|
247
|
+
const iterator = items[Symbol.iterator]();
|
|
212
248
|
let next_index = 0;
|
|
213
249
|
let active_count = 0;
|
|
250
|
+
let aborted = false;
|
|
214
251
|
|
|
215
252
|
return new Promise((resolve) => {
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
253
|
+
const cleanup = signal ? () => signal.removeEventListener('abort', on_abort) : undefined;
|
|
254
|
+
|
|
255
|
+
const done = (): void => {
|
|
256
|
+
cleanup?.();
|
|
257
|
+
resolve(results);
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
function on_abort(): void {
|
|
261
|
+
if (aborted) return;
|
|
262
|
+
aborted = true;
|
|
263
|
+
cleanup?.();
|
|
264
|
+
// Settle in-flight items as rejected with the abort reason
|
|
265
|
+
const reason: unknown = signal!.reason;
|
|
266
|
+
for (let i = 0; i < next_index; i++) {
|
|
267
|
+
if (!(i in results)) {
|
|
268
|
+
results[i] = {status: 'rejected', reason};
|
|
269
|
+
}
|
|
221
270
|
}
|
|
271
|
+
resolve(results);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (signal?.aborted) {
|
|
275
|
+
resolve(results);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
signal?.addEventListener('abort', on_abort);
|
|
279
|
+
|
|
280
|
+
const run_next = (): void => {
|
|
281
|
+
if (aborted) return;
|
|
222
282
|
|
|
223
283
|
// Spawn workers up to concurrency limit
|
|
224
|
-
while (active_count < concurrency
|
|
284
|
+
while (active_count < concurrency) {
|
|
285
|
+
const next = iterator.next();
|
|
286
|
+
if (next.done) {
|
|
287
|
+
if (active_count === 0) done();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
225
290
|
const index = next_index++;
|
|
226
|
-
const item =
|
|
291
|
+
const item = next.value;
|
|
227
292
|
active_count++;
|
|
228
293
|
|
|
229
|
-
fn(item, index)
|
|
294
|
+
new Promise<R>((r) => r(fn(item, index)))
|
|
230
295
|
.then((value) => {
|
|
231
|
-
results[index] = {status: 'fulfilled', value};
|
|
296
|
+
if (!aborted) results[index] = {status: 'fulfilled', value};
|
|
232
297
|
})
|
|
233
298
|
.catch((reason: unknown) => {
|
|
234
|
-
results[index] = {status: 'rejected', reason};
|
|
299
|
+
if (!aborted) results[index] = {status: 'rejected', reason};
|
|
235
300
|
})
|
|
236
301
|
.finally(() => {
|
|
302
|
+
if (aborted) return;
|
|
237
303
|
active_count--;
|
|
238
304
|
run_next();
|
|
239
305
|
});
|
|
240
306
|
}
|
|
241
307
|
};
|
|
242
308
|
|
|
243
|
-
// Handle empty array
|
|
244
|
-
if (items.length === 0) {
|
|
245
|
-
resolve(results);
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
309
|
run_next();
|
|
250
310
|
});
|
|
251
311
|
};
|
|
@@ -260,13 +320,16 @@ export class AsyncSemaphore {
|
|
|
260
320
|
#waiters: Array<() => void> = [];
|
|
261
321
|
|
|
262
322
|
constructor(permits: number) {
|
|
323
|
+
if (!(permits >= 0)) {
|
|
324
|
+
throw new Error('permits must be >= 0');
|
|
325
|
+
}
|
|
263
326
|
this.#permits = permits;
|
|
264
327
|
}
|
|
265
328
|
|
|
266
|
-
|
|
329
|
+
acquire(): Promise<void> {
|
|
267
330
|
if (this.#permits > 0) {
|
|
268
331
|
this.#permits--;
|
|
269
|
-
return;
|
|
332
|
+
return Promise.resolve();
|
|
270
333
|
}
|
|
271
334
|
return new Promise<void>((resolve) => {
|
|
272
335
|
this.#waiters.push(resolve);
|
package/src/lib/path.ts
CHANGED
|
@@ -37,7 +37,10 @@ export const to_file_path = (path_or_url: string | URL): string =>
|
|
|
37
37
|
typeof path_or_url === 'string' ? path_or_url : decodeURIComponent(path_or_url.pathname);
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* @example
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* parse_path_parts('./foo/bar/baz.ts') // => ['foo', 'foo/bar', 'foo/bar/baz.ts']
|
|
43
|
+
* ```
|
|
41
44
|
*/
|
|
42
45
|
export const parse_path_parts = (path: string): Array<string> => {
|
|
43
46
|
const segments = parse_path_segments(path);
|
|
@@ -53,7 +56,10 @@ export const parse_path_parts = (path: string): Array<string> => {
|
|
|
53
56
|
|
|
54
57
|
/**
|
|
55
58
|
* Gets the individual parts of a path, ignoring dots and separators.
|
|
56
|
-
* @example
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* parse_path_segments('/foo/bar/baz.ts') // => ['foo', 'bar', 'baz.ts']
|
|
62
|
+
* ```
|
|
57
63
|
*/
|
|
58
64
|
export const parse_path_segments = (path: string): Array<string> =>
|
|
59
65
|
path.split('/').filter((s) => s && s !== '.' && s !== '..');
|
package/src/lib/process.ts
CHANGED
|
@@ -616,7 +616,10 @@ export const spawn_detached = (
|
|
|
616
616
|
/**
|
|
617
617
|
* Formats a child process for display.
|
|
618
618
|
*
|
|
619
|
-
* @example
|
|
619
|
+
* @example
|
|
620
|
+
* ```ts
|
|
621
|
+
* `pid(1234) <- node server.js`
|
|
622
|
+
* ```
|
|
620
623
|
*/
|
|
621
624
|
export const print_child_process = (child: ChildProcess): string =>
|
|
622
625
|
`${st('gray', 'pid(')}${child.pid ?? 'none'}${st('gray', ')')} ← ${st('green', child.spawnargs.join(' '))}`;
|
package/src/lib/source_json.ts
CHANGED
|
@@ -72,6 +72,16 @@ export const ComponentPropInfo = z.looseObject({
|
|
|
72
72
|
description: z.string().optional(),
|
|
73
73
|
default_value: z.string().optional(),
|
|
74
74
|
bindable: z.boolean().optional(),
|
|
75
|
+
/** Code examples from `@example` tags. */
|
|
76
|
+
examples: z.array(z.string()).optional(),
|
|
77
|
+
/** Deprecation message from `@deprecated` tag. */
|
|
78
|
+
deprecated_message: z.string().optional(),
|
|
79
|
+
/** Related items from `@see` tags, in raw TSDoc format. */
|
|
80
|
+
see_also: z.array(z.string()).optional(),
|
|
81
|
+
/** Exceptions from `@throws` tags. */
|
|
82
|
+
throws: z.array(z.looseObject({type: z.string().optional(), description: z.string()})).optional(),
|
|
83
|
+
/** Version introduced, from `@since` tag. */
|
|
84
|
+
since: z.string().optional(),
|
|
75
85
|
});
|
|
76
86
|
export type ComponentPropInfo = z.infer<typeof ComponentPropInfo>;
|
|
77
87
|
|
|
@@ -110,6 +120,8 @@ export const DeclarationJson = z.looseObject({
|
|
|
110
120
|
throws: z.array(z.looseObject({type: z.string().optional(), description: z.string()})).optional(),
|
|
111
121
|
/** Version introduced, from `@since` tag. */
|
|
112
122
|
since: z.string().optional(),
|
|
123
|
+
/** Mutation documentation from `@mutates` tags (non-standard), mapping parameter names to descriptions. */
|
|
124
|
+
mutates: z.record(z.string(), z.string()).optional(),
|
|
113
125
|
/** Extended classes/interfaces. */
|
|
114
126
|
extends: z.array(z.string()).optional(),
|
|
115
127
|
/** Implemented interfaces. */
|
|
@@ -136,6 +148,7 @@ export const DeclarationJson = z.looseObject({
|
|
|
136
148
|
.object({
|
|
137
149
|
module: z.string(),
|
|
138
150
|
name: z.string(),
|
|
151
|
+
kind: DeclarationKind,
|
|
139
152
|
})
|
|
140
153
|
.optional(),
|
|
141
154
|
});
|
|
@@ -174,8 +187,14 @@ export type SourceJson = z.infer<typeof SourceJson>;
|
|
|
174
187
|
|
|
175
188
|
/**
|
|
176
189
|
* Format declaration name with generic parameters for display.
|
|
177
|
-
*
|
|
190
|
+
*
|
|
191
|
+
* @deprecated Use `getDisplayName` from `@fuzdev/svelte-docinfo/types.js` instead.
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```ts
|
|
195
|
+
* declaration_get_display_name({name: 'Map', kind: 'type', generic_params: [{name: 'K'}, {name: 'V'}]})
|
|
178
196
|
* // => 'Map<K, V>'
|
|
197
|
+
* ```
|
|
179
198
|
*/
|
|
180
199
|
export const declaration_get_display_name = (declaration: DeclarationJson): string => {
|
|
181
200
|
if (!declaration.generic_params?.length) return declaration.name;
|
|
@@ -190,8 +209,14 @@ export const declaration_get_display_name = (declaration: DeclarationJson): stri
|
|
|
190
209
|
|
|
191
210
|
/**
|
|
192
211
|
* Generate TypeScript import statement for a declaration.
|
|
193
|
-
*
|
|
212
|
+
*
|
|
213
|
+
* @deprecated Use `generateImport` from `@fuzdev/svelte-docinfo/types.js` instead.
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```ts
|
|
217
|
+
* declaration_generate_import({name: 'Foo', kind: 'type'}, 'foo.ts', '@pkg/lib')
|
|
194
218
|
* // => "import type {Foo} from '@pkg/lib/foo.js';"
|
|
219
|
+
* ```
|
|
195
220
|
*/
|
|
196
221
|
export const declaration_generate_import = (
|
|
197
222
|
declaration: DeclarationJson,
|