@eaprelsky/nocturna-wheel 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -89,47 +89,16 @@
89
89
  }
90
90
 
91
91
  /**
92
- * Gets or creates an IconProvider instance
93
- * @param {string} basePath - Optional base path for SVG assets
94
- * @returns {Object} The IconProvider instance
92
+ * Gets the IconProvider instance
93
+ * NOTE: IconProvider should be registered externally before use
94
+ * This method only retrieves, does not create
95
+ * @returns {Object|undefined} The IconProvider instance if registered
95
96
  */
96
- static getIconProvider(basePath = './assets/svg/zodiac/') {
97
+ static getIconProvider() {
97
98
  if (!this.has('iconProvider')) {
98
- // Create a simple icon provider
99
- const iconProvider = {
100
- basePath: basePath,
101
-
102
- getPlanetIconPath(planetName) {
103
- return `${this.basePath}zodiac-planet-${planetName.toLowerCase()}.svg`;
104
- },
105
-
106
- getZodiacIconPath(signName) {
107
- return `${this.basePath}zodiac-sign-${signName.toLowerCase()}.svg`;
108
- },
109
-
110
- getAspectIconPath(aspectType) {
111
- return `${this.basePath}zodiac-aspect-${aspectType.toLowerCase()}.svg`;
112
- },
113
-
114
- createTextFallback(svgUtils, options, text) {
115
- const { x, y, size = '16px', color = '#000000', className = 'icon-fallback' } = options;
116
-
117
- const textElement = svgUtils.createSVGElement("text", {
118
- x: x,
119
- y: y,
120
- 'text-anchor': 'middle',
121
- 'dominant-baseline': 'middle',
122
- 'font-size': size,
123
- 'class': className,
124
- 'fill': color
125
- });
126
-
127
- textElement.textContent = text;
128
- return textElement;
129
- }
130
- };
131
-
132
- this.register('iconProvider', iconProvider);
99
+ console.warn('ServiceRegistry: IconProvider not registered. Icons may not work correctly.');
100
+ console.warn('ServiceRegistry: This should be initialized in main.js with inline IconData.');
101
+ return null;
133
102
  }
134
103
  return this.get('iconProvider');
135
104
  }
@@ -142,8 +111,8 @@
142
111
  // Initialize SvgUtils
143
112
  this.getSvgUtils();
144
113
 
145
- // Initialize IconProvider with the assets base path
146
- this.getIconProvider(options.assetBasePath || './assets/svg/zodiac/');
114
+ // Note: IconProvider should be registered externally in main.js
115
+ // with inline IconData before calling this method
147
116
 
148
117
  console.log("ServiceRegistry: Core services initialized");
149
118
  }
@@ -159,17 +128,6 @@
159
128
  * 2. External mode: Uses external file paths (for custom icons)
160
129
  */
161
130
 
162
- // Try to import IconData if available (after build)
163
- let InlineIconData = null;
164
- try {
165
- // This will be replaced by rollup during build
166
- // During development or if IconData doesn't exist, this will fail gracefully
167
- InlineIconData = null; // Will be set up after IconData.js is generated
168
- } catch (e) {
169
- // IconData not available yet
170
- InlineIconData = null;
171
- }
172
-
173
131
  class IconProvider {
174
132
  /**
175
133
  * Constructor
@@ -190,6 +148,9 @@
190
148
 
191
149
  // Lazy-load IconData on first use
192
150
  this.inlineData = null;
151
+
152
+ // Track if warning was already shown (to avoid spam)
153
+ this._warnedAboutMissingData = false;
193
154
  }
194
155
 
195
156
  /**
@@ -197,9 +158,6 @@
197
158
  * @private
198
159
  */
199
160
  _getInlineData() {
200
- if (!this.inlineData && InlineIconData) {
201
- this.inlineData = InlineIconData;
202
- }
203
161
  return this.inlineData;
204
162
  }
205
163
 
@@ -209,7 +167,11 @@
209
167
  */
210
168
  setInlineData(iconData) {
211
169
  this.inlineData = iconData;
212
- InlineIconData = iconData;
170
+ console.log('IconProvider.setInlineData(): Data loaded successfully',
171
+ 'planets:', Object.keys(iconData?.planets || {}).length,
172
+ 'signs:', Object.keys(iconData?.signs || {}).length,
173
+ 'aspects:', Object.keys(iconData?.aspects || {}).length
174
+ );
213
175
  }
214
176
 
215
177
  /**
@@ -230,6 +192,16 @@
230
192
  const inlineData = this._getInlineData();
231
193
  if (inlineData?.planets?.[name]) {
232
194
  return inlineData.planets[name];
195
+ } else {
196
+ // Debug: log when inline data is not available (only once)
197
+ if (!this._warnedAboutMissingData) {
198
+ this._warnedAboutMissingData = true;
199
+ if (!inlineData) {
200
+ console.warn(`IconProvider: Inline data not loaded, falling back to external paths. Call setInlineData() to load inline icons.`);
201
+ } else if (!inlineData.planets) {
202
+ console.warn(`IconProvider: Inline data missing 'planets' category`);
203
+ }
204
+ }
233
205
  }
234
206
  }
235
207
 
@@ -321,7 +293,7 @@
321
293
  /**
322
294
  * IconData.js
323
295
  * Auto-generated module containing inline SVG icons as data URLs
324
- * Generated at: 2025-11-13T13:46:12.044Z
296
+ * Generated at: 2025-11-14T16:02:20.923Z
325
297
  *
326
298
  * This file is automatically generated by the build process.
327
299
  * Do not edit manually - changes will be overwritten.
@@ -1968,11 +1940,18 @@
1968
1940
  */
1969
1941
  constructor(options) {
1970
1942
  super(options);
1971
- if (!options.assetBasePath) {
1972
- throw new Error("ZodiacRenderer: Missing required option assetBasePath");
1943
+
1944
+ // Store the icon provider
1945
+ this.iconProvider = options.iconProvider;
1946
+
1947
+ // assetBasePath is required only if IconProvider is not available
1948
+ if (!options.assetBasePath && !this.iconProvider) {
1949
+ throw new Error("ZodiacRenderer: Missing required option assetBasePath or iconProvider");
1973
1950
  }
1974
-
1975
- this.iconProvider = options.iconProvider; // Store the icon provider
1951
+
1952
+ // Set default assetBasePath if not provided (for backward compatibility)
1953
+ this.assetBasePath = options.assetBasePath || './assets/';
1954
+
1976
1955
  this.signIconRadius = (this.outerRadius + this.middleRadius) / 2;
1977
1956
  this.signIconSize = 30;
1978
1957
  }
@@ -2013,10 +1992,21 @@
2013
1992
  ];
2014
1993
 
2015
1994
  circles.forEach(circleData => {
1995
+ // Determine stroke color and width based on circle type
1996
+ let strokeColor = "#999";
1997
+ let strokeWidth = "0.5";
1998
+ if (circleData.class === "chart-outer-circle") {
1999
+ strokeColor = "#666";
2000
+ strokeWidth = "1";
2001
+ }
2002
+
2016
2003
  const circle = this.svgUtils.createSVGElement("circle", {
2017
2004
  cx: this.centerX,
2018
2005
  cy: this.centerY,
2019
2006
  r: circleData.r,
2007
+ fill: "transparent", // Explicitly set transparent fill to avoid default black
2008
+ stroke: strokeColor, // Explicitly set stroke to ensure visibility
2009
+ "stroke-width": strokeWidth, // Explicitly set stroke width
2020
2010
  class: `zodiac-element ${circleData.class}` // Add base class
2021
2011
  });
2022
2012
  parentGroup.appendChild(circle);
@@ -2051,6 +2041,8 @@
2051
2041
  y1: point1.y,
2052
2042
  x2: point2.x,
2053
2043
  y2: point2.y,
2044
+ stroke: "#999", // Explicitly set stroke to ensure visibility
2045
+ "stroke-width": "0.75", // Explicitly set stroke width
2054
2046
  class: `zodiac-element zodiac-division-line ${specialClass}`
2055
2047
  });
2056
2048
 
@@ -2083,10 +2075,17 @@
2083
2075
  iconHref = this.iconProvider.getZodiacIconPath(signName);
2084
2076
  } else {
2085
2077
  // Fallback to old path construction
2086
- iconHref = `${this.options.assetBasePath}svg/zodiac/zodiac-sign-${signName}.svg`;
2078
+ const basePath = this.options.assetBasePath || this.assetBasePath || './assets/';
2079
+ iconHref = `${basePath}svg/zodiac/zodiac-sign-${signName}.svg`;
2087
2080
  }
2088
2081
 
2089
- console.log(`Loading zodiac sign: ${iconHref}`);
2082
+ // Log icon path for debugging (only log first time for each sign to avoid spam)
2083
+ if (!this._loggedSigns) this._loggedSigns = {};
2084
+ if (!this._loggedSigns[signName]) {
2085
+ console.log(`ZodiacRenderer: Loading sign '${signName}':`,
2086
+ iconHref.startsWith('data:') ? 'inline data URL' : iconHref);
2087
+ this._loggedSigns[signName] = true;
2088
+ }
2090
2089
 
2091
2090
  const icon = this.svgUtils.createSVGElement("image", {
2092
2091
  x: point.x - this.signIconSize / 2, // Offset to center the icon
@@ -2235,12 +2234,34 @@
2235
2234
  const innerPoint = this.svgUtils.pointOnCircle(this.centerX, this.centerY, this.innerRadius, angle);
2236
2235
  const middlePoint = this.svgUtils.pointOnCircle(this.centerX, this.centerY, this.middleRadius, angle);
2237
2236
 
2237
+ // Determine stroke color and width based on line type
2238
+ let innerStrokeColor = "#999";
2239
+ let innerStrokeWidth = "0.75";
2240
+
2241
+ let outerStrokeColor = "#999";
2242
+ let outerStrokeWidth = "0.75";
2243
+ let outerStrokeDasharray = null;
2244
+
2245
+ if (axisClass.includes('axis')) {
2246
+ // Cardinal points (ASC, DSC, IC, MC) - solid, darker
2247
+ innerStrokeColor = "#555";
2248
+ innerStrokeWidth = "1";
2249
+ outerStrokeColor = "#555";
2250
+ outerStrokeWidth = "1";
2251
+ // Axes are always solid
2252
+ } else {
2253
+ // Regular lines - outer lines are dashed
2254
+ outerStrokeDasharray = "2,2";
2255
+ }
2256
+
2238
2257
  // Create line from inner to middle circle
2239
2258
  const innerLine = this.svgUtils.createSVGElement("line", {
2240
2259
  x1: innerPoint.x,
2241
2260
  y1: innerPoint.y,
2242
2261
  x2: middlePoint.x,
2243
2262
  y2: middlePoint.y,
2263
+ stroke: innerStrokeColor, // Explicitly set stroke to ensure visibility
2264
+ "stroke-width": innerStrokeWidth, // Explicitly set stroke width
2244
2265
  class: `house-element house-division-line ${axisClass}`
2245
2266
  });
2246
2267
 
@@ -2262,13 +2283,21 @@
2262
2283
  const extendedPoint = this.svgUtils.pointOnCircle(this.centerX, this.centerY, this.extendedRadius, angle);
2263
2284
 
2264
2285
  // Create line from outer circle to extended point
2265
- const outerLine = this.svgUtils.createSVGElement("line", {
2286
+ const outerLineAttrs = {
2266
2287
  x1: outerPoint.x,
2267
2288
  y1: outerPoint.y,
2268
2289
  x2: extendedPoint.x,
2269
2290
  y2: extendedPoint.y,
2291
+ stroke: outerStrokeColor, // Explicitly set stroke to ensure visibility
2292
+ "stroke-width": outerStrokeWidth, // Explicitly set stroke width
2270
2293
  class: `house-element house-division-line outer ${axisClass}`
2271
- });
2294
+ };
2295
+
2296
+ if (outerStrokeDasharray) {
2297
+ outerLineAttrs["stroke-dasharray"] = outerStrokeDasharray;
2298
+ }
2299
+
2300
+ const outerLine = this.svgUtils.createSVGElement("line", outerLineAttrs);
2272
2301
 
2273
2302
  // Ensure cardinal points render above zodiac lines
2274
2303
  if (axisClass.includes('axis')) {
@@ -2405,12 +2434,17 @@
2405
2434
  */
2406
2435
  constructor(options) {
2407
2436
  super(options);
2408
- if (!options.assetBasePath) {
2409
- throw new Error(`${this.constructor.name}: Missing required option assetBasePath`);
2410
- }
2411
2437
 
2412
2438
  // Store the icon provider
2413
2439
  this.iconProvider = options.iconProvider;
2440
+
2441
+ // assetBasePath is required only if IconProvider is not available
2442
+ if (!options.assetBasePath && !this.iconProvider) {
2443
+ throw new Error(`${this.constructor.name}: Missing required option assetBasePath or iconProvider`);
2444
+ }
2445
+
2446
+ // Set default assetBasePath if not provided (for backward compatibility)
2447
+ this.assetBasePath = options.assetBasePath || './assets/';
2414
2448
  }
2415
2449
 
2416
2450
  /**
@@ -2512,7 +2546,8 @@
2512
2546
  iconPath = this.iconProvider.getPlanetIconPath(planet.name);
2513
2547
  } else {
2514
2548
  // Fallback to old path construction if IconProvider is not available
2515
- iconPath = `${this.options.assetBasePath}svg/zodiac/zodiac-planet-${planet.name.toLowerCase()}.svg`;
2549
+ const basePath = this.options.assetBasePath || this.assetBasePath || './assets/';
2550
+ iconPath = `${basePath}svg/zodiac/zodiac-planet-${planet.name.toLowerCase()}.svg`;
2516
2551
  }
2517
2552
 
2518
2553
  // Calculate top-left position of the icon (centered on the calculated point)
@@ -3514,7 +3549,7 @@
3514
3549
  this.renderedAspects = []; // Store calculated aspects
3515
3550
  this._aspectCacheKey = null; // Cache key for aspect calculations
3516
3551
  this._aspectCache = []; // Cached aspect results
3517
- this.assetBasePath = options.assetBasePath || ''; // Store asset base path
3552
+ this.assetBasePath = options.assetBasePath || './assets/'; // Store asset base path with fallback
3518
3553
  this.iconProvider = options.iconProvider; // Store the icon provider
3519
3554
 
3520
3555
  // Define major aspects and their angles (can be overridden/extended by config)
@@ -4043,7 +4078,12 @@
4043
4078
  this.config = config;
4044
4079
  this.svgNS = svgNS;
4045
4080
  this.svgUtils = ServiceRegistry.getSvgUtils();
4046
- this.iconProvider = ServiceRegistry.getIconProvider(config.assets?.basePath);
4081
+ this.iconProvider = ServiceRegistry.getIconProvider();
4082
+
4083
+ // If IconProvider is null, log error for debugging
4084
+ if (!this.iconProvider) {
4085
+ console.error('RendererFactory: IconProvider not available. Icons will not render correctly.');
4086
+ }
4047
4087
  }
4048
4088
 
4049
4089
  /**
@@ -5347,6 +5387,9 @@
5347
5387
  cx: centerX,
5348
5388
  cy: centerY,
5349
5389
  r: radius,
5390
+ fill: "transparent", // Explicitly set transparent fill to avoid default black
5391
+ stroke: "#999", // Explicitly set stroke to ensure visibility
5392
+ "stroke-width": "0.5", // Explicitly set stroke width
5350
5393
  class: 'zodiac-element chart-innermost-circle'
5351
5394
  });
5352
5395
  zodiacGroup.appendChild(innermostCircle);
@@ -5627,17 +5670,31 @@
5627
5670
  * See examples/factory-injection-example.js for more advanced usage patterns.
5628
5671
  */
5629
5672
 
5630
- // Initialize core services immediately
5631
- ServiceRegistry.initializeServices();
5673
+ // CRITICAL: Register IconProvider BEFORE initializing other services
5674
+ // This ensures renderers get the inline-capable provider, not a legacy stub
5675
+ const iconProvider = new IconProvider({
5676
+ useInline: true,
5677
+ basePath: './assets/svg/zodiac/' // Fallback for external mode
5678
+ });
5632
5679
 
5633
- // Initialize IconProvider with inline data if available
5680
+ // Initialize with inline data if available
5634
5681
  if (IconData && Object.keys(IconData.planets || {}).length > 0) {
5635
- const iconProvider = ServiceRegistry.getIconProvider();
5636
- if (iconProvider && typeof iconProvider.setInlineData === 'function') {
5637
- iconProvider.setInlineData(IconData);
5638
- }
5682
+ iconProvider.setInlineData(IconData);
5683
+ console.log('IconProvider: Initialized with inline icons -',
5684
+ 'Planets:', Object.keys(IconData.planets).length,
5685
+ 'Signs:', Object.keys(IconData.signs).length,
5686
+ 'Aspects:', Object.keys(IconData.aspects).length
5687
+ );
5688
+ } else {
5689
+ console.warn('IconProvider: IconData not loaded, will use external paths');
5639
5690
  }
5640
5691
 
5692
+ // Register IconProvider BEFORE initializing services
5693
+ ServiceRegistry.register('iconProvider', iconProvider);
5694
+
5695
+ // Now initialize other core services
5696
+ ServiceRegistry.initializeServices();
5697
+
5641
5698
  // Library version
5642
5699
  const VERSION = '0.2.0';
5643
5700
 
@@ -5737,11 +5794,21 @@
5737
5794
  }
5738
5795
  }
5739
5796
 
5740
- // Initialize the chart when the DOM is ready
5741
- document.addEventListener('DOMContentLoaded', initChart);
5797
+ // Auto-initialization is DISABLED in production builds to prevent conflicts.
5798
+ // This demo code should only run in development mode with Vite dev server.
5799
+ // In production, users explicitly create their own chart instances.
5742
5800
 
5743
- // Handle hot module replacement for Vite
5801
+ // Handle hot module replacement for Vite (development only)
5744
5802
  if (undefined) {
5803
+ // Initialize the chart when the DOM is ready (ONLY in development)
5804
+ document.addEventListener('DOMContentLoaded', () => {
5805
+ const container = document.getElementById('chart-container');
5806
+ if (container && container.children.length === 0) {
5807
+ console.log('DEV MODE: Auto-initializing demo chart');
5808
+ initChart();
5809
+ }
5810
+ });
5811
+
5745
5812
  undefined.accept((newModule) => {
5746
5813
  console.log('HMR update for main.js');
5747
5814
  cleanup();