@muloka/figma-console-mcp 0.5.0 → 0.5.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.
Files changed (107) hide show
  1. package/README.md +2 -0
  2. package/dist/core/websocket-connector.d.ts +2 -1
  3. package/dist/core/websocket-connector.d.ts.map +1 -1
  4. package/dist/core/websocket-connector.js +17 -2
  5. package/dist/core/websocket-connector.js.map +1 -1
  6. package/dist/core/websocket-server.d.ts +8 -1
  7. package/dist/core/websocket-server.d.ts.map +1 -1
  8. package/dist/core/websocket-server.js +18 -2
  9. package/dist/core/websocket-server.js.map +1 -1
  10. package/dist/core/write-tools.d.ts +3 -1
  11. package/dist/core/write-tools.d.ts.map +1 -1
  12. package/dist/core/write-tools.js +34 -14
  13. package/dist/core/write-tools.js.map +1 -1
  14. package/dist/local.d.ts +2 -1
  15. package/dist/local.d.ts.map +1 -1
  16. package/dist/local.js +5 -4
  17. package/dist/local.js.map +1 -1
  18. package/package.json +1 -1
  19. package/dist/apps/design-system-dashboard/mcp-app.html +0 -521
  20. package/dist/apps/token-browser/mcp-app.html +0 -410
  21. package/dist/cloudflare/apps/design-system-dashboard/scoring/accessibility.js +0 -277
  22. package/dist/cloudflare/apps/design-system-dashboard/scoring/component-metadata.js +0 -357
  23. package/dist/cloudflare/apps/design-system-dashboard/scoring/consistency.js +0 -341
  24. package/dist/cloudflare/apps/design-system-dashboard/scoring/coverage.js +0 -230
  25. package/dist/cloudflare/apps/design-system-dashboard/scoring/engine.js +0 -92
  26. package/dist/cloudflare/apps/design-system-dashboard/scoring/naming-semantics.js +0 -308
  27. package/dist/cloudflare/apps/design-system-dashboard/scoring/token-architecture.js +0 -349
  28. package/dist/cloudflare/apps/design-system-dashboard/scoring/types.js +0 -40
  29. package/dist/cloudflare/apps/design-system-dashboard/server.js +0 -159
  30. package/dist/cloudflare/apps/token-browser/server.js +0 -136
  31. package/dist/cloudflare/browser-manager.js +0 -157
  32. package/dist/cloudflare/core/accessibility-tools.js +0 -361
  33. package/dist/cloudflare/core/annotation-tools.js +0 -230
  34. package/dist/cloudflare/core/cloud-websocket-connector.js +0 -419
  35. package/dist/cloudflare/core/cloud-websocket-relay.js +0 -198
  36. package/dist/cloudflare/core/comment-tools.js +0 -292
  37. package/dist/cloudflare/core/config.js +0 -153
  38. package/dist/cloudflare/core/console-monitor.js +0 -427
  39. package/dist/cloudflare/core/deep-component-tools.js +0 -128
  40. package/dist/cloudflare/core/design-code-tools.js +0 -2793
  41. package/dist/cloudflare/core/design-system-manifest.js +0 -265
  42. package/dist/cloudflare/core/design-system-tools.js +0 -882
  43. package/dist/cloudflare/core/diagnose-tool.js +0 -100
  44. package/dist/cloudflare/core/diff/changelog-formatter.js +0 -275
  45. package/dist/cloudflare/core/diff/diff-engine.js +0 -334
  46. package/dist/cloudflare/core/diff/property-compare.js +0 -36
  47. package/dist/cloudflare/core/diff/version-cache.js +0 -74
  48. package/dist/cloudflare/core/enrichment/enrichment-service.js +0 -374
  49. package/dist/cloudflare/core/enrichment/index.js +0 -7
  50. package/dist/cloudflare/core/enrichment/relationship-mapper.js +0 -351
  51. package/dist/cloudflare/core/enrichment/style-resolver.js +0 -346
  52. package/dist/cloudflare/core/figjam-tools.js +0 -547
  53. package/dist/cloudflare/core/figma-api.js +0 -509
  54. package/dist/cloudflare/core/figma-connector.js +0 -7
  55. package/dist/cloudflare/core/figma-reconstruction-spec.js +0 -402
  56. package/dist/cloudflare/core/figma-style-extractor.js +0 -311
  57. package/dist/cloudflare/core/figma-tools.js +0 -3353
  58. package/dist/cloudflare/core/identity.js +0 -96
  59. package/dist/cloudflare/core/library-tools.js +0 -580
  60. package/dist/cloudflare/core/logger.js +0 -53
  61. package/dist/cloudflare/core/port-discovery.js +0 -935
  62. package/dist/cloudflare/core/resolve-package-root.js +0 -11
  63. package/dist/cloudflare/core/slides-tools.js +0 -714
  64. package/dist/cloudflare/core/slot-tools.js +0 -334
  65. package/dist/cloudflare/core/snippet-injector.js +0 -96
  66. package/dist/cloudflare/core/tokens/alias-resolver.js +0 -205
  67. package/dist/cloudflare/core/tokens/config.js +0 -294
  68. package/dist/cloudflare/core/tokens/dialect.js +0 -232
  69. package/dist/cloudflare/core/tokens/figma-converter.js +0 -323
  70. package/dist/cloudflare/core/tokens/formatters/css-vars.js +0 -338
  71. package/dist/cloudflare/core/tokens/formatters/dtcg.js +0 -376
  72. package/dist/cloudflare/core/tokens/formatters/index.js +0 -45
  73. package/dist/cloudflare/core/tokens/formatters/json.js +0 -205
  74. package/dist/cloudflare/core/tokens/formatters/less.js +0 -4
  75. package/dist/cloudflare/core/tokens/formatters/scss.js +0 -258
  76. package/dist/cloudflare/core/tokens/formatters/stubs.js +0 -13
  77. package/dist/cloudflare/core/tokens/formatters/style-dictionary-v3.js +0 -213
  78. package/dist/cloudflare/core/tokens/formatters/tailwind-v3.js +0 -237
  79. package/dist/cloudflare/core/tokens/formatters/tailwind-v4.js +0 -335
  80. package/dist/cloudflare/core/tokens/formatters/tokens-studio.js +0 -256
  81. package/dist/cloudflare/core/tokens/formatters/ts-module.js +0 -198
  82. package/dist/cloudflare/core/tokens/index.js +0 -16
  83. package/dist/cloudflare/core/tokens/parsers/css-vars.js +0 -4
  84. package/dist/cloudflare/core/tokens/parsers/dtcg.js +0 -280
  85. package/dist/cloudflare/core/tokens/parsers/index.js +0 -138
  86. package/dist/cloudflare/core/tokens/parsers/json.js +0 -7
  87. package/dist/cloudflare/core/tokens/parsers/scss.js +0 -4
  88. package/dist/cloudflare/core/tokens/parsers/stubs.js +0 -20
  89. package/dist/cloudflare/core/tokens/parsers/style-dictionary-v3.js +0 -4
  90. package/dist/cloudflare/core/tokens/parsers/tailwind-v3.js +0 -4
  91. package/dist/cloudflare/core/tokens/parsers/tailwind-v4.js +0 -4
  92. package/dist/cloudflare/core/tokens/parsers/tokens-studio.js +0 -4
  93. package/dist/cloudflare/core/tokens/schemas.js +0 -152
  94. package/dist/cloudflare/core/tokens/transforms/color.js +0 -12
  95. package/dist/cloudflare/core/tokens/transforms/index.js +0 -29
  96. package/dist/cloudflare/core/tokens/transforms/size.js +0 -7
  97. package/dist/cloudflare/core/tokens/types.js +0 -18
  98. package/dist/cloudflare/core/tokens-tools.js +0 -1788
  99. package/dist/cloudflare/core/types/design-code.js +0 -4
  100. package/dist/cloudflare/core/types/enriched.js +0 -5
  101. package/dist/cloudflare/core/types/index.js +0 -4
  102. package/dist/cloudflare/core/variable-resolver.js +0 -85
  103. package/dist/cloudflare/core/version-tools.js +0 -1199
  104. package/dist/cloudflare/core/websocket-connector.js +0 -436
  105. package/dist/cloudflare/core/websocket-server.js +0 -1009
  106. package/dist/cloudflare/core/write-tools.js +0 -2506
  107. 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
- }