@carmaclouds/core 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/cache/CacheManager.d.ts.map +1 -0
  2. package/dist/cache/CacheManager.js +131 -0
  3. package/dist/cache/CacheManager.js.map +1 -0
  4. package/dist/index.d.ts +18 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +22 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/ir/index.d.ts +11 -0
  9. package/dist/ir/index.d.ts.map +1 -0
  10. package/dist/ir/index.js +9 -0
  11. package/dist/ir/index.js.map +1 -0
  12. package/dist/ir/normalize.d.ts +10 -0
  13. package/dist/ir/normalize.d.ts.map +1 -0
  14. package/dist/ir/normalize.js +207 -0
  15. package/dist/ir/normalize.js.map +1 -0
  16. package/dist/ir/persistence.d.ts +26 -0
  17. package/dist/ir/persistence.d.ts.map +1 -0
  18. package/dist/ir/persistence.js +21 -0
  19. package/dist/ir/persistence.js.map +1 -0
  20. package/dist/ir/sync.d.ts +12 -0
  21. package/dist/ir/sync.d.ts.map +1 -0
  22. package/dist/ir/sync.js +36 -0
  23. package/dist/ir/sync.js.map +1 -0
  24. package/dist/ir/types.d.ts +143 -0
  25. package/dist/ir/types.d.ts.map +1 -0
  26. package/dist/ir/types.js +13 -0
  27. package/dist/ir/types.js.map +1 -0
  28. package/dist/ir/views/dnd5e.d.ts +40 -0
  29. package/dist/ir/views/dnd5e.d.ts.map +1 -0
  30. package/dist/ir/views/dnd5e.js +50 -0
  31. package/dist/ir/views/dnd5e.js.map +1 -0
  32. package/dist/render/character.d.ts +19 -0
  33. package/dist/render/character.d.ts.map +1 -0
  34. package/dist/render/character.js +156 -0
  35. package/dist/render/character.js.map +1 -0
  36. package/dist/render/h.d.ts +27 -0
  37. package/dist/render/h.d.ts.map +1 -0
  38. package/dist/render/h.js +64 -0
  39. package/dist/render/h.js.map +1 -0
  40. package/dist/render/index.d.ts +11 -0
  41. package/dist/render/index.d.ts.map +1 -0
  42. package/dist/render/index.js +8 -0
  43. package/dist/render/index.js.map +1 -0
  44. package/dist/render/mount.d.ts +31 -0
  45. package/dist/render/mount.d.ts.map +1 -0
  46. package/dist/render/mount.js +63 -0
  47. package/dist/render/mount.js.map +1 -0
  48. package/dist/supabase/fields.d.ts.map +1 -0
  49. package/dist/supabase/fields.js +120 -0
  50. package/dist/supabase/fields.js.map +1 -0
  51. package/dist/types/character.d.ts.map +1 -0
  52. package/dist/types/character.js +5 -0
  53. package/dist/types/character.js.map +1 -0
  54. package/package.json +73 -0
  55. package/src/browser.js +51 -0
  56. package/src/cache/CacheManager.ts +174 -0
  57. package/src/common/browser-polyfill.js +319 -0
  58. package/src/common/debug.js +123 -0
  59. package/src/common/html-utils.js +134 -0
  60. package/src/common/theme-manager.js +265 -0
  61. package/src/index.ts +25 -0
  62. package/src/ir/__fixtures__/dnd5e-character.json +75962 -0
  63. package/src/ir/__fixtures__/non-dnd-character.json +14218 -0
  64. package/src/ir/index.ts +10 -0
  65. package/src/ir/normalize.ts +245 -0
  66. package/src/ir/persistence.ts +37 -0
  67. package/src/ir/sync.ts +49 -0
  68. package/src/ir/types.ts +161 -0
  69. package/src/ir/views/dnd5e.ts +94 -0
  70. package/src/lib/indexeddb-cache.js +320 -0
  71. package/src/modules/action-announcements.js +102 -0
  72. package/src/modules/action-display.js +1557 -0
  73. package/src/modules/action-executor.js +860 -0
  74. package/src/modules/action-filters.js +167 -0
  75. package/src/modules/action-options.js +117 -0
  76. package/src/modules/card-creator.js +142 -0
  77. package/src/modules/character-portrait.js +169 -0
  78. package/src/modules/character-trait-popups.js +959 -0
  79. package/src/modules/character-traits.js +814 -0
  80. package/src/modules/class-feature-edge-cases.js +1320 -0
  81. package/src/modules/color-utils.js +69 -0
  82. package/src/modules/combat-maneuver-edge-cases.js +660 -0
  83. package/src/modules/companions-manager.js +178 -0
  84. package/src/modules/concentration-tracker.js +178 -0
  85. package/src/modules/data-manager.js +514 -0
  86. package/src/modules/dice-roller.js +719 -0
  87. package/src/modules/effects-manager.js +743 -0
  88. package/src/modules/feature-modals.js +1264 -0
  89. package/src/modules/formula-resolver.js +444 -0
  90. package/src/modules/gm-mode.js +184 -0
  91. package/src/modules/health-modals.js +399 -0
  92. package/src/modules/hp-management.js +752 -0
  93. package/src/modules/inventory-manager.js +242 -0
  94. package/src/modules/macro-system.js +825 -0
  95. package/src/modules/notification-system.js +92 -0
  96. package/src/modules/racial-feature-edge-cases.js +746 -0
  97. package/src/modules/resource-manager.js +775 -0
  98. package/src/modules/sheet-builder.js +654 -0
  99. package/src/modules/spell-action-modals.js +583 -0
  100. package/src/modules/spell-cards.js +602 -0
  101. package/src/modules/spell-casting.js +723 -0
  102. package/src/modules/spell-display.js +314 -0
  103. package/src/modules/spell-edge-cases.js +509 -0
  104. package/src/modules/spell-macros.js +201 -0
  105. package/src/modules/spell-modals.js +1221 -0
  106. package/src/modules/spell-slots.js +224 -0
  107. package/src/modules/status-bar-bridge.js +101 -0
  108. package/src/modules/ui-utilities.js +284 -0
  109. package/src/modules/warlock-invocations.js +219 -0
  110. package/src/modules/window-management.js +211 -0
  111. package/src/render/character.ts +234 -0
  112. package/src/render/h.ts +74 -0
  113. package/src/render/index.ts +10 -0
  114. package/src/render/mount.ts +94 -0
  115. package/src/supabase/client.js +1383 -0
  116. package/src/supabase/config.js +60 -0
  117. package/src/supabase/fields.ts +129 -0
  118. package/src/types/character.ts +85 -0
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Theme Manager Utility
3
+ * Handles light/dark/system theme switching with persistence
4
+ * Configurable for different projects (owlcloud, rollcloud, etc.)
5
+ */
6
+
7
+ /**
8
+ * Create a configured theme manager instance
9
+ * @param {Object} config - Configuration object
10
+ * @param {string} config.storageKey - LocalStorage key for theme persistence
11
+ * @param {string} config.eventName - Custom event name for theme changes
12
+ * @returns {Object} Configured theme manager instance
13
+ */
14
+ function createThemeManager(config = {}) {
15
+ const storageKey = config.storageKey || 'theme';
16
+ const eventName = config.eventName || 'theme-changed';
17
+
18
+ return {
19
+ THEMES: {
20
+ LIGHT: 'light',
21
+ DARK: 'dark',
22
+ SYSTEM: 'system'
23
+ },
24
+
25
+ currentTheme: 'system',
26
+ systemPrefersDark: false,
27
+
28
+ /**
29
+ * Initialize theme manager
30
+ */
31
+ async init() {
32
+ // Check system preference FIRST before loading saved preference
33
+ debug.log('🎨 ThemeManager.init() starting...');
34
+ try {
35
+ if (typeof window === 'undefined' || !window.matchMedia) {
36
+ debug.warn('⚠️ window.matchMedia not available, defaulting to light theme');
37
+ this.systemPrefersDark = false;
38
+ } else {
39
+ const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)');
40
+ this.systemPrefersDark = darkModeQuery.matches;
41
+
42
+ debug.log('🎨 System dark mode query result:', {
43
+ matches: darkModeQuery.matches,
44
+ media: darkModeQuery.media,
45
+ systemPrefersDark: this.systemPrefersDark
46
+ });
47
+ console.log('🎨 THEME DEBUG: Dark mode query matches:', darkModeQuery.matches);
48
+ console.log('🎨 THEME DEBUG: systemPrefersDark set to:', this.systemPrefersDark);
49
+
50
+ // Verify the media query is valid
51
+ if (darkModeQuery.media === 'not all') {
52
+ debug.warn('⚠️ Dark mode media query not supported, defaulting to light theme');
53
+ this.systemPrefersDark = false;
54
+ }
55
+
56
+ // Listen for system theme changes
57
+ try {
58
+ darkModeQuery.addEventListener('change', (e) => {
59
+ this.systemPrefersDark = e.matches;
60
+ debug.log('🎨 System dark mode preference changed:', this.systemPrefersDark);
61
+ if (this.currentTheme === this.THEMES.SYSTEM) {
62
+ this.applyTheme(this.THEMES.SYSTEM);
63
+ }
64
+ });
65
+ } catch (listenerError) {
66
+ debug.warn('⚠️ Could not add dark mode change listener:', listenerError);
67
+ }
68
+ }
69
+ } catch (error) {
70
+ debug.error('❌ Error detecting system theme preference:', error);
71
+ this.systemPrefersDark = false;
72
+ }
73
+
74
+ // Load saved theme preference
75
+ await this.loadThemePreference();
76
+
77
+ // Apply initial theme
78
+ this.applyTheme(this.currentTheme);
79
+
80
+ debug.log('🎨 Theme Manager initialized:', {
81
+ currentTheme: this.currentTheme,
82
+ effectiveTheme: this.getEffectiveTheme(this.currentTheme),
83
+ systemPrefersDark: this.systemPrefersDark
84
+ });
85
+ },
86
+
87
+ /**
88
+ * Load theme preference from storage
89
+ */
90
+ async loadThemePreference() {
91
+ try {
92
+ if (typeof browserAPI !== 'undefined' && browserAPI.storage) {
93
+ const result = await browserAPI.storage.local.get(['theme']);
94
+ if (result.theme) {
95
+ this.currentTheme = result.theme;
96
+ }
97
+ } else if (typeof localStorage !== 'undefined') {
98
+ // Fallback to localStorage for popup windows
99
+ const saved = localStorage.getItem(storageKey);
100
+ if (saved) {
101
+ this.currentTheme = saved;
102
+ }
103
+ }
104
+ } catch (error) {
105
+ debug.error('Failed to load theme preference:', error);
106
+ }
107
+ },
108
+
109
+ /**
110
+ * Save theme preference to storage
111
+ */
112
+ async saveThemePreference(theme) {
113
+ try {
114
+ this.currentTheme = theme;
115
+
116
+ if (typeof browserAPI !== 'undefined' && browserAPI.storage) {
117
+ await browserAPI.storage.local.set({ theme: theme });
118
+ } else if (typeof localStorage !== 'undefined') {
119
+ localStorage.setItem(storageKey, theme);
120
+ }
121
+
122
+ debug.log('💾 Theme preference saved:', theme);
123
+ } catch (error) {
124
+ debug.error('Failed to save theme preference:', error);
125
+ }
126
+ },
127
+
128
+ /**
129
+ * Apply theme to document
130
+ */
131
+ applyTheme(theme) {
132
+ const effectiveTheme = this.getEffectiveTheme(theme);
133
+
134
+ debug.log('🎨 Applying theme:', {
135
+ requested: theme,
136
+ effective: effectiveTheme,
137
+ systemPrefersDark: this.systemPrefersDark
138
+ });
139
+ console.log('🎨 THEME DEBUG: Applying theme - requested:', theme, 'effective:', effectiveTheme, 'systemPrefersDark:', this.systemPrefersDark);
140
+
141
+ // Remove existing theme classes
142
+ document.documentElement.classList.remove('theme-light', 'theme-dark');
143
+
144
+ // Add new theme class
145
+ document.documentElement.classList.add(`theme-${effectiveTheme}`);
146
+
147
+ // Set data attribute for CSS targeting
148
+ document.documentElement.setAttribute('data-theme', effectiveTheme);
149
+
150
+ console.log('🎨 THEME DEBUG: Applied class:', `theme-${effectiveTheme}`, 'to document element');
151
+ console.log('🎨 THEME DEBUG: Document classes:', document.documentElement.className);
152
+
153
+ debug.log('🎨 Theme applied successfully:', effectiveTheme);
154
+ },
155
+
156
+ /**
157
+ * Get the effective theme (resolves 'system' to light/dark)
158
+ */
159
+ getEffectiveTheme(theme) {
160
+ if (theme === this.THEMES.SYSTEM) {
161
+ return this.systemPrefersDark ? this.THEMES.DARK : this.THEMES.LIGHT;
162
+ }
163
+ return theme;
164
+ },
165
+
166
+ /**
167
+ * Set theme and save preference
168
+ */
169
+ async setTheme(theme) {
170
+ if (!Object.values(this.THEMES).includes(theme)) {
171
+ debug.error('Invalid theme:', theme);
172
+ return;
173
+ }
174
+
175
+ await this.saveThemePreference(theme);
176
+ this.applyTheme(theme);
177
+
178
+ // Notify other parts of the extension about theme change
179
+ this.notifyThemeChange(theme);
180
+ },
181
+
182
+ /**
183
+ * Notify about theme change (for communication between popup/content scripts)
184
+ */
185
+ notifyThemeChange(theme) {
186
+ // Send message to background script
187
+ if (typeof browserAPI !== 'undefined' && browserAPI.runtime) {
188
+ browserAPI.runtime.sendMessage({
189
+ action: 'themeChanged',
190
+ theme: theme
191
+ }).catch(() => {
192
+ // Ignore errors if background script isn't listening
193
+ });
194
+ }
195
+
196
+ // Dispatch custom event for same-page listeners
197
+ window.dispatchEvent(new CustomEvent(eventName, {
198
+ detail: { theme: theme }
199
+ }));
200
+ },
201
+
202
+ /**
203
+ * Get current theme
204
+ */
205
+ getCurrentTheme() {
206
+ return this.currentTheme;
207
+ },
208
+
209
+ /**
210
+ * Get effective theme (with system resolved)
211
+ */
212
+ getEffectiveCurrentTheme() {
213
+ return this.getEffectiveTheme(this.currentTheme);
214
+ },
215
+
216
+ /**
217
+ * Force refresh system preference detection
218
+ * Call this if system theme detection seems incorrect
219
+ */
220
+ refreshSystemPreference() {
221
+ try {
222
+ if (window.matchMedia) {
223
+ const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)');
224
+ const oldValue = this.systemPrefersDark;
225
+ this.systemPrefersDark = darkModeQuery.matches;
226
+
227
+ debug.log('🔄 Refreshed system preference:', {
228
+ oldValue: oldValue,
229
+ newValue: this.systemPrefersDark,
230
+ mediaQuery: darkModeQuery.media,
231
+ matches: darkModeQuery.matches
232
+ });
233
+
234
+ // Re-apply theme if using system preference
235
+ if (this.currentTheme === this.THEMES.SYSTEM) {
236
+ this.applyTheme(this.THEMES.SYSTEM);
237
+ }
238
+
239
+ return this.systemPrefersDark;
240
+ }
241
+ } catch (error) {
242
+ debug.error('❌ Error refreshing system preference:', error);
243
+ }
244
+ return this.systemPrefersDark;
245
+ }
246
+ };
247
+ }
248
+
249
+ // Export for use in other modules
250
+ if (typeof module !== 'undefined' && module.exports) {
251
+ module.exports = { createThemeManager };
252
+ }
253
+
254
+ // Make factory available globally
255
+ if (typeof window !== 'undefined') {
256
+ window.createThemeManager = createThemeManager;
257
+
258
+ // Create default instance for carmaclouds
259
+ if (!window.ThemeManager) {
260
+ window.ThemeManager = createThemeManager({
261
+ storageKey: 'carmaclouds-theme',
262
+ eventName: 'carmaclouds-theme-changed'
263
+ });
264
+ }
265
+ }
package/src/index.ts ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @carmaclouds/core
3
+ * Shared utilities and types for CarmaClouds packages
4
+ *
5
+ * Note: This package contains both TypeScript and JavaScript modules.
6
+ * The TypeScript modules are exported below. The JavaScript modules
7
+ * (common/, lib/, modules/) are available in the package but not
8
+ * exported from the main entry point as they're primarily used by
9
+ * browser extensions via importScripts.
10
+ */
11
+
12
+ // Types
13
+ export * from './types/character';
14
+
15
+ // System-agnostic IR (rebuild) - see REBUILD.md
16
+ export * from './ir';
17
+ export * from './render';
18
+
19
+ // Cache Manager
20
+ export * from './cache/CacheManager';
21
+ export { CacheManager } from './cache/CacheManager';
22
+
23
+ // Supabase Field Definitions
24
+ export * from './supabase/fields';
25
+ export { FIELD_SETS } from './supabase/fields';