local-svg 0.0.4 → 0.0.6
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/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { SVGAttributes } from 'react';
|
|
3
3
|
|
|
4
|
+
type LocalSvgNames = string;
|
|
4
5
|
type LocalSvgProps = SVGAttributes<SVGSVGElement> & {
|
|
5
|
-
name:
|
|
6
|
+
name: LocalSvgNames;
|
|
6
7
|
baseUrl?: string;
|
|
7
8
|
as?: React.ElementType;
|
|
8
9
|
};
|
|
9
10
|
declare const LocalSvg: react.NamedExoticComponent<SVGAttributes<SVGSVGElement> & {
|
|
10
|
-
name:
|
|
11
|
+
name: LocalSvgNames;
|
|
11
12
|
baseUrl?: string;
|
|
12
13
|
as?: React.ElementType;
|
|
13
14
|
} & react.RefAttributes<SVGSVGElement>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { SVGAttributes } from 'react';
|
|
3
3
|
|
|
4
|
+
type LocalSvgNames = string;
|
|
4
5
|
type LocalSvgProps = SVGAttributes<SVGSVGElement> & {
|
|
5
|
-
name:
|
|
6
|
+
name: LocalSvgNames;
|
|
6
7
|
baseUrl?: string;
|
|
7
8
|
as?: React.ElementType;
|
|
8
9
|
};
|
|
9
10
|
declare const LocalSvg: react.NamedExoticComponent<SVGAttributes<SVGSVGElement> & {
|
|
10
|
-
name:
|
|
11
|
+
name: LocalSvgNames;
|
|
11
12
|
baseUrl?: string;
|
|
12
13
|
as?: React.ElementType;
|
|
13
14
|
} & react.RefAttributes<SVGSVGElement>>;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var S=Object.defineProperty,z=Object.defineProperties,U=Object.getOwnPropertyDescriptor,V=Object.getOwnPropertyDescriptors,M=Object.getOwnPropertyNames,T=Object.getOwnPropertySymbols;var A=Object.prototype.hasOwnProperty,b=Object.prototype.propertyIsEnumerable;var v=(t,e,r)=>e in t?S(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,d=(t,e)=>{for(var r in e||(e={}))A.call(e,r)&&v(t,r,e[r]);if(T)for(var r of T(e))b.call(e,r)&&v(t,r,e[r]);return t},I=(t,e)=>z(t,V(e));var R=(t,e)=>{var r={};for(var n in t)A.call(t,n)&&e.indexOf(n)<0&&(r[n]=t[n]);if(t!=null&&T)for(var n of T(t))e.indexOf(n)<0&&b.call(t,n)&&(r[n]=t[n]);return r};var Z=(t,e)=>{for(var r in e)S(t,r,{get:e[r],enumerable:!0})},X=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of M(e))!A.call(t,s)&&s!==r&&S(t,s,{get:()=>e[s],enumerable:!(n=U(e,s))||n.enumerable});return t};var W=t=>X(S({},"__esModule",{value:!0}),t);var l=(t,e,r)=>new Promise((n,s)=>{var c=a=>{try{o(r.next(a))}catch(g){s(g)}},i=a=>{try{o(r.throw(a))}catch(g){s(g)}},o=a=>a.done?n(a.value):Promise.resolve(a.value).then(c,i);o((r=r.apply(t,e)).next())});var Y={};Z(Y,{LocalSvg:()=>O});module.exports=W(Y);var u=require("react");var C=require("react");function N(t,e=null,r={},n="0"){return typeof t=="string"?t:(0,C.createElement)(t.type,I(d(d({},t.props),r),{ref:e,key:n}),...t.children.map((s,c)=>N(s,null,{},`${n}-${c}`)))}function P(t){if(!t)return"";let e=t.replace(/\n|\r|\t/g,"").replace(/\s{2,}/g," ").replace(/\s*(=)\s*"/g,'="').replace(/class="[^"]+"/g,"").replace(/<!--.*?-->/g,"").replace(/\sxmlns(?::[a-zA-Z0-9_-]+)?="[^"]*"/g,"").replace(/<\?xml[^>]*>/g,"").replace(/<metadata>.*?<\/metadata>/g,"").replace(/<(\w+)([^>]*)><\/\1>/g,"<$1$2/>").trim(),r=/id="([^"]{8,})"/g,n,s={},c=0;for(;(n=r.exec(e))!==null;){let i=n[1];s[i]||(s[i]=c.toString(),c++)}for(let i in s){let[o,a]=[i,s[i]],g=new RegExp(`id="${o}"`,"g");e=e.replace(g,`id="${a}"`);let m=new RegExp(`url\\(#${o}\\)`,"g");e=e.replace(m,`url(#${a})`)}return s={},e}var y=class{constructor(e,r){this.name=e;this.value=r}},F=[[/^\s+/,null],[/^<\?xml[^]*\?>/,null],[/^<!--[\s\S]*?-->/,null],[/^<[a-zA-Z_][\w\-.]*(?::[a-zA-Z_][\w\-.]*)?(?=[\s>/>])/,"BEGIN_TAG"],[/^[a-zA-Z_][\w\-.]*(?::[a-zA-Z_][\w\-.]*)?=["|'][^"']*["|']/,"ATTRIBUTE"],[/^>/,"END_TAG"],[/^<\/[a-zA-Z_][\w\-.]*(?::[a-zA-Z_][\w\-.]*)?>/,"CLOSE_TAG"],[/^\/>/,"END_CLOSE_TAG"],[/^.+(?=<\/)/,"TEXT"]],E=class{constructor(){this._cursor=0;this._string=""}init(e){this._string=e}isEOF(){return this._cursor===this._string.length}hasMoreTokens(){return this._cursor<this._string.length}getNextToken(){if(!this.hasMoreTokens())return null;let e=this._string.slice(this._cursor);for(let[r,n]of F){let s=this._match(r,e);if(s!=null)return n==null?this.getNextToken():new y(n,s)}throw new SyntaxError(`Unknown token type ${e.slice(0,10)}`)}_match(e,r){let n=e.exec(r);return n===null?null:(this._cursor+=n[0].length,n[0])}};var G={"xlink:actuate":"xlinkActuate","xlink:arcrole":"xlinkArcrole","xlink:href":"xlinkHref","xlink:role":"xlinkRole","xlink:show":"xlinkShow","xlink:title":"xlinkTitle","xlink:type":"xlinkType","xml:lang":"xmlLang","xml:space":"xmlSpace","xml:base":"xmlBase","xmlns:xlink":"xmlnsXlink",class:"className"};var w=class{constructor(e,r={}){this.type=e;this.props=r;this.children=[]}addChild(e){this.children.push(e)}addProp(e,r){this.props[e]=r}},j={BEGIN_TAG:{ATTRIBUTE:!0,END_TAG:!0,END_CLOSE_TAG:!0},ATTRIBUTE:{ATTRIBUTE:!0,END_TAG:!0,END_CLOSE_TAG:!0},END_TAG:{BEGIN_TAG:!0,CLOSE_TAG:!0,TEXT:!0},CLOSE_TAG:{BEGIN_TAG:!0,CLOSE_TAG:!0},END_CLOSE_TAG:{BEGIN_TAG:!0,CLOSE_TAG:!0},TEXT:{CLOSE_TAG:!0}};function H(t){return t.startsWith("aria-")?t:G[t]?G[t]:t.startsWith("rdf:")||t.startsWith("cc:")||t.startsWith("dc:")||t.startsWith("xmlns:")?t.toLowerCase():t.replace(/-([a-zA-Z])/g,(e,r)=>r.toUpperCase())}var x=class{constructor(){this.tokenizer=new E}parse(e){var c;this.tokenizer.init(e);let r=new w("ROOT"),n=[r],s=this.tokenizer.getNextToken();for(;s;){let i=s;if(s=this.tokenizer.getNextToken(),!i)throw new SyntaxError("Not Token found where expected");if(s&&!((c=j[i.name])!=null&&c[s.name]))throw new SyntaxError(`Unexpected token ${s.name} after ${i.name}`);switch(i.name){case"BEGIN_TAG":let o=new w(i.value.slice(1));n[n.length-1].addChild(o),n.push(o);break;case"ATTRIBUTE":let[a,g]=i.value.split("=");n[n.length-1].addProp(H(a),g.slice(1,-1));break;case"END_TAG":break;case"CLOSE_TAG":if(n.length<=1)throw new SyntaxError("Unexpected closing tag");let m=n.pop();if(m.type!==i.value.slice(2,-1))throw new SyntaxError(`Mismatched tag: expected </${m.type}>, got ${i.value}`);break;case"END_CLOSE_TAG":if(n.length<=1)throw new SyntaxError("Unexpected closing tag");n.pop();break;case"TEXT":n[n.length-1].addChild(i.value);break;default:throw new SyntaxError(`Unknown token type: ${i.name}`)}}if(n.length>1)throw new SyntaxError(`Invalid SVG structure: Missing </${n[n.length-1].type}>`);return r.children[0]}};var f=class{getItem(e){return l(this,null,function*(){let r=localStorage.getItem(e);return r?JSON.parse(r):null})}setItem(e,r){return l(this,null,function*(){localStorage.setItem(e,r)})}},k=class{constructor(){this.dbName="LOCAL_SVG_DB";this.storeName="svgs";this.version=1;this.dbPromise=this.openDB()}openDB(){return new Promise((e,r)=>{if(!(window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB)){r(new Error("IndexedDB is not supported in this environment."));return}let s=indexedDB.open(this.dbName,this.version);s.onupgradeneeded=()=>{let c=s.result;c.objectStoreNames.contains(this.storeName)||c.createObjectStore(this.storeName)},s.onsuccess=()=>e(s.result),s.onerror=()=>r(s.error)})}getItem(e){return l(this,null,function*(){let r=yield this.dbPromise;return new Promise((n,s)=>{let o=r.transaction(this.storeName,"readonly").objectStore(this.storeName).get(e);o.onsuccess=()=>{n(o.result||null)},o.onerror=()=>{s(o.error)}})})}setItem(e,r){return l(this,null,function*(){let n=yield this.dbPromise;return new Promise((s,c)=>{let a=n.transaction(this.storeName,"readwrite").objectStore(this.storeName).put(r,e);a.onsuccess=()=>s(),a.onerror=()=>c(a.error)})})}},B=t=>{if(typeof window=="undefined")return console.warn("Store can only be created in a browser environment."),null;try{return t==="localstorage"?new f:new k}catch(e){return new f}},_=class{constructor(){this.cache=new Map}get(e){return this.cache.get(e)}set(e,r){this.cache.set(e,r)}};var p=B(),D=new _,J=(t,e="/")=>e+t+".svg",K=t=>l(null,null,function*(){try{return yield(yield fetch(t)).text()}catch(e){return console.error(e),null}}),Q=t=>l(null,null,function*(){try{return new x().parse(t)}catch(e){console.error(e)}}),L=(t,e="/")=>l(null,null,function*(){let r=J(t,e),n=D.get(r);if(n)return n;let s=new Promise((c,i)=>l(null,null,function*(){try{let o=yield p==null?void 0:p.getItem(r);if(o||(o=yield K(r),o&&setTimeout(()=>{try{let a=P(o);p==null||p.setItem(r,a)}catch(a){console.warn("Storage is full, cannot cache SVG.")}})),o){let a=yield Q(o);c(a)}i(`Error occured processing Svg ${r}`)}catch(o){i(o)}}));return D.set(r,s),s});var $=require("react/jsx-runtime"),O=(0,u.memo)((0,u.forwardRef)((c,s)=>{var i=c,{name:t,baseUrl:e="/",as:r="span"}=i,n=R(i,["name","baseUrl","as"]);let[o,a]=(0,u.useState)(null);return(0,u.useEffect)(()=>{let m=!0;return L(t,e).then(h=>{m&&h&&a(h)}).catch(h=>console.error(h)),()=>{m=!1}},[t,e]),o?N(o,s,n):(0,$.jsx)(r,{className:n.className,style:d({width:n.width,height:n.height,display:"inline-block"},n.style)})}));0&&(module.exports={LocalSvg});
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/LocalSvg.tsx","../src/tree.ts","../src/tokenizer.ts","../src/namespace.ts","../src/parser.ts","../src/query.ts"],"sourcesContent":["export { LocalSvg, type LocalSvgProps } from \"./LocalSvg\";\n","import { forwardRef, memo, SVGAttributes, useEffect, useState } from \"react\";\nimport { SvgNode } from \"./parser\";\nimport { buildSvgReactTree } from \"./tree\";\nimport { createSvg } from \"./query\";\n\nexport type LocalSvgProps = SVGAttributes<SVGSVGElement> & {\n name: string;\n baseUrl?: string;\n as?: React.ElementType;\n};\n\nconst LocalSvg = memo(\n forwardRef<SVGSVGElement, LocalSvgProps>(\n ({ name, baseUrl = \"/\", as = \"span\", ...props }, ref) => {\n const [node, setNode] = useState<SvgNode | null>(null);\n\n useEffect(() => {\n const loadSvg = async () => {\n const node = await createSvg(name, baseUrl);\n if (node) {\n setNode(node);\n }\n };\n\n loadSvg();\n }, []);\n\n const Com = as;\n\n return node ? (\n buildSvgReactTree(node, ref, props)\n ) : (\n <Com\n className={props.className}\n style={{\n width: props.width,\n height: props.height,\n display: \"inline-block\",\n ...props.style,\n }}\n />\n );\n }\n )\n);\n\nexport { LocalSvg };\n","import { createElement, Ref } from \"react\";\nimport { SvgNode } from \"./parser\";\n\nexport function buildSvgReactTree(\n node: SvgNode | string,\n ref: Ref<SVGSVGElement> | null = null,\n props: Record<string, any> = {},\n keyPath: string = \"0\"\n): React.ReactElement | string {\n if (typeof node === \"string\") return node;\n\n return createElement(\n node.type,\n { ...node.props, ...props, ref, key: keyPath },\n ...node.children.map((child, i) =>\n buildSvgReactTree(child, null, {}, `${keyPath}-${i}`)\n )\n );\n}\n","import { TOKEN_TYPE } from \"./enums\";\n\nexport class Token {\n constructor(public name: TOKEN_TYPE, public value: string) {}\n}\n\nconst Spec: [RegExp, TOKEN_TYPE | null][] = [\n [/^\\s+/, null],\n [/^<\\?xml[^]*\\?>/, null],\n [/^<!--[\\s\\S]*?-->/, null],\n [\n /^<[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?(?=[\\s>/>])/,\n TOKEN_TYPE.BEGIN_TAG,\n ],\n [\n /^[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?=[\"|'][^\"']*[\"|']/,\n TOKEN_TYPE.ATTRIBUTE,\n ],\n [/^>/, TOKEN_TYPE.END_TAG],\n [/^<\\/[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?>/, TOKEN_TYPE.CLOSE_TAG],\n [/^\\/>/, TOKEN_TYPE.END_CLOSE_TAG],\n [/^.+(?=<\\/)/, TOKEN_TYPE.TEXT],\n];\n\nclass Tokenizer {\n private _cursor = 0;\n private _string = \"\";\n\n init(str: string) {\n this._string = str;\n }\n\n isEOF() {\n return this._cursor === this._string.length;\n }\n\n hasMoreTokens() {\n return this._cursor < this._string.length;\n }\n\n getNextToken(): Token | null {\n if (!this.hasMoreTokens()) {\n return null;\n }\n\n const string = this._string.slice(this._cursor);\n\n for (const [regexp, tokenType] of Spec) {\n const tokenValue = this._match(regexp, string);\n\n if (tokenValue == null) {\n continue;\n }\n\n if (tokenType == null) {\n return this.getNextToken();\n }\n\n return new Token(tokenType, tokenValue);\n }\n\n throw new SyntaxError(`Unknown token type ${string.slice(0, 10)}`);\n }\n\n _match(reg: RegExp, string: string) {\n let matched = reg.exec(string);\n\n if (matched === null) {\n return null;\n }\n\n this._cursor += matched[0].length;\n return matched[0];\n }\n}\n\nexport { Tokenizer };\n","export const REACT_NAMESPACE_ATTRS: Record<string, string> = {\n \"xlink:actuate\": \"xlinkActuate\",\n \"xlink:arcrole\": \"xlinkArcrole\",\n \"xlink:href\": \"xlinkHref\",\n \"xlink:role\": \"xlinkRole\",\n \"xlink:show\": \"xlinkShow\",\n \"xlink:title\": \"xlinkTitle\",\n \"xlink:type\": \"xlinkType\",\n \"xml:lang\": \"xmlLang\",\n \"xml:space\": \"xmlSpace\",\n \"xml:base\": \"xmlBase\",\n \"xmlns:xlink\": \"xmlnsXlink\",\n class: \"className\",\n};\n","import { TOKEN_TYPE } from \"./enums\";\nimport { Tokenizer } from \"./tokenizer\";\nimport { REACT_NAMESPACE_ATTRS } from \"./namespace\";\n\nclass SvgNode {\n public children: (SvgNode | string)[] = [];\n constructor(\n public type: string,\n public props: { [key: string]: string } = {}\n ) {}\n\n addChild(node: SvgNode | string) {\n this.children.push(node);\n }\n\n addProp(key: string, value: string) {\n this.props[key] = value;\n }\n}\n\nconst AllowedLookAhead: Record<\n TOKEN_TYPE,\n Partial<Record<TOKEN_TYPE, boolean>>\n> = {\n [TOKEN_TYPE.BEGIN_TAG]: {\n [TOKEN_TYPE.ATTRIBUTE]: true,\n [TOKEN_TYPE.END_TAG]: true,\n [TOKEN_TYPE.END_CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.ATTRIBUTE]: {\n [TOKEN_TYPE.ATTRIBUTE]: true,\n [TOKEN_TYPE.END_TAG]: true,\n [TOKEN_TYPE.END_CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.END_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n [TOKEN_TYPE.TEXT]: true,\n },\n [TOKEN_TYPE.CLOSE_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.END_CLOSE_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.TEXT]: {\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n};\n\nfunction formatAttributeName(name: string) {\n // 1. ARIA → passthrough\n if (name.startsWith(\"aria-\")) {\n return name;\n }\n\n // 2. Explicit React namespace mapping\n if (REACT_NAMESPACE_ATTRS[name]) {\n return REACT_NAMESPACE_ATTRS[name];\n }\n\n // 3. Unsupported XML namespaces → bail out\n if (\n name.startsWith(\"rdf:\") ||\n name.startsWith(\"cc:\") ||\n name.startsWith(\"dc:\") ||\n name.startsWith(\"xmlns:\")\n ) {\n return name.toLowerCase();\n }\n\n // 4. Standard HTML/SVG attribute\n return name.replace(/-([a-zA-Z])/g, (_, char) => char.toUpperCase());\n}\n\nclass Parser {\n tokenizer: Tokenizer;\n\n constructor() {\n this.tokenizer = new Tokenizer();\n }\n\n parse(str: string) {\n this.tokenizer.init(str);\n const root = new SvgNode(\"ROOT\");\n let tags: SvgNode[] = [root];\n let lookAhead = this.tokenizer.getNextToken();\n\n while (lookAhead) {\n const token = lookAhead;\n lookAhead = this.tokenizer.getNextToken();\n\n if (!token) {\n throw new SyntaxError(`Not Token found where expected`);\n }\n\n if (lookAhead && !AllowedLookAhead[token.name]?.[lookAhead.name]) {\n throw new SyntaxError(\n `Unexpected token ${lookAhead.name} after ${token.name}`\n );\n }\n\n switch (token.name) {\n case TOKEN_TYPE.BEGIN_TAG:\n const node = new SvgNode(token.value.slice(1));\n tags[tags.length - 1].addChild(node);\n tags.push(node);\n break;\n\n case TOKEN_TYPE.ATTRIBUTE:\n const [name, value] = token.value.split(\"=\");\n\n tags[tags.length - 1].addProp(\n formatAttributeName(name),\n value.slice(1, -1)\n );\n break;\n\n case TOKEN_TYPE.END_TAG:\n //Do nothing\n break;\n\n case TOKEN_TYPE.CLOSE_TAG:\n if (tags.length <= 1) {\n // ✅ NOW in the right place\n throw new SyntaxError(\"Unexpected closing tag\");\n }\n const current = tags.pop()!;\n if (current.type !== token.value.slice(2, -1)) {\n throw new SyntaxError(\n `Mismatched tag: expected </${current.type}>, got ${token.value}`\n );\n }\n break;\n\n case TOKEN_TYPE.END_CLOSE_TAG:\n if (tags.length <= 1) {\n // ✅ NOW in the right place\n throw new SyntaxError(\"Unexpected closing tag\");\n }\n tags.pop();\n break;\n\n case TOKEN_TYPE.TEXT:\n tags[tags.length - 1].addChild(token.value);\n break;\n\n default:\n throw new SyntaxError(`Unknown token type: ${token.name}`);\n }\n }\n\n if (tags.length > 1) {\n throw new SyntaxError(\n `Invalid SVG structure: Missing </${tags[tags.length - 1].type}>`\n );\n }\n\n return root.children[0] as SvgNode;\n }\n}\n\nexport { Parser, SvgNode };\n","import { Parser, SvgNode } from \"./parser\";\n\ntype ResultPromise = Promise<SvgNode | undefined>;\nconst promiseCache: Record<string, ResultPromise | null> = {};\n\nconst composeUrl = (name: string, baseUrl = \"/\") => {\n return baseUrl + name + \".svg\";\n};\n\nconst _fetch = async (url: string) => {\n try {\n const response = await fetch(url);\n return await response.text();\n } catch (error) {\n console.error(error);\n return null;\n }\n};\n\n// const fullUrl = composeUrl(name, baseUrl);\n\nconst processSvgText = async (text: string) => {\n try {\n const parser = new Parser();\n return parser.parse(text);\n } catch (error) {\n console.log(error);\n }\n};\n\n/**\n * Minify SVG string dynamically\n * - Removes whitespace, line breaks\n * - Collapses multiple spaces\n * - Shortens linearGradient and other IDs\n * @param {string} svg\n * @returns {string} minified SVG\n */\n\nfunction minifySVG(svg: string) {\n if (!svg) return \"\";\n\n // 1️⃣ Remove newlines, tabs, multiple spaces\n let min = svg\n .replace(/\\n|\\r|\\t/g, \"\")\n .replace(/\\s{2,}/g, \" \")\n .replace(/\\s*(=)\\s*\"/g, '=\"')\n .trim();\n\n // 2️⃣ Collect all IDs that look like IconifyId* or long random IDs\n const idRegex = /id=\"([^\"]{8,})\"/g;\n let match;\n const idMap: Record<string, string> = {};\n let counter = 0;\n const letters = \"abcdefghijklmnopqrstuvwxyz\";\n\n while ((match = idRegex.exec(min)) !== null) {\n const longId = match[1];\n if (!idMap[longId]) {\n idMap[longId] = letters[counter] || `id${counter}`;\n counter++;\n }\n }\n\n // 3️⃣ Replace IDs and corresponding url(#ID) references\n for (const key in idMap) {\n const [longId, shortId] = [key, idMap[key]];\n const idPattern = new RegExp(`id=\"${longId}\"`, \"g\");\n min = min.replace(idPattern, `id=\"${shortId}\"`);\n const urlPattern = new RegExp(`url\\\\(#${longId}\\\\)`, \"g\");\n min = min.replace(urlPattern, `url(#${shortId})`);\n }\n\n // 4️⃣ Collapse self-closing tags (optional)\n min = min.replace(/<(\\w+)([^>]*)><\\/\\1>/g, \"<$1$2/>\");\n\n return min;\n}\n\nexport const createSvg = async (name: string, baseUrl = \"/\") => {\n const fullUrl = composeUrl(name, baseUrl);\n\n if (promiseCache[fullUrl]) {\n return promiseCache[fullUrl];\n }\n\n promiseCache[fullUrl] = new Promise(async (resolve, reject) => {\n try {\n let text = localStorage.getItem(fullUrl);\n\n if (!text) {\n text = await _fetch(fullUrl);\n\n if (text) {\n try {\n localStorage.setItem(fullUrl, text);\n } catch (error) {\n console.warn(\"LocalStorage is full, cannot cache SVG.\");\n }\n }\n }\n\n if (text) {\n setTimeout(() => {\n const diff = text.length - minifySVG(text).length;\n console.log(\n text.length,\n text.length - diff,\n `SVG Minification saved ${diff} bytes for ${name}, percentage: ${(\n (diff / text.length) *\n 100\n ).toFixed(2)}%`\n );\n });\n\n const node = await processSvgText(text);\n resolve(node);\n }\n resolve(undefined);\n } catch (error) {\n reject(error);\n }\n });\n\n return promiseCache[fullUrl]!;\n};\n"],"mappings":"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","names":["index_exports","__export","LocalSvg","__toCommonJS","import_react","import_react","buildSvgReactTree","node","ref","props","keyPath","__spreadProps","__spreadValues","child","i","Token","name","value","Spec","Tokenizer","str","string","regexp","tokenType","tokenValue","reg","matched","REACT_NAMESPACE_ATTRS","SvgNode","type","props","node","key","value","AllowedLookAhead","formatAttributeName","name","REACT_NAMESPACE_ATTRS","_","char","Parser","Tokenizer","str","_a","root","tags","lookAhead","token","current","promiseCache","composeUrl","name","baseUrl","_fetch","url","__async","error","processSvgText","text","Parser","minifySVG","svg","min","idRegex","match","idMap","counter","letters","longId","key","shortId","idPattern","urlPattern","createSvg","fullUrl","resolve","reject","diff","node","import_jsx_runtime","LocalSvg","_a","ref","_b","name","baseUrl","as","props","__objRest","node","setNode","__async","createSvg","buildSvgReactTree","__spreadValues"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/LocalSvg.tsx","../src/tree.ts","../src/minification.ts","../src/tokenizer.ts","../src/namespace.ts","../src/parser.ts","../src/store.ts","../src/query.ts"],"sourcesContent":["export { LocalSvg, type LocalSvgProps } from \"./LocalSvg\";\n","import { forwardRef, memo, SVGAttributes, useEffect, useState } from \"react\";\nimport { SvgNode } from \"./parser\";\nimport { buildSvgReactTree } from \"./tree\";\nimport { createSvg } from \"./query\";\n\nexport type LocalSvgNames = string;\nexport type LocalSvgProps = SVGAttributes<SVGSVGElement> & {\n name: LocalSvgNames;\n baseUrl?: string;\n as?: React.ElementType;\n};\n\nexport const LocalSvg = memo(\n forwardRef<SVGSVGElement, LocalSvgProps>(\n ({ name, baseUrl = \"/\", as = \"span\", ...props }, ref) => {\n const [node, setNode] = useState<SvgNode | null>(null);\n\n useEffect(() => {\n let alive = true;\n\n createSvg(name, baseUrl)\n .then((node) => {\n if (alive && node) setNode(node);\n })\n .catch((err) => console.error(err));\n\n return () => {\n alive = false;\n };\n }, [name, baseUrl]);\n\n const Com = as;\n\n return node ? (\n buildSvgReactTree(node, ref, props)\n ) : (\n <Com\n className={props.className}\n style={{\n width: props.width,\n height: props.height,\n display: \"inline-block\",\n ...props.style,\n }}\n />\n );\n }\n )\n);\n","import { createElement, Ref } from \"react\";\nimport { SvgNode } from \"./parser\";\n\nexport function buildSvgReactTree(\n node: SvgNode | string,\n ref: Ref<SVGSVGElement> | null = null,\n props: Record<string, any> = {},\n keyPath: string = \"0\"\n): React.ReactElement | string {\n if (typeof node === \"string\") return node;\n\n return createElement(\n node.type,\n { ...node.props, ...props, ref, key: keyPath },\n ...node.children.map((child, i) =>\n buildSvgReactTree(child, null, {}, `${keyPath}-${i}`)\n )\n );\n}\n","/**\n * Minifies an SVG string for more efficient usage in the browser or inline.\n *\n * Features:\n * 1. Removes unnecessary whitespace, line breaks, tabs, and extra spaces.\n * 2. Strips XML declarations, comments, metadata, `class` attributes, and `xmlns` attributes.\n * 3. Collapses empty tags into self-closing tags.\n * 4. Shortens long IDs (8+ characters) to sequential numeric IDs and updates all corresponding `url(#ID)` references.\n *\n * @param {string} svg - The raw SVG string to minify.\n * @returns {string} The minified SVG string with optimized IDs and whitespace removed.\n *\n * @example\n * const raw = `<svg xmlns=\"http://www.w3.org/2000/svg\">\n * <defs>\n * <linearGradient id=\"longGradient12345678\"><stop offset=\"0%\" /></linearGradient>\n * </defs>\n * <rect fill=\"url(#longGradient12345678)\" width=\"100\" height=\"100\"/>\n * </svg>`;\n *\n * const minified = minifySVG(raw);\n * console.log(minified);\n */\nexport function minifySVG(svg: string) {\n if (!svg) return \"\";\n\n // 1️⃣ Remove newlines, tabs, multiple spaces\n let min = svg\n .replace(/\\n|\\r|\\t/g, \"\")\n .replace(/\\s{2,}/g, \" \")\n .replace(/\\s*(=)\\s*\"/g, '=\"')\n .replace(/class=\"[^\"]+\"/g, \"\")\n .replace(/<!--.*?-->/g, \"\") // Remove comments\n .replace(/\\sxmlns(?::[a-zA-Z0-9_-]+)?=\"[^\"]*\"/g, \"\") // Remove xmlns attribute\n .replace(/<\\?xml[^>]*>/g, \"\") // Remove XML declaration\n .replace(/<metadata>.*?<\\/metadata>/g, \"\") // Remove metadata\n .replace(/<(\\w+)([^>]*)><\\/\\1>/g, \"<$1$2/>\") // 4️⃣ Collapse self-closing tags (optional)\n .trim();\n\n // 2️⃣ Collect all IDs that look like IconifyId* or long random IDs\n const idRegex = /id=\"([^\"]{8,})\"/g;\n let match;\n let idMap: Record<string, string> = {};\n let counter = 0;\n\n while ((match = idRegex.exec(min)) !== null) {\n const longId = match[1];\n if (!idMap[longId]) {\n idMap[longId] = counter.toString();\n counter++;\n }\n }\n\n // 3️⃣ Replace IDs and corresponding url(#ID) references\n for (const key in idMap) {\n const [longId, shortId] = [key, idMap[key]];\n const idPattern = new RegExp(`id=\"${longId}\"`, \"g\");\n min = min.replace(idPattern, `id=\"${shortId}\"`);\n const urlPattern = new RegExp(`url\\\\(#${longId}\\\\)`, \"g\");\n min = min.replace(urlPattern, `url(#${shortId})`);\n }\n\n idMap = {};\n\n return min;\n}\n","import { TOKEN_TYPE } from \"./enums\";\n\nexport class Token {\n constructor(public name: TOKEN_TYPE, public value: string) {}\n}\n\nconst Spec: [RegExp, TOKEN_TYPE | null][] = [\n [/^\\s+/, null],\n [/^<\\?xml[^]*\\?>/, null],\n [/^<!--[\\s\\S]*?-->/, null],\n [\n /^<[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?(?=[\\s>/>])/,\n TOKEN_TYPE.BEGIN_TAG,\n ],\n [\n /^[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?=[\"|'][^\"']*[\"|']/,\n TOKEN_TYPE.ATTRIBUTE,\n ],\n [/^>/, TOKEN_TYPE.END_TAG],\n [/^<\\/[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?>/, TOKEN_TYPE.CLOSE_TAG],\n [/^\\/>/, TOKEN_TYPE.END_CLOSE_TAG],\n [/^.+(?=<\\/)/, TOKEN_TYPE.TEXT],\n];\n\nclass Tokenizer {\n private _cursor = 0;\n private _string = \"\";\n\n init(str: string) {\n this._string = str;\n }\n\n isEOF() {\n return this._cursor === this._string.length;\n }\n\n hasMoreTokens() {\n return this._cursor < this._string.length;\n }\n\n getNextToken(): Token | null {\n if (!this.hasMoreTokens()) {\n return null;\n }\n\n const string = this._string.slice(this._cursor);\n\n for (const [regexp, tokenType] of Spec) {\n const tokenValue = this._match(regexp, string);\n\n if (tokenValue == null) {\n continue;\n }\n\n if (tokenType == null) {\n return this.getNextToken();\n }\n\n return new Token(tokenType, tokenValue);\n }\n\n throw new SyntaxError(`Unknown token type ${string.slice(0, 10)}`);\n }\n\n _match(reg: RegExp, string: string) {\n let matched = reg.exec(string);\n\n if (matched === null) {\n return null;\n }\n\n this._cursor += matched[0].length;\n return matched[0];\n }\n}\n\nexport { Tokenizer };\n","export const REACT_NAMESPACE_ATTRS: Record<string, string> = {\n \"xlink:actuate\": \"xlinkActuate\",\n \"xlink:arcrole\": \"xlinkArcrole\",\n \"xlink:href\": \"xlinkHref\",\n \"xlink:role\": \"xlinkRole\",\n \"xlink:show\": \"xlinkShow\",\n \"xlink:title\": \"xlinkTitle\",\n \"xlink:type\": \"xlinkType\",\n \"xml:lang\": \"xmlLang\",\n \"xml:space\": \"xmlSpace\",\n \"xml:base\": \"xmlBase\",\n \"xmlns:xlink\": \"xmlnsXlink\",\n class: \"className\",\n};\n","import { TOKEN_TYPE } from \"./enums\";\nimport { Tokenizer } from \"./tokenizer\";\nimport { REACT_NAMESPACE_ATTRS } from \"./namespace\";\n\nclass SvgNode {\n public children: (SvgNode | string)[] = [];\n constructor(\n public type: string,\n public props: { [key: string]: string } = {}\n ) {}\n\n addChild(node: SvgNode | string) {\n this.children.push(node);\n }\n\n addProp(key: string, value: string) {\n this.props[key] = value;\n }\n}\n\nconst AllowedLookAhead: Record<\n TOKEN_TYPE,\n Partial<Record<TOKEN_TYPE, boolean>>\n> = {\n [TOKEN_TYPE.BEGIN_TAG]: {\n [TOKEN_TYPE.ATTRIBUTE]: true,\n [TOKEN_TYPE.END_TAG]: true,\n [TOKEN_TYPE.END_CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.ATTRIBUTE]: {\n [TOKEN_TYPE.ATTRIBUTE]: true,\n [TOKEN_TYPE.END_TAG]: true,\n [TOKEN_TYPE.END_CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.END_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n [TOKEN_TYPE.TEXT]: true,\n },\n [TOKEN_TYPE.CLOSE_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.END_CLOSE_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.TEXT]: {\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n};\n\nfunction formatAttributeName(name: string) {\n // 1. ARIA → passthrough\n if (name.startsWith(\"aria-\")) {\n return name;\n }\n\n // 2. Explicit React namespace mapping\n if (REACT_NAMESPACE_ATTRS[name]) {\n return REACT_NAMESPACE_ATTRS[name];\n }\n\n // 3. Unsupported XML namespaces → bail out\n if (\n name.startsWith(\"rdf:\") ||\n name.startsWith(\"cc:\") ||\n name.startsWith(\"dc:\") ||\n name.startsWith(\"xmlns:\")\n ) {\n return name.toLowerCase();\n }\n\n // 4. Standard HTML/SVG attribute\n return name.replace(/-([a-zA-Z])/g, (_, char) => char.toUpperCase());\n}\n\nclass Parser {\n tokenizer: Tokenizer;\n\n constructor() {\n this.tokenizer = new Tokenizer();\n }\n\n parse(str: string) {\n this.tokenizer.init(str);\n const root = new SvgNode(\"ROOT\");\n let tags: SvgNode[] = [root];\n let lookAhead = this.tokenizer.getNextToken();\n\n while (lookAhead) {\n const token = lookAhead;\n lookAhead = this.tokenizer.getNextToken();\n\n if (!token) {\n throw new SyntaxError(`Not Token found where expected`);\n }\n\n if (lookAhead && !AllowedLookAhead[token.name]?.[lookAhead.name]) {\n throw new SyntaxError(\n `Unexpected token ${lookAhead.name} after ${token.name}`\n );\n }\n\n switch (token.name) {\n case TOKEN_TYPE.BEGIN_TAG:\n const node = new SvgNode(token.value.slice(1));\n tags[tags.length - 1].addChild(node);\n tags.push(node);\n break;\n\n case TOKEN_TYPE.ATTRIBUTE:\n const [name, value] = token.value.split(\"=\");\n\n tags[tags.length - 1].addProp(\n formatAttributeName(name),\n value.slice(1, -1)\n );\n break;\n\n case TOKEN_TYPE.END_TAG:\n //Do nothing\n break;\n\n case TOKEN_TYPE.CLOSE_TAG:\n if (tags.length <= 1) {\n // ✅ NOW in the right place\n throw new SyntaxError(\"Unexpected closing tag\");\n }\n const current = tags.pop()!;\n if (current.type !== token.value.slice(2, -1)) {\n throw new SyntaxError(\n `Mismatched tag: expected </${current.type}>, got ${token.value}`\n );\n }\n break;\n\n case TOKEN_TYPE.END_CLOSE_TAG:\n if (tags.length <= 1) {\n // ✅ NOW in the right place\n throw new SyntaxError(\"Unexpected closing tag\");\n }\n tags.pop();\n break;\n\n case TOKEN_TYPE.TEXT:\n tags[tags.length - 1].addChild(token.value);\n break;\n\n default:\n throw new SyntaxError(`Unknown token type: ${token.name}`);\n }\n }\n\n if (tags.length > 1) {\n throw new SyntaxError(\n `Invalid SVG structure: Missing </${tags[tags.length - 1].type}>`\n );\n }\n\n return root.children[0] as SvgNode;\n }\n}\n\nexport { Parser, SvgNode };\n","interface Store {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, content:string): Promise<void>;\n}\n\nclass LocalStorageStore implements Store {\n async getItem(key: string): Promise<string | null> {\n const item = localStorage.getItem(key);\n return item ? (JSON.parse(item) as string) : null;\n }\n\n async setItem(key: string, value: string) {\n localStorage.setItem(key, value);\n }\n}\n\nclass IndexedDBStore implements Store {\n private dbName = \"LOCAL_SVG_DB\";\n private storeName = \"svgs\";\n private dbPromise: Promise<IDBDatabase>;\n private version = 1;\n\n constructor() {\n this.dbPromise = this.openDB();\n }\n\n private openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const idb: IDBFactory | null =\n window.indexedDB ||\n (window as any).mozIndexedDB ||\n (window as any).webkitIndexedDB ||\n (window as any).msIndexedDB;\n if (!idb) {\n reject(new Error(\"IndexedDB is not supported in this environment.\"));\n return;\n }\n const request = indexedDB.open(this.dbName, this.version);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(this.storeName)) {\n db.createObjectStore(this.storeName);\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n\n async getItem(key: string): Promise<string | null> {\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(this.storeName, \"readonly\");\n const store = transaction.objectStore(this.storeName);\n const request = store.get(key);\n request.onsuccess = () => {\n resolve((request.result as string) || null);\n };\n request.onerror = () => {\n reject(request.error);\n };\n });\n }\n\n async setItem(key: string, value: string): Promise<void> {\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(this.storeName, \"readwrite\");\n const store = transaction.objectStore(this.storeName);\n const request = store.put(value, key);\n request.onsuccess = () => resolve();\n request.onerror = () => reject(request.error);\n });\n }\n}\n\nexport const createStore = (storage?: \"localstorage\" | \"indexdb\"): Store => {\n if (typeof window === \"undefined\") {\n console.warn(\"Store can only be created in a browser environment.\");\n return null;\n }\n try {\n if (storage === \"localstorage\") {\n return new LocalStorageStore();\n }\n return new IndexedDBStore();\n } catch (error) {\n return new LocalStorageStore();\n }\n};\n\nexport class PromiseCache<T> {\n private cache: Map<string, Promise<T>>;\n\n constructor() {\n this.cache = new Map();\n }\n\n get(key: string): Promise<T> | undefined {\n return this.cache.get(key);\n }\n\n set(key: string, promise: Promise<T>): void {\n this.cache.set(key, promise);\n }\n}","import { minifySVG } from \"./minification\";\nimport { Parser, SvgNode } from \"./parser\";\nimport { createStore, PromiseCache } from \"./store\";\n\nconst store = createStore();\nconst promiseCache = new PromiseCache<SvgNode>();\n\nconst composeUrl = (name: string, baseUrl = \"/\") => {\n return baseUrl + name + \".svg\";\n};\n\nconst _fetch = async (url: string) => {\n try {\n const response = await fetch(url);\n return await response.text();\n } catch (error) {\n console.error(error);\n return null;\n }\n};\n\nconst processSvgText = async (text: string) => {\n try {\n const parser = new Parser();\n return parser.parse(text);\n } catch (error) {\n console.error(error);\n }\n};\n\nexport const createSvg = async (name: string, baseUrl = \"/\") => {\n const fullUrl = composeUrl(name, baseUrl);\n const promise = promiseCache.get(fullUrl);\n\n if (promise) {\n return promise;\n }\n\n const newPromise = new Promise<SvgNode>(async (resolve, reject) => {\n try {\n let text = await store?.getItem(fullUrl);\n\n if (!text) {\n text = await _fetch(fullUrl);\n\n if (text) {\n setTimeout(() => {\n try {\n const minified = minifySVG(text);\n store?.setItem(fullUrl, minified);\n } catch (error) {\n console.warn(\"Storage is full, cannot cache SVG.\");\n }\n });\n }\n }\n\n if (text) {\n const node = await processSvgText(text);\n resolve(node);\n }\n\n reject(`Error occured processing Svg ${fullUrl}`);\n } catch (error) {\n reject(error);\n }\n });\n\n promiseCache.set(fullUrl, newPromise);\n\n return newPromise;\n};\n"],"mappings":"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","names":["index_exports","__export","LocalSvg","__toCommonJS","import_react","import_react","buildSvgReactTree","node","ref","props","keyPath","__spreadProps","__spreadValues","child","i","minifySVG","svg","min","idRegex","match","idMap","counter","longId","key","shortId","idPattern","urlPattern","Token","name","value","Spec","Tokenizer","str","string","regexp","tokenType","tokenValue","reg","matched","REACT_NAMESPACE_ATTRS","SvgNode","type","props","node","key","value","AllowedLookAhead","formatAttributeName","name","REACT_NAMESPACE_ATTRS","_","char","Parser","Tokenizer","str","_a","root","tags","lookAhead","token","current","LocalStorageStore","key","__async","item","value","IndexedDBStore","resolve","reject","request","db","createStore","storage","error","PromiseCache","promise","store","createStore","promiseCache","PromiseCache","composeUrl","name","baseUrl","_fetch","url","__async","error","processSvgText","text","Parser","createSvg","fullUrl","promise","newPromise","resolve","reject","minified","minifySVG","node","import_jsx_runtime","LocalSvg","_a","ref","_b","name","baseUrl","as","props","__objRest","node","setNode","alive","createSvg","err","buildSvgReactTree","__spreadValues"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
1
|
+
var B=Object.defineProperty,D=Object.defineProperties;var L=Object.getOwnPropertyDescriptors;var h=Object.getOwnPropertySymbols;var G=Object.prototype.hasOwnProperty,k=Object.prototype.propertyIsEnumerable;var y=(t,e,r)=>e in t?B(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,p=(t,e)=>{for(var r in e||(e={}))G.call(e,r)&&y(t,r,e[r]);if(h)for(var r of h(e))k.call(e,r)&&y(t,r,e[r]);return t},v=(t,e)=>D(t,L(e));var b=(t,e)=>{var r={};for(var n in t)G.call(t,n)&&e.indexOf(n)<0&&(r[n]=t[n]);if(t!=null&&h)for(var n of h(t))e.indexOf(n)<0&&k.call(t,n)&&(r[n]=t[n]);return r};var l=(t,e,r)=>new Promise((n,s)=>{var c=a=>{try{o(r.next(a))}catch(g){s(g)}},i=a=>{try{o(r.throw(a))}catch(g){s(g)}},o=a=>a.done?n(a.value):Promise.resolve(a.value).then(c,i);o((r=r.apply(t,e)).next())});import{forwardRef as W,memo as q,useEffect as F,useState as j}from"react";import{createElement as O}from"react";function f(t,e=null,r={},n="0"){return typeof t=="string"?t:O(t.type,v(p(p({},t.props),r),{ref:e,key:n}),...t.children.map((s,c)=>f(s,null,{},`${n}-${c}`)))}function I(t){if(!t)return"";let e=t.replace(/\n|\r|\t/g,"").replace(/\s{2,}/g," ").replace(/\s*(=)\s*"/g,'="').replace(/class="[^"]+"/g,"").replace(/<!--.*?-->/g,"").replace(/\sxmlns(?::[a-zA-Z0-9_-]+)?="[^"]*"/g,"").replace(/<\?xml[^>]*>/g,"").replace(/<metadata>.*?<\/metadata>/g,"").replace(/<(\w+)([^>]*)><\/\1>/g,"<$1$2/>").trim(),r=/id="([^"]{8,})"/g,n,s={},c=0;for(;(n=r.exec(e))!==null;){let i=n[1];s[i]||(s[i]=c.toString(),c++)}for(let i in s){let[o,a]=[i,s[i]],g=new RegExp(`id="${o}"`,"g");e=e.replace(g,`id="${a}"`);let u=new RegExp(`url\\(#${o}\\)`,"g");e=e.replace(u,`url(#${a})`)}return s={},e}var _=class{constructor(e,r){this.name=e;this.value=r}},z=[[/^\s+/,null],[/^<\?xml[^]*\?>/,null],[/^<!--[\s\S]*?-->/,null],[/^<[a-zA-Z_][\w\-.]*(?::[a-zA-Z_][\w\-.]*)?(?=[\s>/>])/,"BEGIN_TAG"],[/^[a-zA-Z_][\w\-.]*(?::[a-zA-Z_][\w\-.]*)?=["|'][^"']*["|']/,"ATTRIBUTE"],[/^>/,"END_TAG"],[/^<\/[a-zA-Z_][\w\-.]*(?::[a-zA-Z_][\w\-.]*)?>/,"CLOSE_TAG"],[/^\/>/,"END_CLOSE_TAG"],[/^.+(?=<\/)/,"TEXT"]],T=class{constructor(){this._cursor=0;this._string=""}init(e){this._string=e}isEOF(){return this._cursor===this._string.length}hasMoreTokens(){return this._cursor<this._string.length}getNextToken(){if(!this.hasMoreTokens())return null;let e=this._string.slice(this._cursor);for(let[r,n]of z){let s=this._match(r,e);if(s!=null)return n==null?this.getNextToken():new _(n,s)}throw new SyntaxError(`Unknown token type ${e.slice(0,10)}`)}_match(e,r){let n=e.exec(r);return n===null?null:(this._cursor+=n[0].length,n[0])}};var A={"xlink:actuate":"xlinkActuate","xlink:arcrole":"xlinkArcrole","xlink:href":"xlinkHref","xlink:role":"xlinkRole","xlink:show":"xlinkShow","xlink:title":"xlinkTitle","xlink:type":"xlinkType","xml:lang":"xmlLang","xml:space":"xmlSpace","xml:base":"xmlBase","xmlns:xlink":"xmlnsXlink",class:"className"};var S=class{constructor(e,r={}){this.type=e;this.props=r;this.children=[]}addChild(e){this.children.push(e)}addProp(e,r){this.props[e]=r}},U={BEGIN_TAG:{ATTRIBUTE:!0,END_TAG:!0,END_CLOSE_TAG:!0},ATTRIBUTE:{ATTRIBUTE:!0,END_TAG:!0,END_CLOSE_TAG:!0},END_TAG:{BEGIN_TAG:!0,CLOSE_TAG:!0,TEXT:!0},CLOSE_TAG:{BEGIN_TAG:!0,CLOSE_TAG:!0},END_CLOSE_TAG:{BEGIN_TAG:!0,CLOSE_TAG:!0},TEXT:{CLOSE_TAG:!0}};function V(t){return t.startsWith("aria-")?t:A[t]?A[t]:t.startsWith("rdf:")||t.startsWith("cc:")||t.startsWith("dc:")||t.startsWith("xmlns:")?t.toLowerCase():t.replace(/-([a-zA-Z])/g,(e,r)=>r.toUpperCase())}var E=class{constructor(){this.tokenizer=new T}parse(e){var c;this.tokenizer.init(e);let r=new S("ROOT"),n=[r],s=this.tokenizer.getNextToken();for(;s;){let i=s;if(s=this.tokenizer.getNextToken(),!i)throw new SyntaxError("Not Token found where expected");if(s&&!((c=U[i.name])!=null&&c[s.name]))throw new SyntaxError(`Unexpected token ${s.name} after ${i.name}`);switch(i.name){case"BEGIN_TAG":let o=new S(i.value.slice(1));n[n.length-1].addChild(o),n.push(o);break;case"ATTRIBUTE":let[a,g]=i.value.split("=");n[n.length-1].addProp(V(a),g.slice(1,-1));break;case"END_TAG":break;case"CLOSE_TAG":if(n.length<=1)throw new SyntaxError("Unexpected closing tag");let u=n.pop();if(u.type!==i.value.slice(2,-1))throw new SyntaxError(`Mismatched tag: expected </${u.type}>, got ${i.value}`);break;case"END_CLOSE_TAG":if(n.length<=1)throw new SyntaxError("Unexpected closing tag");n.pop();break;case"TEXT":n[n.length-1].addChild(i.value);break;default:throw new SyntaxError(`Unknown token type: ${i.name}`)}}if(n.length>1)throw new SyntaxError(`Invalid SVG structure: Missing </${n[n.length-1].type}>`);return r.children[0]}};var w=class{getItem(e){return l(this,null,function*(){let r=localStorage.getItem(e);return r?JSON.parse(r):null})}setItem(e,r){return l(this,null,function*(){localStorage.setItem(e,r)})}},N=class{constructor(){this.dbName="LOCAL_SVG_DB";this.storeName="svgs";this.version=1;this.dbPromise=this.openDB()}openDB(){return new Promise((e,r)=>{if(!(window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB)){r(new Error("IndexedDB is not supported in this environment."));return}let s=indexedDB.open(this.dbName,this.version);s.onupgradeneeded=()=>{let c=s.result;c.objectStoreNames.contains(this.storeName)||c.createObjectStore(this.storeName)},s.onsuccess=()=>e(s.result),s.onerror=()=>r(s.error)})}getItem(e){return l(this,null,function*(){let r=yield this.dbPromise;return new Promise((n,s)=>{let o=r.transaction(this.storeName,"readonly").objectStore(this.storeName).get(e);o.onsuccess=()=>{n(o.result||null)},o.onerror=()=>{s(o.error)}})})}setItem(e,r){return l(this,null,function*(){let n=yield this.dbPromise;return new Promise((s,c)=>{let a=n.transaction(this.storeName,"readwrite").objectStore(this.storeName).put(r,e);a.onsuccess=()=>s(),a.onerror=()=>c(a.error)})})}},R=t=>{if(typeof window=="undefined")return console.warn("Store can only be created in a browser environment."),null;try{return t==="localstorage"?new w:new N}catch(e){return new w}},x=class{constructor(){this.cache=new Map}get(e){return this.cache.get(e)}set(e,r){this.cache.set(e,r)}};var m=R(),C=new x,M=(t,e="/")=>e+t+".svg",Z=t=>l(null,null,function*(){try{return yield(yield fetch(t)).text()}catch(e){return console.error(e),null}}),X=t=>l(null,null,function*(){try{return new E().parse(t)}catch(e){console.error(e)}}),P=(t,e="/")=>l(null,null,function*(){let r=M(t,e),n=C.get(r);if(n)return n;let s=new Promise((c,i)=>l(null,null,function*(){try{let o=yield m==null?void 0:m.getItem(r);if(o||(o=yield Z(r),o&&setTimeout(()=>{try{let a=I(o);m==null||m.setItem(r,a)}catch(a){console.warn("Storage is full, cannot cache SVG.")}})),o){let a=yield X(o);c(a)}i(`Error occured processing Svg ${r}`)}catch(o){i(o)}}));return C.set(r,s),s});import{jsx as J}from"react/jsx-runtime";var H=q(W((c,s)=>{var i=c,{name:t,baseUrl:e="/",as:r="span"}=i,n=b(i,["name","baseUrl","as"]);let[o,a]=j(null);return F(()=>{let u=!0;return P(t,e).then(d=>{u&&d&&a(d)}).catch(d=>console.error(d)),()=>{u=!1}},[t,e]),o?f(o,s,n):J(r,{className:n.className,style:p({width:n.width,height:n.height,display:"inline-block"},n.style)})}));export{H as LocalSvg};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/LocalSvg.tsx","../src/tree.ts","../src/tokenizer.ts","../src/namespace.ts","../src/parser.ts","../src/query.ts"],"sourcesContent":["import { forwardRef, memo, SVGAttributes, useEffect, useState } from \"react\";\nimport { SvgNode } from \"./parser\";\nimport { buildSvgReactTree } from \"./tree\";\nimport { createSvg } from \"./query\";\n\nexport type LocalSvgProps = SVGAttributes<SVGSVGElement> & {\n name: string;\n baseUrl?: string;\n as?: React.ElementType;\n};\n\nconst LocalSvg = memo(\n forwardRef<SVGSVGElement, LocalSvgProps>(\n ({ name, baseUrl = \"/\", as = \"span\", ...props }, ref) => {\n const [node, setNode] = useState<SvgNode | null>(null);\n\n useEffect(() => {\n const loadSvg = async () => {\n const node = await createSvg(name, baseUrl);\n if (node) {\n setNode(node);\n }\n };\n\n loadSvg();\n }, []);\n\n const Com = as;\n\n return node ? (\n buildSvgReactTree(node, ref, props)\n ) : (\n <Com\n className={props.className}\n style={{\n width: props.width,\n height: props.height,\n display: \"inline-block\",\n ...props.style,\n }}\n />\n );\n }\n )\n);\n\nexport { LocalSvg };\n","import { createElement, Ref } from \"react\";\nimport { SvgNode } from \"./parser\";\n\nexport function buildSvgReactTree(\n node: SvgNode | string,\n ref: Ref<SVGSVGElement> | null = null,\n props: Record<string, any> = {},\n keyPath: string = \"0\"\n): React.ReactElement | string {\n if (typeof node === \"string\") return node;\n\n return createElement(\n node.type,\n { ...node.props, ...props, ref, key: keyPath },\n ...node.children.map((child, i) =>\n buildSvgReactTree(child, null, {}, `${keyPath}-${i}`)\n )\n );\n}\n","import { TOKEN_TYPE } from \"./enums\";\n\nexport class Token {\n constructor(public name: TOKEN_TYPE, public value: string) {}\n}\n\nconst Spec: [RegExp, TOKEN_TYPE | null][] = [\n [/^\\s+/, null],\n [/^<\\?xml[^]*\\?>/, null],\n [/^<!--[\\s\\S]*?-->/, null],\n [\n /^<[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?(?=[\\s>/>])/,\n TOKEN_TYPE.BEGIN_TAG,\n ],\n [\n /^[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?=[\"|'][^\"']*[\"|']/,\n TOKEN_TYPE.ATTRIBUTE,\n ],\n [/^>/, TOKEN_TYPE.END_TAG],\n [/^<\\/[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?>/, TOKEN_TYPE.CLOSE_TAG],\n [/^\\/>/, TOKEN_TYPE.END_CLOSE_TAG],\n [/^.+(?=<\\/)/, TOKEN_TYPE.TEXT],\n];\n\nclass Tokenizer {\n private _cursor = 0;\n private _string = \"\";\n\n init(str: string) {\n this._string = str;\n }\n\n isEOF() {\n return this._cursor === this._string.length;\n }\n\n hasMoreTokens() {\n return this._cursor < this._string.length;\n }\n\n getNextToken(): Token | null {\n if (!this.hasMoreTokens()) {\n return null;\n }\n\n const string = this._string.slice(this._cursor);\n\n for (const [regexp, tokenType] of Spec) {\n const tokenValue = this._match(regexp, string);\n\n if (tokenValue == null) {\n continue;\n }\n\n if (tokenType == null) {\n return this.getNextToken();\n }\n\n return new Token(tokenType, tokenValue);\n }\n\n throw new SyntaxError(`Unknown token type ${string.slice(0, 10)}`);\n }\n\n _match(reg: RegExp, string: string) {\n let matched = reg.exec(string);\n\n if (matched === null) {\n return null;\n }\n\n this._cursor += matched[0].length;\n return matched[0];\n }\n}\n\nexport { Tokenizer };\n","export const REACT_NAMESPACE_ATTRS: Record<string, string> = {\n \"xlink:actuate\": \"xlinkActuate\",\n \"xlink:arcrole\": \"xlinkArcrole\",\n \"xlink:href\": \"xlinkHref\",\n \"xlink:role\": \"xlinkRole\",\n \"xlink:show\": \"xlinkShow\",\n \"xlink:title\": \"xlinkTitle\",\n \"xlink:type\": \"xlinkType\",\n \"xml:lang\": \"xmlLang\",\n \"xml:space\": \"xmlSpace\",\n \"xml:base\": \"xmlBase\",\n \"xmlns:xlink\": \"xmlnsXlink\",\n class: \"className\",\n};\n","import { TOKEN_TYPE } from \"./enums\";\nimport { Tokenizer } from \"./tokenizer\";\nimport { REACT_NAMESPACE_ATTRS } from \"./namespace\";\n\nclass SvgNode {\n public children: (SvgNode | string)[] = [];\n constructor(\n public type: string,\n public props: { [key: string]: string } = {}\n ) {}\n\n addChild(node: SvgNode | string) {\n this.children.push(node);\n }\n\n addProp(key: string, value: string) {\n this.props[key] = value;\n }\n}\n\nconst AllowedLookAhead: Record<\n TOKEN_TYPE,\n Partial<Record<TOKEN_TYPE, boolean>>\n> = {\n [TOKEN_TYPE.BEGIN_TAG]: {\n [TOKEN_TYPE.ATTRIBUTE]: true,\n [TOKEN_TYPE.END_TAG]: true,\n [TOKEN_TYPE.END_CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.ATTRIBUTE]: {\n [TOKEN_TYPE.ATTRIBUTE]: true,\n [TOKEN_TYPE.END_TAG]: true,\n [TOKEN_TYPE.END_CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.END_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n [TOKEN_TYPE.TEXT]: true,\n },\n [TOKEN_TYPE.CLOSE_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.END_CLOSE_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.TEXT]: {\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n};\n\nfunction formatAttributeName(name: string) {\n // 1. ARIA → passthrough\n if (name.startsWith(\"aria-\")) {\n return name;\n }\n\n // 2. Explicit React namespace mapping\n if (REACT_NAMESPACE_ATTRS[name]) {\n return REACT_NAMESPACE_ATTRS[name];\n }\n\n // 3. Unsupported XML namespaces → bail out\n if (\n name.startsWith(\"rdf:\") ||\n name.startsWith(\"cc:\") ||\n name.startsWith(\"dc:\") ||\n name.startsWith(\"xmlns:\")\n ) {\n return name.toLowerCase();\n }\n\n // 4. Standard HTML/SVG attribute\n return name.replace(/-([a-zA-Z])/g, (_, char) => char.toUpperCase());\n}\n\nclass Parser {\n tokenizer: Tokenizer;\n\n constructor() {\n this.tokenizer = new Tokenizer();\n }\n\n parse(str: string) {\n this.tokenizer.init(str);\n const root = new SvgNode(\"ROOT\");\n let tags: SvgNode[] = [root];\n let lookAhead = this.tokenizer.getNextToken();\n\n while (lookAhead) {\n const token = lookAhead;\n lookAhead = this.tokenizer.getNextToken();\n\n if (!token) {\n throw new SyntaxError(`Not Token found where expected`);\n }\n\n if (lookAhead && !AllowedLookAhead[token.name]?.[lookAhead.name]) {\n throw new SyntaxError(\n `Unexpected token ${lookAhead.name} after ${token.name}`\n );\n }\n\n switch (token.name) {\n case TOKEN_TYPE.BEGIN_TAG:\n const node = new SvgNode(token.value.slice(1));\n tags[tags.length - 1].addChild(node);\n tags.push(node);\n break;\n\n case TOKEN_TYPE.ATTRIBUTE:\n const [name, value] = token.value.split(\"=\");\n\n tags[tags.length - 1].addProp(\n formatAttributeName(name),\n value.slice(1, -1)\n );\n break;\n\n case TOKEN_TYPE.END_TAG:\n //Do nothing\n break;\n\n case TOKEN_TYPE.CLOSE_TAG:\n if (tags.length <= 1) {\n // ✅ NOW in the right place\n throw new SyntaxError(\"Unexpected closing tag\");\n }\n const current = tags.pop()!;\n if (current.type !== token.value.slice(2, -1)) {\n throw new SyntaxError(\n `Mismatched tag: expected </${current.type}>, got ${token.value}`\n );\n }\n break;\n\n case TOKEN_TYPE.END_CLOSE_TAG:\n if (tags.length <= 1) {\n // ✅ NOW in the right place\n throw new SyntaxError(\"Unexpected closing tag\");\n }\n tags.pop();\n break;\n\n case TOKEN_TYPE.TEXT:\n tags[tags.length - 1].addChild(token.value);\n break;\n\n default:\n throw new SyntaxError(`Unknown token type: ${token.name}`);\n }\n }\n\n if (tags.length > 1) {\n throw new SyntaxError(\n `Invalid SVG structure: Missing </${tags[tags.length - 1].type}>`\n );\n }\n\n return root.children[0] as SvgNode;\n }\n}\n\nexport { Parser, SvgNode };\n","import { Parser, SvgNode } from \"./parser\";\n\ntype ResultPromise = Promise<SvgNode | undefined>;\nconst promiseCache: Record<string, ResultPromise | null> = {};\n\nconst composeUrl = (name: string, baseUrl = \"/\") => {\n return baseUrl + name + \".svg\";\n};\n\nconst _fetch = async (url: string) => {\n try {\n const response = await fetch(url);\n return await response.text();\n } catch (error) {\n console.error(error);\n return null;\n }\n};\n\n// const fullUrl = composeUrl(name, baseUrl);\n\nconst processSvgText = async (text: string) => {\n try {\n const parser = new Parser();\n return parser.parse(text);\n } catch (error) {\n console.log(error);\n }\n};\n\n/**\n * Minify SVG string dynamically\n * - Removes whitespace, line breaks\n * - Collapses multiple spaces\n * - Shortens linearGradient and other IDs\n * @param {string} svg\n * @returns {string} minified SVG\n */\n\nfunction minifySVG(svg: string) {\n if (!svg) return \"\";\n\n // 1️⃣ Remove newlines, tabs, multiple spaces\n let min = svg\n .replace(/\\n|\\r|\\t/g, \"\")\n .replace(/\\s{2,}/g, \" \")\n .replace(/\\s*(=)\\s*\"/g, '=\"')\n .trim();\n\n // 2️⃣ Collect all IDs that look like IconifyId* or long random IDs\n const idRegex = /id=\"([^\"]{8,})\"/g;\n let match;\n const idMap: Record<string, string> = {};\n let counter = 0;\n const letters = \"abcdefghijklmnopqrstuvwxyz\";\n\n while ((match = idRegex.exec(min)) !== null) {\n const longId = match[1];\n if (!idMap[longId]) {\n idMap[longId] = letters[counter] || `id${counter}`;\n counter++;\n }\n }\n\n // 3️⃣ Replace IDs and corresponding url(#ID) references\n for (const key in idMap) {\n const [longId, shortId] = [key, idMap[key]];\n const idPattern = new RegExp(`id=\"${longId}\"`, \"g\");\n min = min.replace(idPattern, `id=\"${shortId}\"`);\n const urlPattern = new RegExp(`url\\\\(#${longId}\\\\)`, \"g\");\n min = min.replace(urlPattern, `url(#${shortId})`);\n }\n\n // 4️⃣ Collapse self-closing tags (optional)\n min = min.replace(/<(\\w+)([^>]*)><\\/\\1>/g, \"<$1$2/>\");\n\n return min;\n}\n\nexport const createSvg = async (name: string, baseUrl = \"/\") => {\n const fullUrl = composeUrl(name, baseUrl);\n\n if (promiseCache[fullUrl]) {\n return promiseCache[fullUrl];\n }\n\n promiseCache[fullUrl] = new Promise(async (resolve, reject) => {\n try {\n let text = localStorage.getItem(fullUrl);\n\n if (!text) {\n text = await _fetch(fullUrl);\n\n if (text) {\n try {\n localStorage.setItem(fullUrl, text);\n } catch (error) {\n console.warn(\"LocalStorage is full, cannot cache SVG.\");\n }\n }\n }\n\n if (text) {\n setTimeout(() => {\n const diff = text.length - minifySVG(text).length;\n console.log(\n text.length,\n text.length - diff,\n `SVG Minification saved ${diff} bytes for ${name}, percentage: ${(\n (diff / text.length) *\n 100\n ).toFixed(2)}%`\n );\n });\n\n const node = await processSvgText(text);\n resolve(node);\n }\n resolve(undefined);\n } catch (error) {\n reject(error);\n }\n });\n\n return promiseCache[fullUrl]!;\n};\n"],"mappings":"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","names":["forwardRef","memo","useEffect","useState","createElement","buildSvgReactTree","node","ref","props","keyPath","createElement","__spreadProps","__spreadValues","child","i","Token","name","value","Spec","Tokenizer","str","string","regexp","tokenType","tokenValue","reg","matched","REACT_NAMESPACE_ATTRS","SvgNode","type","props","node","key","value","AllowedLookAhead","formatAttributeName","name","REACT_NAMESPACE_ATTRS","_","char","Parser","Tokenizer","str","_a","root","tags","lookAhead","token","current","promiseCache","composeUrl","name","baseUrl","_fetch","url","__async","error","processSvgText","text","Parser","minifySVG","svg","min","idRegex","match","idMap","counter","letters","longId","key","shortId","idPattern","urlPattern","createSvg","fullUrl","resolve","reject","diff","node","jsx","LocalSvg","memo","forwardRef","_a","ref","_b","name","baseUrl","as","props","__objRest","node","setNode","useState","useEffect","__async","createSvg","buildSvgReactTree","__spreadValues"]}
|
|
1
|
+
{"version":3,"sources":["../src/LocalSvg.tsx","../src/tree.ts","../src/minification.ts","../src/tokenizer.ts","../src/namespace.ts","../src/parser.ts","../src/store.ts","../src/query.ts"],"sourcesContent":["import { forwardRef, memo, SVGAttributes, useEffect, useState } from \"react\";\nimport { SvgNode } from \"./parser\";\nimport { buildSvgReactTree } from \"./tree\";\nimport { createSvg } from \"./query\";\n\nexport type LocalSvgNames = string;\nexport type LocalSvgProps = SVGAttributes<SVGSVGElement> & {\n name: LocalSvgNames;\n baseUrl?: string;\n as?: React.ElementType;\n};\n\nexport const LocalSvg = memo(\n forwardRef<SVGSVGElement, LocalSvgProps>(\n ({ name, baseUrl = \"/\", as = \"span\", ...props }, ref) => {\n const [node, setNode] = useState<SvgNode | null>(null);\n\n useEffect(() => {\n let alive = true;\n\n createSvg(name, baseUrl)\n .then((node) => {\n if (alive && node) setNode(node);\n })\n .catch((err) => console.error(err));\n\n return () => {\n alive = false;\n };\n }, [name, baseUrl]);\n\n const Com = as;\n\n return node ? (\n buildSvgReactTree(node, ref, props)\n ) : (\n <Com\n className={props.className}\n style={{\n width: props.width,\n height: props.height,\n display: \"inline-block\",\n ...props.style,\n }}\n />\n );\n }\n )\n);\n","import { createElement, Ref } from \"react\";\nimport { SvgNode } from \"./parser\";\n\nexport function buildSvgReactTree(\n node: SvgNode | string,\n ref: Ref<SVGSVGElement> | null = null,\n props: Record<string, any> = {},\n keyPath: string = \"0\"\n): React.ReactElement | string {\n if (typeof node === \"string\") return node;\n\n return createElement(\n node.type,\n { ...node.props, ...props, ref, key: keyPath },\n ...node.children.map((child, i) =>\n buildSvgReactTree(child, null, {}, `${keyPath}-${i}`)\n )\n );\n}\n","/**\n * Minifies an SVG string for more efficient usage in the browser or inline.\n *\n * Features:\n * 1. Removes unnecessary whitespace, line breaks, tabs, and extra spaces.\n * 2. Strips XML declarations, comments, metadata, `class` attributes, and `xmlns` attributes.\n * 3. Collapses empty tags into self-closing tags.\n * 4. Shortens long IDs (8+ characters) to sequential numeric IDs and updates all corresponding `url(#ID)` references.\n *\n * @param {string} svg - The raw SVG string to minify.\n * @returns {string} The minified SVG string with optimized IDs and whitespace removed.\n *\n * @example\n * const raw = `<svg xmlns=\"http://www.w3.org/2000/svg\">\n * <defs>\n * <linearGradient id=\"longGradient12345678\"><stop offset=\"0%\" /></linearGradient>\n * </defs>\n * <rect fill=\"url(#longGradient12345678)\" width=\"100\" height=\"100\"/>\n * </svg>`;\n *\n * const minified = minifySVG(raw);\n * console.log(minified);\n */\nexport function minifySVG(svg: string) {\n if (!svg) return \"\";\n\n // 1️⃣ Remove newlines, tabs, multiple spaces\n let min = svg\n .replace(/\\n|\\r|\\t/g, \"\")\n .replace(/\\s{2,}/g, \" \")\n .replace(/\\s*(=)\\s*\"/g, '=\"')\n .replace(/class=\"[^\"]+\"/g, \"\")\n .replace(/<!--.*?-->/g, \"\") // Remove comments\n .replace(/\\sxmlns(?::[a-zA-Z0-9_-]+)?=\"[^\"]*\"/g, \"\") // Remove xmlns attribute\n .replace(/<\\?xml[^>]*>/g, \"\") // Remove XML declaration\n .replace(/<metadata>.*?<\\/metadata>/g, \"\") // Remove metadata\n .replace(/<(\\w+)([^>]*)><\\/\\1>/g, \"<$1$2/>\") // 4️⃣ Collapse self-closing tags (optional)\n .trim();\n\n // 2️⃣ Collect all IDs that look like IconifyId* or long random IDs\n const idRegex = /id=\"([^\"]{8,})\"/g;\n let match;\n let idMap: Record<string, string> = {};\n let counter = 0;\n\n while ((match = idRegex.exec(min)) !== null) {\n const longId = match[1];\n if (!idMap[longId]) {\n idMap[longId] = counter.toString();\n counter++;\n }\n }\n\n // 3️⃣ Replace IDs and corresponding url(#ID) references\n for (const key in idMap) {\n const [longId, shortId] = [key, idMap[key]];\n const idPattern = new RegExp(`id=\"${longId}\"`, \"g\");\n min = min.replace(idPattern, `id=\"${shortId}\"`);\n const urlPattern = new RegExp(`url\\\\(#${longId}\\\\)`, \"g\");\n min = min.replace(urlPattern, `url(#${shortId})`);\n }\n\n idMap = {};\n\n return min;\n}\n","import { TOKEN_TYPE } from \"./enums\";\n\nexport class Token {\n constructor(public name: TOKEN_TYPE, public value: string) {}\n}\n\nconst Spec: [RegExp, TOKEN_TYPE | null][] = [\n [/^\\s+/, null],\n [/^<\\?xml[^]*\\?>/, null],\n [/^<!--[\\s\\S]*?-->/, null],\n [\n /^<[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?(?=[\\s>/>])/,\n TOKEN_TYPE.BEGIN_TAG,\n ],\n [\n /^[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?=[\"|'][^\"']*[\"|']/,\n TOKEN_TYPE.ATTRIBUTE,\n ],\n [/^>/, TOKEN_TYPE.END_TAG],\n [/^<\\/[a-zA-Z_][\\w\\-.]*(?::[a-zA-Z_][\\w\\-.]*)?>/, TOKEN_TYPE.CLOSE_TAG],\n [/^\\/>/, TOKEN_TYPE.END_CLOSE_TAG],\n [/^.+(?=<\\/)/, TOKEN_TYPE.TEXT],\n];\n\nclass Tokenizer {\n private _cursor = 0;\n private _string = \"\";\n\n init(str: string) {\n this._string = str;\n }\n\n isEOF() {\n return this._cursor === this._string.length;\n }\n\n hasMoreTokens() {\n return this._cursor < this._string.length;\n }\n\n getNextToken(): Token | null {\n if (!this.hasMoreTokens()) {\n return null;\n }\n\n const string = this._string.slice(this._cursor);\n\n for (const [regexp, tokenType] of Spec) {\n const tokenValue = this._match(regexp, string);\n\n if (tokenValue == null) {\n continue;\n }\n\n if (tokenType == null) {\n return this.getNextToken();\n }\n\n return new Token(tokenType, tokenValue);\n }\n\n throw new SyntaxError(`Unknown token type ${string.slice(0, 10)}`);\n }\n\n _match(reg: RegExp, string: string) {\n let matched = reg.exec(string);\n\n if (matched === null) {\n return null;\n }\n\n this._cursor += matched[0].length;\n return matched[0];\n }\n}\n\nexport { Tokenizer };\n","export const REACT_NAMESPACE_ATTRS: Record<string, string> = {\n \"xlink:actuate\": \"xlinkActuate\",\n \"xlink:arcrole\": \"xlinkArcrole\",\n \"xlink:href\": \"xlinkHref\",\n \"xlink:role\": \"xlinkRole\",\n \"xlink:show\": \"xlinkShow\",\n \"xlink:title\": \"xlinkTitle\",\n \"xlink:type\": \"xlinkType\",\n \"xml:lang\": \"xmlLang\",\n \"xml:space\": \"xmlSpace\",\n \"xml:base\": \"xmlBase\",\n \"xmlns:xlink\": \"xmlnsXlink\",\n class: \"className\",\n};\n","import { TOKEN_TYPE } from \"./enums\";\nimport { Tokenizer } from \"./tokenizer\";\nimport { REACT_NAMESPACE_ATTRS } from \"./namespace\";\n\nclass SvgNode {\n public children: (SvgNode | string)[] = [];\n constructor(\n public type: string,\n public props: { [key: string]: string } = {}\n ) {}\n\n addChild(node: SvgNode | string) {\n this.children.push(node);\n }\n\n addProp(key: string, value: string) {\n this.props[key] = value;\n }\n}\n\nconst AllowedLookAhead: Record<\n TOKEN_TYPE,\n Partial<Record<TOKEN_TYPE, boolean>>\n> = {\n [TOKEN_TYPE.BEGIN_TAG]: {\n [TOKEN_TYPE.ATTRIBUTE]: true,\n [TOKEN_TYPE.END_TAG]: true,\n [TOKEN_TYPE.END_CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.ATTRIBUTE]: {\n [TOKEN_TYPE.ATTRIBUTE]: true,\n [TOKEN_TYPE.END_TAG]: true,\n [TOKEN_TYPE.END_CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.END_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n [TOKEN_TYPE.TEXT]: true,\n },\n [TOKEN_TYPE.CLOSE_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.END_CLOSE_TAG]: {\n [TOKEN_TYPE.BEGIN_TAG]: true,\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n [TOKEN_TYPE.TEXT]: {\n [TOKEN_TYPE.CLOSE_TAG]: true,\n },\n};\n\nfunction formatAttributeName(name: string) {\n // 1. ARIA → passthrough\n if (name.startsWith(\"aria-\")) {\n return name;\n }\n\n // 2. Explicit React namespace mapping\n if (REACT_NAMESPACE_ATTRS[name]) {\n return REACT_NAMESPACE_ATTRS[name];\n }\n\n // 3. Unsupported XML namespaces → bail out\n if (\n name.startsWith(\"rdf:\") ||\n name.startsWith(\"cc:\") ||\n name.startsWith(\"dc:\") ||\n name.startsWith(\"xmlns:\")\n ) {\n return name.toLowerCase();\n }\n\n // 4. Standard HTML/SVG attribute\n return name.replace(/-([a-zA-Z])/g, (_, char) => char.toUpperCase());\n}\n\nclass Parser {\n tokenizer: Tokenizer;\n\n constructor() {\n this.tokenizer = new Tokenizer();\n }\n\n parse(str: string) {\n this.tokenizer.init(str);\n const root = new SvgNode(\"ROOT\");\n let tags: SvgNode[] = [root];\n let lookAhead = this.tokenizer.getNextToken();\n\n while (lookAhead) {\n const token = lookAhead;\n lookAhead = this.tokenizer.getNextToken();\n\n if (!token) {\n throw new SyntaxError(`Not Token found where expected`);\n }\n\n if (lookAhead && !AllowedLookAhead[token.name]?.[lookAhead.name]) {\n throw new SyntaxError(\n `Unexpected token ${lookAhead.name} after ${token.name}`\n );\n }\n\n switch (token.name) {\n case TOKEN_TYPE.BEGIN_TAG:\n const node = new SvgNode(token.value.slice(1));\n tags[tags.length - 1].addChild(node);\n tags.push(node);\n break;\n\n case TOKEN_TYPE.ATTRIBUTE:\n const [name, value] = token.value.split(\"=\");\n\n tags[tags.length - 1].addProp(\n formatAttributeName(name),\n value.slice(1, -1)\n );\n break;\n\n case TOKEN_TYPE.END_TAG:\n //Do nothing\n break;\n\n case TOKEN_TYPE.CLOSE_TAG:\n if (tags.length <= 1) {\n // ✅ NOW in the right place\n throw new SyntaxError(\"Unexpected closing tag\");\n }\n const current = tags.pop()!;\n if (current.type !== token.value.slice(2, -1)) {\n throw new SyntaxError(\n `Mismatched tag: expected </${current.type}>, got ${token.value}`\n );\n }\n break;\n\n case TOKEN_TYPE.END_CLOSE_TAG:\n if (tags.length <= 1) {\n // ✅ NOW in the right place\n throw new SyntaxError(\"Unexpected closing tag\");\n }\n tags.pop();\n break;\n\n case TOKEN_TYPE.TEXT:\n tags[tags.length - 1].addChild(token.value);\n break;\n\n default:\n throw new SyntaxError(`Unknown token type: ${token.name}`);\n }\n }\n\n if (tags.length > 1) {\n throw new SyntaxError(\n `Invalid SVG structure: Missing </${tags[tags.length - 1].type}>`\n );\n }\n\n return root.children[0] as SvgNode;\n }\n}\n\nexport { Parser, SvgNode };\n","interface Store {\n getItem(key: string): Promise<string | null>;\n setItem(key: string, content:string): Promise<void>;\n}\n\nclass LocalStorageStore implements Store {\n async getItem(key: string): Promise<string | null> {\n const item = localStorage.getItem(key);\n return item ? (JSON.parse(item) as string) : null;\n }\n\n async setItem(key: string, value: string) {\n localStorage.setItem(key, value);\n }\n}\n\nclass IndexedDBStore implements Store {\n private dbName = \"LOCAL_SVG_DB\";\n private storeName = \"svgs\";\n private dbPromise: Promise<IDBDatabase>;\n private version = 1;\n\n constructor() {\n this.dbPromise = this.openDB();\n }\n\n private openDB(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const idb: IDBFactory | null =\n window.indexedDB ||\n (window as any).mozIndexedDB ||\n (window as any).webkitIndexedDB ||\n (window as any).msIndexedDB;\n if (!idb) {\n reject(new Error(\"IndexedDB is not supported in this environment.\"));\n return;\n }\n const request = indexedDB.open(this.dbName, this.version);\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(this.storeName)) {\n db.createObjectStore(this.storeName);\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n\n async getItem(key: string): Promise<string | null> {\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(this.storeName, \"readonly\");\n const store = transaction.objectStore(this.storeName);\n const request = store.get(key);\n request.onsuccess = () => {\n resolve((request.result as string) || null);\n };\n request.onerror = () => {\n reject(request.error);\n };\n });\n }\n\n async setItem(key: string, value: string): Promise<void> {\n const db = await this.dbPromise;\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(this.storeName, \"readwrite\");\n const store = transaction.objectStore(this.storeName);\n const request = store.put(value, key);\n request.onsuccess = () => resolve();\n request.onerror = () => reject(request.error);\n });\n }\n}\n\nexport const createStore = (storage?: \"localstorage\" | \"indexdb\"): Store => {\n if (typeof window === \"undefined\") {\n console.warn(\"Store can only be created in a browser environment.\");\n return null;\n }\n try {\n if (storage === \"localstorage\") {\n return new LocalStorageStore();\n }\n return new IndexedDBStore();\n } catch (error) {\n return new LocalStorageStore();\n }\n};\n\nexport class PromiseCache<T> {\n private cache: Map<string, Promise<T>>;\n\n constructor() {\n this.cache = new Map();\n }\n\n get(key: string): Promise<T> | undefined {\n return this.cache.get(key);\n }\n\n set(key: string, promise: Promise<T>): void {\n this.cache.set(key, promise);\n }\n}","import { minifySVG } from \"./minification\";\nimport { Parser, SvgNode } from \"./parser\";\nimport { createStore, PromiseCache } from \"./store\";\n\nconst store = createStore();\nconst promiseCache = new PromiseCache<SvgNode>();\n\nconst composeUrl = (name: string, baseUrl = \"/\") => {\n return baseUrl + name + \".svg\";\n};\n\nconst _fetch = async (url: string) => {\n try {\n const response = await fetch(url);\n return await response.text();\n } catch (error) {\n console.error(error);\n return null;\n }\n};\n\nconst processSvgText = async (text: string) => {\n try {\n const parser = new Parser();\n return parser.parse(text);\n } catch (error) {\n console.error(error);\n }\n};\n\nexport const createSvg = async (name: string, baseUrl = \"/\") => {\n const fullUrl = composeUrl(name, baseUrl);\n const promise = promiseCache.get(fullUrl);\n\n if (promise) {\n return promise;\n }\n\n const newPromise = new Promise<SvgNode>(async (resolve, reject) => {\n try {\n let text = await store?.getItem(fullUrl);\n\n if (!text) {\n text = await _fetch(fullUrl);\n\n if (text) {\n setTimeout(() => {\n try {\n const minified = minifySVG(text);\n store?.setItem(fullUrl, minified);\n } catch (error) {\n console.warn(\"Storage is full, cannot cache SVG.\");\n }\n });\n }\n }\n\n if (text) {\n const node = await processSvgText(text);\n resolve(node);\n }\n\n reject(`Error occured processing Svg ${fullUrl}`);\n } catch (error) {\n reject(error);\n }\n });\n\n promiseCache.set(fullUrl, newPromise);\n\n return newPromise;\n};\n"],"mappings":"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","names":["forwardRef","memo","useEffect","useState","createElement","buildSvgReactTree","node","ref","props","keyPath","createElement","__spreadProps","__spreadValues","child","i","minifySVG","svg","min","idRegex","match","idMap","counter","longId","key","shortId","idPattern","urlPattern","Token","name","value","Spec","Tokenizer","str","string","regexp","tokenType","tokenValue","reg","matched","REACT_NAMESPACE_ATTRS","SvgNode","type","props","node","key","value","AllowedLookAhead","formatAttributeName","name","REACT_NAMESPACE_ATTRS","_","char","Parser","Tokenizer","str","_a","root","tags","lookAhead","token","current","LocalStorageStore","key","__async","item","value","IndexedDBStore","resolve","reject","request","db","createStore","storage","error","PromiseCache","promise","store","createStore","promiseCache","PromiseCache","composeUrl","name","baseUrl","_fetch","url","__async","error","processSvgText","text","Parser","createSvg","fullUrl","promise","newPromise","resolve","reject","minified","minifySVG","node","jsx","LocalSvg","memo","forwardRef","_a","ref","_b","name","baseUrl","as","props","__objRest","node","setNode","useState","useEffect","alive","createSvg","err","buildSvgReactTree","__spreadValues"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "local-svg",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "LocalSvg - A lightweight React component for loading local or remote SVGs. Skip bloated icon sets and streamline your custom icon workflow.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -21,9 +21,11 @@
|
|
|
21
21
|
"dist"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
|
-
"build": "tsup"
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"publish": "npm publish --access public "
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
28
|
+
"@types/node": "^25.0.8",
|
|
27
29
|
"@types/react": "^19.2.7",
|
|
28
30
|
"@types/react-dom": "^19.2.3",
|
|
29
31
|
"tsup": "^8.5.1",
|