@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 @@
1
+ {"version":3,"file":"CacheManager.d.ts","sourceRoot":"","sources":["../../src/cache/CacheManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,YAAY,CAAC,CAAC,GAAG,GAAG;IAC/B,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,KAAK,CAKX;IACF,OAAO,CAAC,KAAK,CAAU;gBAEX,OAAO,GAAE,mBAAwB;IAgB7C;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IA2B1B;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAY/B;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAW5B;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,QAAQ,IAAI,UAAU;IAgBtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Generic Cache Manager for CarmaClouds
3
+ * Reduces database egress costs with configurable TTL caching
4
+ */
5
+ export class CacheManager {
6
+ constructor(options = {}) {
7
+ this.cache = new Map();
8
+ this.expiryMs = options.expiryMs || 15 * 60 * 1000; // Default 15 minutes
9
+ this.debug = options.debug || false;
10
+ this.stats = {
11
+ hits: 0,
12
+ misses: 0,
13
+ stores: 0,
14
+ invalidations: 0
15
+ };
16
+ // Auto-cleanup expired entries
17
+ const cleanupInterval = options.cleanupIntervalMs || 5 * 60 * 1000;
18
+ this.cleanupInterval = setInterval(() => this.cleanupExpired(), cleanupInterval);
19
+ }
20
+ /**
21
+ * Get value from cache
22
+ */
23
+ get(key) {
24
+ const entry = this.cache.get(key);
25
+ if (!entry) {
26
+ this.stats.misses++;
27
+ return null;
28
+ }
29
+ // Check if expired
30
+ const now = Date.now();
31
+ if (now - entry.timestamp >= this.expiryMs) {
32
+ this.cache.delete(key);
33
+ this.stats.misses++;
34
+ if (this.debug) {
35
+ console.log(`⏰ [Cache] Expired: ${key}`);
36
+ }
37
+ return null;
38
+ }
39
+ this.stats.hits++;
40
+ if (this.debug) {
41
+ const age = Math.floor((now - entry.timestamp) / 1000);
42
+ console.log(`✅ [Cache] Hit: ${key} (age: ${age}s)`);
43
+ }
44
+ return entry.data;
45
+ }
46
+ /**
47
+ * Store value in cache
48
+ */
49
+ set(key, data) {
50
+ this.cache.set(key, {
51
+ data,
52
+ timestamp: Date.now()
53
+ });
54
+ this.stats.stores++;
55
+ if (this.debug) {
56
+ console.log(`📦 [Cache] Stored: ${key}`);
57
+ }
58
+ }
59
+ /**
60
+ * Check if key exists and is valid
61
+ */
62
+ has(key) {
63
+ return this.get(key) !== null;
64
+ }
65
+ /**
66
+ * Delete specific cache entry
67
+ */
68
+ delete(key) {
69
+ const deleted = this.cache.delete(key);
70
+ if (deleted) {
71
+ this.stats.invalidations++;
72
+ if (this.debug) {
73
+ console.log(`🗑️ [Cache] Invalidated: ${key}`);
74
+ }
75
+ }
76
+ return deleted;
77
+ }
78
+ /**
79
+ * Clear all cache
80
+ */
81
+ clear() {
82
+ const size = this.cache.size;
83
+ this.cache.clear();
84
+ if (this.debug) {
85
+ console.log(`🗑️ [Cache] Cleared ${size} entries`);
86
+ }
87
+ }
88
+ /**
89
+ * Get cache statistics
90
+ */
91
+ getStats() {
92
+ const hitRate = this.stats.hits + this.stats.misses > 0
93
+ ? ((this.stats.hits / (this.stats.hits + this.stats.misses)) * 100).toFixed(2)
94
+ : '0';
95
+ return {
96
+ size: this.cache.size,
97
+ hits: this.stats.hits,
98
+ misses: this.stats.misses,
99
+ stores: this.stats.stores,
100
+ invalidations: this.stats.invalidations,
101
+ hitRate: `${hitRate}%`,
102
+ expiryMinutes: this.expiryMs / 60000
103
+ };
104
+ }
105
+ /**
106
+ * Cleanup expired cache entries
107
+ */
108
+ cleanupExpired() {
109
+ const now = Date.now();
110
+ let cleaned = 0;
111
+ for (const [key, entry] of this.cache.entries()) {
112
+ if (now - entry.timestamp >= this.expiryMs) {
113
+ this.cache.delete(key);
114
+ cleaned++;
115
+ }
116
+ }
117
+ if (cleaned > 0 && this.debug) {
118
+ console.log(`🧹 [Cache] Cleaned up ${cleaned} expired entries`);
119
+ }
120
+ }
121
+ /**
122
+ * Destroy cache manager (cleanup interval)
123
+ */
124
+ destroy() {
125
+ if (this.cleanupInterval) {
126
+ clearInterval(this.cleanupInterval);
127
+ }
128
+ this.clear();
129
+ }
130
+ }
131
+ //# sourceMappingURL=CacheManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheManager.js","sourceRoot":"","sources":["../../src/cache/CacheManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
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
+ export * from './types/character';
12
+ export * from './ir';
13
+ export * from './render';
14
+ export * from './cache/CacheManager';
15
+ export { CacheManager } from './cache/CacheManager';
16
+ export * from './supabase/fields';
17
+ export { FIELD_SETS } from './supabase/fields';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,cAAc,mBAAmB,CAAC;AAGlC,cAAc,MAAM,CAAC;AACrB,cAAc,UAAU,CAAC;AAGzB,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
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
+ // Types
12
+ export * from './types/character';
13
+ // System-agnostic IR (rebuild) - see REBUILD.md
14
+ export * from './ir';
15
+ export * from './render';
16
+ // Cache Manager
17
+ export * from './cache/CacheManager';
18
+ export { CacheManager } from './cache/CacheManager';
19
+ // Supabase Field Definitions
20
+ export * from './supabase/fields';
21
+ export { FIELD_SETS } from './supabase/fields';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,QAAQ;AACR,cAAc,mBAAmB,CAAC;AAElC,gDAAgD;AAChD,cAAc,MAAM,CAAC;AACrB,cAAc,UAAU,CAAC;AAEzB,gBAAgB;AAChB,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,6BAA6B;AAC7B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * System-agnostic IR for DiceCloud characters. See REBUILD.md.
3
+ */
4
+ export * from './types';
5
+ export { normalize } from './normalize';
6
+ export { deriveDnd, DND_ABILITIES } from './views/dnd5e';
7
+ export type { Dnd5eView, AbilityView, PoolView, HitDicePool } from './views/dnd5e';
8
+ export { IR_VERSION, toIRRow } from './persistence';
9
+ export type { IRRow } from './persistence';
10
+ export { upsertCharacterIR } from './sync';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ir/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACzD,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * System-agnostic IR for DiceCloud characters. See REBUILD.md.
3
+ */
4
+ export * from './types';
5
+ export { normalize } from './normalize';
6
+ export { deriveDnd, DND_ABILITIES } from './views/dnd5e';
7
+ export { IR_VERSION, toIRRow } from './persistence';
8
+ export { upsertCharacterIR } from './sync';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ir/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * normalize(raw) -> IRCharacter
3
+ *
4
+ * Pure transform from a raw DiceCloud API response into the system-agnostic IR.
5
+ * No D&D assumptions: every attribute is carried with its type/reset, every
6
+ * action/spell keeps its real uses + consumed resources.
7
+ */
8
+ import type { IRCharacter, RawDiceCloud } from './types';
9
+ export declare function normalize(raw: RawDiceCloud): IRCharacter;
10
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/ir/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAGV,WAAW,EAKX,YAAY,EAEb,MAAM,SAAS,CAAC;AAsLjB,wBAAgB,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,WAAW,CA6CxD"}
@@ -0,0 +1,207 @@
1
+ const DND_ABILITIES = [
2
+ 'strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma',
3
+ ];
4
+ /**
5
+ * Best-effort system hint (never load-bearing). PF2e also uses the six abilities,
6
+ * so we additionally require D&D-5e-specific signals: a single proficiencyBonus
7
+ * variable and a class-based hit-dice attribute.
8
+ */
9
+ function detectSystem(byVar) {
10
+ const hasAbilities = DND_ABILITIES.every((ab) => byVar[ab]);
11
+ const hasProfBonus = !!byVar['proficiencyBonus'];
12
+ const hasHitDice = Object.values(byVar).some((a) => a.type === 'hitDice');
13
+ return hasAbilities && hasProfBonus && hasHitDice ? 'dnd5e' : 'generic';
14
+ }
15
+ /** Coerce a DiceCloud value (number, calculation object, or string) to a number. */
16
+ function numOf(v) {
17
+ if (v == null)
18
+ return 0;
19
+ if (typeof v === 'number')
20
+ return Number.isFinite(v) ? v : 0;
21
+ if (typeof v === 'object')
22
+ return numOf(v.value ?? v.total ?? 0);
23
+ const n = Number(v);
24
+ return Number.isFinite(n) ? n : 0;
25
+ }
26
+ /** True when a DiceCloud calculation/value is actually present (not just absent). */
27
+ function has(v) {
28
+ return v != null && !(typeof v === 'object' && v.value == null && v.total == null);
29
+ }
30
+ /** Pull display text out of a DiceCloud description ({ text } | { value } | string). */
31
+ function textOf(d) {
32
+ if (!d)
33
+ return undefined;
34
+ if (typeof d === 'string')
35
+ return d || undefined;
36
+ return d.text ?? d.value ?? undefined;
37
+ }
38
+ function resetOf(p) {
39
+ return p.reset ?? null;
40
+ }
41
+ /** Whether a property has been soft-deleted (truly gone). */
42
+ function isRemoved(p) {
43
+ return !p || p.removed === true;
44
+ }
45
+ /**
46
+ * Whether a property is currently active. Deactivated properties (e.g. an
47
+ * unprepared spell, a toggled-off feature) are still imported - we carry this
48
+ * flag so adapters can grey them out rather than dropping data.
49
+ */
50
+ function activeOf(p) {
51
+ return !p.inactive && !p.deactivatedBySelf && !p.deactivatedByAncestor;
52
+ }
53
+ function normalizeAttribute(p) {
54
+ const value = numOf(p.value);
55
+ const total = numOf(p.total);
56
+ const damage = numOf(p.damage);
57
+ const attr = {
58
+ id: p._id,
59
+ name: p.name ?? p.variableName ?? '',
60
+ variableName: p.variableName ?? '',
61
+ type: p.attributeType ?? 'stat',
62
+ value,
63
+ total,
64
+ damage,
65
+ reset: resetOf(p),
66
+ active: activeOf(p),
67
+ tags: Array.isArray(p.tags) ? p.tags : [],
68
+ description: textOf(p.description),
69
+ };
70
+ if (p.attributeType === 'ability') {
71
+ attr.modifier = has(p.modifier) ? numOf(p.modifier) : Math.floor((value - 10) / 2);
72
+ }
73
+ if (p.attributeType === 'hitDice' && p.hitDiceSize) {
74
+ attr.hitDiceSize = String(p.hitDiceSize);
75
+ }
76
+ if (p.attributeType === 'spellSlot' && has(p.spellSlotLevel)) {
77
+ attr.spellSlotLevel = numOf(p.spellSlotLevel);
78
+ }
79
+ return attr;
80
+ }
81
+ function normalizeSkill(p) {
82
+ return {
83
+ id: p._id,
84
+ name: p.name ?? p.variableName ?? '',
85
+ variableName: p.variableName ?? '',
86
+ skillType: p.skillType ?? 'skill',
87
+ value: numOf(p.value),
88
+ ability: p.ability || undefined,
89
+ proficiency: numOf(p.proficiency),
90
+ active: activeOf(p),
91
+ tags: Array.isArray(p.tags) ? p.tags : [],
92
+ };
93
+ }
94
+ function normalizeItem(p) {
95
+ return {
96
+ id: p._id,
97
+ name: p.name ?? '',
98
+ plural: p.plural || undefined,
99
+ quantity: p.quantity != null ? numOf(p.quantity) : 1,
100
+ equipped: !!p.equipped,
101
+ weight: has(p.weight) ? numOf(p.weight) : undefined,
102
+ value: has(p.value) ? numOf(p.value) : undefined,
103
+ description: textOf(p.description),
104
+ tags: Array.isArray(p.tags) ? p.tags : [],
105
+ };
106
+ }
107
+ function consumesOf(p) {
108
+ const consumed = p.resources?.attributesConsumed;
109
+ if (!Array.isArray(consumed))
110
+ return [];
111
+ return consumed.map((c) => ({
112
+ variableName: c.variableName || undefined,
113
+ propertyId: c._id || c.variableId || undefined,
114
+ amount: numOf(c.quantity ?? c.amount ?? 1),
115
+ }));
116
+ }
117
+ function normalizeAction(p, damageByParent) {
118
+ const kind = p.type === 'spell' ? 'spell' : p.type === 'feature' ? 'feature' : 'action';
119
+ const damage = (damageByParent[p._id] ?? [])
120
+ .map((d) => ({
121
+ formula: d.amount?.calculation ?? String(d.amount?.value ?? ''),
122
+ type: d.damageType || undefined,
123
+ }))
124
+ .filter((d) => d.formula);
125
+ const action = {
126
+ id: p._id,
127
+ name: p.name ?? '',
128
+ kind,
129
+ active: activeOf(p),
130
+ consumes: consumesOf(p),
131
+ damage,
132
+ tags: Array.isArray(p.tags) ? p.tags : [],
133
+ description: textOf(p.description),
134
+ };
135
+ const max = numOf(p.uses);
136
+ if (has(p.uses) && max > 0) {
137
+ const current = has(p.usesLeft) ? numOf(p.usesLeft) : Math.max(0, max - numOf(p.usesUsed));
138
+ action.uses = { current, max, reset: resetOf(p) };
139
+ }
140
+ if (has(p.attackRoll)) {
141
+ action.attack = { bonus: numOf(p.attackRoll) };
142
+ }
143
+ if (kind === 'spell') {
144
+ action.spell = {
145
+ level: numOf(p.level),
146
+ school: p.school || undefined,
147
+ castingTime: p.castingTime || undefined,
148
+ range: p.range || undefined,
149
+ duration: p.duration || undefined,
150
+ components: p.components || undefined,
151
+ concentration: p.components?.concentration ?? undefined,
152
+ ritual: p.components?.ritual ?? undefined,
153
+ };
154
+ }
155
+ return action;
156
+ }
157
+ /** Whether a property should appear in `actions` (things that do something). */
158
+ function isActionLike(p) {
159
+ if (p.type === 'action' || p.type === 'spell')
160
+ return true;
161
+ // Include only features that have a limited-use pool (e.g. Channel Divinity).
162
+ if (p.type === 'feature')
163
+ return has(p.uses) && numOf(p.uses) > 0;
164
+ return false;
165
+ }
166
+ export function normalize(raw) {
167
+ var _a;
168
+ // Accept both the REST API shape ({ creatures[], creatureProperties[] }) and the
169
+ // extension's internal shape ({ creature, properties[] }).
170
+ const creature = raw?.creatures?.[0] ?? raw?.creature ?? {};
171
+ const allProps = raw?.creatureProperties ?? raw?.properties ?? [];
172
+ const props = allProps.filter((p) => !isRemoved(p));
173
+ const attributes = props
174
+ .filter((p) => p.type === 'attribute')
175
+ .map(normalizeAttribute);
176
+ const skills = props
177
+ .filter((p) => p.type === 'skill')
178
+ .map(normalizeSkill);
179
+ // Damage is stored as child `damage` properties pointing at their action/spell.
180
+ const damageByParent = {};
181
+ for (const p of props) {
182
+ if (p.type === 'damage' && p.parent?.id) {
183
+ (damageByParent[_a = p.parent.id] ?? (damageByParent[_a] = [])).push(p);
184
+ }
185
+ }
186
+ const actions = props.filter(isActionLike).map((p) => normalizeAction(p, damageByParent));
187
+ const inventory = props
188
+ .filter((p) => p.type === 'item')
189
+ .map(normalizeItem);
190
+ const byVar = {};
191
+ for (const a of attributes) {
192
+ if (a.variableName)
193
+ byVar[a.variableName] = a;
194
+ }
195
+ return {
196
+ id: creature._id ?? '',
197
+ name: creature.name ?? '',
198
+ portrait: creature.picture || creature.avatarPicture || undefined,
199
+ systemHint: detectSystem(byVar),
200
+ attributes,
201
+ skills,
202
+ actions,
203
+ inventory,
204
+ byVar,
205
+ };
206
+ }
207
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/ir/normalize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Persistence shape for the clouds_character_ir table (see the matching SQL
3
+ * migration). The IR is already plain JSON, so this just frames the upsert row
4
+ * and stamps the schema version.
5
+ */
6
+ import type { IRCharacter, RawDiceCloud } from './types';
7
+ /** Bump when the IR shape changes in a way consumers must migrate for. */
8
+ export declare const IR_VERSION = 1;
9
+ export interface IRRow {
10
+ dicecloud_character_id: string;
11
+ character_name: string;
12
+ system_hint: string;
13
+ ir: IRCharacter;
14
+ ir_version: number;
15
+ raw?: RawDiceCloud;
16
+ }
17
+ /**
18
+ * Build the row to upsert into clouds_character_ir.
19
+ *
20
+ * supabase.from('clouds_character_ir')
21
+ * .upsert(toIRRow(normalize(raw), raw), { onConflict: 'dicecloud_character_id' })
22
+ *
23
+ * Pass `raw` to keep a re-normalizable snapshot; omit it to store IR only.
24
+ */
25
+ export declare function toIRRow(ir: IRCharacter, raw?: RawDiceCloud): IRRow;
26
+ //# sourceMappingURL=persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/ir/persistence.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzD,0EAA0E;AAC1E,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,MAAM,WAAW,KAAK;IACpB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,WAAW,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,YAAY,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,KAAK,CASlE"}
@@ -0,0 +1,21 @@
1
+ /** Bump when the IR shape changes in a way consumers must migrate for. */
2
+ export const IR_VERSION = 1;
3
+ /**
4
+ * Build the row to upsert into clouds_character_ir.
5
+ *
6
+ * supabase.from('clouds_character_ir')
7
+ * .upsert(toIRRow(normalize(raw), raw), { onConflict: 'dicecloud_character_id' })
8
+ *
9
+ * Pass `raw` to keep a re-normalizable snapshot; omit it to store IR only.
10
+ */
11
+ export function toIRRow(ir, raw) {
12
+ return {
13
+ dicecloud_character_id: ir.id,
14
+ character_name: ir.name,
15
+ system_hint: ir.systemHint,
16
+ ir,
17
+ ir_version: IR_VERSION,
18
+ ...(raw ? { raw } : {}),
19
+ };
20
+ }
21
+ //# sourceMappingURL=persistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../src/ir/persistence.ts"],"names":[],"mappings":"AAOA,0EAA0E;AAC1E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAW5B;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,EAAe,EAAE,GAAkB;IACzD,OAAO;QACL,sBAAsB,EAAE,EAAE,CAAC,EAAE;QAC7B,cAAc,EAAE,EAAE,CAAC,IAAI;QACvB,WAAW,EAAE,EAAE,CAAC,UAAU;QAC1B,EAAE;QACF,UAAU,EAAE,UAAU;QACtB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { IRCharacter, RawDiceCloud } from './types';
2
+ export interface SupabaseRestTarget {
3
+ url: string;
4
+ anonKey: string;
5
+ }
6
+ /**
7
+ * Normalize raw DiceCloud data and upsert it into clouds_character_ir.
8
+ * Returns the IR. Throws on a real upsert error; callers should treat IR sync as
9
+ * non-fatal (wrap in try/catch) so it never blocks the legacy sync.
10
+ */
11
+ export declare function upsertCharacterIR(raw: RawDiceCloud, target: SupabaseRestTarget): Promise<IRCharacter>;
12
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/ir/sync.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEzD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,WAAW,CAAC,CAsBtB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Write the system-agnostic IR to Supabase. Called from each sync path alongside
3
+ * the existing clouds_characters write, so the rebuild's data flows into its own
4
+ * table without disturbing the legacy path. See REBUILD.md.
5
+ *
6
+ * Uses the Supabase REST API via fetch so it works everywhere the extension runs
7
+ * (background service worker, content scripts, popups) regardless of whether a
8
+ * supabase-js client is in scope.
9
+ */
10
+ import { normalize } from './normalize';
11
+ import { toIRRow } from './persistence';
12
+ /**
13
+ * Normalize raw DiceCloud data and upsert it into clouds_character_ir.
14
+ * Returns the IR. Throws on a real upsert error; callers should treat IR sync as
15
+ * non-fatal (wrap in try/catch) so it never blocks the legacy sync.
16
+ */
17
+ export async function upsertCharacterIR(raw, target) {
18
+ const ir = normalize(raw);
19
+ if (!ir.id)
20
+ throw new Error('upsertCharacterIR: normalized IR has no character id');
21
+ const res = await fetch(`${target.url}/rest/v1/clouds_character_ir?on_conflict=dicecloud_character_id`, {
22
+ method: 'POST',
23
+ headers: {
24
+ apikey: target.anonKey,
25
+ Authorization: `Bearer ${target.anonKey}`,
26
+ 'Content-Type': 'application/json',
27
+ Prefer: 'resolution=merge-duplicates,return=minimal',
28
+ },
29
+ body: JSON.stringify(toIRRow(ir)),
30
+ });
31
+ if (!res.ok) {
32
+ throw new Error(`clouds_character_ir upsert failed: ${res.status} ${await res.text()}`);
33
+ }
34
+ return ir;
35
+ }
36
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/ir/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAQxC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAiB,EACjB,MAA0B;IAE1B,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,EAAE,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAEpF,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,MAAM,CAAC,GAAG,iEAAiE,EAC9E;QACE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAC,OAAO;YACtB,aAAa,EAAE,UAAU,MAAM,CAAC,OAAO,EAAE;YACzC,cAAc,EAAE,kBAAkB;YAClC,MAAM,EAAE,4CAA4C;SACrD;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;KAClC,CACF,CAAC;IAEF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}