@adecore/editor-react 0.39.0 → 0.40.1
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/CallHierarchyPanel.js +30 -55
- package/dist/CodeAuthorsCard.js +0 -1
- package/dist/CompletionPopup.js +150 -181
- package/dist/DiffView.d.ts +1 -1
- package/dist/DiffView.js +2 -29
- package/dist/PickPopup.js +54 -80
- package/dist/SplitDiffView.js +27 -57
- package/dist/SymbolPicker.js +2 -8
- package/dist/code-actions-model.js +2 -9
- package/dist/code-actions.js +10 -11
- package/dist/code-vision.js +2 -1
- package/dist/completion-model.js +2 -2
- package/dist/completion.js +13 -34
- package/dist/definition-link.d.ts +1 -0
- package/dist/definition-link.js +22 -18
- package/dist/diagnostics-model.d.ts +1 -0
- package/dist/diagnostics-model.js +3 -1
- package/dist/diagnostics.js +1 -2
- package/dist/diff-syntax.d.ts +1 -0
- package/dist/diff-syntax.js +31 -0
- package/dist/doc-comment-model.d.ts +1 -0
- package/dist/doc-comment-model.js +1 -1
- package/dist/folding.js +2 -3
- package/dist/format-on-type.js +6 -10
- package/dist/hover-content.d.ts +0 -2
- package/dist/hover-content.js +1 -9
- package/dist/inlay-hints.d.ts +0 -1
- package/dist/inlay-hints.js +11 -41
- package/dist/navigation.js +4 -14
- package/dist/peek.js +2 -12
- package/dist/popup-focus.d.ts +3 -1
- package/dist/popup-focus.js +33 -0
- package/dist/recent-choices.d.ts +0 -1
- package/dist/recent-choices.js +0 -4
- package/dist/rendered-docs.d.ts +1 -0
- package/dist/rendered-docs.js +15 -28
- package/dist/snippet-field-transforms.d.ts +5 -0
- package/dist/snippet-field-transforms.js +27 -16
- package/dist/snippet-session.js +8 -20
- package/dist/symbol-links.js +3 -10
- package/dist/symbol-picker-model.d.ts +1 -0
- package/dist/symbol-picker-model.js +7 -0
- package/dist/unique.d.ts +10 -0
- package/dist/unique.js +15 -0
- package/package.json +9 -9
- package/src/AnchoredPopup.tsx +2 -0
- package/src/BaselineStatus.tsx +1 -0
- package/src/CallHierarchyPanel.tsx +16 -6
- package/src/ChangeReview.tsx +7 -0
- package/src/CodeAuthorsCard.tsx +2 -5
- package/src/CompletionPopup.tsx +21 -15
- package/src/DiffView.tsx +53 -30
- package/src/EditorContextMenu.tsx +7 -0
- package/src/EditorView.tsx +28 -0
- package/src/FindReplace.tsx +8 -0
- package/src/HoverCard.tsx +8 -0
- package/src/HoverSections.tsx +11 -0
- package/src/LanguagePopups.tsx +1 -0
- package/src/PanelResizeHandle.tsx +8 -0
- package/src/PathText.tsx +1 -0
- package/src/PeekPanel.tsx +13 -0
- package/src/PickPopup.tsx +7 -6
- package/src/RenameCard.tsx +13 -0
- package/src/RenderedDocs.tsx +11 -0
- package/src/SplitDiffView.tsx +91 -56
- package/src/SymbolPicker.tsx +10 -18
- package/src/call-hierarchy-model.ts +10 -0
- package/src/call-hierarchy.ts +82 -0
- package/src/code-actions-model.ts +21 -9
- package/src/code-actions.ts +83 -7
- package/src/code-authors.ts +20 -0
- package/src/code-vision-model.ts +37 -0
- package/src/code-vision.ts +47 -3
- package/src/completion-call.ts +19 -0
- package/src/completion-model.ts +58 -2
- package/src/completion.ts +156 -30
- package/src/conflict-model.ts +4 -0
- package/src/context-menu-rows.ts +1 -0
- package/src/context-menu.ts +7 -0
- package/src/definition-link.ts +42 -18
- package/src/diagnostics-model.ts +19 -1
- package/src/diagnostics.ts +31 -2
- package/src/diff-expansion.ts +9 -0
- package/src/diff-overlays.tsx +8 -0
- package/src/diff-syntax.ts +54 -0
- package/src/diff-wordmarks.ts +8 -0
- package/src/doc-comment-model.ts +51 -1
- package/src/editor-language.ts +11 -0
- package/src/find-query.ts +7 -0
- package/src/folding.ts +10 -3
- package/src/format-on-type.ts +23 -10
- package/src/highlight-layers.ts +3 -0
- package/src/highlights.ts +18 -0
- package/src/history.ts +11 -0
- package/src/holder.ts +3 -0
- package/src/hover-content.ts +34 -17
- package/src/hover.ts +57 -0
- package/src/index.ts +4 -0
- package/src/inlay-hints.ts +86 -47
- package/src/key-priority.ts +2 -0
- package/src/line-edits.ts +8 -0
- package/src/models.ts +6 -0
- package/src/navigation-history.ts +5 -0
- package/src/navigation.ts +28 -13
- package/src/panel-size.ts +7 -0
- package/src/patch-decorations.ts +39 -0
- package/src/patch-layout.ts +47 -0
- package/src/peek-model.ts +21 -0
- package/src/peek.ts +49 -13
- package/src/pick.ts +35 -0
- package/src/popup-focus.ts +11 -1
- package/src/popup-placement.ts +5 -0
- package/src/popups.ts +2 -6
- package/src/project-language.ts +33 -0
- package/src/project-problems.ts +11 -0
- package/src/proposal-model.ts +40 -0
- package/src/recent-choices.ts +3 -5
- package/src/refresher.ts +3 -0
- package/src/rename-model.ts +28 -0
- package/src/rename.ts +56 -0
- package/src/rendered-docs.ts +89 -19
- package/src/review-group.ts +4 -0
- package/src/row-host.ts +12 -0
- package/src/selection-ranges.ts +6 -0
- package/src/semantic-delta.ts +7 -0
- package/src/semantic-model.ts +11 -0
- package/src/semantic-tokens.ts +37 -0
- package/src/shortcut-keys.ts +3 -0
- package/src/signature-model.ts +7 -0
- package/src/signature.ts +27 -0
- package/src/snippet-field-transforms.ts +48 -13
- package/src/snippet-indent.ts +10 -0
- package/src/snippet-range-order.ts +5 -0
- package/src/snippet-session.ts +173 -31
- package/src/snippet-transform-client.ts +14 -0
- package/src/snippet-transform-format.ts +98 -0
- package/src/snippet-transform-protocol.ts +5 -0
- package/src/snippet-transform-queue.ts +53 -0
- package/src/snippet-transform-worker.ts +14 -0
- package/src/snippet-variables.ts +9 -0
- package/src/snippet.ts +107 -0
- package/src/split-alignment.ts +10 -0
- package/src/split-scroll.ts +8 -0
- package/src/symbol-links.ts +9 -12
- package/src/symbol-picker-model.ts +25 -0
- package/src/symbol-picker.ts +9 -0
- package/src/symbols.ts +21 -0
- package/src/testing.ts +7 -0
- package/src/timers.ts +5 -0
- package/src/unique.ts +23 -0
- package/src/use-problem-counts.ts +4 -0
- package/src/view-state.ts +9 -0
- package/src/word-diff.ts +5 -0
- package/src/workspace-edit.ts +84 -0
|
@@ -9,10 +9,12 @@ interface RequestOptions {
|
|
|
9
9
|
readonly kind?: 'accept' | 'exit';
|
|
10
10
|
readonly current?: () => boolean;
|
|
11
11
|
}
|
|
12
|
+
|
|
12
13
|
export interface SnippetTransformLease {
|
|
13
14
|
request(jobs: readonly SnippetTransformJob[], options?: RequestOptions): Promise<readonly string[]>;
|
|
14
15
|
dispose(): void;
|
|
15
16
|
}
|
|
17
|
+
|
|
16
18
|
interface Job {
|
|
17
19
|
readonly owner: symbol;
|
|
18
20
|
readonly kind: 'accept' | 'exit';
|
|
@@ -21,6 +23,7 @@ interface Job {
|
|
|
21
23
|
readonly resolve: (values: readonly string[]) => void;
|
|
22
24
|
readonly reject: (error: unknown) => void;
|
|
23
25
|
}
|
|
26
|
+
|
|
24
27
|
export class SnippetTransformQueueError extends Error {}
|
|
25
28
|
|
|
26
29
|
const IDLE_RELEASE_MS = 1000;
|
|
@@ -34,91 +37,121 @@ export class SnippetTransforms {
|
|
|
34
37
|
private active: Job | null = null;
|
|
35
38
|
private idle: unknown;
|
|
36
39
|
private disposed = false;
|
|
40
|
+
|
|
37
41
|
constructor(factory: () => WorkerRequestPort, timers: Timers = realTimers) {
|
|
38
42
|
this.timers = timers;
|
|
43
|
+
|
|
39
44
|
this.client = createSnippetTransformClient({
|
|
40
45
|
workerFactory: factory,
|
|
41
46
|
schedule: (callback, delay) => {
|
|
42
47
|
const timer = timers.set(callback, delay);
|
|
48
|
+
|
|
43
49
|
return () => timers.clear(timer);
|
|
44
50
|
}
|
|
45
51
|
});
|
|
46
52
|
}
|
|
53
|
+
|
|
47
54
|
acquire(): SnippetTransformLease {
|
|
48
55
|
const owner = Symbol('snippet');
|
|
49
56
|
this.owners.add(owner);
|
|
57
|
+
|
|
50
58
|
return {
|
|
51
59
|
request: (jobs, options = {}) => this.request(owner, jobs, options),
|
|
52
60
|
dispose: () => this.releaseOwner(owner)
|
|
53
61
|
};
|
|
54
62
|
}
|
|
63
|
+
|
|
55
64
|
private request(owner: symbol, jobs: readonly SnippetTransformJob[], options: RequestOptions): Promise<readonly string[]> {
|
|
56
65
|
if (this.disposed || !this.owners.has(owner)) {
|
|
57
66
|
return Promise.reject(new SnippetTransformError('disposed', 'The snippet owner was disposed.'));
|
|
58
67
|
}
|
|
68
|
+
|
|
59
69
|
let copied: SnippetTransformJob[];
|
|
70
|
+
|
|
60
71
|
try {
|
|
61
72
|
validateSnippetTransformJobs(jobs);
|
|
73
|
+
|
|
62
74
|
if (jobs.reduce((sum, job) => sum + job.value.length, 0) > MAX_TRANSFORM_WORK) {
|
|
63
75
|
throw new RangeError('The snippet transform inputs exceed the work budget.');
|
|
64
76
|
}
|
|
77
|
+
|
|
65
78
|
copied = jobs.map((job) => ({ ...job, format: job.format.map((node) => ({ ...node })) }));
|
|
66
79
|
} catch (error) {
|
|
67
80
|
return Promise.reject(
|
|
68
81
|
new SnippetTransformError(error instanceof RangeError ? 'range' : 'syntax', error instanceof Error ? error.message : String(error))
|
|
69
82
|
);
|
|
70
83
|
}
|
|
84
|
+
|
|
71
85
|
if (copied.length === 0) {
|
|
72
86
|
return Promise.resolve([]);
|
|
73
87
|
}
|
|
88
|
+
|
|
74
89
|
this.pending = this.pending.filter((job) => {
|
|
75
90
|
if (job.current()) {
|
|
76
91
|
return true;
|
|
77
92
|
}
|
|
93
|
+
|
|
78
94
|
job.reject(new SnippetTransformError('superseded', 'The queued snippet changed.'));
|
|
95
|
+
|
|
79
96
|
return false;
|
|
80
97
|
});
|
|
98
|
+
|
|
81
99
|
const kind = options.kind ?? 'accept';
|
|
100
|
+
|
|
82
101
|
if (kind === 'accept') {
|
|
83
102
|
this.pending = this.pending.filter((job) => {
|
|
84
103
|
if (job.owner !== owner || job.kind !== 'accept') {
|
|
85
104
|
return true;
|
|
86
105
|
}
|
|
106
|
+
|
|
87
107
|
job.reject(new SnippetTransformError('superseded', 'A newer snippet accept replaced the queued one.'));
|
|
108
|
+
|
|
88
109
|
return false;
|
|
89
110
|
});
|
|
90
111
|
}
|
|
112
|
+
|
|
91
113
|
if (this.pending.length >= MAX_PENDING) {
|
|
92
114
|
return Promise.reject(new SnippetTransformQueueError('Too many queued snippet transforms.'));
|
|
93
115
|
}
|
|
116
|
+
|
|
94
117
|
this.timers.clear(this.idle);
|
|
118
|
+
|
|
95
119
|
return new Promise((resolve, reject) => {
|
|
96
120
|
this.pending.push({ owner, kind, jobs: copied, current: () => this.owners.has(owner) && (options.current?.() ?? true), resolve, reject });
|
|
97
121
|
queueMicrotask(() => this.pump());
|
|
98
122
|
});
|
|
99
123
|
}
|
|
124
|
+
|
|
100
125
|
private pump(): void {
|
|
101
126
|
if (this.disposed || this.active !== null) {
|
|
102
127
|
return;
|
|
103
128
|
}
|
|
129
|
+
|
|
104
130
|
const job = this.pending.shift();
|
|
131
|
+
|
|
105
132
|
if (job === undefined) {
|
|
106
133
|
this.timers.clear(this.idle);
|
|
107
134
|
this.idle = this.timers.set(() => this.client.release(), IDLE_RELEASE_MS);
|
|
135
|
+
|
|
108
136
|
return;
|
|
109
137
|
}
|
|
138
|
+
|
|
110
139
|
if (!job.current()) {
|
|
111
140
|
job.reject(new SnippetTransformError('superseded', 'The queued snippet changed.'));
|
|
112
141
|
this.pump();
|
|
142
|
+
|
|
113
143
|
return;
|
|
114
144
|
}
|
|
145
|
+
|
|
115
146
|
this.active = job;
|
|
147
|
+
|
|
116
148
|
void this.client
|
|
117
149
|
.transform(job.jobs)
|
|
118
150
|
.then((values) => {
|
|
119
151
|
if (!job.current()) {
|
|
120
152
|
throw new SnippetTransformError('superseded', 'The snippet changed while transforming.');
|
|
121
153
|
}
|
|
154
|
+
|
|
122
155
|
job.resolve(values);
|
|
123
156
|
})
|
|
124
157
|
.catch((error) => job.reject(error))
|
|
@@ -127,29 +160,37 @@ export class SnippetTransforms {
|
|
|
127
160
|
this.pump();
|
|
128
161
|
});
|
|
129
162
|
}
|
|
163
|
+
|
|
130
164
|
private releaseOwner(owner: symbol): void {
|
|
131
165
|
if (!this.owners.delete(owner)) {
|
|
132
166
|
return;
|
|
133
167
|
}
|
|
168
|
+
|
|
134
169
|
this.pending = this.pending.filter((job) => {
|
|
135
170
|
if (job.owner !== owner) {
|
|
136
171
|
return true;
|
|
137
172
|
}
|
|
173
|
+
|
|
138
174
|
job.reject(new SnippetTransformError('disposed', 'The snippet owner was disposed.'));
|
|
175
|
+
|
|
139
176
|
return false;
|
|
140
177
|
});
|
|
178
|
+
|
|
141
179
|
if (this.active?.owner === owner) {
|
|
142
180
|
this.active.reject(new SnippetTransformError('disposed', 'The snippet owner was disposed.'));
|
|
143
181
|
this.client.cancel();
|
|
144
182
|
}
|
|
183
|
+
|
|
145
184
|
if (this.owners.size === 0) {
|
|
146
185
|
this.dispose();
|
|
147
186
|
}
|
|
148
187
|
}
|
|
188
|
+
|
|
149
189
|
dispose(): void {
|
|
150
190
|
if (this.disposed) {
|
|
151
191
|
return;
|
|
152
192
|
}
|
|
193
|
+
|
|
153
194
|
this.disposed = true;
|
|
154
195
|
this.timers.clear(this.idle);
|
|
155
196
|
this.owners.clear();
|
|
@@ -160,39 +201,51 @@ export class SnippetTransforms {
|
|
|
160
201
|
this.client.dispose();
|
|
161
202
|
}
|
|
162
203
|
}
|
|
204
|
+
|
|
163
205
|
interface Entry {
|
|
164
206
|
readonly queue: SnippetTransforms;
|
|
165
207
|
references: number;
|
|
166
208
|
}
|
|
209
|
+
|
|
167
210
|
const projects = new WeakMap<ProjectLanguage, Entry>();
|
|
211
|
+
|
|
168
212
|
export function acquireSnippetTransforms(project: ProjectLanguage, timers: Timers): SnippetTransformLease | null {
|
|
169
213
|
const factory = project.host.snippetTransformWorker;
|
|
214
|
+
|
|
170
215
|
if (factory === undefined) {
|
|
171
216
|
return null;
|
|
172
217
|
}
|
|
218
|
+
|
|
173
219
|
let entry = projects.get(project);
|
|
220
|
+
|
|
174
221
|
if (entry === undefined) {
|
|
175
222
|
entry = { queue: new SnippetTransforms(factory, timers), references: 0 };
|
|
176
223
|
projects.set(project, entry);
|
|
177
224
|
}
|
|
225
|
+
|
|
178
226
|
const held = entry,
|
|
179
227
|
lease = held.queue.acquire();
|
|
228
|
+
|
|
180
229
|
held.references++;
|
|
181
230
|
let disposed = false;
|
|
231
|
+
|
|
182
232
|
return {
|
|
183
233
|
request: (jobs, options) => lease.request(jobs, options),
|
|
184
234
|
dispose: () => {
|
|
185
235
|
if (disposed) {
|
|
186
236
|
return;
|
|
187
237
|
}
|
|
238
|
+
|
|
188
239
|
disposed = true;
|
|
189
240
|
lease.dispose();
|
|
241
|
+
|
|
190
242
|
if (--held.references === 0 && projects.get(project) === held) {
|
|
191
243
|
projects.delete(project);
|
|
192
244
|
}
|
|
193
245
|
}
|
|
194
246
|
};
|
|
195
247
|
}
|
|
248
|
+
|
|
196
249
|
export function disposeSnippetTransforms(project: ProjectLanguage): void {
|
|
197
250
|
projects.get(project)?.queue.dispose();
|
|
198
251
|
projects.delete(project);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { applySnippetTransform, createSnippetTransformBudget, validateSnippetTransformJobs } from './snippet-transform-format.ts';
|
|
2
2
|
import { MAX_TRANSFORM_CHARACTERS, type SnippetTransformInput, type SnippetTransformOutput } from './snippet-transform-protocol.ts';
|
|
3
|
+
|
|
3
4
|
export {
|
|
4
5
|
createSnippetTransformClient,
|
|
5
6
|
SnippetTransformError,
|
|
@@ -7,7 +8,9 @@ export {
|
|
|
7
8
|
type SnippetTransformClientOptions,
|
|
8
9
|
type SnippetTransformErrorKind
|
|
9
10
|
} from './snippet-transform-client.ts';
|
|
11
|
+
|
|
10
12
|
export { compileSnippetTransformFormat } from './snippet-transform-format.ts';
|
|
13
|
+
|
|
11
14
|
export type {
|
|
12
15
|
SnippetTransformJob,
|
|
13
16
|
SnippetTransformInput,
|
|
@@ -15,33 +18,42 @@ export type {
|
|
|
15
18
|
SnippetTransformCase,
|
|
16
19
|
SnippetTransformFormatNode
|
|
17
20
|
} from './snippet-transform-protocol.ts';
|
|
21
|
+
|
|
18
22
|
export interface SnippetTransformWorkerEndpoint {
|
|
19
23
|
addEventListener(type: 'message', listener: (event: MessageEvent<SnippetTransformInput>) => void): void;
|
|
20
24
|
removeEventListener(type: 'message', listener: (event: MessageEvent<SnippetTransformInput>) => void): void;
|
|
21
25
|
postMessage(message: SnippetTransformOutput): void;
|
|
22
26
|
}
|
|
27
|
+
|
|
23
28
|
export function serveSnippetTransforms(endpoint: SnippetTransformWorkerEndpoint): () => void {
|
|
24
29
|
const receive = ({ data: request }: MessageEvent<SnippetTransformInput>): void => {
|
|
25
30
|
const id = request !== null && typeof request === 'object' && Number.isSafeInteger(request.id) && request.id > 0 ? request.id : 0;
|
|
31
|
+
|
|
26
32
|
try {
|
|
27
33
|
if (id === 0 || request.type !== 'transform') {
|
|
28
34
|
throw new RangeError('Invalid snippet transform request.');
|
|
29
35
|
}
|
|
36
|
+
|
|
30
37
|
validateSnippetTransformJobs(request.jobs);
|
|
31
38
|
let remaining = MAX_TRANSFORM_CHARACTERS;
|
|
32
39
|
const budget = createSnippetTransformBudget();
|
|
33
40
|
const patterns = new Map<string, RegExp>();
|
|
41
|
+
|
|
34
42
|
const values = request.jobs.map((job) => {
|
|
35
43
|
const key = job.flags + '\0' + job.pattern;
|
|
36
44
|
let expression = patterns.get(key);
|
|
45
|
+
|
|
37
46
|
if (expression === undefined) {
|
|
38
47
|
expression = new RegExp(job.pattern, job.flags);
|
|
39
48
|
patterns.set(key, expression);
|
|
40
49
|
}
|
|
50
|
+
|
|
41
51
|
const value = applySnippetTransform(job, remaining, expression, budget);
|
|
42
52
|
remaining -= value.length;
|
|
53
|
+
|
|
43
54
|
return value;
|
|
44
55
|
});
|
|
56
|
+
|
|
45
57
|
endpoint.postMessage({ type: 'transformed', id: request.id, values });
|
|
46
58
|
} catch (error) {
|
|
47
59
|
endpoint.postMessage({
|
|
@@ -52,7 +64,9 @@ export function serveSnippetTransforms(endpoint: SnippetTransformWorkerEndpoint)
|
|
|
52
64
|
});
|
|
53
65
|
}
|
|
54
66
|
};
|
|
67
|
+
|
|
55
68
|
endpoint.addEventListener('message', receive);
|
|
56
69
|
endpoint.postMessage({ type: 'ready' });
|
|
70
|
+
|
|
57
71
|
return () => endpoint.removeEventListener('message', receive);
|
|
58
72
|
}
|
package/src/snippet-variables.ts
CHANGED
|
@@ -15,8 +15,11 @@ export function createSnippetResolver(
|
|
|
15
15
|
const filename = path?.replace(/\\/g, '/').split('/').at(-1);
|
|
16
16
|
const folder = context.folder?.replace(/\\/g, '/').replace(/\/$/, '');
|
|
17
17
|
const normalized = path?.replace(/\\/g, '/');
|
|
18
|
+
|
|
18
19
|
const pad = (value: number): string => String(value).padStart(2, '0');
|
|
20
|
+
|
|
19
21
|
const timezone = -now.getTimezoneOffset();
|
|
22
|
+
|
|
20
23
|
const values: Record<string, string | undefined> = {
|
|
21
24
|
TM_SELECTED_TEXT: context.selectedText,
|
|
22
25
|
TM_CURRENT_LINE: context.currentLine,
|
|
@@ -46,16 +49,20 @@ export function createSnippetResolver(
|
|
|
46
49
|
CURRENT_SECONDS_UNIX: String(Math.floor(now.getTime() / 1000)),
|
|
47
50
|
CURRENT_TIMEZONE_OFFSET: (timezone < 0 ? '-' : '+') + pad(Math.floor(Math.abs(timezone) / 60)) + pad(Math.abs(timezone) % 60)
|
|
48
51
|
};
|
|
52
|
+
|
|
49
53
|
const builtins = new Map(Object.entries(values));
|
|
50
54
|
const cache = new Map<string, string | undefined>();
|
|
55
|
+
|
|
51
56
|
return (name) => {
|
|
52
57
|
if (!cache.has(name)) {
|
|
53
58
|
let supplied: string | undefined;
|
|
59
|
+
|
|
54
60
|
try {
|
|
55
61
|
supplied = custom?.(name, context);
|
|
56
62
|
} catch {
|
|
57
63
|
// A failed host override leaves the built-in or editable variable available.
|
|
58
64
|
}
|
|
65
|
+
|
|
59
66
|
const value =
|
|
60
67
|
supplied ??
|
|
61
68
|
(name === 'RANDOM'
|
|
@@ -67,8 +74,10 @@ export function createSnippetResolver(
|
|
|
67
74
|
: name === 'UUID'
|
|
68
75
|
? (sources.uuid?.() ?? globalThis.crypto?.randomUUID())
|
|
69
76
|
: builtins.get(name));
|
|
77
|
+
|
|
70
78
|
cache.set(name, value);
|
|
71
79
|
}
|
|
80
|
+
|
|
72
81
|
return cache.get(name);
|
|
73
82
|
};
|
|
74
83
|
}
|