react-icons-sprite 1.0.0 → 1.0.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.
@@ -1,4 +1,4 @@
1
- import { r as resolveIconImport, t as computeIconId } from "./compute-icon-id-B590yK7l.mjs";
1
+ import { i as resolveIconImport, t as computeIconId } from "./compute-icon-id-CVIo3z9m.mjs";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { pathToFileURL } from "node:url";
@@ -1,4 +1,4 @@
1
- import { i as createCollector } from "./compute-icon-id-B590yK7l.mjs";
1
+ import { a as createCollector } from "./compute-icon-id-CVIo3z9m.mjs";
2
2
  //#region src/collector.ts
3
3
  const collector = createCollector();
4
4
  //#endregion
@@ -73,4 +73,4 @@ const computeIconId = (pack, iconName) => {
73
73
  return `ri-${normalizePackAlias(pack)}-${iconName}`;
74
74
  };
75
75
  //#endregion
76
- export { createCollector as i, DEFAULT_ICON_SOURCES as n, resolveIconImport as r, computeIconId as t };
76
+ export { createCollector as a, resolveIconImport as i, normalizePackAlias as n, DEFAULT_ICON_SOURCES as r, computeIconId as t };
@@ -1,4 +1,4 @@
1
- import { n as DEFAULT_ICON_SOURCES, t as computeIconId } from "./compute-icon-id-B590yK7l.mjs";
1
+ import { n as normalizePackAlias, r as DEFAULT_ICON_SOURCES } from "./compute-icon-id-CVIo3z9m.mjs";
2
2
  import MagicString from "magic-string";
3
3
  //#region src/transform/edit-applier.ts
4
4
  const applyEdits = (code, edits) => {
@@ -13,9 +13,9 @@ const applyEdits = (code, edits) => {
13
13
  const editStart = (edit) => {
14
14
  return edit.type === "insert" ? edit.pos : edit.from;
15
15
  };
16
- const applyEditsToString = (code, edits) => {
16
+ const applyEditsToString = (code, edits, presorted = false) => {
17
17
  if (!edits.length) return code;
18
- const orderedEdits = [...edits].sort((left, right) => {
18
+ const orderedEdits = presorted ? edits : [...edits].sort((left, right) => {
19
19
  const startDelta = editStart(left) - editStart(right);
20
20
  if (startDelta !== 0) return startDelta;
21
21
  if (left.type === "insert" && right.type !== "insert") return 1;
@@ -41,38 +41,6 @@ const applyEditsToString = (code, edits) => {
41
41
  return result + code.slice(cursor);
42
42
  };
43
43
  //#endregion
44
- //#region src/transform/edit-builder.ts
45
- const buildEdits = (usages, componentName, usedSymbols, register) => {
46
- const edits = [];
47
- const iconIdCache = /* @__PURE__ */ new Map();
48
- for (const usage of usages) {
49
- edits.push({
50
- type: "replace",
51
- from: usage.range[0],
52
- to: usage.range[1],
53
- value: componentName
54
- });
55
- if (usage.kind === "opening") {
56
- if (!usage.hasIconId) {
57
- const key = `${usage.pack}:${usage.exportName}`;
58
- let iconId = iconIdCache.get(key);
59
- if (!iconId) {
60
- iconId = computeIconId(usage.pack, usage.exportName);
61
- iconIdCache.set(key, iconId);
62
- }
63
- edits.push({
64
- type: "insert",
65
- pos: usage.range[1],
66
- value: ` iconId="${iconId}"`
67
- });
68
- }
69
- usedSymbols.add(usage.local);
70
- register(usage.pack, usage.exportName);
71
- }
72
- }
73
- return edits;
74
- };
75
- //#endregion
76
44
  //#region src/transform/fast-filter.ts
77
45
  const fastFilter = (code) => {
78
46
  if (!code.includes("<")) return false;
@@ -163,12 +131,23 @@ const scanImportsDetailed = (code, sources) => {
163
131
  return imports;
164
132
  };
165
133
  const buildScannedSymbolTable = (imports) => {
166
- const table = /* @__PURE__ */ new Map();
167
- for (const item of imports) for (const specifier of item.specifiers) table.set(specifier.local, {
168
- pack: item.pack,
169
- exportName: specifier.exportName
170
- });
171
- return table;
134
+ const items = Object.create(null);
135
+ let size = 0;
136
+ for (const item of imports) {
137
+ const iconIdPrefix = `ri-${normalizePackAlias(item.pack)}-`;
138
+ for (const specifier of item.specifiers) {
139
+ if (items[specifier.local] === void 0) size += 1;
140
+ items[specifier.local] = {
141
+ pack: item.pack,
142
+ exportName: specifier.exportName,
143
+ iconId: iconIdPrefix + specifier.exportName
144
+ };
145
+ }
146
+ }
147
+ return {
148
+ items,
149
+ size
150
+ };
172
151
  };
173
152
  const scanSpriteIconImport = (code) => {
174
153
  IMPORT_RE.lastIndex = 0;
@@ -199,11 +178,17 @@ const isIdentifierPart = (char) => {
199
178
  const isWhitespace = (char) => {
200
179
  return char === " " || char === " " || char === "\n" || char === "\r" || char === "\f";
201
180
  };
202
- const scanJsxIconUsages = (code, symbols) => {
203
- if (!symbols.size) return [];
204
- const usages = [];
205
- for (let index = 0; index < code.length; index += 1) {
206
- if (code.charCodeAt(index) !== 60) continue;
181
+ const isWhitespaceCode = (code) => {
182
+ return code === 32 || code === 9 || code === 10 || code === 13 || code === 12;
183
+ };
184
+ const scanJsxIconEdits = (code, symbols, componentName, usedSymbols, register, hasAnyIconId) => {
185
+ if (symbols.size === 0) return {
186
+ edits: [],
187
+ count: 0
188
+ };
189
+ const edits = [];
190
+ let count = 0;
191
+ for (let index = code.indexOf("<"); index !== -1; index = code.indexOf("<", index + 1)) {
207
192
  let cursor = index + 1;
208
193
  while (isWhitespace(code[cursor])) cursor += 1;
209
194
  const closing = code[cursor] === "/";
@@ -216,24 +201,35 @@ const scanJsxIconUsages = (code, symbols) => {
216
201
  cursor += 1;
217
202
  while (isIdentifierPart(code[cursor])) cursor += 1;
218
203
  const local = code.slice(localStart, cursor);
219
- const symbol = symbols.get(local);
204
+ const symbol = symbols.items[local];
220
205
  if (!symbol) continue;
221
- const kind = closing ? "closing" : "opening";
222
206
  let hasIconId = false;
223
- if (!closing) {
207
+ if (hasAnyIconId && !closing) {
224
208
  const tagEnd = findJsxOpeningTagEnd(code, cursor);
225
209
  hasIconId = tagEnd !== -1 && hasIconIdAttribute(code, cursor, tagEnd);
226
210
  }
227
- usages.push({
228
- local,
229
- range: [localStart, cursor],
230
- pack: symbol.pack,
231
- exportName: symbol.exportName,
232
- kind,
233
- hasIconId
211
+ if (closing || hasIconId) edits.push({
212
+ type: "replace",
213
+ from: localStart,
214
+ to: cursor,
215
+ value: componentName
234
216
  });
217
+ else edits.push({
218
+ type: "replace",
219
+ from: localStart,
220
+ to: cursor,
221
+ value: `${componentName} iconId="${symbol.iconId}"`
222
+ });
223
+ count += 1;
224
+ if (!closing) {
225
+ usedSymbols.add(local);
226
+ register(symbol.pack, symbol.exportName);
227
+ }
235
228
  }
236
- return usages;
229
+ return {
230
+ edits,
231
+ count
232
+ };
237
233
  };
238
234
  const hasIconIdAttribute = (code, start, end) => {
239
235
  for (let index = start; index < end; index += 1) {
@@ -295,7 +291,7 @@ const scanFontAwesomeUsages = (code, symbols, componentLocals) => {
295
291
  const attributes = code.slice(componentStart + componentLocal.length, tagEnd);
296
292
  const iconMatch = /\sicon\s*=\s*\{\s*([A-Za-z_$][\w$]*)\s*\}/.exec(attributes);
297
293
  if (!iconMatch || iconMatch.index === void 0) continue;
298
- const symbol = symbols.get(iconMatch[1]);
294
+ const symbol = symbols.items[iconMatch[1]];
299
295
  if (!symbol || !isFontAwesomeIconPack(symbol.pack)) continue;
300
296
  const attributeStart = componentStart + componentLocal.length + iconMatch.index;
301
297
  usages.push({
@@ -305,7 +301,8 @@ const scanFontAwesomeUsages = (code, symbols, componentLocals) => {
305
301
  hasIconId: /\biconId\s*=/.test(attributes),
306
302
  iconLocal: iconMatch[1],
307
303
  pack: symbol.pack,
308
- exportName: symbol.exportName
304
+ exportName: symbol.exportName,
305
+ iconId: symbol.iconId
309
306
  });
310
307
  }
311
308
  return usages;
@@ -365,7 +362,11 @@ const cleanupScannedFontAwesomeComponentImports = (code, usedLocals) => {
365
362
  };
366
363
  const extendToLineEnd = (code, end) => {
367
364
  let to = end;
368
- while (to < code.length && /[ \t]/.test(code[to])) to += 1;
365
+ while (to < code.length) {
366
+ const char = code.charCodeAt(to);
367
+ if (char !== 32 && char !== 9) break;
368
+ to += 1;
369
+ }
369
370
  if (code[to] === "\r" && code[to + 1] === "\n") return to + 2;
370
371
  if (code[to] === "\n") return to + 1;
371
372
  return to;
@@ -374,19 +375,19 @@ const specifierRemovalRange = (code, [start, end]) => {
374
375
  let from = start;
375
376
  let to = end;
376
377
  let before = start - 1;
377
- while (before >= 0 && /\s/.test(code[before])) before -= 1;
378
+ while (before >= 0 && isWhitespaceCode(code.charCodeAt(before))) before -= 1;
378
379
  if (before >= 0 && code[before] === ",") {
379
380
  from = before;
380
381
  return [from, to];
381
382
  }
382
383
  let after = end;
383
- while (after < code.length && /\s/.test(code[after])) after += 1;
384
+ while (after < code.length && isWhitespaceCode(code.charCodeAt(after))) after += 1;
384
385
  if (after < code.length && code[after] === ",") to = consumeTrailingWhitespace(code, after + 1);
385
386
  return [from, to];
386
387
  };
387
388
  const consumeTrailingWhitespace = (code, start) => {
388
389
  let to = start;
389
- while (to < code.length && /\s/.test(code[to])) to += 1;
390
+ while (to < code.length && isWhitespaceCode(code.charCodeAt(to))) to += 1;
390
391
  return to;
391
392
  };
392
393
  const transformModule = (code, id, register, sources = DEFAULT_ICON_SOURCES, options = {}) => {
@@ -413,16 +414,16 @@ const transformModule = (code, id, register, sources = DEFAULT_ICON_SOURCES, opt
413
414
  hasImport: false,
414
415
  localName: ICON_COMPONENT_NAME
415
416
  };
416
- const usages = scanJsxIconUsages(code, table);
417
+ const used = /* @__PURE__ */ new Set();
418
+ const usedFontAwesomeComponents = /* @__PURE__ */ new Set();
419
+ const jsxScan = scanJsxIconEdits(code, table, spriteIconImport.localName, used, register, code.includes("iconId"));
417
420
  const fontAwesomeUsages = hasPotentialFontAwesomeUsage ? scanFontAwesomeUsages(code, table, scanFontAwesomeComponents(code)) : [];
418
- if (!usages.length && !fontAwesomeUsages.length) return {
421
+ if (jsxScan.count === 0 && !fontAwesomeUsages.length) return {
419
422
  code,
420
423
  map: null,
421
424
  anyReplacements: false
422
425
  };
423
- const used = /* @__PURE__ */ new Set();
424
- const usedFontAwesomeComponents = /* @__PURE__ */ new Set();
425
- const edits = buildEdits(usages, spriteIconImport.localName, used, register);
426
+ const edits = jsxScan.edits;
426
427
  const registeredFontAwesomeIcons = /* @__PURE__ */ new Set();
427
428
  for (const usage of fontAwesomeUsages) {
428
429
  edits.push({
@@ -434,7 +435,7 @@ const transformModule = (code, id, register, sources = DEFAULT_ICON_SOURCES, opt
434
435
  if (!usage.hasIconId) edits.push({
435
436
  type: "insert",
436
437
  pos: usage.componentRange[1],
437
- value: ` iconId="${computeIconId(usage.pack, usage.exportName)}"`
438
+ value: ` iconId="${usage.iconId}"`
438
439
  });
439
440
  edits.push({
440
441
  type: "remove",
@@ -451,14 +452,15 @@ const transformModule = (code, id, register, sources = DEFAULT_ICON_SOURCES, opt
451
452
  }
452
453
  const cleanupEdits = cleanupScannedImports(code, scannedImports, used);
453
454
  const cleanupFontAwesomeEdits = usedFontAwesomeComponents.size ? cleanupScannedFontAwesomeComponentImports(code, usedFontAwesomeComponents) : [];
454
- const allEdits = [
455
+ const canUsePresortedEdits = cleanupFontAwesomeEdits.length === 0;
456
+ const allEdits = canUsePresortedEdits ? [...cleanupEdits, ...edits] : [
455
457
  ...edits,
456
458
  ...cleanupEdits,
457
459
  ...cleanupFontAwesomeEdits
458
460
  ];
459
461
  const importPrefix = `import { ${ICON_COMPONENT_NAME} } from "${ICON_SOURCE}";\n`;
460
462
  if (!sourceMap) return {
461
- code: `${spriteIconImport.hasImport ? "" : importPrefix}${applyEditsToString(code, allEdits)}`,
463
+ code: `${spriteIconImport.hasImport ? "" : importPrefix}${applyEditsToString(code, allEdits, canUsePresortedEdits)}`,
462
464
  map: null,
463
465
  anyReplacements: true
464
466
  };
@@ -1,7 +1,7 @@
1
1
  import { REACT_ICONS_SPRITE_URL_PLACEHOLDER } from "../index.mjs";
2
- import { i as createCollector, n as DEFAULT_ICON_SOURCES } from "../compute-icon-id-B590yK7l.mjs";
3
- import { t as buildSprite } from "../build-sprite-j9zt_17z.mjs";
4
- import { t as transformModule } from "../transform-module-zJo6_2rz.mjs";
2
+ import { a as createCollector, r as DEFAULT_ICON_SOURCES } from "../compute-icon-id-CVIo3z9m.mjs";
3
+ import { t as buildSprite } from "../build-sprite-DgeWMz2D.mjs";
4
+ import { t as transformModule } from "../transform-module-CIpNj5Na.mjs";
5
5
  import { createHash } from "node:crypto";
6
6
  //#region src/vite/plugin.ts
7
7
  const reactIconsSprite = (options = {}) => {
@@ -1,5 +1,5 @@
1
- import { t as transformModule } from "../transform-module-zJo6_2rz.mjs";
2
- import { t as collector } from "../collector-YV25X1xI.mjs";
1
+ import { t as transformModule } from "../transform-module-CIpNj5Na.mjs";
2
+ import { t as collector } from "../collector-DxE_zcTH.mjs";
3
3
  //#region src/webpack/loader.ts
4
4
  const reactIconsSpriteLoader = async function(source) {
5
5
  if (this.mode === "development") return source;
@@ -1,6 +1,6 @@
1
1
  import { REACT_ICONS_SPRITE_URL_PLACEHOLDER } from "../index.mjs";
2
- import { t as buildSprite } from "../build-sprite-j9zt_17z.mjs";
3
- import { t as collector } from "../collector-YV25X1xI.mjs";
2
+ import { t as buildSprite } from "../build-sprite-DgeWMz2D.mjs";
3
+ import { t as collector } from "../collector-DxE_zcTH.mjs";
4
4
  import { createHash } from "node:crypto";
5
5
  //#region src/webpack/plugin.ts
6
6
  var ReactIconsSpriteWebpackPlugin = class {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://www.schemastore.org/package.json",
3
3
  "name": "react-icons-sprite",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "type": "module",
6
6
  "description": "A lightweight Vite, Rsbuild and Webpack plugin for react-icons that builds a single SVG sprite and rewrites icons to <use>, reducing bundle size and runtime overhead.",
7
7
  "author": "Jure Rotar <hello@jurerotar.com>",