@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.
- package/dist/cache/CacheManager.d.ts.map +1 -0
- package/dist/cache/CacheManager.js +131 -0
- package/dist/cache/CacheManager.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/ir/index.d.ts +11 -0
- package/dist/ir/index.d.ts.map +1 -0
- package/dist/ir/index.js +9 -0
- package/dist/ir/index.js.map +1 -0
- package/dist/ir/normalize.d.ts +10 -0
- package/dist/ir/normalize.d.ts.map +1 -0
- package/dist/ir/normalize.js +207 -0
- package/dist/ir/normalize.js.map +1 -0
- package/dist/ir/persistence.d.ts +26 -0
- package/dist/ir/persistence.d.ts.map +1 -0
- package/dist/ir/persistence.js +21 -0
- package/dist/ir/persistence.js.map +1 -0
- package/dist/ir/sync.d.ts +12 -0
- package/dist/ir/sync.d.ts.map +1 -0
- package/dist/ir/sync.js +36 -0
- package/dist/ir/sync.js.map +1 -0
- package/dist/ir/types.d.ts +143 -0
- package/dist/ir/types.d.ts.map +1 -0
- package/dist/ir/types.js +13 -0
- package/dist/ir/types.js.map +1 -0
- package/dist/ir/views/dnd5e.d.ts +40 -0
- package/dist/ir/views/dnd5e.d.ts.map +1 -0
- package/dist/ir/views/dnd5e.js +50 -0
- package/dist/ir/views/dnd5e.js.map +1 -0
- package/dist/render/character.d.ts +19 -0
- package/dist/render/character.d.ts.map +1 -0
- package/dist/render/character.js +156 -0
- package/dist/render/character.js.map +1 -0
- package/dist/render/h.d.ts +27 -0
- package/dist/render/h.d.ts.map +1 -0
- package/dist/render/h.js +64 -0
- package/dist/render/h.js.map +1 -0
- package/dist/render/index.d.ts +11 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +8 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/mount.d.ts +31 -0
- package/dist/render/mount.d.ts.map +1 -0
- package/dist/render/mount.js +63 -0
- package/dist/render/mount.js.map +1 -0
- package/dist/supabase/fields.d.ts.map +1 -0
- package/dist/supabase/fields.js +120 -0
- package/dist/supabase/fields.js.map +1 -0
- package/dist/types/character.d.ts.map +1 -0
- package/dist/types/character.js +5 -0
- package/dist/types/character.js.map +1 -0
- package/package.json +73 -0
- package/src/browser.js +51 -0
- package/src/cache/CacheManager.ts +174 -0
- package/src/common/browser-polyfill.js +319 -0
- package/src/common/debug.js +123 -0
- package/src/common/html-utils.js +134 -0
- package/src/common/theme-manager.js +265 -0
- package/src/index.ts +25 -0
- package/src/ir/__fixtures__/dnd5e-character.json +75962 -0
- package/src/ir/__fixtures__/non-dnd-character.json +14218 -0
- package/src/ir/index.ts +10 -0
- package/src/ir/normalize.ts +245 -0
- package/src/ir/persistence.ts +37 -0
- package/src/ir/sync.ts +49 -0
- package/src/ir/types.ts +161 -0
- package/src/ir/views/dnd5e.ts +94 -0
- package/src/lib/indexeddb-cache.js +320 -0
- package/src/modules/action-announcements.js +102 -0
- package/src/modules/action-display.js +1557 -0
- package/src/modules/action-executor.js +860 -0
- package/src/modules/action-filters.js +167 -0
- package/src/modules/action-options.js +117 -0
- package/src/modules/card-creator.js +142 -0
- package/src/modules/character-portrait.js +169 -0
- package/src/modules/character-trait-popups.js +959 -0
- package/src/modules/character-traits.js +814 -0
- package/src/modules/class-feature-edge-cases.js +1320 -0
- package/src/modules/color-utils.js +69 -0
- package/src/modules/combat-maneuver-edge-cases.js +660 -0
- package/src/modules/companions-manager.js +178 -0
- package/src/modules/concentration-tracker.js +178 -0
- package/src/modules/data-manager.js +514 -0
- package/src/modules/dice-roller.js +719 -0
- package/src/modules/effects-manager.js +743 -0
- package/src/modules/feature-modals.js +1264 -0
- package/src/modules/formula-resolver.js +444 -0
- package/src/modules/gm-mode.js +184 -0
- package/src/modules/health-modals.js +399 -0
- package/src/modules/hp-management.js +752 -0
- package/src/modules/inventory-manager.js +242 -0
- package/src/modules/macro-system.js +825 -0
- package/src/modules/notification-system.js +92 -0
- package/src/modules/racial-feature-edge-cases.js +746 -0
- package/src/modules/resource-manager.js +775 -0
- package/src/modules/sheet-builder.js +654 -0
- package/src/modules/spell-action-modals.js +583 -0
- package/src/modules/spell-cards.js +602 -0
- package/src/modules/spell-casting.js +723 -0
- package/src/modules/spell-display.js +314 -0
- package/src/modules/spell-edge-cases.js +509 -0
- package/src/modules/spell-macros.js +201 -0
- package/src/modules/spell-modals.js +1221 -0
- package/src/modules/spell-slots.js +224 -0
- package/src/modules/status-bar-bridge.js +101 -0
- package/src/modules/ui-utilities.js +284 -0
- package/src/modules/warlock-invocations.js +219 -0
- package/src/modules/window-management.js +211 -0
- package/src/render/character.ts +234 -0
- package/src/render/h.ts +74 -0
- package/src/render/index.ts +10 -0
- package/src/render/mount.ts +94 -0
- package/src/supabase/client.js +1383 -0
- package/src/supabase/config.js +60 -0
- package/src/supabase/fields.ts +129 -0
- 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';
|