@muloka/figma-console-mcp 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +3 -1
  2. package/dist/core/port-discovery.d.ts +9 -0
  3. package/dist/core/port-discovery.d.ts.map +1 -1
  4. package/dist/core/port-discovery.js +40 -14
  5. package/dist/core/port-discovery.js.map +1 -1
  6. package/dist/core/websocket-connector.d.ts +2 -1
  7. package/dist/core/websocket-connector.d.ts.map +1 -1
  8. package/dist/core/websocket-connector.js +17 -2
  9. package/dist/core/websocket-connector.js.map +1 -1
  10. package/dist/core/websocket-server.d.ts +8 -1
  11. package/dist/core/websocket-server.d.ts.map +1 -1
  12. package/dist/core/websocket-server.js +18 -2
  13. package/dist/core/websocket-server.js.map +1 -1
  14. package/dist/core/write-tools.d.ts +3 -1
  15. package/dist/core/write-tools.d.ts.map +1 -1
  16. package/dist/core/write-tools.js +34 -14
  17. package/dist/core/write-tools.js.map +1 -1
  18. package/dist/local.d.ts +2 -1
  19. package/dist/local.d.ts.map +1 -1
  20. package/dist/local.js +10 -14
  21. package/dist/local.js.map +1 -1
  22. package/package.json +1 -1
  23. package/dist/apps/design-system-dashboard/mcp-app.html +0 -521
  24. package/dist/apps/token-browser/mcp-app.html +0 -410
  25. package/dist/cloudflare/apps/design-system-dashboard/scoring/accessibility.js +0 -277
  26. package/dist/cloudflare/apps/design-system-dashboard/scoring/component-metadata.js +0 -357
  27. package/dist/cloudflare/apps/design-system-dashboard/scoring/consistency.js +0 -341
  28. package/dist/cloudflare/apps/design-system-dashboard/scoring/coverage.js +0 -230
  29. package/dist/cloudflare/apps/design-system-dashboard/scoring/engine.js +0 -92
  30. package/dist/cloudflare/apps/design-system-dashboard/scoring/naming-semantics.js +0 -308
  31. package/dist/cloudflare/apps/design-system-dashboard/scoring/token-architecture.js +0 -349
  32. package/dist/cloudflare/apps/design-system-dashboard/scoring/types.js +0 -40
  33. package/dist/cloudflare/apps/design-system-dashboard/server.js +0 -159
  34. package/dist/cloudflare/apps/token-browser/server.js +0 -136
  35. package/dist/cloudflare/browser-manager.js +0 -157
  36. package/dist/cloudflare/core/accessibility-tools.js +0 -361
  37. package/dist/cloudflare/core/annotation-tools.js +0 -230
  38. package/dist/cloudflare/core/cloud-websocket-connector.js +0 -419
  39. package/dist/cloudflare/core/cloud-websocket-relay.js +0 -198
  40. package/dist/cloudflare/core/comment-tools.js +0 -292
  41. package/dist/cloudflare/core/config.js +0 -153
  42. package/dist/cloudflare/core/console-monitor.js +0 -427
  43. package/dist/cloudflare/core/deep-component-tools.js +0 -128
  44. package/dist/cloudflare/core/design-code-tools.js +0 -2793
  45. package/dist/cloudflare/core/design-system-manifest.js +0 -265
  46. package/dist/cloudflare/core/design-system-tools.js +0 -882
  47. package/dist/cloudflare/core/diagnose-tool.js +0 -100
  48. package/dist/cloudflare/core/diff/changelog-formatter.js +0 -275
  49. package/dist/cloudflare/core/diff/diff-engine.js +0 -334
  50. package/dist/cloudflare/core/diff/property-compare.js +0 -36
  51. package/dist/cloudflare/core/diff/version-cache.js +0 -74
  52. package/dist/cloudflare/core/enrichment/enrichment-service.js +0 -374
  53. package/dist/cloudflare/core/enrichment/index.js +0 -7
  54. package/dist/cloudflare/core/enrichment/relationship-mapper.js +0 -351
  55. package/dist/cloudflare/core/enrichment/style-resolver.js +0 -346
  56. package/dist/cloudflare/core/figjam-tools.js +0 -547
  57. package/dist/cloudflare/core/figma-api.js +0 -509
  58. package/dist/cloudflare/core/figma-connector.js +0 -7
  59. package/dist/cloudflare/core/figma-reconstruction-spec.js +0 -402
  60. package/dist/cloudflare/core/figma-style-extractor.js +0 -311
  61. package/dist/cloudflare/core/figma-tools.js +0 -3353
  62. package/dist/cloudflare/core/identity.js +0 -96
  63. package/dist/cloudflare/core/library-tools.js +0 -580
  64. package/dist/cloudflare/core/logger.js +0 -53
  65. package/dist/cloudflare/core/port-discovery.js +0 -935
  66. package/dist/cloudflare/core/resolve-package-root.js +0 -11
  67. package/dist/cloudflare/core/slides-tools.js +0 -714
  68. package/dist/cloudflare/core/slot-tools.js +0 -334
  69. package/dist/cloudflare/core/snippet-injector.js +0 -96
  70. package/dist/cloudflare/core/tokens/alias-resolver.js +0 -205
  71. package/dist/cloudflare/core/tokens/config.js +0 -294
  72. package/dist/cloudflare/core/tokens/dialect.js +0 -232
  73. package/dist/cloudflare/core/tokens/figma-converter.js +0 -323
  74. package/dist/cloudflare/core/tokens/formatters/css-vars.js +0 -338
  75. package/dist/cloudflare/core/tokens/formatters/dtcg.js +0 -376
  76. package/dist/cloudflare/core/tokens/formatters/index.js +0 -45
  77. package/dist/cloudflare/core/tokens/formatters/json.js +0 -205
  78. package/dist/cloudflare/core/tokens/formatters/less.js +0 -4
  79. package/dist/cloudflare/core/tokens/formatters/scss.js +0 -258
  80. package/dist/cloudflare/core/tokens/formatters/stubs.js +0 -13
  81. package/dist/cloudflare/core/tokens/formatters/style-dictionary-v3.js +0 -213
  82. package/dist/cloudflare/core/tokens/formatters/tailwind-v3.js +0 -237
  83. package/dist/cloudflare/core/tokens/formatters/tailwind-v4.js +0 -335
  84. package/dist/cloudflare/core/tokens/formatters/tokens-studio.js +0 -256
  85. package/dist/cloudflare/core/tokens/formatters/ts-module.js +0 -198
  86. package/dist/cloudflare/core/tokens/index.js +0 -16
  87. package/dist/cloudflare/core/tokens/parsers/css-vars.js +0 -4
  88. package/dist/cloudflare/core/tokens/parsers/dtcg.js +0 -280
  89. package/dist/cloudflare/core/tokens/parsers/index.js +0 -138
  90. package/dist/cloudflare/core/tokens/parsers/json.js +0 -7
  91. package/dist/cloudflare/core/tokens/parsers/scss.js +0 -4
  92. package/dist/cloudflare/core/tokens/parsers/stubs.js +0 -20
  93. package/dist/cloudflare/core/tokens/parsers/style-dictionary-v3.js +0 -4
  94. package/dist/cloudflare/core/tokens/parsers/tailwind-v3.js +0 -4
  95. package/dist/cloudflare/core/tokens/parsers/tailwind-v4.js +0 -4
  96. package/dist/cloudflare/core/tokens/parsers/tokens-studio.js +0 -4
  97. package/dist/cloudflare/core/tokens/schemas.js +0 -152
  98. package/dist/cloudflare/core/tokens/transforms/color.js +0 -12
  99. package/dist/cloudflare/core/tokens/transforms/index.js +0 -29
  100. package/dist/cloudflare/core/tokens/transforms/size.js +0 -7
  101. package/dist/cloudflare/core/tokens/types.js +0 -18
  102. package/dist/cloudflare/core/tokens-tools.js +0 -1788
  103. package/dist/cloudflare/core/types/design-code.js +0 -4
  104. package/dist/cloudflare/core/types/enriched.js +0 -5
  105. package/dist/cloudflare/core/types/index.js +0 -4
  106. package/dist/cloudflare/core/variable-resolver.js +0 -85
  107. package/dist/cloudflare/core/version-tools.js +0 -1199
  108. package/dist/cloudflare/core/websocket-connector.js +0 -436
  109. package/dist/cloudflare/core/websocket-server.js +0 -1009
  110. package/dist/cloudflare/core/write-tools.js +0 -2506
  111. package/dist/cloudflare/index.js +0 -3010
@@ -1,334 +0,0 @@
1
- /**
2
- * Diff engine — pure functions for comparing Figma file/node snapshots
3
- * across two versions.
4
- *
5
- * Scope (v1):
6
- * - Page-structure diff (added/removed/renamed pages) from depth=1 file fetches
7
- * - Per-node diff for scoped fetches: name, description, children added/removed,
8
- * componentPropertyDefinitions changes (for COMPONENT_SET), boundVariables changes
9
- *
10
- * NOT in scope (deferred):
11
- * - Variable VALUE history (Figma REST does not expose this; planned forward
12
- * ledger will fill the gap going forward, never retroactively)
13
- * - Style-content diffs (only style add/remove via reachable styles map)
14
- * - Inside-fills/strokes binding diffs (top-level boundVariables only for v1)
15
- */
16
- /**
17
- * Compare two file documents (from /v1/files/:key?version=X with depth=1 or higher).
18
- * Both arguments should be the `document` field of a Figma file response.
19
- */
20
- export function diffPageStructure(fromDoc, toDoc) {
21
- const fromPages = extractPages(fromDoc);
22
- const toPages = extractPages(toDoc);
23
- const fromById = new Map(fromPages.map((p) => [p.id, p]));
24
- const toById = new Map(toPages.map((p) => [p.id, p]));
25
- const added = [];
26
- const removed = [];
27
- const renamed = [];
28
- for (const p of toPages) {
29
- if (!fromById.has(p.id)) {
30
- added.push(p);
31
- }
32
- else {
33
- const old = fromById.get(p.id);
34
- if (old.name !== p.name) {
35
- renamed.push({ id: p.id, old_name: old.name, new_name: p.name });
36
- }
37
- }
38
- }
39
- for (const p of fromPages) {
40
- if (!toById.has(p.id))
41
- removed.push(p);
42
- }
43
- return {
44
- pages_added: added,
45
- pages_removed: removed,
46
- pages_renamed: renamed,
47
- summary: {
48
- added: added.length,
49
- removed: removed.length,
50
- renamed: renamed.length,
51
- },
52
- };
53
- }
54
- function extractPages(doc) {
55
- const children = doc?.children;
56
- if (!Array.isArray(children))
57
- return [];
58
- return children
59
- .filter((c) => c && typeof c.id === "string" && typeof c.name === "string")
60
- .map((c) => ({ id: c.id, name: c.name }));
61
- }
62
- /**
63
- * Diff a COMPONENT_SET's componentPropertyDefinitions map.
64
- * Each definition is keyed by `propName#nodeId` in Figma's response.
65
- */
66
- export function diffComponentPropertyDefinitions(fromDefs, toDefs) {
67
- const from = fromDefs ?? {};
68
- const to = toDefs ?? {};
69
- const added = [];
70
- const removed = [];
71
- const typeChanged = [];
72
- const defaultChanged = [];
73
- for (const key of Object.keys(to)) {
74
- const toDef = to[key];
75
- if (!(key in from)) {
76
- added.push({ name: key, type: toDef.type, default_value: toDef.defaultValue });
77
- }
78
- else {
79
- const fromDef = from[key];
80
- if (fromDef.type !== toDef.type) {
81
- typeChanged.push({ name: key, from_type: fromDef.type, to_type: toDef.type });
82
- }
83
- if (!deepEqual(fromDef.defaultValue, toDef.defaultValue)) {
84
- defaultChanged.push({
85
- name: key,
86
- from_default: fromDef.defaultValue,
87
- to_default: toDef.defaultValue,
88
- });
89
- }
90
- }
91
- }
92
- for (const key of Object.keys(from)) {
93
- if (!(key in to)) {
94
- const fromDef = from[key];
95
- removed.push({ name: key, type: fromDef.type, default_value: fromDef.defaultValue });
96
- }
97
- }
98
- return {
99
- added,
100
- removed,
101
- type_changed: typeChanged,
102
- default_changed: defaultChanged,
103
- summary: {
104
- added: added.length,
105
- removed: removed.length,
106
- type_changed: typeChanged.length,
107
- default_changed: defaultChanged.length,
108
- },
109
- };
110
- }
111
- /**
112
- * Walk both node trees in parallel (matched by node id), comparing top-level
113
- * boundVariables. Inside-fills/strokes binding diffs are explicitly NOT included
114
- * in v1 — they add complexity for marginal additional value over node-level deltas.
115
- */
116
- export function collectBindingChanges(fromNode, toNode) {
117
- const changes = [];
118
- walkBoth(fromNode, toNode, (a, b) => {
119
- const aBindings = extractTopLevelBindings(a);
120
- const bBindings = extractTopLevelBindings(b);
121
- const allKeys = new Set([...Object.keys(aBindings), ...Object.keys(bBindings)]);
122
- for (const key of allKeys) {
123
- const fromId = aBindings[key] ?? null;
124
- const toId = bBindings[key] ?? null;
125
- if (fromId === toId)
126
- continue;
127
- let kind;
128
- if (fromId === null)
129
- kind = "added";
130
- else if (toId === null)
131
- kind = "removed";
132
- else
133
- kind = "rebound";
134
- changes.push({
135
- node_id: (b ?? a).id,
136
- node_name: (b ?? a).name ?? "",
137
- property: key,
138
- from_variable_id: fromId,
139
- to_variable_id: toId,
140
- change_kind: kind,
141
- });
142
- }
143
- });
144
- return changes;
145
- }
146
- function extractTopLevelBindings(node) {
147
- const out = {};
148
- const bv = node?.boundVariables;
149
- if (!bv || typeof bv !== "object")
150
- return out;
151
- for (const [prop, ref] of Object.entries(bv)) {
152
- if (ref && typeof ref === "object") {
153
- // Single VARIABLE_ALIAS reference
154
- if (ref.type === "VARIABLE_ALIAS" && typeof ref.id === "string") {
155
- out[prop] = ref.id;
156
- continue;
157
- }
158
- // Array of refs (e.g., fills binding can be an array — surface first match for v1)
159
- if (Array.isArray(ref)) {
160
- const first = ref.find((r) => r && r.type === "VARIABLE_ALIAS" && typeof r.id === "string");
161
- if (first)
162
- out[`${prop}[0]`] = first.id;
163
- }
164
- }
165
- }
166
- return out;
167
- }
168
- function walkBoth(fromNode, toNode, visit) {
169
- if (!fromNode && !toNode)
170
- return;
171
- visit(fromNode, toNode);
172
- const fromChildren = Array.isArray(fromNode?.children) ? fromNode.children : [];
173
- const toChildren = Array.isArray(toNode?.children) ? toNode.children : [];
174
- const byIdFrom = new Map();
175
- for (const c of fromChildren)
176
- if (c?.id)
177
- byIdFrom.set(c.id, c);
178
- const byIdTo = new Map();
179
- for (const c of toChildren)
180
- if (c?.id)
181
- byIdTo.set(c.id, c);
182
- const allIds = new Set([...byIdFrom.keys(), ...byIdTo.keys()]);
183
- for (const id of allIds) {
184
- walkBoth(byIdFrom.get(id), byIdTo.get(id), visit);
185
- }
186
- }
187
- /**
188
- * Diff a single node (typically a COMPONENT_SET) at depth=2. Either side may be
189
- * null/undefined to represent "newly added" or "removed entirely."
190
- */
191
- export function diffNode(fromNode, toNode, mode = "standard") {
192
- const id = (toNode ?? fromNode)?.id ?? "";
193
- const name = (toNode ?? fromNode)?.name ?? "";
194
- const type = (toNode ?? fromNode)?.type ?? "";
195
- const out = {
196
- node_id: id,
197
- node_name: name,
198
- node_type: type,
199
- name_changed: null,
200
- description_changed: null,
201
- children_added: [],
202
- children_removed: [],
203
- component_properties: null,
204
- binding_changes: [],
205
- change_count: 0,
206
- notes: [],
207
- };
208
- if (!fromNode && toNode) {
209
- out.notes.push("Node was added in the target version (no prior state to compare).");
210
- out.change_count = 1;
211
- return out;
212
- }
213
- if (fromNode && !toNode) {
214
- out.notes.push("Node was removed in the target version (no later state to compare).");
215
- out.change_count = 1;
216
- return out;
217
- }
218
- if (!fromNode && !toNode) {
219
- out.notes.push("Node not found in either version.");
220
- return out;
221
- }
222
- if (fromNode.name !== toNode.name) {
223
- out.name_changed = { from: fromNode.name, to: toNode.name };
224
- }
225
- if ((fromNode.description ?? "") !== (toNode.description ?? "")) {
226
- out.description_changed = {
227
- from: fromNode.description ?? "",
228
- to: toNode.description ?? "",
229
- };
230
- }
231
- const fromChildIds = new Set((fromNode.children ?? []).filter((c) => c?.id).map((c) => c.id));
232
- const toChildIds = new Set((toNode.children ?? []).filter((c) => c?.id).map((c) => c.id));
233
- for (const c of toNode.children ?? []) {
234
- if (c?.id && !fromChildIds.has(c.id)) {
235
- out.children_added.push({ id: c.id, name: c.name ?? "", type: c.type ?? "" });
236
- }
237
- }
238
- for (const c of fromNode.children ?? []) {
239
- if (c?.id && !toChildIds.has(c.id)) {
240
- out.children_removed.push({ id: c.id, name: c.name ?? "", type: c.type ?? "" });
241
- }
242
- }
243
- if (fromNode.type === "COMPONENT_SET" || toNode.type === "COMPONENT_SET") {
244
- const propDiff = diffComponentPropertyDefinitions(fromNode.componentPropertyDefinitions, toNode.componentPropertyDefinitions);
245
- const hasAny = propDiff.summary.added > 0 ||
246
- propDiff.summary.removed > 0 ||
247
- propDiff.summary.type_changed > 0 ||
248
- propDiff.summary.default_changed > 0;
249
- if (hasAny)
250
- out.component_properties = propDiff;
251
- }
252
- out.binding_changes = collectBindingChanges(fromNode, toNode);
253
- out.change_count =
254
- (out.name_changed ? 1 : 0) +
255
- (out.description_changed ? 1 : 0) +
256
- out.children_added.length +
257
- out.children_removed.length +
258
- (out.component_properties
259
- ? out.component_properties.summary.added +
260
- out.component_properties.summary.removed +
261
- out.component_properties.summary.type_changed +
262
- out.component_properties.summary.default_changed
263
- : 0) +
264
- out.binding_changes.length;
265
- if (mode === "summary") {
266
- // Strip detail arrays, keep counts only
267
- out.children_added = [];
268
- out.children_removed = [];
269
- if (out.component_properties) {
270
- out.component_properties = {
271
- added: [],
272
- removed: [],
273
- type_changed: [],
274
- default_changed: [],
275
- summary: out.component_properties.summary,
276
- };
277
- }
278
- out.binding_changes = [];
279
- }
280
- else if (mode === "standard") {
281
- // Keep the lightweight summaries (children_added, children_removed,
282
- // component_properties.summary). Strip the heavy detail arrays.
283
- if (out.component_properties) {
284
- out.component_properties = {
285
- added: out.component_properties.added.map((p) => ({ ...p, default_value: undefined })),
286
- removed: out.component_properties.removed.map((p) => ({
287
- ...p,
288
- default_value: undefined,
289
- })),
290
- type_changed: out.component_properties.type_changed,
291
- default_changed: out.component_properties.default_changed.map((d) => ({
292
- name: d.name,
293
- from_default: undefined,
294
- to_default: undefined,
295
- })),
296
- summary: out.component_properties.summary,
297
- };
298
- }
299
- // Bindings: keep as-is, they're already compact.
300
- }
301
- // mode === "detailed" → keep everything
302
- return out;
303
- }
304
- // ============================================================================
305
- // Helpers
306
- // ============================================================================
307
- function deepEqual(a, b) {
308
- if (a === b)
309
- return true;
310
- if (a === null || b === null)
311
- return false;
312
- if (typeof a !== typeof b)
313
- return false;
314
- if (typeof a !== "object")
315
- return false;
316
- if (Array.isArray(a) !== Array.isArray(b))
317
- return false;
318
- if (Array.isArray(a)) {
319
- if (a.length !== b.length)
320
- return false;
321
- for (let i = 0; i < a.length; i++)
322
- if (!deepEqual(a[i], b[i]))
323
- return false;
324
- return true;
325
- }
326
- const aKeys = Object.keys(a);
327
- const bKeys = Object.keys(b);
328
- if (aKeys.length !== bKeys.length)
329
- return false;
330
- for (const k of aKeys)
331
- if (!deepEqual(a[k], b[k]))
332
- return false;
333
- return true;
334
- }
@@ -1,36 +0,0 @@
1
- /**
2
- * Property comparison primitives.
3
- *
4
- * Pure helper functions used by both the design-code parity tools and
5
- * the version diff engine. Moved here from src/core/design-code-tools.ts
6
- * so multiple consumers can share without circular dependencies.
7
- */
8
- /** Convert Figma RGBA (0-1 floats) to hex string */
9
- export function figmaRGBAToHex(color) {
10
- const r = Math.round(color.r * 255);
11
- const g = Math.round(color.g * 255);
12
- const b = Math.round(color.b * 255);
13
- const hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`.toUpperCase();
14
- if (color.a !== undefined && color.a < 1) {
15
- const a = Math.round(color.a * 255);
16
- return `${hex}${a.toString(16).padStart(2, "0")}`;
17
- }
18
- return hex;
19
- }
20
- /** Normalize a color string for comparison (uppercase hex without alpha if fully opaque) */
21
- export function normalizeColor(color) {
22
- let c = color.trim().toUpperCase();
23
- // Strip alpha if fully opaque (FF)
24
- if (c.length === 9 && c.endsWith("FF")) {
25
- c = c.slice(0, 7);
26
- }
27
- // Expand shorthand (#RGB -> #RRGGBB)
28
- if (/^#[0-9A-F]{3}$/.test(c)) {
29
- c = `#${c[1]}${c[1]}${c[2]}${c[2]}${c[3]}${c[3]}`;
30
- }
31
- return c;
32
- }
33
- /** Compare numeric values with a tolerance */
34
- export function numericClose(a, b, tolerance = 1) {
35
- return Math.abs(a - b) <= tolerance;
36
- }
@@ -1,74 +0,0 @@
1
- /**
2
- * In-memory LRU cache for Figma file snapshots at past versions.
3
- *
4
- * Past versions are immutable, so a cached snapshot for `${fileKey}:${versionId}`
5
- * never goes stale. The cache is process-scoped (no persistence) and bounded by
6
- * a max-entries cap rather than a byte budget — keeps the implementation simple
7
- * and avoids assumptions about JSON serialization size.
8
- *
9
- * HEAD ("current") is intentionally NOT cached because it changes on every save.
10
- * Callers should pass `null` as the versionId for HEAD requests; the cache
11
- * methods short-circuit on null.
12
- *
13
- * Usage:
14
- * const cache = new VersionSnapshotCache();
15
- * const key = cache.makeKey(fileKey, versionId, depth, nodeIds);
16
- * let snapshot = cache.get(key);
17
- * if (!snapshot) {
18
- * snapshot = await api.getFile(fileKey, { version: versionId, depth });
19
- * cache.set(key, snapshot);
20
- * }
21
- */
22
- export class VersionSnapshotCache {
23
- constructor(options = {}) {
24
- // Map preserves insertion order — first key is the LRU.
25
- this.store = new Map();
26
- this.maxEntries = options.maxEntries ?? 50;
27
- }
28
- /**
29
- * Build a stable cache key from the request parameters.
30
- * Returns null for HEAD requests (versionId is null/undefined/empty).
31
- */
32
- makeKey(fileKey, versionId, depth, nodeIds) {
33
- if (!versionId)
34
- return null;
35
- const idsHash = nodeIds && nodeIds.length > 0
36
- ? [...nodeIds].sort().join(",")
37
- : "";
38
- const depthPart = depth === undefined ? "full" : String(depth);
39
- return `${fileKey}:${versionId}:${depthPart}:${idsHash}`;
40
- }
41
- get(key) {
42
- if (key === null)
43
- return undefined;
44
- if (!this.store.has(key))
45
- return undefined;
46
- // Refresh recency: delete + re-insert moves the key to the end.
47
- const value = this.store.get(key);
48
- this.store.delete(key);
49
- this.store.set(key, value);
50
- return value;
51
- }
52
- set(key, value) {
53
- if (key === null)
54
- return;
55
- if (this.store.has(key))
56
- this.store.delete(key);
57
- this.store.set(key, value);
58
- while (this.store.size > this.maxEntries) {
59
- const oldestKey = this.store.keys().next().value;
60
- if (oldestKey === undefined)
61
- break;
62
- this.store.delete(oldestKey);
63
- }
64
- }
65
- has(key) {
66
- return key !== null && this.store.has(key);
67
- }
68
- get size() {
69
- return this.store.size;
70
- }
71
- clear() {
72
- this.store.clear();
73
- }
74
- }