@shumoku/core 0.1.0

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 (220) hide show
  1. package/dist/icons/build-icons.d.ts +6 -0
  2. package/dist/icons/build-icons.d.ts.map +1 -0
  3. package/dist/icons/build-icons.js +163 -0
  4. package/dist/icons/build-icons.js.map +1 -0
  5. package/dist/icons/generated-icons.d.ts +32 -0
  6. package/dist/icons/generated-icons.d.ts.map +1 -0
  7. package/dist/icons/generated-icons.js +88 -0
  8. package/dist/icons/generated-icons.js.map +1 -0
  9. package/dist/icons/index.d.ts +2 -0
  10. package/dist/icons/index.d.ts.map +1 -0
  11. package/dist/icons/index.js +2 -0
  12. package/dist/icons/index.js.map +1 -0
  13. package/dist/index.d.ts +10 -0
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +16 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/layout/hierarchical.d.ts +73 -0
  18. package/dist/layout/hierarchical.d.ts.map +1 -0
  19. package/dist/layout/hierarchical.js +1320 -0
  20. package/dist/layout/hierarchical.js.map +1 -0
  21. package/dist/layout/index.d.ts +6 -0
  22. package/dist/layout/index.d.ts.map +1 -0
  23. package/dist/layout/index.js +5 -0
  24. package/dist/layout/index.js.map +1 -0
  25. package/dist/models/index.d.ts +5 -0
  26. package/dist/models/index.d.ts.map +1 -0
  27. package/dist/models/index.js +5 -0
  28. package/dist/models/index.js.map +1 -0
  29. package/dist/models/types.d.ts +381 -0
  30. package/dist/models/types.d.ts.map +1 -0
  31. package/dist/models/types.js +61 -0
  32. package/dist/models/types.js.map +1 -0
  33. package/dist/renderer/components/index.d.ts +8 -0
  34. package/dist/renderer/components/index.d.ts.map +1 -0
  35. package/dist/renderer/components/index.js +8 -0
  36. package/dist/renderer/components/index.js.map +1 -0
  37. package/dist/renderer/components/link-renderer.d.ts +11 -0
  38. package/dist/renderer/components/link-renderer.d.ts.map +1 -0
  39. package/dist/renderer/components/link-renderer.js +340 -0
  40. package/dist/renderer/components/link-renderer.js.map +1 -0
  41. package/dist/renderer/components/node-renderer.d.ts +14 -0
  42. package/dist/renderer/components/node-renderer.d.ts.map +1 -0
  43. package/dist/renderer/components/node-renderer.js +242 -0
  44. package/dist/renderer/components/node-renderer.js.map +1 -0
  45. package/dist/renderer/components/port-renderer.d.ts +8 -0
  46. package/dist/renderer/components/port-renderer.d.ts.map +1 -0
  47. package/dist/renderer/components/port-renderer.js +85 -0
  48. package/dist/renderer/components/port-renderer.js.map +1 -0
  49. package/dist/renderer/components/subgraph-renderer.d.ts +13 -0
  50. package/dist/renderer/components/subgraph-renderer.d.ts.map +1 -0
  51. package/dist/renderer/components/subgraph-renderer.js +85 -0
  52. package/dist/renderer/components/subgraph-renderer.js.map +1 -0
  53. package/dist/renderer/icon-registry/index.d.ts +6 -0
  54. package/dist/renderer/icon-registry/index.d.ts.map +1 -0
  55. package/dist/renderer/icon-registry/index.js +5 -0
  56. package/dist/renderer/icon-registry/index.js.map +1 -0
  57. package/dist/renderer/icon-registry/registry.d.ts +25 -0
  58. package/dist/renderer/icon-registry/registry.d.ts.map +1 -0
  59. package/dist/renderer/icon-registry/registry.js +85 -0
  60. package/dist/renderer/icon-registry/registry.js.map +1 -0
  61. package/dist/renderer/icon-registry/types.d.ts +44 -0
  62. package/dist/renderer/icon-registry/types.d.ts.map +1 -0
  63. package/dist/renderer/icon-registry/types.js +5 -0
  64. package/dist/renderer/icon-registry/types.js.map +1 -0
  65. package/dist/renderer/index.d.ts +6 -0
  66. package/dist/renderer/index.d.ts.map +1 -0
  67. package/dist/renderer/index.js +5 -0
  68. package/dist/renderer/index.js.map +1 -0
  69. package/dist/renderer/render-model/builder.d.ts +43 -0
  70. package/dist/renderer/render-model/builder.d.ts.map +1 -0
  71. package/dist/renderer/render-model/builder.js +646 -0
  72. package/dist/renderer/render-model/builder.js.map +1 -0
  73. package/dist/renderer/render-model/index.d.ts +6 -0
  74. package/dist/renderer/render-model/index.d.ts.map +1 -0
  75. package/dist/renderer/render-model/index.js +5 -0
  76. package/dist/renderer/render-model/index.js.map +1 -0
  77. package/dist/renderer/render-model/types.d.ts +216 -0
  78. package/dist/renderer/render-model/types.d.ts.map +1 -0
  79. package/dist/renderer/render-model/types.js +6 -0
  80. package/dist/renderer/render-model/types.js.map +1 -0
  81. package/dist/renderer/renderer-types.d.ts +55 -0
  82. package/dist/renderer/renderer-types.d.ts.map +1 -0
  83. package/dist/renderer/renderer-types.js +5 -0
  84. package/dist/renderer/renderer-types.js.map +1 -0
  85. package/dist/renderer/svg-builder.d.ts +152 -0
  86. package/dist/renderer/svg-builder.d.ts.map +1 -0
  87. package/dist/renderer/svg-builder.js +176 -0
  88. package/dist/renderer/svg-builder.js.map +1 -0
  89. package/dist/renderer/svg-dom/builders/defs.d.ts +10 -0
  90. package/dist/renderer/svg-dom/builders/defs.d.ts.map +1 -0
  91. package/dist/renderer/svg-dom/builders/defs.js +82 -0
  92. package/dist/renderer/svg-dom/builders/defs.js.map +1 -0
  93. package/dist/renderer/svg-dom/builders/index.d.ts +9 -0
  94. package/dist/renderer/svg-dom/builders/index.d.ts.map +1 -0
  95. package/dist/renderer/svg-dom/builders/index.js +9 -0
  96. package/dist/renderer/svg-dom/builders/index.js.map +1 -0
  97. package/dist/renderer/svg-dom/builders/link.d.ts +18 -0
  98. package/dist/renderer/svg-dom/builders/link.d.ts.map +1 -0
  99. package/dist/renderer/svg-dom/builders/link.js +188 -0
  100. package/dist/renderer/svg-dom/builders/link.js.map +1 -0
  101. package/dist/renderer/svg-dom/builders/node.d.ts +15 -0
  102. package/dist/renderer/svg-dom/builders/node.d.ts.map +1 -0
  103. package/dist/renderer/svg-dom/builders/node.js +262 -0
  104. package/dist/renderer/svg-dom/builders/node.js.map +1 -0
  105. package/dist/renderer/svg-dom/builders/subgraph.d.ts +14 -0
  106. package/dist/renderer/svg-dom/builders/subgraph.d.ts.map +1 -0
  107. package/dist/renderer/svg-dom/builders/subgraph.js +63 -0
  108. package/dist/renderer/svg-dom/builders/subgraph.js.map +1 -0
  109. package/dist/renderer/svg-dom/builders/utils.d.ts +40 -0
  110. package/dist/renderer/svg-dom/builders/utils.d.ts.map +1 -0
  111. package/dist/renderer/svg-dom/builders/utils.js +79 -0
  112. package/dist/renderer/svg-dom/builders/utils.js.map +1 -0
  113. package/dist/renderer/svg-dom/index.d.ts +9 -0
  114. package/dist/renderer/svg-dom/index.d.ts.map +1 -0
  115. package/dist/renderer/svg-dom/index.js +7 -0
  116. package/dist/renderer/svg-dom/index.js.map +1 -0
  117. package/dist/renderer/svg-dom/interaction.d.ts +69 -0
  118. package/dist/renderer/svg-dom/interaction.d.ts.map +1 -0
  119. package/dist/renderer/svg-dom/interaction.js +296 -0
  120. package/dist/renderer/svg-dom/interaction.js.map +1 -0
  121. package/dist/renderer/svg-dom/renderer.d.ts +47 -0
  122. package/dist/renderer/svg-dom/renderer.d.ts.map +1 -0
  123. package/dist/renderer/svg-dom/renderer.js +188 -0
  124. package/dist/renderer/svg-dom/renderer.js.map +1 -0
  125. package/dist/renderer/svg-string/builders/defs.d.ts +10 -0
  126. package/dist/renderer/svg-string/builders/defs.d.ts.map +1 -0
  127. package/dist/renderer/svg-string/builders/defs.js +43 -0
  128. package/dist/renderer/svg-string/builders/defs.js.map +1 -0
  129. package/dist/renderer/svg-string/builders/link.d.ts +10 -0
  130. package/dist/renderer/svg-string/builders/link.d.ts.map +1 -0
  131. package/dist/renderer/svg-string/builders/link.js +149 -0
  132. package/dist/renderer/svg-string/builders/link.js.map +1 -0
  133. package/dist/renderer/svg-string/builders/node.d.ts +10 -0
  134. package/dist/renderer/svg-string/builders/node.d.ts.map +1 -0
  135. package/dist/renderer/svg-string/builders/node.js +134 -0
  136. package/dist/renderer/svg-string/builders/node.js.map +1 -0
  137. package/dist/renderer/svg-string/builders/subgraph.d.ts +10 -0
  138. package/dist/renderer/svg-string/builders/subgraph.d.ts.map +1 -0
  139. package/dist/renderer/svg-string/builders/subgraph.js +59 -0
  140. package/dist/renderer/svg-string/builders/subgraph.js.map +1 -0
  141. package/dist/renderer/svg-string/index.d.ts +5 -0
  142. package/dist/renderer/svg-string/index.d.ts.map +1 -0
  143. package/dist/renderer/svg-string/index.js +5 -0
  144. package/dist/renderer/svg-string/index.js.map +1 -0
  145. package/dist/renderer/svg-string/renderer.d.ts +17 -0
  146. package/dist/renderer/svg-string/renderer.d.ts.map +1 -0
  147. package/dist/renderer/svg-string/renderer.js +53 -0
  148. package/dist/renderer/svg-string/renderer.js.map +1 -0
  149. package/dist/renderer/svg.d.ts +105 -0
  150. package/dist/renderer/svg.d.ts.map +1 -0
  151. package/dist/renderer/svg.js +804 -0
  152. package/dist/renderer/svg.js.map +1 -0
  153. package/dist/renderer/text-measurer/browser-measurer.d.ts +25 -0
  154. package/dist/renderer/text-measurer/browser-measurer.d.ts.map +1 -0
  155. package/dist/renderer/text-measurer/browser-measurer.js +85 -0
  156. package/dist/renderer/text-measurer/browser-measurer.js.map +1 -0
  157. package/dist/renderer/text-measurer/fallback-measurer.d.ts +22 -0
  158. package/dist/renderer/text-measurer/fallback-measurer.d.ts.map +1 -0
  159. package/dist/renderer/text-measurer/fallback-measurer.js +113 -0
  160. package/dist/renderer/text-measurer/fallback-measurer.js.map +1 -0
  161. package/dist/renderer/text-measurer/index.d.ts +13 -0
  162. package/dist/renderer/text-measurer/index.d.ts.map +1 -0
  163. package/dist/renderer/text-measurer/index.js +35 -0
  164. package/dist/renderer/text-measurer/index.js.map +1 -0
  165. package/dist/renderer/text-measurer/types.d.ts +30 -0
  166. package/dist/renderer/text-measurer/types.d.ts.map +1 -0
  167. package/dist/renderer/text-measurer/types.js +5 -0
  168. package/dist/renderer/text-measurer/types.js.map +1 -0
  169. package/dist/renderer/theme.d.ts +29 -0
  170. package/dist/renderer/theme.d.ts.map +1 -0
  171. package/dist/renderer/theme.js +80 -0
  172. package/dist/renderer/theme.js.map +1 -0
  173. package/dist/themes/dark.d.ts +6 -0
  174. package/dist/themes/dark.d.ts.map +1 -0
  175. package/dist/themes/dark.js +96 -0
  176. package/dist/themes/dark.js.map +1 -0
  177. package/dist/themes/index.d.ts +13 -0
  178. package/dist/themes/index.d.ts.map +1 -0
  179. package/dist/themes/index.js +15 -0
  180. package/dist/themes/index.js.map +1 -0
  181. package/dist/themes/modern.d.ts +6 -0
  182. package/dist/themes/modern.d.ts.map +1 -0
  183. package/dist/themes/modern.js +164 -0
  184. package/dist/themes/modern.js.map +1 -0
  185. package/dist/themes/types.d.ts +234 -0
  186. package/dist/themes/types.d.ts.map +1 -0
  187. package/dist/themes/types.js +5 -0
  188. package/dist/themes/types.js.map +1 -0
  189. package/dist/themes/utils.d.ts +21 -0
  190. package/dist/themes/utils.d.ts.map +1 -0
  191. package/dist/themes/utils.js +124 -0
  192. package/dist/themes/utils.js.map +1 -0
  193. package/package.json +92 -0
  194. package/src/icons/build-icons.ts +189 -0
  195. package/src/icons/default/access-point.svg +3 -0
  196. package/src/icons/default/cloud.svg +3 -0
  197. package/src/icons/default/database.svg +3 -0
  198. package/src/icons/default/firewall.svg +4 -0
  199. package/src/icons/default/generic.svg +3 -0
  200. package/src/icons/default/internet.svg +3 -0
  201. package/src/icons/default/l2-switch.svg +3 -0
  202. package/src/icons/default/l3-switch.svg +3 -0
  203. package/src/icons/default/load-balancer.svg +3 -0
  204. package/src/icons/default/router.svg +3 -0
  205. package/src/icons/default/server.svg +3 -0
  206. package/src/icons/default/vpn.svg +3 -0
  207. package/src/icons/generated-icons.ts +111 -0
  208. package/src/icons/index.ts +1 -0
  209. package/src/index.ts +21 -0
  210. package/src/layout/hierarchical.ts +1543 -0
  211. package/src/layout/index.ts +6 -0
  212. package/src/models/index.ts +5 -0
  213. package/src/models/types.ts +528 -0
  214. package/src/renderer/index.ts +6 -0
  215. package/src/renderer/svg.ts +997 -0
  216. package/src/themes/dark.ts +110 -0
  217. package/src/themes/index.ts +24 -0
  218. package/src/themes/modern.ts +186 -0
  219. package/src/themes/types.ts +262 -0
  220. package/src/themes/utils.ts +143 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Theme utilities
3
+ */
4
+ /**
5
+ * Merge theme with overrides
6
+ */
7
+ export function mergeTheme(base, overrides) {
8
+ if (!overrides)
9
+ return base;
10
+ return deepMerge(base, overrides);
11
+ }
12
+ /**
13
+ * Create custom theme
14
+ */
15
+ export function createTheme(options) {
16
+ const base = options.extends || getDefaultTheme();
17
+ return mergeTheme(base, options.overrides);
18
+ }
19
+ /**
20
+ * Apply theme to CSS variables
21
+ */
22
+ export function applyThemeToCSS(theme, root = document.documentElement) {
23
+ const prefix = '--shumoku';
24
+ // Colors
25
+ root.style.setProperty(`${prefix}-bg`, theme.colors.background);
26
+ root.style.setProperty(`${prefix}-surface`, theme.colors.surface);
27
+ root.style.setProperty(`${prefix}-text`, theme.colors.text);
28
+ root.style.setProperty(`${prefix}-text-secondary`, theme.colors.textSecondary);
29
+ root.style.setProperty(`${prefix}-primary`, theme.colors.primary);
30
+ root.style.setProperty(`${prefix}-secondary`, theme.colors.secondary);
31
+ root.style.setProperty(`${prefix}-success`, theme.colors.success);
32
+ root.style.setProperty(`${prefix}-warning`, theme.colors.warning);
33
+ root.style.setProperty(`${prefix}-error`, theme.colors.error);
34
+ root.style.setProperty(`${prefix}-info`, theme.colors.info);
35
+ // Dimensions
36
+ root.style.setProperty(`${prefix}-radius-sm`, `${theme.dimensions.radius.small}px`);
37
+ root.style.setProperty(`${prefix}-radius-md`, `${theme.dimensions.radius.medium}px`);
38
+ root.style.setProperty(`${prefix}-radius-lg`, `${theme.dimensions.radius.large}px`);
39
+ // Spacing
40
+ root.style.setProperty(`${prefix}-space-xs`, `${theme.dimensions.spacing.xs}px`);
41
+ root.style.setProperty(`${prefix}-space-sm`, `${theme.dimensions.spacing.sm}px`);
42
+ root.style.setProperty(`${prefix}-space-md`, `${theme.dimensions.spacing.md}px`);
43
+ root.style.setProperty(`${prefix}-space-lg`, `${theme.dimensions.spacing.lg}px`);
44
+ root.style.setProperty(`${prefix}-space-xl`, `${theme.dimensions.spacing.xl}px`);
45
+ // Typography
46
+ root.style.setProperty(`${prefix}-font-sans`, theme.typography.fontFamily.sans);
47
+ root.style.setProperty(`${prefix}-font-mono`, theme.typography.fontFamily.mono);
48
+ // Shadows
49
+ const shadowToCSS = (shadow) => {
50
+ const alpha = shadow.alpha || 1;
51
+ const color = hexToRgba(shadow.color, alpha);
52
+ return `${shadow.offsetX}px ${shadow.offsetY}px ${shadow.blur}px ${color}`;
53
+ };
54
+ root.style.setProperty(`${prefix}-shadow-sm`, shadowToCSS(theme.shadows.small));
55
+ root.style.setProperty(`${prefix}-shadow-md`, shadowToCSS(theme.shadows.medium));
56
+ root.style.setProperty(`${prefix}-shadow-lg`, shadowToCSS(theme.shadows.large));
57
+ // Set theme variant
58
+ root.setAttribute('data-theme', theme.variant);
59
+ }
60
+ /**
61
+ * Get theme from CSS variables
62
+ */
63
+ export function getThemeFromCSS(root = document.documentElement) {
64
+ const prefix = '--shumoku';
65
+ const style = getComputedStyle(root);
66
+ const getVar = (name) => style.getPropertyValue(`${prefix}-${name}`).trim();
67
+ return {
68
+ variant: root.getAttribute('data-theme') || 'light',
69
+ colors: {
70
+ background: getVar('bg'),
71
+ surface: getVar('surface'),
72
+ text: getVar('text'),
73
+ textSecondary: getVar('text-secondary'),
74
+ primary: getVar('primary'),
75
+ secondary: getVar('secondary'),
76
+ success: getVar('success'),
77
+ warning: getVar('warning'),
78
+ error: getVar('error'),
79
+ info: getVar('info'),
80
+ },
81
+ };
82
+ }
83
+ /**
84
+ * Convert hex color to rgba
85
+ */
86
+ function hexToRgba(hex, alpha = 1) {
87
+ if (hex === 'transparent')
88
+ return 'transparent';
89
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
90
+ if (!result)
91
+ return hex;
92
+ const r = parseInt(result[1], 16);
93
+ const g = parseInt(result[2], 16);
94
+ const b = parseInt(result[3], 16);
95
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
96
+ }
97
+ /**
98
+ * Deep merge utility
99
+ */
100
+ function deepMerge(target, source) {
101
+ if (!source)
102
+ return target;
103
+ const result = { ...target };
104
+ for (const key in source) {
105
+ if (source.hasOwnProperty(key)) {
106
+ if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
107
+ result[key] = deepMerge(target[key] || {}, source[key]);
108
+ }
109
+ else {
110
+ result[key] = source[key];
111
+ }
112
+ }
113
+ }
114
+ return result;
115
+ }
116
+ /**
117
+ * Get default theme
118
+ */
119
+ function getDefaultTheme() {
120
+ // Lazy import to avoid circular dependency
121
+ const { modernTheme } = require('./modern');
122
+ return modernTheme;
123
+ }
124
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/themes/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAW,EAAE,SAA8B;IACpE,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAA;IAE3B,OAAO,SAAS,CAAC,IAAI,EAAE,SAAS,CAAU,CAAA;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAqB;IAC/C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,IAAI,eAAe,EAAE,CAAA;IACjD,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAY,EAAE,OAAoB,QAAQ,CAAC,eAAe;IACxF,MAAM,MAAM,GAAG,WAAW,CAAA;IAE1B,SAAS;IACT,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAC/D,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3D,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,iBAAiB,EAAE,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;IAC9E,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IACrE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC7D,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAE3D,aAAa;IACb,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,YAAY,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAA;IACnF,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,YAAY,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAA;IACpF,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,YAAY,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAA;IAEnF,UAAU;IACV,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,WAAW,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAA;IAChF,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,WAAW,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAA;IAChF,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,WAAW,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAA;IAChF,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,WAAW,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAA;IAChF,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,WAAW,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAA;IAEhF,aAAa;IACb,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;IAC/E,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;IAE/E,UAAU;IACV,MAAM,WAAW,GAAG,CAAC,MAAgD,EAAE,EAAE;QACvE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC,CAAA;QAC/B,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;QAC5C,OAAO,GAAG,MAAM,CAAC,OAAO,MAAM,MAAM,CAAC,OAAO,MAAM,MAAM,CAAC,IAAI,MAAM,KAAK,EAAE,CAAA;IAC5E,CAAC,CAAA;IAED,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IAC/E,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAChF,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,MAAM,YAAY,EAAE,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IAE/E,oBAAoB;IACpB,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,OAAoB,QAAQ,CAAC,eAAe;IAC1E,MAAM,MAAM,GAAG,WAAW,CAAA;IAC1B,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAEpC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IAEnF,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY,CAAqB,IAAI,OAAO;QACvE,MAAM,EAAE;YACN,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC;YACxB,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC;YAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC;YACpB,aAAa,EAAE,MAAM,CAAC,gBAAgB,CAAC;YACvC,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC;YAC1B,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC;YAC9B,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC;YAC1B,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC;YAC1B,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC;SACF;KACrB,CAAA;AACH,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,GAAW,EAAE,QAAgB,CAAC;IAC/C,IAAI,GAAG,KAAK,aAAa;QAAE,OAAO,aAAa,CAAA;IAE/C,MAAM,MAAM,GAAG,2CAA2C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACpE,IAAI,CAAC,MAAM;QAAE,OAAO,GAAG,CAAA;IAEvB,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACjC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACjC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEjC,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,GAAG,CAAA;AAC3C,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,MAAW,EAAE,MAAW;IACzC,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,CAAA;IAE1B,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,CAAA;IAE5B,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAClF,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;YACzD,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;GAEG;AACH,SAAS,eAAe;IACtB,2CAA2C;IAC3C,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IAC3C,OAAO,WAAW,CAAA;AACpB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@shumoku/core",
3
+ "version": "0.1.0",
4
+ "description": "Core library for shumoku network topology visualization",
5
+ "license": "MIT",
6
+ "author": "konoe-akitoshi",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/konoe-akitoshi/shumoku.git",
10
+ "directory": "packages/@shumoku/core"
11
+ },
12
+ "homepage": "https://shumoku.packof.me/",
13
+ "bugs": {
14
+ "url": "https://github.com/konoe-akitoshi/shumoku/issues"
15
+ },
16
+ "keywords": [
17
+ "network",
18
+ "topology",
19
+ "diagram",
20
+ "visualization",
21
+ "svg"
22
+ ],
23
+ "type": "module",
24
+ "main": "./dist/index.js",
25
+ "module": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ },
32
+ "./models": {
33
+ "types": "./dist/models/index.d.ts",
34
+ "import": "./dist/models/index.js"
35
+ },
36
+ "./parser": {
37
+ "types": "./dist/parser/index.d.ts",
38
+ "import": "./dist/parser/index.js"
39
+ },
40
+ "./layout": {
41
+ "types": "./dist/layout/index.d.ts",
42
+ "import": "./dist/layout/index.js"
43
+ },
44
+ "./renderer": {
45
+ "types": "./dist/renderer/index.d.ts",
46
+ "import": "./dist/renderer/index.js"
47
+ },
48
+ "./themes": {
49
+ "types": "./dist/themes/index.d.ts",
50
+ "import": "./dist/themes/index.js"
51
+ },
52
+ "./icons": {
53
+ "types": "./dist/icons/index.d.ts",
54
+ "import": "./dist/icons/index.js"
55
+ }
56
+ },
57
+ "files": [
58
+ "dist",
59
+ "src"
60
+ ],
61
+ "scripts": {
62
+ "build": "tsc",
63
+ "dev": "tsc --watch",
64
+ "test": "vitest",
65
+ "typecheck": "tsc --noEmit",
66
+ "lint": "biome check ."
67
+ },
68
+ "dependencies": {
69
+ "elkjs": "^0.11.0",
70
+ "pixi.js": "^8.5.2"
71
+ },
72
+ "devDependencies": {
73
+ "@types/node": "^20.11.0",
74
+ "typescript": "^5.6.3",
75
+ "vitest": "^2.1.5"
76
+ },
77
+ "peerDependencies": {
78
+ "@pixi/react": "^8.0.0",
79
+ "react": "^18.0.0 || ^19.0.0"
80
+ },
81
+ "peerDependenciesMeta": {
82
+ "@pixi/react": {
83
+ "optional": true
84
+ },
85
+ "react": {
86
+ "optional": true
87
+ }
88
+ },
89
+ "publishConfig": {
90
+ "access": "public"
91
+ }
92
+ }
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Build script to convert default SVG icons to TypeScript
3
+ * Run with: bun src/icons/build-icons.ts
4
+ */
5
+
6
+ import * as fs from 'fs'
7
+ import * as path from 'path'
8
+ import { fileURLToPath } from 'url'
9
+
10
+ const __filename = fileURLToPath(import.meta.url)
11
+ const __dirname = path.dirname(__filename)
12
+
13
+ const ICONS_DIR = path.join(__dirname)
14
+ const OUTPUT_FILE = path.join(__dirname, 'generated-icons.ts')
15
+
16
+ function extractSvgContent(svgContent: string): string {
17
+ const contentMatch = svgContent.match(/<svg[^>]*>([\s\S]*?)<\/svg>/i)
18
+ if (!contentMatch) return ''
19
+ return contentMatch[1].trim().replace(/\s+/g, ' ')
20
+ }
21
+
22
+ function scanDefaultIconFolder(folderPath: string): Record<string, string> {
23
+ const icons: Record<string, string> = {}
24
+
25
+ if (!fs.existsSync(folderPath)) {
26
+ return icons
27
+ }
28
+
29
+ const files = fs.readdirSync(folderPath)
30
+
31
+ for (const file of files) {
32
+ if (!file.endsWith('.svg')) continue
33
+
34
+ const filePath = path.join(folderPath, file)
35
+ const content = fs.readFileSync(filePath, 'utf-8')
36
+ const iconName = file.replace('.svg', '')
37
+ const svgContent = extractSvgContent(content)
38
+
39
+ if (svgContent) {
40
+ icons[iconName] = svgContent
41
+ }
42
+ }
43
+
44
+ return icons
45
+ }
46
+
47
+ function generateTypeScript(icons: Record<string, string>): string {
48
+ const lines: string[] = [
49
+ '/**',
50
+ ' * Auto-generated default icon definitions',
51
+ ' * DO NOT EDIT - Run build-icons.ts to regenerate',
52
+ ' */',
53
+ '',
54
+ "import { DeviceType } from '../models/index.js'",
55
+ '',
56
+ "export type IconThemeVariant = 'light' | 'dark' | 'default'",
57
+ '',
58
+ 'export interface IconEntry {',
59
+ ' default: string',
60
+ ' light?: string',
61
+ ' dark?: string',
62
+ ' viewBox?: string',
63
+ '}',
64
+ '',
65
+ '// Default network device icons',
66
+ 'const defaultIcons: Record<string, string> = {',
67
+ ]
68
+
69
+ for (const [name, content] of Object.entries(icons)) {
70
+ lines.push(` '${name}': \`${content}\`,`)
71
+ }
72
+
73
+ lines.push('}')
74
+ lines.push('')
75
+
76
+ // DeviceType mapping
77
+ lines.push('// Map DeviceType to icon key')
78
+ lines.push('const deviceTypeToIcon: Record<DeviceType, string> = {')
79
+ lines.push(" [DeviceType.Router]: 'router',")
80
+ lines.push(" [DeviceType.L3Switch]: 'l3-switch',")
81
+ lines.push(" [DeviceType.L2Switch]: 'l2-switch',")
82
+ lines.push(" [DeviceType.Firewall]: 'firewall',")
83
+ lines.push(" [DeviceType.LoadBalancer]: 'load-balancer',")
84
+ lines.push(" [DeviceType.Server]: 'server',")
85
+ lines.push(" [DeviceType.AccessPoint]: 'access-point',")
86
+ lines.push(" [DeviceType.Cloud]: 'cloud',")
87
+ lines.push(" [DeviceType.Internet]: 'internet',")
88
+ lines.push(" [DeviceType.VPN]: 'vpn',")
89
+ lines.push(" [DeviceType.Database]: 'database',")
90
+ lines.push(" [DeviceType.Generic]: 'generic',")
91
+ lines.push('}')
92
+ lines.push('')
93
+
94
+ // Getter function
95
+ lines.push('/**')
96
+ lines.push(' * Get SVG icon content for a device type')
97
+ lines.push(' */')
98
+ lines.push('export function getDeviceIcon(type?: DeviceType): string | undefined {')
99
+ lines.push(' if (!type) return undefined')
100
+ lines.push(' const iconKey = deviceTypeToIcon[type]')
101
+ lines.push(' if (!iconKey) return undefined')
102
+ lines.push(' return defaultIcons[iconKey]')
103
+ lines.push('}')
104
+ lines.push('')
105
+
106
+ // Vendor icon stubs (for compatibility, actual implementation in @shumoku/icons)
107
+ lines.push('// Vendor icon registry (populated by @shumoku/icons if installed)')
108
+ lines.push('let vendorIconRegistry: Record<string, Record<string, IconEntry>> = {}')
109
+ lines.push('')
110
+
111
+ lines.push('/**')
112
+ lines.push(' * Register vendor icons (called by @shumoku/icons)')
113
+ lines.push(' */')
114
+ lines.push('export function registerVendorIcons(vendor: string, icons: Record<string, IconEntry>): void {')
115
+ lines.push(' vendorIconRegistry[vendor] = icons')
116
+ lines.push('}')
117
+ lines.push('')
118
+
119
+ lines.push('/**')
120
+ lines.push(' * Get vendor icon entry')
121
+ lines.push(' */')
122
+ lines.push('export function getVendorIconEntry(')
123
+ lines.push(' vendor: string,')
124
+ lines.push(' service: string,')
125
+ lines.push(' resource?: string')
126
+ lines.push('): IconEntry | undefined {')
127
+ lines.push(" if (vendor === 'default' || !vendor) {")
128
+ lines.push(' const content = defaultIcons[service] || (resource ? defaultIcons[resource] : undefined)')
129
+ lines.push(' return content ? { default: content } : undefined')
130
+ lines.push(' }')
131
+ lines.push('')
132
+ lines.push(' const vendorIcons = vendorIconRegistry[vendor]')
133
+ lines.push(' if (!vendorIcons) return undefined')
134
+ lines.push('')
135
+ lines.push(' const key = resource ? `${service}/${resource}` : service')
136
+ lines.push(' const entry = vendorIcons[key]')
137
+ lines.push(' if (!entry) {')
138
+ lines.push(" const serviceKey = Object.keys(vendorIcons).find(k => k.startsWith(service + '/'))")
139
+ lines.push(' if (serviceKey) return vendorIcons[serviceKey]')
140
+ lines.push(' return undefined')
141
+ lines.push(' }')
142
+ lines.push(' return entry')
143
+ lines.push('}')
144
+ lines.push('')
145
+
146
+ lines.push('/**')
147
+ lines.push(' * Get vendor icon with theme support')
148
+ lines.push(' */')
149
+ lines.push('export function getVendorIcon(')
150
+ lines.push(' vendor: string,')
151
+ lines.push(' service: string,')
152
+ lines.push(' resource?: string,')
153
+ lines.push(" theme: IconThemeVariant = 'default'")
154
+ lines.push('): string | undefined {')
155
+ lines.push(' const entry = getVendorIconEntry(vendor, service, resource)')
156
+ lines.push(' if (!entry) return undefined')
157
+ lines.push(' return entry[theme] || entry.default')
158
+ lines.push('}')
159
+ lines.push('')
160
+
161
+ // Export
162
+ lines.push('export const iconSets = {')
163
+ lines.push(' default: defaultIcons,')
164
+ lines.push('}')
165
+ lines.push('')
166
+
167
+ return lines.join('\n')
168
+ }
169
+
170
+ function main() {
171
+ console.log('Building default icons...')
172
+
173
+ const defaultFolder = path.join(ICONS_DIR, 'default')
174
+ const icons = scanDefaultIconFolder(defaultFolder)
175
+
176
+ if (Object.keys(icons).length === 0) {
177
+ console.log('No default icons found!')
178
+ return
179
+ }
180
+
181
+ console.log(` Found ${Object.keys(icons).length} default icons`)
182
+
183
+ const output = generateTypeScript(icons)
184
+ fs.writeFileSync(OUTPUT_FILE, output, 'utf-8')
185
+
186
+ console.log(`Generated ${OUTPUT_FILE}`)
187
+ }
188
+
189
+ main()
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M12 10a2 2 0 100 4 2 2 0 000-4zm-4.5-2.5a6.5 6.5 0 019 0l-1.4 1.4a4.5 4.5 0 00-6.2 0l-1.4-1.4zm-2.8-2.8a10 10 0 0114.6 0l-1.4 1.4a8 8 0 00-11.8 0L4.7 4.7z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M19.4 10.6A7 7 0 006 12a5 5 0 00.7 9.9h11.8a4.5 4.5 0 00.9-8.9z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M12 4c-4.4 0-8 1.3-8 3v10c0 1.7 3.6 3 8 3s8-1.3 8-3V7c0-1.7-3.6-3-8-3zm0 2c3.3 0 6 .9 6 2s-2.7 2-6 2-6-.9-6-2 2.7-2 6-2zM6 10.5c1.4.7 3.5 1 6 1s4.6-.3 6-1V12c0 1.1-2.7 2-6 2s-6-.9-6-2v-1.5zm0 4c1.4.7 3.5 1 6 1s4.6-.3 6-1V16c0 1.1-2.7 2-6 2s-6-.9-6-2v-1.5z"/>
3
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M12 2L4 6v6c0 5.5 3.4 10.3 8 12 4.6-1.7 8-6.5 8-12V6l-8-4zm0 2.2l6 3v5.3c0 4.3-2.6 8.1-6 9.5-3.4-1.4-6-5.2-6-9.5V7.2l6-3z"/>
3
+ <path d="M11 8h2v5h-2V8zm0 6h2v2h-2v-2z"/>
4
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M4 4h16v16H4V4zm2 2v12h12V6H6zm2 2h8v2H8V8zm0 4h8v2H8v-2z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M12 2a10 10 0 100 20 10 10 0 000-20zm0 2c.6 0 1.3.8 1.8 2H10.2c.5-1.2 1.2-2 1.8-2zm-3.2.7A8 8 0 005 10h2.5c.1-2 .5-3.7 1.3-5.3zm6.4 0c.8 1.6 1.2 3.3 1.3 5.3H19a8 8 0 00-3.8-5.3zM5 12h2.5c.1 2 .5 3.7 1.3 5.3A8 8 0 015 12zm4.5 0h5c0 1.5-.3 3-1 4h-3c-.7-1-1-2.5-1-4zm7 0H19a8 8 0 01-3.8 5.3c.8-1.6 1.2-3.3 1.3-5.3zM10.2 18h3.6c-.5 1.2-1.2 2-1.8 2s-1.3-.8-1.8-2z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M3 8h18v8H3V8zm2 2v4h14v-4H5zm2 1h2v2H7v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M3 6h18v12H3V6zm2 2v8h14V8H5zm2 2h4v1H7v-1zm6 0h4v1h-4v-1zm-6 3h4v1H7v-1zm6 0h4v1h-4v-1z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M12 4L4 8l8 4 8-4-8-4zm0 2.5L16 8l-4 2-4-2 4-1.5zM4 12l8 4 8-4v2l-8 4-8-4v-2zm0 4l8 4 8-4v2l-8 4-8-4v-2z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M4 8h16v8H4V8zm2 2v4h12v-4H6zm1 1h2v2H7v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M4 4h16v4H4V4zm0 6h16v4H4v-4zm0 6h16v4H4v-4zm2-10v2h2V6H6zm0 6v2h2v-2H6zm0 6v2h2v-2H6zm10-12v2h2V6h-2zm0 6v2h2v-2h-2zm0 6v2h2v-2h-2z"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
2
+ <path d="M12 2L4 5v6.5c0 5.3 3.4 10 8 11.5 4.6-1.5 8-6.2 8-11.5V5l-8-3zm0 4a3 3 0 110 6 3 3 0 010-6zm-4 8h8v1c0 2-1.8 3-4 3s-4-1-4-3v-1z"/>
3
+ </svg>
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Auto-generated default icon definitions
3
+ * DO NOT EDIT - Run build-icons.ts to regenerate
4
+ */
5
+
6
+ import { DeviceType } from '../models/index.js'
7
+
8
+ export type IconThemeVariant = 'light' | 'dark' | 'default'
9
+
10
+ export interface IconEntry {
11
+ default: string
12
+ light?: string
13
+ dark?: string
14
+ viewBox?: string
15
+ }
16
+
17
+ // Default network device icons
18
+ const defaultIcons: Record<string, string> = {
19
+ 'access-point': `<path d="M12 10a2 2 0 100 4 2 2 0 000-4zm-4.5-2.5a6.5 6.5 0 019 0l-1.4 1.4a4.5 4.5 0 00-6.2 0l-1.4-1.4zm-2.8-2.8a10 10 0 0114.6 0l-1.4 1.4a8 8 0 00-11.8 0L4.7 4.7z"/>`,
20
+ 'cloud': `<path d="M19.4 10.6A7 7 0 006 12a5 5 0 00.7 9.9h11.8a4.5 4.5 0 00.9-8.9z"/>`,
21
+ 'database': `<path d="M12 4c-4.4 0-8 1.3-8 3v10c0 1.7 3.6 3 8 3s8-1.3 8-3V7c0-1.7-3.6-3-8-3zm0 2c3.3 0 6 .9 6 2s-2.7 2-6 2-6-.9-6-2 2.7-2 6-2zM6 10.5c1.4.7 3.5 1 6 1s4.6-.3 6-1V12c0 1.1-2.7 2-6 2s-6-.9-6-2v-1.5zm0 4c1.4.7 3.5 1 6 1s4.6-.3 6-1V16c0 1.1-2.7 2-6 2s-6-.9-6-2v-1.5z"/>`,
22
+ 'firewall': `<path d="M12 2L4 6v6c0 5.5 3.4 10.3 8 12 4.6-1.7 8-6.5 8-12V6l-8-4zm0 2.2l6 3v5.3c0 4.3-2.6 8.1-6 9.5-3.4-1.4-6-5.2-6-9.5V7.2l6-3z"/> <path d="M11 8h2v5h-2V8zm0 6h2v2h-2v-2z"/>`,
23
+ 'generic': `<path d="M4 4h16v16H4V4zm2 2v12h12V6H6zm2 2h8v2H8V8zm0 4h8v2H8v-2z"/>`,
24
+ 'internet': `<path d="M12 2a10 10 0 100 20 10 10 0 000-20zm0 2c.6 0 1.3.8 1.8 2H10.2c.5-1.2 1.2-2 1.8-2zm-3.2.7A8 8 0 005 10h2.5c.1-2 .5-3.7 1.3-5.3zm6.4 0c.8 1.6 1.2 3.3 1.3 5.3H19a8 8 0 00-3.8-5.3zM5 12h2.5c.1 2 .5 3.7 1.3 5.3A8 8 0 015 12zm4.5 0h5c0 1.5-.3 3-1 4h-3c-.7-1-1-2.5-1-4zm7 0H19a8 8 0 01-3.8 5.3c.8-1.6 1.2-3.3 1.3-5.3zM10.2 18h3.6c-.5 1.2-1.2 2-1.8 2s-1.3-.8-1.8-2z"/>`,
25
+ 'l2-switch': `<path d="M3 8h18v8H3V8zm2 2v4h14v-4H5zm2 1h2v2H7v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2z"/>`,
26
+ 'l3-switch': `<path d="M3 6h18v12H3V6zm2 2v8h14V8H5zm2 2h4v1H7v-1zm6 0h4v1h-4v-1zm-6 3h4v1H7v-1zm6 0h4v1h-4v-1z"/>`,
27
+ 'load-balancer': `<path d="M12 4L4 8l8 4 8-4-8-4zm0 2.5L16 8l-4 2-4-2 4-1.5zM4 12l8 4 8-4v2l-8 4-8-4v-2zm0 4l8 4 8-4v2l-8 4-8-4v-2z"/>`,
28
+ 'router': `<path d="M4 8h16v8H4V8zm2 2v4h12v-4H6zm1 1h2v2H7v-2zm4 0h2v2h-2v-2zm4 0h2v2h-2v-2z"/>`,
29
+ 'server': `<path d="M4 4h16v4H4V4zm0 6h16v4H4v-4zm0 6h16v4H4v-4zm2-10v2h2V6H6zm0 6v2h2v-2H6zm0 6v2h2v-2H6zm10-12v2h2V6h-2zm0 6v2h2v-2h-2zm0 6v2h2v-2h-2z"/>`,
30
+ 'vpn': `<path d="M12 2L4 5v6.5c0 5.3 3.4 10 8 11.5 4.6-1.5 8-6.2 8-11.5V5l-8-3zm0 4a3 3 0 110 6 3 3 0 010-6zm-4 8h8v1c0 2-1.8 3-4 3s-4-1-4-3v-1z"/>`,
31
+ }
32
+
33
+ // Map DeviceType to icon key
34
+ const deviceTypeToIcon: Record<DeviceType, string> = {
35
+ [DeviceType.Router]: 'router',
36
+ [DeviceType.L3Switch]: 'l3-switch',
37
+ [DeviceType.L2Switch]: 'l2-switch',
38
+ [DeviceType.Firewall]: 'firewall',
39
+ [DeviceType.LoadBalancer]: 'load-balancer',
40
+ [DeviceType.Server]: 'server',
41
+ [DeviceType.AccessPoint]: 'access-point',
42
+ [DeviceType.Cloud]: 'cloud',
43
+ [DeviceType.Internet]: 'internet',
44
+ [DeviceType.VPN]: 'vpn',
45
+ [DeviceType.Database]: 'database',
46
+ [DeviceType.Generic]: 'generic',
47
+ }
48
+
49
+ /**
50
+ * Get SVG icon content for a device type
51
+ */
52
+ export function getDeviceIcon(type?: DeviceType): string | undefined {
53
+ if (!type) return undefined
54
+ const iconKey = deviceTypeToIcon[type]
55
+ if (!iconKey) return undefined
56
+ return defaultIcons[iconKey]
57
+ }
58
+
59
+ // Vendor icon registry (populated by @shumoku/icons if installed)
60
+ let vendorIconRegistry: Record<string, Record<string, IconEntry>> = {}
61
+
62
+ /**
63
+ * Register vendor icons (called by @shumoku/icons)
64
+ */
65
+ export function registerVendorIcons(vendor: string, icons: Record<string, IconEntry>): void {
66
+ vendorIconRegistry[vendor] = icons
67
+ }
68
+
69
+ /**
70
+ * Get vendor icon entry
71
+ */
72
+ export function getVendorIconEntry(
73
+ vendor: string,
74
+ service: string,
75
+ resource?: string
76
+ ): IconEntry | undefined {
77
+ if (vendor === 'default' || !vendor) {
78
+ const content = defaultIcons[service] || (resource ? defaultIcons[resource] : undefined)
79
+ return content ? { default: content } : undefined
80
+ }
81
+
82
+ const vendorIcons = vendorIconRegistry[vendor]
83
+ if (!vendorIcons) return undefined
84
+
85
+ const key = resource ? `${service}/${resource}` : service
86
+ const entry = vendorIcons[key]
87
+ if (!entry) {
88
+ const serviceKey = Object.keys(vendorIcons).find(k => k.startsWith(service + '/'))
89
+ if (serviceKey) return vendorIcons[serviceKey]
90
+ return undefined
91
+ }
92
+ return entry
93
+ }
94
+
95
+ /**
96
+ * Get vendor icon with theme support
97
+ */
98
+ export function getVendorIcon(
99
+ vendor: string,
100
+ service: string,
101
+ resource?: string,
102
+ theme: IconThemeVariant = 'default'
103
+ ): string | undefined {
104
+ const entry = getVendorIconEntry(vendor, service, resource)
105
+ if (!entry) return undefined
106
+ return entry[theme] || entry.default
107
+ }
108
+
109
+ export const iconSets = {
110
+ default: defaultIcons,
111
+ }
@@ -0,0 +1 @@
1
+ export * from './generated-icons.js'
package/src/index.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @shumoku/core - Network topology visualization core library
3
+ */
4
+
5
+ // Models
6
+ export * from './models/index.js'
7
+
8
+ // Layout
9
+ export * from './layout/index.js'
10
+
11
+ // Themes
12
+ export * from './themes/index.js'
13
+
14
+ // Icons
15
+ export * from './icons/index.js'
16
+
17
+ // Renderer
18
+ export * from './renderer/index.js'
19
+
20
+ // Version
21
+ export const version = '0.0.0'