@superbright/indexeddb-orm 0.1.8 → 1.0.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 (139) hide show
  1. package/dist/_virtual/_commonjsHelpers.cjs +2 -0
  2. package/dist/_virtual/_commonjsHelpers.cjs.map +1 -0
  3. package/dist/_virtual/_commonjsHelpers.mjs +9 -0
  4. package/dist/_virtual/_commonjsHelpers.mjs.map +1 -0
  5. package/dist/_virtual/dexie.min.cjs +2 -0
  6. package/dist/_virtual/dexie.min.cjs.map +1 -0
  7. package/dist/_virtual/dexie.min.mjs +5 -0
  8. package/dist/_virtual/dexie.min.mjs.map +1 -0
  9. package/dist/adapters/dexie.cjs +2 -0
  10. package/dist/adapters/dexie.cjs.map +1 -0
  11. package/dist/adapters/dexie.mjs +14 -0
  12. package/dist/adapters/dexie.mjs.map +1 -0
  13. package/dist/adapters/structured-store.cjs +2 -0
  14. package/dist/adapters/structured-store.cjs.map +1 -0
  15. package/dist/adapters/structured-store.mjs +50 -0
  16. package/dist/adapters/structured-store.mjs.map +1 -0
  17. package/dist/adapters/zustand-store.cjs +2 -0
  18. package/dist/adapters/zustand-store.cjs.map +1 -0
  19. package/dist/adapters/zustand-store.mjs +169 -0
  20. package/dist/adapters/zustand-store.mjs.map +1 -0
  21. package/dist/api/favorites.cjs +2 -0
  22. package/dist/api/favorites.cjs.map +1 -0
  23. package/dist/api/favorites.mjs +34 -0
  24. package/dist/api/favorites.mjs.map +1 -0
  25. package/dist/api/properties.cjs +2 -0
  26. package/dist/api/properties.cjs.map +1 -0
  27. package/dist/api/properties.mjs +197 -0
  28. package/dist/api/properties.mjs.map +1 -0
  29. package/dist/api/users.cjs +2 -0
  30. package/dist/api/users.cjs.map +1 -0
  31. package/dist/api/users.mjs +54 -0
  32. package/dist/api/users.mjs.map +1 -0
  33. package/dist/db.cjs +2 -0
  34. package/dist/db.cjs.map +1 -0
  35. package/dist/db.mjs +116 -0
  36. package/dist/db.mjs.map +1 -0
  37. package/dist/debug.cjs +2 -0
  38. package/dist/debug.cjs.map +1 -0
  39. package/dist/debug.mjs +18 -0
  40. package/dist/debug.mjs.map +1 -0
  41. package/dist/errors.cjs +2 -0
  42. package/dist/errors.cjs.map +1 -0
  43. package/dist/errors.mjs +15 -0
  44. package/dist/errors.mjs.map +1 -0
  45. package/dist/features/analytics/MixpanelProvider.cjs +2 -0
  46. package/dist/features/analytics/MixpanelProvider.cjs.map +1 -0
  47. package/dist/features/analytics/MixpanelProvider.mjs +40 -0
  48. package/dist/features/analytics/MixpanelProvider.mjs.map +1 -0
  49. package/dist/features/analytics/analytics.cjs +2 -0
  50. package/dist/features/analytics/analytics.cjs.map +1 -0
  51. package/dist/features/analytics/analytics.d.ts +520 -397
  52. package/dist/features/analytics/analytics.mjs +230 -0
  53. package/dist/features/analytics/analytics.mjs.map +1 -0
  54. package/dist/features/analytics/generateUserUUID.cjs +2 -0
  55. package/dist/features/analytics/generateUserUUID.cjs.map +1 -0
  56. package/dist/features/analytics/generateUserUUID.mjs +6 -0
  57. package/dist/features/analytics/generateUserUUID.mjs.map +1 -0
  58. package/dist/features/units/transformers.cjs +2 -0
  59. package/dist/features/units/transformers.cjs.map +1 -0
  60. package/dist/features/units/transformers.mjs +69 -0
  61. package/dist/features/units/transformers.mjs.map +1 -0
  62. package/dist/index.cjs +1 -65
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.mjs +84 -14875
  66. package/dist/index.mjs.map +1 -1
  67. package/dist/node_modules/.pnpm/dexie@4.2.0/node_modules/dexie/dist/dexie.min.cjs +4 -0
  68. package/dist/node_modules/.pnpm/dexie@4.2.0/node_modules/dexie/dist/dexie.min.cjs.map +1 -0
  69. package/dist/node_modules/.pnpm/dexie@4.2.0/node_modules/dexie/dist/dexie.min.mjs +3048 -0
  70. package/dist/node_modules/.pnpm/dexie@4.2.0/node_modules/dexie/dist/dexie.min.mjs.map +1 -0
  71. package/dist/node_modules/.pnpm/dexie@4.2.0/node_modules/dexie/import-wrapper-prod.cjs +2 -0
  72. package/dist/node_modules/.pnpm/dexie@4.2.0/node_modules/dexie/import-wrapper-prod.cjs.map +1 -0
  73. package/dist/node_modules/.pnpm/dexie@4.2.0/node_modules/dexie/import-wrapper-prod.mjs +33 -0
  74. package/dist/node_modules/.pnpm/dexie@4.2.0/node_modules/dexie/import-wrapper-prod.mjs.map +1 -0
  75. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.cjs +2 -0
  76. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.cjs.map +1 -0
  77. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.mjs +88 -0
  78. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.mjs.map +1 -0
  79. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.cjs +2 -0
  80. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.cjs.map +1 -0
  81. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.mjs +10 -0
  82. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.mjs.map +1 -0
  83. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.cjs +2 -0
  84. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.cjs.map +1 -0
  85. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.mjs +8 -0
  86. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.mjs.map +1 -0
  87. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.cjs +2 -0
  88. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.cjs.map +1 -0
  89. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.mjs +98 -0
  90. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.mjs.map +1 -0
  91. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.cjs +2 -0
  92. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.cjs.map +1 -0
  93. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.mjs +95 -0
  94. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.mjs.map +1 -0
  95. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.cjs +2 -0
  96. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.cjs.map +1 -0
  97. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.mjs +62 -0
  98. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.mjs.map +1 -0
  99. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.cjs +2 -0
  100. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.cjs.map +1 -0
  101. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.mjs +2402 -0
  102. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.mjs.map +1 -0
  103. package/dist/schema.cjs +2 -0
  104. package/dist/schema.cjs.map +1 -0
  105. package/dist/schema.d.ts +165 -0
  106. package/dist/schema.mjs +209 -0
  107. package/dist/schema.mjs.map +1 -0
  108. package/dist/storage.cjs +2 -0
  109. package/dist/storage.cjs.map +1 -0
  110. package/dist/storage.mjs +54 -0
  111. package/dist/storage.mjs.map +1 -0
  112. package/dist/stores/store.cjs +2 -0
  113. package/dist/stores/store.cjs.map +1 -0
  114. package/dist/stores/store.mjs +607 -0
  115. package/dist/stores/store.mjs.map +1 -0
  116. package/dist/units/favorites.cjs +2 -0
  117. package/dist/units/favorites.cjs.map +1 -0
  118. package/dist/units/favorites.mjs +19 -0
  119. package/dist/units/favorites.mjs.map +1 -0
  120. package/dist/utils/casing.cjs +2 -0
  121. package/dist/utils/casing.cjs.map +1 -0
  122. package/dist/utils/casing.d.ts +6 -0
  123. package/dist/utils/casing.mjs +12 -0
  124. package/dist/utils/casing.mjs.map +1 -0
  125. package/dist/utils/collections.cjs +2 -0
  126. package/dist/utils/collections.cjs.map +1 -0
  127. package/dist/utils/collections.d.ts +1 -0
  128. package/dist/utils/collections.mjs +13 -0
  129. package/dist/utils/collections.mjs.map +1 -0
  130. package/dist/utils/dimensions.cjs +2 -0
  131. package/dist/utils/dimensions.cjs.map +1 -0
  132. package/dist/utils/dimensions.d.ts +32 -0
  133. package/dist/utils/dimensions.mjs +29 -0
  134. package/dist/utils/dimensions.mjs.map +1 -0
  135. package/dist/validation.cjs +2 -0
  136. package/dist/validation.cjs.map +1 -0
  137. package/dist/validation.mjs +18 -0
  138. package/dist/validation.mjs.map +1 -0
  139. package/package.json +18 -4
@@ -0,0 +1,197 @@
1
+ import { kvGet as y, kvSet as l } from "../storage.mjs";
2
+ import { PropertyStoreDataSchema as p, UserPropertyStateSchema as S } from "../schema.mjs";
3
+ const c = {
4
+ data: {},
5
+ propertySlug: null,
6
+ propertyId: null,
7
+ hasPreviouslySearched: []
8
+ };
9
+ class f {
10
+ async getState() {
11
+ const e = await y("property");
12
+ if (!e) return c;
13
+ const t = {
14
+ ...e,
15
+ propertyId: e.propertyId == null ? null : String(e.propertyId),
16
+ propertySlug: e.propertySlug ?? null,
17
+ hasPreviouslySearched: Array.isArray(e.hasPreviouslySearched) ? e.hasPreviouslySearched.map(String) : []
18
+ }, r = p.safeParse(t);
19
+ if (r.success) return r.data;
20
+ const a = Object.entries(t.data ?? {}).reduce((i, [s, d]) => {
21
+ const u = S.safeParse(d);
22
+ return u.success && (i[s] = u.data), i;
23
+ }, {}), n = {
24
+ ...c,
25
+ ...t,
26
+ data: a
27
+ }, o = p.safeParse(n);
28
+ return o.success ? o.data : c;
29
+ }
30
+ async setState(e) {
31
+ const t = await this.getState(), r = e(t), a = p.parse(r);
32
+ await l("property", a);
33
+ }
34
+ // Basic state operations (legacy direct setters removed in vNext)
35
+ async setHasPreviouslySearched(e) {
36
+ await this.setState((t) => ({
37
+ ...t,
38
+ hasPreviouslySearched: Array.from(
39
+ /* @__PURE__ */ new Set([...t.hasPreviouslySearched, e])
40
+ )
41
+ }));
42
+ }
43
+ // Property-specific operations
44
+ async setTourContactedOn() {
45
+ await this.setState((e) => {
46
+ const t = e.propertyId;
47
+ if (!t) return e;
48
+ const r = e.data[t];
49
+ return r ? {
50
+ ...e,
51
+ data: {
52
+ ...e.data,
53
+ [t]: {
54
+ ...r,
55
+ tourContactedOn: (/* @__PURE__ */ new Date()).toISOString()
56
+ }
57
+ }
58
+ } : e;
59
+ });
60
+ }
61
+ async getTourContactedOn() {
62
+ var r;
63
+ const e = await this.getState(), t = e.propertyId;
64
+ return t ? ((r = e.data[t]) == null ? void 0 : r.tourContactedOn) ?? null : null;
65
+ }
66
+ async setQuestionnaireResults(e) {
67
+ await this.setState((t) => {
68
+ const r = t.propertyId;
69
+ if (!r) return t;
70
+ const a = t.data[r];
71
+ return a ? {
72
+ ...t,
73
+ data: {
74
+ ...t.data,
75
+ [r]: {
76
+ ...a,
77
+ questionnaireResults: e
78
+ }
79
+ }
80
+ } : t;
81
+ });
82
+ }
83
+ async setTourContactData(e) {
84
+ await this.setState((t) => {
85
+ const r = t.propertyId;
86
+ if (!r) return t;
87
+ const a = t.data[r];
88
+ return a ? {
89
+ ...t,
90
+ data: {
91
+ ...t.data,
92
+ [r]: {
93
+ ...a,
94
+ tourContactData: e
95
+ }
96
+ }
97
+ } : t;
98
+ });
99
+ }
100
+ async toggleFavorite(e) {
101
+ await this.setState((t) => {
102
+ const r = t.propertyId;
103
+ if (!r) return t;
104
+ const a = t.data[r];
105
+ if (!a) return t;
106
+ const o = a.favoritedUnits.includes(e) ? a.favoritedUnits.filter((i) => i !== e) : [...a.favoritedUnits, e];
107
+ return {
108
+ ...t,
109
+ data: {
110
+ ...t.data,
111
+ [r]: {
112
+ ...a,
113
+ favoritedUnits: o
114
+ }
115
+ }
116
+ };
117
+ });
118
+ }
119
+ async markUnitAsViewed(e, t) {
120
+ const r = /* @__PURE__ */ new Date(), a = `${String(r.getMonth() + 1).padStart(
121
+ 2,
122
+ "0"
123
+ )}/${String(r.getDate()).padStart(2, "0")}`;
124
+ await this.setState((n) => {
125
+ const o = n.propertyId;
126
+ if (!o) return n;
127
+ const i = n.data[o];
128
+ if (!i) return n;
129
+ const s = [
130
+ // Remove existing entry if it exists
131
+ ...i.viewedUnits.filter((d) => d.unitId !== e),
132
+ // Add updated one
133
+ {
134
+ unitId: e,
135
+ viewedDate: a
136
+ }
137
+ ];
138
+ return {
139
+ ...n,
140
+ data: {
141
+ ...n.data,
142
+ [o]: {
143
+ ...i,
144
+ viewedUnits: s
145
+ }
146
+ }
147
+ };
148
+ }), typeof window < "u" && window.open(`//${t}`, "_blank");
149
+ }
150
+ // Utility methods for getting specific data
151
+ async getUnitState(e) {
152
+ var a;
153
+ const t = await this.getState(), r = t.propertyId ? t.data[t.propertyId] : null;
154
+ return {
155
+ isFavorite: (r == null ? void 0 : r.favoritedUnits.includes(e)) ?? !1,
156
+ viewedDate: ((a = r == null ? void 0 : r.viewedUnits.find((n) => n.unitId === e)) == null ? void 0 : a.viewedDate) ?? ""
157
+ };
158
+ }
159
+ async getPropertyData(e) {
160
+ const t = await this.getState(), r = e == null ? t.propertyId : String(e);
161
+ return r ? t.data[r] ?? null : null;
162
+ }
163
+ async getCurrentProperty() {
164
+ const e = await this.getState();
165
+ return e.propertyId ? e.data[e.propertyId] ?? null : null;
166
+ }
167
+ async getFullState() {
168
+ return this.getState();
169
+ }
170
+ // Initialize property if it doesn't exist
171
+ async initializeProperty(e, t) {
172
+ const r = String(e);
173
+ await this.setState((a) => a.data[r] ? { ...a, propertyId: r, propertySlug: t } : {
174
+ ...a,
175
+ propertyId: r,
176
+ propertySlug: t,
177
+ data: {
178
+ ...a.data,
179
+ [r]: {
180
+ id: r,
181
+ slug: t,
182
+ favoritedUnits: [],
183
+ tourContactedOn: null,
184
+ viewedUnits: [],
185
+ questionnaireResults: null,
186
+ tourContactData: null
187
+ }
188
+ }
189
+ });
190
+ }
191
+ }
192
+ const g = new f();
193
+ export {
194
+ f as PropertyStore,
195
+ g as propertyStore
196
+ };
197
+ //# sourceMappingURL=properties.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"properties.mjs","sources":["../../src/api/properties.ts"],"sourcesContent":["import { kvGet, kvSet } from \"../storage\";\nimport {\n ViewedUnitSchema,\n TourContactDataSchema,\n UserPropertyStateSchema,\n PropertyStoreDataSchema,\n type ViewedUnit,\n type TourContactData,\n type UserPropertyState,\n type PropertyStoreData,\n} from \"../schema\";\n\n// Re-export types for legacy import paths\nexport type { ViewedUnit, TourContactData, UserPropertyState, PropertyStoreData } from \"../schema\";\n\n// Default state\nconst defaultPropertyStoreData: PropertyStoreData = {\n data: {},\n propertySlug: null,\n propertyId: null,\n hasPreviouslySearched: [],\n};\n\n// Core property store API\nexport class PropertyStore {\n private async getState(): Promise<PropertyStoreData> {\n const state = await kvGet<PropertyStoreData>(\"property\");\n if (!state) return defaultPropertyStoreData;\n\n const normalized = {\n ...state,\n propertyId: state.propertyId == null ? null : String(state.propertyId),\n propertySlug: state.propertySlug ?? null,\n hasPreviouslySearched: Array.isArray(state.hasPreviouslySearched)\n ? state.hasPreviouslySearched.map(String)\n : [],\n };\n\n const parsed = PropertyStoreDataSchema.safeParse(normalized);\n if (parsed.success) return parsed.data;\n\n const sanitizedData = Object.entries(normalized.data ?? {}).reduce<\n Record<string, UserPropertyState>\n >((acc, [key, value]) => {\n const entry = UserPropertyStateSchema.safeParse(value);\n if (entry.success) acc[key] = entry.data;\n return acc;\n }, {});\n\n const fallbackState = {\n ...defaultPropertyStoreData,\n ...normalized,\n data: sanitizedData,\n };\n\n const fallbackParsed = PropertyStoreDataSchema.safeParse(fallbackState);\n return fallbackParsed.success ? fallbackParsed.data : defaultPropertyStoreData;\n }\n\n private async setState(updater: (state: PropertyStoreData) => PropertyStoreData): Promise<void> {\n const currentState = await this.getState();\n const newState = updater(currentState);\n const validatedState = PropertyStoreDataSchema.parse(newState);\n await kvSet(\"property\", validatedState);\n }\n\n // Basic state operations (legacy direct setters removed in vNext)\n\n async setHasPreviouslySearched(slug: string): Promise<void> {\n await this.setState(state => ({\n ...state,\n hasPreviouslySearched: Array.from(\n new Set([...state.hasPreviouslySearched, slug])\n ),\n }));\n }\n\n // Property-specific operations\n async setTourContactedOn(): Promise<void> {\n await this.setState(state => {\n const propertyId = state.propertyId;\n if (!propertyId) return state;\n\n const property = state.data[propertyId];\n if (!property) return state;\n\n return {\n ...state,\n data: {\n ...state.data,\n [propertyId]: {\n ...property,\n tourContactedOn: new Date().toISOString(),\n },\n },\n };\n });\n }\n\n async getTourContactedOn(): Promise<string | null> {\n const state = await this.getState();\n const propertyId = state.propertyId;\n if (!propertyId) return null;\n\n return state.data[propertyId]?.tourContactedOn ?? null;\n }\n\n async setQuestionnaireResults(results: unknown): Promise<void> {\n await this.setState(state => {\n const propertyId = state.propertyId;\n if (!propertyId) return state;\n\n const property = state.data[propertyId];\n if (!property) return state;\n\n return {\n ...state,\n data: {\n ...state.data,\n [propertyId]: {\n ...property,\n questionnaireResults: results,\n },\n },\n };\n });\n }\n\n async setTourContactData(data: TourContactData): Promise<void> {\n await this.setState(state => {\n const propertyId = state.propertyId;\n if (!propertyId) return state;\n\n const property = state.data[propertyId];\n if (!property) return state;\n\n return {\n ...state,\n data: {\n ...state.data,\n [propertyId]: {\n ...property,\n tourContactData: data,\n },\n },\n };\n });\n }\n\n async toggleFavorite(unitId: string): Promise<void> {\n await this.setState(state => {\n const propertyId = state.propertyId;\n if (!propertyId) return state;\n\n const property = state.data[propertyId];\n if (!property) return state;\n\n const isFavorited = property.favoritedUnits.includes(unitId);\n const updatedFavoritedUnits = isFavorited\n ? property.favoritedUnits.filter((id) => id !== unitId)\n : [...property.favoritedUnits, unitId];\n\n return {\n ...state,\n data: {\n ...state.data,\n [propertyId]: {\n ...property,\n favoritedUnits: updatedFavoritedUnits,\n },\n },\n };\n });\n }\n\n async markUnitAsViewed(unitId: string, slug: string): Promise<void> {\n const today = new Date();\n const formattedDate = `${String(today.getMonth() + 1).padStart(\n 2,\n \"0\"\n )}/${String(today.getDate()).padStart(2, \"0\")}`;\n\n await this.setState(state => {\n const propertyId = state.propertyId;\n if (!propertyId) return state;\n\n const property = state.data[propertyId];\n if (!property) return state;\n\n const updatedViewedUnits = [\n // Remove existing entry if it exists\n ...property.viewedUnits.filter((u) => u.unitId !== unitId),\n // Add updated one\n {\n unitId,\n viewedDate: formattedDate,\n },\n ];\n\n return {\n ...state,\n data: {\n ...state.data,\n [propertyId]: {\n ...property,\n viewedUnits: updatedViewedUnits,\n },\n },\n };\n });\n\n // Note: This opens a new window - you might want to handle this in the consuming app\n if (typeof window !== 'undefined') {\n window.open(`//${slug}`, \"_blank\");\n }\n }\n\n // Utility methods for getting specific data\n async getUnitState(unitId: string): Promise<{\n isFavorite: boolean;\n viewedDate: string;\n }> {\n const state = await this.getState();\n const property = state.propertyId ? state.data[state.propertyId] : null;\n\n return {\n isFavorite: property?.favoritedUnits.includes(unitId) ?? false,\n viewedDate:\n property?.viewedUnits.find((u) => u.unitId === unitId)?.viewedDate ?? \"\",\n };\n }\n\n async getPropertyData(propertyId?: string | number): Promise<UserPropertyState | null> {\n const state = await this.getState();\n const id = propertyId == null ? state.propertyId : String(propertyId);\n return id ? state.data[id] ?? null : null;\n }\n\n async getCurrentProperty(): Promise<UserPropertyState | null> {\n const state = await this.getState();\n return state.propertyId ? state.data[state.propertyId] ?? null : null;\n }\n\n async getFullState(): Promise<PropertyStoreData> {\n return this.getState();\n }\n\n // Initialize property if it doesn't exist\n async initializeProperty(propertyId: string | number, slug: string): Promise<void> {\n const id = String(propertyId);\n await this.setState(state => {\n if (state.data[id]) {\n return { ...state, propertyId: id, propertySlug: slug };\n }\n\n return {\n ...state,\n propertyId: id,\n propertySlug: slug,\n data: {\n ...state.data,\n [id]: {\n id,\n slug,\n favoritedUnits: [],\n tourContactedOn: null,\n viewedUnits: [],\n questionnaireResults: null,\n tourContactData: null,\n },\n },\n };\n });\n }\n}\n\n// Export singleton instance\nexport const propertyStore = new PropertyStore();\n"],"names":["defaultPropertyStoreData","PropertyStore","state","kvGet","normalized","parsed","PropertyStoreDataSchema","sanitizedData","acc","key","value","entry","UserPropertyStateSchema","fallbackState","fallbackParsed","updater","currentState","newState","validatedState","kvSet","slug","propertyId","property","_a","results","data","unitId","updatedFavoritedUnits","id","today","formattedDate","updatedViewedUnits","u","propertyStore"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("../db.cjs"),i=require("../schema.cjs"),u="user",d=()=>{var a;return typeof((a=globalThis.crypto)==null?void 0:a.randomUUID)=="function"?globalThis.crypto.randomUUID():(()=>{var t,r;const e=((r=(t=globalThis.crypto)==null?void 0:t.getRandomValues)==null?void 0:r.call(t,new Uint8Array(16)))??Uint8Array.from({length:16},()=>Math.random()*256|0);e[6]=e[6]&15|64,e[8]=e[8]&63|128;const s=[...e].map(n=>n.toString(16).padStart(2,"0")).join("");return`${s.slice(0,8)}-${s.slice(8,12)}-${s.slice(12,16)}-${s.slice(16,20)}-${s.slice(20)}`})()},c=a=>{var e,s;return((e=a==null?void 0:a.value)==null?void 0:e.useruuid)??((s=a==null?void 0:a.value)==null?void 0:s.uuid)};async function U(a=d){const e=await g.getDB(),s=c(await e.kv.get(u));if(s){const t=await e.users.get(s);if(t)return i.UserSchema.parse(t)}try{return await e.transaction("rw",e.kv,e.users,async()=>{const t=c(await e.kv.get(u));if(t){const o=await e.users.get(t);if(o)return i.UserSchema.parse(o)}const r=a();await e.kv.add({key:u,value:{useruuid:r}});const n=i.UserSchema.parse({uuid:r,createdAt:new Date().toISOString()});return await e.users.add(n),n})}catch(t){if((t==null?void 0:t.name)==="ConstraintError"){const r=c(await e.kv.get(u));if(r){const n=await e.users.get(r);if(n)return i.UserSchema.parse(n)}}throw t}}const l=async a=>(await U(a)).uuid;exports.defaultIdGenerator=d;exports.ensureUser=U;exports.getUserUUID=l;
2
+ //# sourceMappingURL=users.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.cjs","sources":["../../src/api/users.ts"],"sourcesContent":["import { getDB } from \"../db\";\nimport { UserSchema, type User } from \"../schema\";\n\nconst USER_POINTER_KEY = \"user\";\n\nexport type IdGenerator = () => string;\nexport const defaultIdGenerator: IdGenerator = () =>\n typeof globalThis.crypto?.randomUUID === \"function\"\n ? globalThis.crypto.randomUUID()\n : (() => {\n const b =\n globalThis.crypto?.getRandomValues?.(new Uint8Array(16)) ??\n Uint8Array.from({ length: 16 }, () => (Math.random() * 256) | 0);\n b[6] = (b[6] & 0x0f) | 0x40; // v4\n b[8] = (b[8] & 0x3f) | 0x80; // variant\n const h = [...b].map((x) => x.toString(16).padStart(2, \"0\")).join(\"\");\n return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;\n })();\n\nconst getPointerUuid = (row: any) => row?.value?.useruuid ?? row?.value?.uuid;\n\nexport async function ensureUser(\n gen: IdGenerator = defaultIdGenerator,\n): Promise<User> {\n const db = await getDB();\n\n // Fast path\n const ptrUuid = getPointerUuid(await db.kv.get(USER_POINTER_KEY));\n if (ptrUuid) {\n const existing = await db.users.get(ptrUuid);\n if (existing) return UserSchema.parse(existing);\n }\n\n // Race-safe creation\n try {\n return await db.transaction(\"rw\", db.kv, db.users, async () => {\n const insideUuid = getPointerUuid(await db.kv.get(USER_POINTER_KEY));\n if (insideUuid) {\n const existing = await db.users.get(insideUuid);\n if (existing) return UserSchema.parse(existing);\n }\n\n const uuid = gen();\n await db.kv.add({ key: USER_POINTER_KEY, value: { useruuid: uuid } }); // claim pointer\n const newUser: User = UserSchema.parse({\n uuid,\n createdAt: new Date().toISOString(),\n });\n await db.users.add(newUser);\n return newUser;\n });\n } catch (e: any) {\n if (e?.name === \"ConstraintError\") {\n // Lost the race → read winner\n const uuid = getPointerUuid(await db.kv.get(USER_POINTER_KEY));\n if (uuid) {\n const winner = await db.users.get(uuid);\n if (winner) return UserSchema.parse(winner);\n }\n }\n throw e;\n }\n}\n\nexport const getUserUUID = async (gen?: IdGenerator) =>\n (await ensureUser(gen)).uuid;\n"],"names":["USER_POINTER_KEY","defaultIdGenerator","_a","b","_b","h","x","getPointerUuid","row","ensureUser","gen","db","getDB","ptrUuid","existing","UserSchema","insideUuid","uuid","newUser","e","winner","getUserUUID"],"mappings":"wIAGMA,EAAmB,OAGZC,EAAkC,IAAA,OAC7C,eAAOC,EAAA,WAAW,SAAX,YAAAA,EAAmB,aAAe,WACrC,WAAW,OAAO,WAAA,GACjB,IAAM,SACL,MAAMC,IACJC,GAAAF,EAAA,WAAW,SAAX,YAAAA,EAAmB,kBAAnB,YAAAE,EAAA,KAAAF,EAAqC,IAAI,WAAW,EAAE,KACtD,WAAW,KAAK,CAAE,OAAQ,IAAM,IAAO,KAAK,OAAA,EAAW,IAAO,CAAC,EACjEC,EAAE,CAAC,EAAKA,EAAE,CAAC,EAAI,GAAQ,GACvBA,EAAE,CAAC,EAAKA,EAAE,CAAC,EAAI,GAAQ,IACvB,MAAME,EAAI,CAAC,GAAGF,CAAC,EAAE,IAAKG,GAAMA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAAE,KAAK,EAAE,EACpE,MAAO,GAAGD,EAAE,MAAM,EAAG,CAAC,CAAC,IAAIA,EAAE,MAAM,EAAG,EAAE,CAAC,IAAIA,EAAE,MAAM,GAAI,EAAE,CAAC,IAAIA,EAAE,MAAM,GAAI,EAAE,CAAC,IAAIA,EAAE,MAAM,EAAE,CAAC,EAChG,GAAA,GAEAE,EAAkBC,YAAa,QAAAN,EAAAM,GAAA,YAAAA,EAAK,QAAL,YAAAN,EAAY,aAAYE,EAAAI,GAAA,YAAAA,EAAK,QAAL,YAAAJ,EAAY,OAEzE,eAAsBK,EACpBC,EAAmBT,EACJ,CACf,MAAMU,EAAK,MAAMC,QAAA,EAGXC,EAAUN,EAAe,MAAMI,EAAG,GAAG,IAAIX,CAAgB,CAAC,EAChE,GAAIa,EAAS,CACX,MAAMC,EAAW,MAAMH,EAAG,MAAM,IAAIE,CAAO,EAC3C,GAAIC,EAAU,OAAOC,aAAW,MAAMD,CAAQ,CAChD,CAGA,GAAI,CACF,OAAO,MAAMH,EAAG,YAAY,KAAMA,EAAG,GAAIA,EAAG,MAAO,SAAY,CAC7D,MAAMK,EAAaT,EAAe,MAAMI,EAAG,GAAG,IAAIX,CAAgB,CAAC,EACnE,GAAIgB,EAAY,CACd,MAAMF,EAAW,MAAMH,EAAG,MAAM,IAAIK,CAAU,EAC9C,GAAIF,EAAU,OAAOC,aAAW,MAAMD,CAAQ,CAChD,CAEA,MAAMG,EAAOP,EAAA,EACb,MAAMC,EAAG,GAAG,IAAI,CAAE,IAAKX,EAAkB,MAAO,CAAE,SAAUiB,CAAA,EAAQ,EACpE,MAAMC,EAAgBH,EAAAA,WAAW,MAAM,CACrC,KAAAE,EACA,UAAW,IAAI,KAAA,EAAO,YAAA,CAAY,CACnC,EACD,aAAMN,EAAG,MAAM,IAAIO,CAAO,EACnBA,CACT,CAAC,CACH,OAASC,EAAQ,CACf,IAAIA,GAAA,YAAAA,EAAG,QAAS,kBAAmB,CAEjC,MAAMF,EAAOV,EAAe,MAAMI,EAAG,GAAG,IAAIX,CAAgB,CAAC,EAC7D,GAAIiB,EAAM,CACR,MAAMG,EAAS,MAAMT,EAAG,MAAM,IAAIM,CAAI,EACtC,GAAIG,EAAQ,OAAOL,aAAW,MAAMK,CAAM,CAC5C,CACF,CACA,MAAMD,CACR,CACF,CAEO,MAAME,EAAc,MAAOX,IAC/B,MAAMD,EAAWC,CAAG,GAAG"}
@@ -0,0 +1,54 @@
1
+ import { getDB as d } from "../db.mjs";
2
+ import { UserSchema as r } from "../schema.mjs";
3
+ const u = "user", g = () => {
4
+ var a;
5
+ return typeof ((a = globalThis.crypto) == null ? void 0 : a.randomUUID) == "function" ? globalThis.crypto.randomUUID() : (() => {
6
+ var e, n;
7
+ const t = ((n = (e = globalThis.crypto) == null ? void 0 : e.getRandomValues) == null ? void 0 : n.call(e, new Uint8Array(16))) ?? Uint8Array.from({ length: 16 }, () => Math.random() * 256 | 0);
8
+ t[6] = t[6] & 15 | 64, t[8] = t[8] & 63 | 128;
9
+ const i = [...t].map((s) => s.toString(16).padStart(2, "0")).join("");
10
+ return `${i.slice(0, 8)}-${i.slice(8, 12)}-${i.slice(12, 16)}-${i.slice(16, 20)}-${i.slice(20)}`;
11
+ })();
12
+ }, o = (a) => {
13
+ var t, i;
14
+ return ((t = a == null ? void 0 : a.value) == null ? void 0 : t.useruuid) ?? ((i = a == null ? void 0 : a.value) == null ? void 0 : i.uuid);
15
+ };
16
+ async function l(a = g) {
17
+ const t = await d(), i = o(await t.kv.get(u));
18
+ if (i) {
19
+ const e = await t.users.get(i);
20
+ if (e) return r.parse(e);
21
+ }
22
+ try {
23
+ return await t.transaction("rw", t.kv, t.users, async () => {
24
+ const e = o(await t.kv.get(u));
25
+ if (e) {
26
+ const c = await t.users.get(e);
27
+ if (c) return r.parse(c);
28
+ }
29
+ const n = a();
30
+ await t.kv.add({ key: u, value: { useruuid: n } });
31
+ const s = r.parse({
32
+ uuid: n,
33
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
34
+ });
35
+ return await t.users.add(s), s;
36
+ });
37
+ } catch (e) {
38
+ if ((e == null ? void 0 : e.name) === "ConstraintError") {
39
+ const n = o(await t.kv.get(u));
40
+ if (n) {
41
+ const s = await t.users.get(n);
42
+ if (s) return r.parse(s);
43
+ }
44
+ }
45
+ throw e;
46
+ }
47
+ }
48
+ const p = async (a) => (await l(a)).uuid;
49
+ export {
50
+ g as defaultIdGenerator,
51
+ l as ensureUser,
52
+ p as getUserUUID
53
+ };
54
+ //# sourceMappingURL=users.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.mjs","sources":["../../src/api/users.ts"],"sourcesContent":["import { getDB } from \"../db\";\nimport { UserSchema, type User } from \"../schema\";\n\nconst USER_POINTER_KEY = \"user\";\n\nexport type IdGenerator = () => string;\nexport const defaultIdGenerator: IdGenerator = () =>\n typeof globalThis.crypto?.randomUUID === \"function\"\n ? globalThis.crypto.randomUUID()\n : (() => {\n const b =\n globalThis.crypto?.getRandomValues?.(new Uint8Array(16)) ??\n Uint8Array.from({ length: 16 }, () => (Math.random() * 256) | 0);\n b[6] = (b[6] & 0x0f) | 0x40; // v4\n b[8] = (b[8] & 0x3f) | 0x80; // variant\n const h = [...b].map((x) => x.toString(16).padStart(2, \"0\")).join(\"\");\n return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;\n })();\n\nconst getPointerUuid = (row: any) => row?.value?.useruuid ?? row?.value?.uuid;\n\nexport async function ensureUser(\n gen: IdGenerator = defaultIdGenerator,\n): Promise<User> {\n const db = await getDB();\n\n // Fast path\n const ptrUuid = getPointerUuid(await db.kv.get(USER_POINTER_KEY));\n if (ptrUuid) {\n const existing = await db.users.get(ptrUuid);\n if (existing) return UserSchema.parse(existing);\n }\n\n // Race-safe creation\n try {\n return await db.transaction(\"rw\", db.kv, db.users, async () => {\n const insideUuid = getPointerUuid(await db.kv.get(USER_POINTER_KEY));\n if (insideUuid) {\n const existing = await db.users.get(insideUuid);\n if (existing) return UserSchema.parse(existing);\n }\n\n const uuid = gen();\n await db.kv.add({ key: USER_POINTER_KEY, value: { useruuid: uuid } }); // claim pointer\n const newUser: User = UserSchema.parse({\n uuid,\n createdAt: new Date().toISOString(),\n });\n await db.users.add(newUser);\n return newUser;\n });\n } catch (e: any) {\n if (e?.name === \"ConstraintError\") {\n // Lost the race → read winner\n const uuid = getPointerUuid(await db.kv.get(USER_POINTER_KEY));\n if (uuid) {\n const winner = await db.users.get(uuid);\n if (winner) return UserSchema.parse(winner);\n }\n }\n throw e;\n }\n}\n\nexport const getUserUUID = async (gen?: IdGenerator) =>\n (await ensureUser(gen)).uuid;\n"],"names":["USER_POINTER_KEY","defaultIdGenerator","_a","b","_b","h","x","getPointerUuid","row","ensureUser","gen","db","getDB","ptrUuid","existing","UserSchema","insideUuid","uuid","newUser","winner","getUserUUID"],"mappings":";;AAGA,MAAMA,IAAmB,QAGZC,IAAkC,MAAA;;AAC7C,kBAAOC,IAAA,WAAW,WAAX,gBAAAA,EAAmB,eAAe,aACrC,WAAW,OAAO,WAAA,KACjB,MAAM;;AACL,UAAMC,MACJC,KAAAF,IAAA,WAAW,WAAX,gBAAAA,EAAmB,oBAAnB,gBAAAE,EAAA,KAAAF,GAAqC,IAAI,WAAW,EAAE,OACtD,WAAW,KAAK,EAAE,QAAQ,MAAM,MAAO,KAAK,OAAA,IAAW,MAAO,CAAC;AACjE,IAAAC,EAAE,CAAC,IAAKA,EAAE,CAAC,IAAI,KAAQ,IACvBA,EAAE,CAAC,IAAKA,EAAE,CAAC,IAAI,KAAQ;AACvB,UAAME,IAAI,CAAC,GAAGF,CAAC,EAAE,IAAI,CAACG,MAAMA,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACpE,WAAO,GAAGD,EAAE,MAAM,GAAG,CAAC,CAAC,IAAIA,EAAE,MAAM,GAAG,EAAE,CAAC,IAAIA,EAAE,MAAM,IAAI,EAAE,CAAC,IAAIA,EAAE,MAAM,IAAI,EAAE,CAAC,IAAIA,EAAE,MAAM,EAAE,CAAC;AAAA,EAChG,GAAA;AAAA,GAEAE,IAAiB,CAACC;;AAAa,WAAAN,IAAAM,KAAA,gBAAAA,EAAK,UAAL,gBAAAN,EAAY,eAAYE,IAAAI,KAAA,gBAAAA,EAAK,UAAL,gBAAAJ,EAAY;AAAA;AAEzE,eAAsBK,EACpBC,IAAmBT,GACJ;AACf,QAAMU,IAAK,MAAMC,EAAA,GAGXC,IAAUN,EAAe,MAAMI,EAAG,GAAG,IAAIX,CAAgB,CAAC;AAChE,MAAIa,GAAS;AACX,UAAMC,IAAW,MAAMH,EAAG,MAAM,IAAIE,CAAO;AAC3C,QAAIC,EAAU,QAAOC,EAAW,MAAMD,CAAQ;AAAA,EAChD;AAGA,MAAI;AACF,WAAO,MAAMH,EAAG,YAAY,MAAMA,EAAG,IAAIA,EAAG,OAAO,YAAY;AAC7D,YAAMK,IAAaT,EAAe,MAAMI,EAAG,GAAG,IAAIX,CAAgB,CAAC;AACnE,UAAIgB,GAAY;AACd,cAAMF,IAAW,MAAMH,EAAG,MAAM,IAAIK,CAAU;AAC9C,YAAIF,EAAU,QAAOC,EAAW,MAAMD,CAAQ;AAAA,MAChD;AAEA,YAAMG,IAAOP,EAAA;AACb,YAAMC,EAAG,GAAG,IAAI,EAAE,KAAKX,GAAkB,OAAO,EAAE,UAAUiB,EAAA,GAAQ;AACpE,YAAMC,IAAgBH,EAAW,MAAM;AAAA,QACrC,MAAAE;AAAA,QACA,YAAW,oBAAI,KAAA,GAAO,YAAA;AAAA,MAAY,CACnC;AACD,mBAAMN,EAAG,MAAM,IAAIO,CAAO,GACnBA;AAAA,IACT,CAAC;AAAA,EACH,SAAS,GAAQ;AACf,SAAI,uBAAG,UAAS,mBAAmB;AAEjC,YAAMD,IAAOV,EAAe,MAAMI,EAAG,GAAG,IAAIX,CAAgB,CAAC;AAC7D,UAAIiB,GAAM;AACR,cAAME,IAAS,MAAMR,EAAG,MAAM,IAAIM,CAAI;AACtC,YAAIE,EAAQ,QAAOJ,EAAW,MAAMI,CAAM;AAAA,MAC5C;AAAA,IACF;AACA,UAAM;AAAA,EACR;AACF;AAEO,MAAMC,IAAc,OAAOV,OAC/B,MAAMD,EAAWC,CAAG,GAAG;"}
package/dist/db.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("./adapters/dexie.cjs"),D=require("./errors.cjs"),m=require("./schema.cjs"),v=require("./validation.cjs"),_=require("./node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.cjs");var k=typeof document<"u"?document.currentScript:null;const E={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1},w="manifest",b=_.object({schemaVersion:_.number().int()});let o=null,f=null;const g=Symbol("validationInstalled");function R(e,a){const l=e;if(l[g])return;if(l[g]=!0,((d,c,n)=>{d.hook("creating",(t,u)=>{const i=v.validate(c,u,`${n}.creating`);if(!i)throw new Error(`Rejected invalid ${n} on create`);return i}),d.hook("updating",(t,u,i)=>{const r={...i,...t};return v.validate(c,r,`${n}.updating`)?t:{}})})(e.users,m.UserSchema,"users"),(a==null?void 0:a.validateReads)??!0){const d=(a==null?void 0:a.dropInvalidOnRead)??!0;((n,t,u)=>{n.hook("reading",i=>{const r=v.validate(t,i,`${u}.reading`);return r||(d?void 0:i)})})(e.users,m.UserSchema,"users")}}function I(){try{if(typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:k&&k.tagName.toUpperCase()==="SCRIPT"&&k.src||new URL("db.cjs",document.baseURI).href}<"u"&&E)return!1}catch{}try{if(typeof process<"u"&&process.env)return process.env.NODE_ENV!=="production"}catch{}return!1}async function V(e={}){if(o)return o;if(f)return f;const a=e.dbName??"inresi-orm";return f=(async()=>{var l,h,y,d;try{const c=I()?"warn":"strict";v.configureValidation({mode:((l=e.validation)==null?void 0:l.mode)??c,onIssue:(h=e.validation)==null?void 0:h.onIssue});const n=new S.OrmDexie(a);n.on("versionchange",()=>{var r;try{n.close()}finally{(r=e.onReset)==null||r.call(e,"versionchange")}}),n.on("blocked",()=>{var r;(r=e.onReset)==null||r.call(e,"blocked")}),await n.open();const t=await n.kv.get(w),u=(t==null?void 0:t.value)??null;if(!u)return await n.transaction("rw",n.kv,async()=>{await n.kv.put({key:w,value:{schemaVersion:m.SCHEMA_VERSION}})}),R(n,e.validation),o=n,n;const i=b.safeParse(u);if(!i.success||i.data.schemaVersion!==m.SCHEMA_VERSION){await n.delete();const r=new S.OrmDexie(a);return r.on("versionchange",()=>{var s;try{r.close()}finally{(s=e.onReset)==null||s.call(e,"versionchange")}}),r.on("blocked",()=>{var s;(s=e.onReset)==null||s.call(e,"blocked")}),await r.open(),await r.kv.put({key:w,value:{schemaVersion:m.SCHEMA_VERSION}}),R(r,e.validation),(y=e.onReset)==null||y.call(e,"incompatible"),o=r,r}return R(n,e.validation),o=n,n}catch(c){throw(d=e.onError)==null||d.call(e,c),new D.OpenDBError("Failed to open IndexedDB",c)}finally{f=null}})(),f}async function O(e){const a=e??"inresi-orm";if(o)try{await o.close()}catch{}await new S.OrmDexie(a).delete(),o=null}exports.getDB=V;exports.resetDB=O;
2
+ //# sourceMappingURL=db.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.cjs","sources":["../src/db.ts"],"sourcesContent":["// src/db.ts\nimport { OrmDexie } from \"./adapters/dexie\";\nimport { OpenDBError } from \"./errors\";\nimport { SCHEMA_VERSION, UserSchema } from \"./schema\";\nimport {\n validate,\n configureValidation,\n type ValidationMode,\n} from \"./validation\";\nimport type { Table } from \"dexie\";\nimport { z } from \"zod\";\n\nconst MANIFEST_KEY = \"manifest\";\nconst ManifestSchema = z.object({ schemaVersion: z.number().int() });\ntype Manifest = z.infer<typeof ManifestSchema>;\n\nexport type OrmOptions = {\n dbName?: string;\n onReset?: (reason: \"incompatible\" | \"versionchange\" | \"blocked\") => void;\n onError?: (err: unknown) => void;\n validation?: {\n mode?: ValidationMode; // 'strict' | 'warn' | 'silent'\n onIssue?: (ctx: string, details: unknown) => void;\n validateReads?: boolean; // default: true\n dropInvalidOnRead?: boolean; // default: true (when validateReads)\n };\n};\n\nlet db: OrmDexie | null = null;\nlet openPromise: Promise<OrmDexie> | null = null;\n\n// Prevent double-installing hooks on the same instance\nconst VALIDATION_INSTALLED = Symbol(\"validationInstalled\");\n\nfunction installValidationHooks(\n instance: OrmDexie,\n vopts: OrmOptions[\"validation\"] | undefined,\n) {\n const anyDb = instance as any;\n if (anyDb[VALIDATION_INSTALLED]) return;\n anyDb[VALIDATION_INSTALLED] = true;\n\n const writeHook = <T>(table: Table<T, any>, schema: any, name: string) => {\n table.hook(\"creating\", (_pk, obj) => {\n const v = validate(schema, obj, `${name}.creating`);\n if (!v) throw new Error(`Rejected invalid ${name} on create`);\n return v as T; // allow coercion/stripping\n });\n table.hook(\"updating\", (mods, _pk, obj) => {\n const next = { ...(obj as any), ...(mods as any) };\n const v = validate(schema, next, `${name}.updating`);\n if (!v) return {}; // cancel update in warn/silent\n return mods;\n });\n };\n\n writeHook(instance.users, UserSchema, \"users\");\n\n const shouldValidateReads = vopts?.validateReads ?? true;\n if (shouldValidateReads) {\n const dropInvalid = vopts?.dropInvalidOnRead ?? true;\n const readHook = <T>(table: Table<T, any>, schema: any, name: string) => {\n table.hook(\"reading\", (obj) => {\n const v = validate(schema, obj, `${name}.reading`);\n if (v) return v;\n return dropInvalid ? undefined : obj; // pass-through if you prefer\n });\n };\n readHook(instance.users, UserSchema, \"users\");\n }\n}\n\nfunction isProbablyDev(): boolean {\n try {\n // @ts-ignore\n if (typeof import.meta !== \"undefined\" && import.meta.env)\n // @ts-ignore\n return !!import.meta.env.DEV;\n } catch {}\n try {\n if (typeof process !== \"undefined\" && process.env)\n return process.env.NODE_ENV !== \"production\";\n } catch {}\n return false;\n}\n\nexport async function getDB(opts: OrmOptions = {}): Promise<OrmDexie> {\n if (db) return db;\n if (openPromise) return openPromise;\n\n const name = opts.dbName ?? \"inresi-orm\";\n\n openPromise = (async () => {\n try {\n // Configure validation once per open\n const defaultMode: ValidationMode = isProbablyDev() ? \"warn\" : \"strict\";\n configureValidation({\n mode: opts.validation?.mode ?? defaultMode,\n onIssue: opts.validation?.onIssue,\n });\n\n const instance = new OrmDexie(name);\n\n // Multi-tab friendliness\n instance.on(\"versionchange\", () => {\n try {\n instance.close();\n } finally {\n opts.onReset?.(\"versionchange\");\n }\n });\n instance.on(\"blocked\", () => {\n opts.onReset?.(\"blocked\");\n });\n\n await instance.open();\n\n // Validate/initialize manifest\n const row = await instance.kv.get(MANIFEST_KEY);\n const saved = (row?.value ?? null) as unknown;\n\n if (!saved) {\n await instance.transaction(\"rw\", instance.kv, async () => {\n await instance.kv.put({\n key: MANIFEST_KEY,\n value: { schemaVersion: SCHEMA_VERSION },\n });\n });\n installValidationHooks(instance, opts.validation);\n db = instance;\n return instance;\n }\n\n const parsed = ManifestSchema.safeParse(saved as Manifest);\n if (!parsed.success || parsed.data.schemaVersion !== SCHEMA_VERSION) {\n await instance.delete();\n const fresh = new OrmDexie(name);\n fresh.on(\"versionchange\", () => {\n try {\n fresh.close();\n } finally {\n opts.onReset?.(\"versionchange\");\n }\n });\n fresh.on(\"blocked\", () => {\n opts.onReset?.(\"blocked\");\n });\n await fresh.open();\n await fresh.kv.put({\n key: MANIFEST_KEY,\n value: { schemaVersion: SCHEMA_VERSION },\n });\n installValidationHooks(fresh, opts.validation);\n opts.onReset?.(\"incompatible\");\n db = fresh;\n return fresh;\n }\n\n installValidationHooks(instance, opts.validation);\n db = instance;\n return instance;\n } catch (e) {\n opts.onError?.(e);\n throw new OpenDBError(\"Failed to open IndexedDB\", e);\n } finally {\n openPromise = null; // allow future reuse/retry\n }\n })();\n\n return openPromise;\n}\n\nexport async function resetDB(dbName?: string) {\n const name = dbName ?? \"inresi-orm\";\n if (db) {\n try {\n await db.close();\n } catch {\n /* ignore */\n }\n }\n const instance = new OrmDexie(name);\n await instance.delete();\n db = null;\n}\n"],"names":["MANIFEST_KEY","ManifestSchema","z.object","z.number","db","openPromise","VALIDATION_INSTALLED","installValidationHooks","instance","vopts","anyDb","table","schema","name","_pk","obj","v","validate","mods","next","UserSchema","dropInvalid","isProbablyDev","_documentCurrentScript","__vite_import_meta_env__","getDB","opts","defaultMode","configureValidation","_a","_b","OrmDexie","row","saved","SCHEMA_VERSION","parsed","fresh","_c","e","_d","OpenDBError","resetDB","dbName"],"mappings":"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"}
package/dist/db.mjs ADDED
@@ -0,0 +1,116 @@
1
+ import { OrmDexie as R } from "./adapters/dexie.mjs";
2
+ import { OpenDBError as g } from "./errors.mjs";
3
+ import { SCHEMA_VERSION as y, UserSchema as _ } from "./schema.mjs";
4
+ import { configureValidation as D, validate as h } from "./validation.mjs";
5
+ import { object as E, number as V } from "./node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.mjs";
6
+ const I = { BASE_URL: "/", DEV: !1, MODE: "production", PROD: !0, SSR: !1 }, k = "manifest", S = E({ schemaVersion: V().int() });
7
+ let c = null, f = null;
8
+ const b = Symbol("validationInstalled");
9
+ function w(e, a) {
10
+ const u = e;
11
+ if (u[b]) return;
12
+ if (u[b] = !0, ((l, o, n) => {
13
+ l.hook("creating", (t, d) => {
14
+ const i = h(o, d, `${n}.creating`);
15
+ if (!i) throw new Error(`Rejected invalid ${n} on create`);
16
+ return i;
17
+ }), l.hook("updating", (t, d, i) => {
18
+ const r = { ...i, ...t };
19
+ return h(o, r, `${n}.updating`) ? t : {};
20
+ });
21
+ })(e.users, _, "users"), (a == null ? void 0 : a.validateReads) ?? !0) {
22
+ const l = (a == null ? void 0 : a.dropInvalidOnRead) ?? !0;
23
+ ((n, t, d) => {
24
+ n.hook("reading", (i) => {
25
+ const r = h(t, i, `${d}.reading`);
26
+ return r || (l ? void 0 : i);
27
+ });
28
+ })(e.users, _, "users");
29
+ }
30
+ }
31
+ function O() {
32
+ try {
33
+ if (typeof import.meta < "u" && I)
34
+ return !1;
35
+ } catch {
36
+ }
37
+ try {
38
+ if (typeof process < "u" && process.env)
39
+ return process.env.NODE_ENV !== "production";
40
+ } catch {
41
+ }
42
+ return !1;
43
+ }
44
+ async function T(e = {}) {
45
+ if (c) return c;
46
+ if (f) return f;
47
+ const a = e.dbName ?? "inresi-orm";
48
+ return f = (async () => {
49
+ var u, m, v, l;
50
+ try {
51
+ const o = O() ? "warn" : "strict";
52
+ D({
53
+ mode: ((u = e.validation) == null ? void 0 : u.mode) ?? o,
54
+ onIssue: (m = e.validation) == null ? void 0 : m.onIssue
55
+ });
56
+ const n = new R(a);
57
+ n.on("versionchange", () => {
58
+ var r;
59
+ try {
60
+ n.close();
61
+ } finally {
62
+ (r = e.onReset) == null || r.call(e, "versionchange");
63
+ }
64
+ }), n.on("blocked", () => {
65
+ var r;
66
+ (r = e.onReset) == null || r.call(e, "blocked");
67
+ }), await n.open();
68
+ const t = await n.kv.get(k), d = (t == null ? void 0 : t.value) ?? null;
69
+ if (!d)
70
+ return await n.transaction("rw", n.kv, async () => {
71
+ await n.kv.put({
72
+ key: k,
73
+ value: { schemaVersion: y }
74
+ });
75
+ }), w(n, e.validation), c = n, n;
76
+ const i = S.safeParse(d);
77
+ if (!i.success || i.data.schemaVersion !== y) {
78
+ await n.delete();
79
+ const r = new R(a);
80
+ return r.on("versionchange", () => {
81
+ var s;
82
+ try {
83
+ r.close();
84
+ } finally {
85
+ (s = e.onReset) == null || s.call(e, "versionchange");
86
+ }
87
+ }), r.on("blocked", () => {
88
+ var s;
89
+ (s = e.onReset) == null || s.call(e, "blocked");
90
+ }), await r.open(), await r.kv.put({
91
+ key: k,
92
+ value: { schemaVersion: y }
93
+ }), w(r, e.validation), (v = e.onReset) == null || v.call(e, "incompatible"), c = r, r;
94
+ }
95
+ return w(n, e.validation), c = n, n;
96
+ } catch (o) {
97
+ throw (l = e.onError) == null || l.call(e, o), new g("Failed to open IndexedDB", o);
98
+ } finally {
99
+ f = null;
100
+ }
101
+ })(), f;
102
+ }
103
+ async function x(e) {
104
+ const a = e ?? "inresi-orm";
105
+ if (c)
106
+ try {
107
+ await c.close();
108
+ } catch {
109
+ }
110
+ await new R(a).delete(), c = null;
111
+ }
112
+ export {
113
+ T as getDB,
114
+ x as resetDB
115
+ };
116
+ //# sourceMappingURL=db.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.mjs","sources":["../src/db.ts"],"sourcesContent":["// src/db.ts\nimport { OrmDexie } from \"./adapters/dexie\";\nimport { OpenDBError } from \"./errors\";\nimport { SCHEMA_VERSION, UserSchema } from \"./schema\";\nimport {\n validate,\n configureValidation,\n type ValidationMode,\n} from \"./validation\";\nimport type { Table } from \"dexie\";\nimport { z } from \"zod\";\n\nconst MANIFEST_KEY = \"manifest\";\nconst ManifestSchema = z.object({ schemaVersion: z.number().int() });\ntype Manifest = z.infer<typeof ManifestSchema>;\n\nexport type OrmOptions = {\n dbName?: string;\n onReset?: (reason: \"incompatible\" | \"versionchange\" | \"blocked\") => void;\n onError?: (err: unknown) => void;\n validation?: {\n mode?: ValidationMode; // 'strict' | 'warn' | 'silent'\n onIssue?: (ctx: string, details: unknown) => void;\n validateReads?: boolean; // default: true\n dropInvalidOnRead?: boolean; // default: true (when validateReads)\n };\n};\n\nlet db: OrmDexie | null = null;\nlet openPromise: Promise<OrmDexie> | null = null;\n\n// Prevent double-installing hooks on the same instance\nconst VALIDATION_INSTALLED = Symbol(\"validationInstalled\");\n\nfunction installValidationHooks(\n instance: OrmDexie,\n vopts: OrmOptions[\"validation\"] | undefined,\n) {\n const anyDb = instance as any;\n if (anyDb[VALIDATION_INSTALLED]) return;\n anyDb[VALIDATION_INSTALLED] = true;\n\n const writeHook = <T>(table: Table<T, any>, schema: any, name: string) => {\n table.hook(\"creating\", (_pk, obj) => {\n const v = validate(schema, obj, `${name}.creating`);\n if (!v) throw new Error(`Rejected invalid ${name} on create`);\n return v as T; // allow coercion/stripping\n });\n table.hook(\"updating\", (mods, _pk, obj) => {\n const next = { ...(obj as any), ...(mods as any) };\n const v = validate(schema, next, `${name}.updating`);\n if (!v) return {}; // cancel update in warn/silent\n return mods;\n });\n };\n\n writeHook(instance.users, UserSchema, \"users\");\n\n const shouldValidateReads = vopts?.validateReads ?? true;\n if (shouldValidateReads) {\n const dropInvalid = vopts?.dropInvalidOnRead ?? true;\n const readHook = <T>(table: Table<T, any>, schema: any, name: string) => {\n table.hook(\"reading\", (obj) => {\n const v = validate(schema, obj, `${name}.reading`);\n if (v) return v;\n return dropInvalid ? undefined : obj; // pass-through if you prefer\n });\n };\n readHook(instance.users, UserSchema, \"users\");\n }\n}\n\nfunction isProbablyDev(): boolean {\n try {\n // @ts-ignore\n if (typeof import.meta !== \"undefined\" && import.meta.env)\n // @ts-ignore\n return !!import.meta.env.DEV;\n } catch {}\n try {\n if (typeof process !== \"undefined\" && process.env)\n return process.env.NODE_ENV !== \"production\";\n } catch {}\n return false;\n}\n\nexport async function getDB(opts: OrmOptions = {}): Promise<OrmDexie> {\n if (db) return db;\n if (openPromise) return openPromise;\n\n const name = opts.dbName ?? \"inresi-orm\";\n\n openPromise = (async () => {\n try {\n // Configure validation once per open\n const defaultMode: ValidationMode = isProbablyDev() ? \"warn\" : \"strict\";\n configureValidation({\n mode: opts.validation?.mode ?? defaultMode,\n onIssue: opts.validation?.onIssue,\n });\n\n const instance = new OrmDexie(name);\n\n // Multi-tab friendliness\n instance.on(\"versionchange\", () => {\n try {\n instance.close();\n } finally {\n opts.onReset?.(\"versionchange\");\n }\n });\n instance.on(\"blocked\", () => {\n opts.onReset?.(\"blocked\");\n });\n\n await instance.open();\n\n // Validate/initialize manifest\n const row = await instance.kv.get(MANIFEST_KEY);\n const saved = (row?.value ?? null) as unknown;\n\n if (!saved) {\n await instance.transaction(\"rw\", instance.kv, async () => {\n await instance.kv.put({\n key: MANIFEST_KEY,\n value: { schemaVersion: SCHEMA_VERSION },\n });\n });\n installValidationHooks(instance, opts.validation);\n db = instance;\n return instance;\n }\n\n const parsed = ManifestSchema.safeParse(saved as Manifest);\n if (!parsed.success || parsed.data.schemaVersion !== SCHEMA_VERSION) {\n await instance.delete();\n const fresh = new OrmDexie(name);\n fresh.on(\"versionchange\", () => {\n try {\n fresh.close();\n } finally {\n opts.onReset?.(\"versionchange\");\n }\n });\n fresh.on(\"blocked\", () => {\n opts.onReset?.(\"blocked\");\n });\n await fresh.open();\n await fresh.kv.put({\n key: MANIFEST_KEY,\n value: { schemaVersion: SCHEMA_VERSION },\n });\n installValidationHooks(fresh, opts.validation);\n opts.onReset?.(\"incompatible\");\n db = fresh;\n return fresh;\n }\n\n installValidationHooks(instance, opts.validation);\n db = instance;\n return instance;\n } catch (e) {\n opts.onError?.(e);\n throw new OpenDBError(\"Failed to open IndexedDB\", e);\n } finally {\n openPromise = null; // allow future reuse/retry\n }\n })();\n\n return openPromise;\n}\n\nexport async function resetDB(dbName?: string) {\n const name = dbName ?? \"inresi-orm\";\n if (db) {\n try {\n await db.close();\n } catch {\n /* ignore */\n }\n }\n const instance = new OrmDexie(name);\n await instance.delete();\n db = null;\n}\n"],"names":["MANIFEST_KEY","ManifestSchema","z.object","z.number","db","openPromise","VALIDATION_INSTALLED","installValidationHooks","instance","vopts","anyDb","table","schema","name","_pk","obj","v","validate","mods","next","UserSchema","dropInvalid","isProbablyDev","__vite_import_meta_env__","getDB","opts","defaultMode","configureValidation","_a","_b","OrmDexie","row","saved","SCHEMA_VERSION","parsed","fresh","_c","e","_d","OpenDBError","resetDB","dbName"],"mappings":"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"}
package/dist/debug.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./db.cjs");async function r(){const n=await a.getDB(),o={};for(const t of n.tables)o[t.name]=await t.toArray();return o}async function c(n="inresi-orm-export.json"){if(typeof window>"u"||typeof document>"u")throw new Error("exportJSON can only run in a browser.");const o=await r(),t=new Blob([JSON.stringify(o,null,2)],{type:"application/json"}),e=document.createElement("a");e.href=URL.createObjectURL(t),e.download=n,document.body.appendChild(e),e.click(),e.remove(),URL.revokeObjectURL(e.href)}exports.debugDump=r;exports.exportJSON=c;
2
+ //# sourceMappingURL=debug.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.cjs","sources":["../src/debug.ts"],"sourcesContent":["import { getDB } from \"./db\";\n\nexport async function debugDump(): Promise<Record<string, unknown[]>> {\n const db = await getDB();\n const out: Record<string, unknown[]> = {};\n for (const t of db.tables) {\n out[t.name] = await t.toArray();\n }\n return out;\n}\n\nexport async function exportJSON(filename = \"inresi-orm-export.json\"): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n throw new Error(\"exportJSON can only run in a browser.\");\n }\n const snapshot = await debugDump();\n const blob = new Blob([JSON.stringify(snapshot, null, 2)], { type: \"application/json\" });\n const a = document.createElement(\"a\");\n a.href = URL.createObjectURL(blob);\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(a.href);\n}\n"],"names":["debugDump","db","getDB","out","exportJSON","filename","snapshot","blob","a"],"mappings":"4GAEA,eAAsBA,GAAgD,CACpE,MAAMC,EAAK,MAAMC,QAAA,EACXC,EAAiC,CAAA,EACvC,UAAW,KAAKF,EAAG,OACjBE,EAAI,EAAE,IAAI,EAAI,MAAM,EAAE,QAAA,EAExB,OAAOA,CACT,CAEA,eAAsBC,EAAWC,EAAW,yBAAyC,CACnF,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IACvD,MAAM,IAAI,MAAM,uCAAuC,EAEzD,MAAMC,EAAW,MAAMN,EAAA,EACjBO,EAAO,IAAI,KAAK,CAAC,KAAK,UAAUD,EAAU,KAAM,CAAC,CAAC,EAAG,CAAE,KAAM,mBAAoB,EACjFE,EAAI,SAAS,cAAc,GAAG,EACpCA,EAAE,KAAO,IAAI,gBAAgBD,CAAI,EACjCC,EAAE,SAAWH,EACb,SAAS,KAAK,YAAYG,CAAC,EAC3BA,EAAE,MAAA,EACFA,EAAE,OAAA,EACF,IAAI,gBAAgBA,EAAE,IAAI,CAC5B"}
package/dist/debug.mjs ADDED
@@ -0,0 +1,18 @@
1
+ import { getDB as r } from "./db.mjs";
2
+ async function a() {
3
+ const t = await r(), e = {};
4
+ for (const n of t.tables)
5
+ e[n.name] = await n.toArray();
6
+ return e;
7
+ }
8
+ async function i(t = "inresi-orm-export.json") {
9
+ if (typeof window > "u" || typeof document > "u")
10
+ throw new Error("exportJSON can only run in a browser.");
11
+ const e = await a(), n = new Blob([JSON.stringify(e, null, 2)], { type: "application/json" }), o = document.createElement("a");
12
+ o.href = URL.createObjectURL(n), o.download = t, document.body.appendChild(o), o.click(), o.remove(), URL.revokeObjectURL(o.href);
13
+ }
14
+ export {
15
+ a as debugDump,
16
+ i as exportJSON
17
+ };
18
+ //# sourceMappingURL=debug.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug.mjs","sources":["../src/debug.ts"],"sourcesContent":["import { getDB } from \"./db\";\n\nexport async function debugDump(): Promise<Record<string, unknown[]>> {\n const db = await getDB();\n const out: Record<string, unknown[]> = {};\n for (const t of db.tables) {\n out[t.name] = await t.toArray();\n }\n return out;\n}\n\nexport async function exportJSON(filename = \"inresi-orm-export.json\"): Promise<void> {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n throw new Error(\"exportJSON can only run in a browser.\");\n }\n const snapshot = await debugDump();\n const blob = new Blob([JSON.stringify(snapshot, null, 2)], { type: \"application/json\" });\n const a = document.createElement(\"a\");\n a.href = URL.createObjectURL(blob);\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(a.href);\n}\n"],"names":["debugDump","db","getDB","out","t","exportJSON","filename","snapshot","blob","a"],"mappings":";AAEA,eAAsBA,IAAgD;AACpE,QAAMC,IAAK,MAAMC,EAAA,GACXC,IAAiC,CAAA;AACvC,aAAWC,KAAKH,EAAG;AACjB,IAAAE,EAAIC,EAAE,IAAI,IAAI,MAAMA,EAAE,QAAA;AAExB,SAAOD;AACT;AAEA,eAAsBE,EAAWC,IAAW,0BAAyC;AACnF,MAAI,OAAO,SAAW,OAAe,OAAO,WAAa;AACvD,UAAM,IAAI,MAAM,uCAAuC;AAEzD,QAAMC,IAAW,MAAMP,EAAA,GACjBQ,IAAO,IAAI,KAAK,CAAC,KAAK,UAAUD,GAAU,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,oBAAoB,GACjFE,IAAI,SAAS,cAAc,GAAG;AACpC,EAAAA,EAAE,OAAO,IAAI,gBAAgBD,CAAI,GACjCC,EAAE,WAAWH,GACb,SAAS,KAAK,YAAYG,CAAC,GAC3BA,EAAE,MAAA,GACFA,EAAE,OAAA,GACF,IAAI,gBAAgBA,EAAE,IAAI;AAC5B;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class s extends Error{constructor(r,e){super(r),this.detail=e,this.name="SchemaMismatchError"}}class o extends Error{constructor(r,e){super(r),this.detail=e,this.name="OpenDBError"}}exports.OpenDBError=o;exports.SchemaMismatchError=s;
2
+ //# sourceMappingURL=errors.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.cjs","sources":["../src/errors.ts"],"sourcesContent":["export class SchemaMismatchError extends Error {\n constructor(message: string, public detail?: unknown) {\n super(message);\n this.name = \"SchemaMismatchError\";\n }\n}\n\nexport class OpenDBError extends Error {\n constructor(message: string, public detail?: unknown) {\n super(message);\n this.name = \"OpenDBError\";\n }\n}\n"],"names":["SchemaMismatchError","message","detail","OpenDBError"],"mappings":"gFAAO,MAAMA,UAA4B,KAAM,CAC7C,YAAYC,EAAwBC,EAAkB,CACpD,MAAMD,CAAO,EADqB,KAAA,OAAAC,EAElC,KAAK,KAAO,qBACd,CACF,CAEO,MAAMC,UAAoB,KAAM,CACrC,YAAYF,EAAwBC,EAAkB,CACpD,MAAMD,CAAO,EADqB,KAAA,OAAAC,EAElC,KAAK,KAAO,aACd,CACF"}
@@ -0,0 +1,15 @@
1
+ class t extends Error {
2
+ constructor(r, s) {
3
+ super(r), this.detail = s, this.name = "SchemaMismatchError";
4
+ }
5
+ }
6
+ class o extends Error {
7
+ constructor(r, s) {
8
+ super(r), this.detail = s, this.name = "OpenDBError";
9
+ }
10
+ }
11
+ export {
12
+ o as OpenDBError,
13
+ t as SchemaMismatchError
14
+ };
15
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","sources":["../src/errors.ts"],"sourcesContent":["export class SchemaMismatchError extends Error {\n constructor(message: string, public detail?: unknown) {\n super(message);\n this.name = \"SchemaMismatchError\";\n }\n}\n\nexport class OpenDBError extends Error {\n constructor(message: string, public detail?: unknown) {\n super(message);\n this.name = \"OpenDBError\";\n }\n}\n"],"names":["SchemaMismatchError","message","detail","OpenDBError"],"mappings":"AAAO,MAAMA,UAA4B,MAAM;AAAA,EAC7C,YAAYC,GAAwBC,GAAkB;AACpD,UAAMD,CAAO,GADqB,KAAA,SAAAC,GAElC,KAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAMC,UAAoB,MAAM;AAAA,EACrC,YAAYF,GAAwBC,GAAkB;AACpD,UAAMD,CAAO,GADqB,KAAA,SAAAC,GAElC,KAAK,OAAO;AAAA,EACd;AACF;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("react/jsx-runtime"),i=require("react"),d=require("./generateUserUUID.cjs"),o=require("mixpanel-browser"),u=i.createContext(null),x=({children:e,token:t,envMode:s})=>(i.useEffect(()=>{const r=(s??"production").toLowerCase(),l=r==="development"||r==="staging",c=r==="development",a="Mixpanel token not set. Pass a token prop to MixpanelProvider or define VITE_MIXPANEL_TOKEN.";if(!t){l?console.error(`❌ ${a}`):console.warn(`⚠️ ${a}`);return}o.init(t,{debug:c,persistence:"localStorage",autocapture:{pageview:"full-url",click:!0,input:!0,rage_click:!0,scroll:!0,submit:!0,capture_text_content:!1}}),(async()=>{try{const n=await d.generateUserUUID;o.identify(n)}catch(n){console.error("❌ Failed to set Mixpanel identity:",n)}})()},[s,t]),p.jsx(u.Provider,{value:o,children:e})),g=()=>{const e=i.useContext(u);if(!e)throw new Error("useMixpanel must be used within MixpanelProvider");return e};exports.MixpanelProvider=x;exports.useMixpanel=g;
2
+ //# sourceMappingURL=MixpanelProvider.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MixpanelProvider.cjs","sources":["../../../src/features/analytics/MixpanelProvider.tsx"],"sourcesContent":["import React, { createContext, useContext, useEffect, useRef } from \"react\";\n\nimport { generateUserUUID } from \"./generateUserUUID\";\nimport mixpanel from \"mixpanel-browser\";\n\nconst MixpanelContext = createContext<typeof mixpanel | null>(null);\n\ninterface MixpanelProviderProps {\n children: React.ReactNode;\n token?: string;\n envMode?: string;\n}\n\nexport const MixpanelProvider = ({ children, token, envMode }: MixpanelProviderProps) => {\n\n\n useEffect(() => {\n const normalizedMode = (envMode ?? \"production\").toLowerCase();\n const shouldError =\n normalizedMode === \"development\" || normalizedMode === \"staging\";\n const debugEnabled = normalizedMode === \"development\";\n\n const message =\n \"Mixpanel token not set. Pass a token prop to MixpanelProvider or define VITE_MIXPANEL_TOKEN.\";\n\n if (!token) {\n if (shouldError) {\n console.error(`❌ ${message}`);\n } else {\n console.warn(`⚠️ ${message}`);\n }\n return;\n }\n\n\n\n mixpanel.init(token, {\n debug: debugEnabled,\n persistence: \"localStorage\",\n autocapture: {\n pageview: \"full-url\",\n click: true,\n input: true,\n rage_click: true,\n scroll: true,\n submit: true,\n capture_text_content: false,\n },\n });\n\n\n (async () => {\n try {\n const uuid = await generateUserUUID;\n mixpanel.identify(uuid);\n } catch (err) {\n console.error(\"❌ Failed to set Mixpanel identity:\", err);\n }\n })();\n }, [envMode, token]);\n\n return (\n <MixpanelContext.Provider value={mixpanel}>\n {children}\n </MixpanelContext.Provider>\n );\n};\n\nexport const useMixpanel = () => {\n const ctx = useContext(MixpanelContext);\n if (!ctx) throw new Error(\"useMixpanel must be used within MixpanelProvider\");\n return ctx;\n};\n"],"names":["MixpanelContext","createContext","MixpanelProvider","children","token","envMode","useEffect","normalizedMode","shouldError","debugEnabled","message","mixpanel","uuid","generateUserUUID","err","useMixpanel","ctx","useContext"],"mappings":"0MAKMA,EAAkBC,EAAAA,cAAsC,IAAI,EAQrDC,EAAmB,CAAC,CAAE,SAAAC,EAAU,MAAAC,EAAO,QAAAC,MAGlDC,EAAAA,UAAU,IAAM,CACd,MAAMC,GAAkBF,GAAW,cAAc,YAAA,EAC3CG,EACJD,IAAmB,eAAiBA,IAAmB,UACnDE,EAAeF,IAAmB,cAElCG,EACJ,+FAEF,GAAI,CAACN,EAAO,CACNI,EACF,QAAQ,MAAM,KAAKE,CAAO,EAAE,EAE5B,QAAQ,KAAK,MAAMA,CAAO,EAAE,EAE9B,MACF,CAIAC,EAAS,KAAKP,EAAO,CACnB,MAAOK,EACP,YAAa,eACb,YAAa,CACX,SAAU,WACV,MAAO,GACP,MAAO,GACP,WAAY,GACZ,OAAQ,GACR,OAAQ,GACR,qBAAsB,EAAA,CACxB,CACD,GAGA,SAAY,CACX,GAAI,CACF,MAAMG,EAAO,MAAMC,EAAAA,iBACnBF,EAAS,SAASC,CAAI,CACxB,OAASE,EAAK,CACZ,QAAQ,MAAM,qCAAsCA,CAAG,CACzD,CACF,GAAA,CACF,EAAG,CAACT,EAASD,CAAK,CAAC,QAGhBJ,EAAgB,SAAhB,CAAyB,MAAOW,EAC9B,SAAAR,EACH,GAISY,EAAc,IAAM,CAC/B,MAAMC,EAAMC,EAAAA,WAAWjB,CAAe,EACtC,GAAI,CAACgB,EAAK,MAAM,IAAI,MAAM,kDAAkD,EAC5E,OAAOA,CACT"}
@@ -0,0 +1,40 @@
1
+ import { jsx as u } from "react/jsx-runtime";
2
+ import { useEffect as p, createContext as d, useContext as x } from "react";
3
+ import { generateUserUUID as m } from "./generateUserUUID.mjs";
4
+ import n from "mixpanel-browser";
5
+ const a = d(null), w = ({ children: e, token: t, envMode: i }) => (p(() => {
6
+ const r = (i ?? "production").toLowerCase(), l = r === "development" || r === "staging", c = r === "development", s = "Mixpanel token not set. Pass a token prop to MixpanelProvider or define VITE_MIXPANEL_TOKEN.";
7
+ if (!t) {
8
+ l ? console.error(`❌ ${s}`) : console.warn(`⚠️ ${s}`);
9
+ return;
10
+ }
11
+ n.init(t, {
12
+ debug: c,
13
+ persistence: "localStorage",
14
+ autocapture: {
15
+ pageview: "full-url",
16
+ click: !0,
17
+ input: !0,
18
+ rage_click: !0,
19
+ scroll: !0,
20
+ submit: !0,
21
+ capture_text_content: !1
22
+ }
23
+ }), (async () => {
24
+ try {
25
+ const o = await m;
26
+ n.identify(o);
27
+ } catch (o) {
28
+ console.error("❌ Failed to set Mixpanel identity:", o);
29
+ }
30
+ })();
31
+ }, [i, t]), /* @__PURE__ */ u(a.Provider, { value: n, children: e })), E = () => {
32
+ const e = x(a);
33
+ if (!e) throw new Error("useMixpanel must be used within MixpanelProvider");
34
+ return e;
35
+ };
36
+ export {
37
+ w as MixpanelProvider,
38
+ E as useMixpanel
39
+ };
40
+ //# sourceMappingURL=MixpanelProvider.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MixpanelProvider.mjs","sources":["../../../src/features/analytics/MixpanelProvider.tsx"],"sourcesContent":["import React, { createContext, useContext, useEffect, useRef } from \"react\";\n\nimport { generateUserUUID } from \"./generateUserUUID\";\nimport mixpanel from \"mixpanel-browser\";\n\nconst MixpanelContext = createContext<typeof mixpanel | null>(null);\n\ninterface MixpanelProviderProps {\n children: React.ReactNode;\n token?: string;\n envMode?: string;\n}\n\nexport const MixpanelProvider = ({ children, token, envMode }: MixpanelProviderProps) => {\n\n\n useEffect(() => {\n const normalizedMode = (envMode ?? \"production\").toLowerCase();\n const shouldError =\n normalizedMode === \"development\" || normalizedMode === \"staging\";\n const debugEnabled = normalizedMode === \"development\";\n\n const message =\n \"Mixpanel token not set. Pass a token prop to MixpanelProvider or define VITE_MIXPANEL_TOKEN.\";\n\n if (!token) {\n if (shouldError) {\n console.error(`❌ ${message}`);\n } else {\n console.warn(`⚠️ ${message}`);\n }\n return;\n }\n\n\n\n mixpanel.init(token, {\n debug: debugEnabled,\n persistence: \"localStorage\",\n autocapture: {\n pageview: \"full-url\",\n click: true,\n input: true,\n rage_click: true,\n scroll: true,\n submit: true,\n capture_text_content: false,\n },\n });\n\n\n (async () => {\n try {\n const uuid = await generateUserUUID;\n mixpanel.identify(uuid);\n } catch (err) {\n console.error(\"❌ Failed to set Mixpanel identity:\", err);\n }\n })();\n }, [envMode, token]);\n\n return (\n <MixpanelContext.Provider value={mixpanel}>\n {children}\n </MixpanelContext.Provider>\n );\n};\n\nexport const useMixpanel = () => {\n const ctx = useContext(MixpanelContext);\n if (!ctx) throw new Error(\"useMixpanel must be used within MixpanelProvider\");\n return ctx;\n};\n"],"names":["MixpanelContext","createContext","MixpanelProvider","children","token","envMode","useEffect","normalizedMode","shouldError","debugEnabled","message","mixpanel","uuid","generateUserUUID","err","useMixpanel","ctx","useContext"],"mappings":";;;;AAKA,MAAMA,IAAkBC,EAAsC,IAAI,GAQrDC,IAAmB,CAAC,EAAE,UAAAC,GAAU,OAAAC,GAAO,SAAAC,SAGlDC,EAAU,MAAM;AACd,QAAMC,KAAkBF,KAAW,cAAc,YAAA,GAC3CG,IACJD,MAAmB,iBAAiBA,MAAmB,WACnDE,IAAeF,MAAmB,eAElCG,IACJ;AAEF,MAAI,CAACN,GAAO;AACV,IAAII,IACF,QAAQ,MAAM,KAAKE,CAAO,EAAE,IAE5B,QAAQ,KAAK,MAAMA,CAAO,EAAE;AAE9B;AAAA,EACF;AAIA,EAAAC,EAAS,KAAKP,GAAO;AAAA,IACnB,OAAOK;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,UAAU;AAAA,MACV,OAAO;AAAA,MACP,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,sBAAsB;AAAA,IAAA;AAAA,EACxB,CACD,IAGA,YAAY;AACX,QAAI;AACF,YAAMG,IAAO,MAAMC;AACnB,MAAAF,EAAS,SAASC,CAAI;AAAA,IACxB,SAASE,GAAK;AACZ,cAAQ,MAAM,sCAAsCA,CAAG;AAAA,IACzD;AAAA,EACF,GAAA;AACF,GAAG,CAACT,GAASD,CAAK,CAAC,qBAGhBJ,EAAgB,UAAhB,EAAyB,OAAOW,GAC9B,UAAAR,GACH,IAISY,IAAc,MAAM;AAC/B,QAAMC,IAAMC,EAAWjB,CAAe;AACtC,MAAI,CAACgB,EAAK,OAAM,IAAI,MAAM,kDAAkD;AAC5E,SAAOA;AACT;"}