@superbright/indexeddb-orm 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +369 -19
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +777 -476
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,30 +1,364 @@
|
|
|
1
|
-
#
|
|
1
|
+
# IndexedDB ORM with Structured Store Actions
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A TypeScript-first IndexedDB ORM built with Dexie and Zod, featuring structured Zustand store integration for React applications.
|
|
4
4
|
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
|
|
7
|
+
- **TypeScript-First**: Full type safety with Zod schema validation
|
|
8
|
+
- **Structured Store Actions**: Organized, nested API for better developer experience
|
|
9
|
+
- **IndexedDB Powered**: Built on Dexie for robust browser storage
|
|
10
|
+
- **Zustand Integration**: Seamless state management with React
|
|
11
|
+
- **Schema Validation**: Runtime validation with Zod schemas
|
|
12
|
+
- **Developer Experience**: Hot reloading, type inference, and great autocomplete
|
|
13
|
+
- **Production Ready**: Optimized builds with proper package exports
|
|
14
|
+
|
|
15
|
+
## 📦 Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm install @superbright/indexeddb-orm zustand
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 🏃 Quick Start
|
|
22
|
+
|
|
23
|
+
### 1. Basic Setup
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { create } from "zustand";
|
|
27
|
+
import { devtools } from "zustand/middleware";
|
|
28
|
+
import {
|
|
29
|
+
createStructuredStore,
|
|
30
|
+
createUseUnitState,
|
|
31
|
+
type StructuredStore,
|
|
32
|
+
type Filters,
|
|
33
|
+
type QueryParams,
|
|
34
|
+
} from "@superbright/indexeddb-orm";
|
|
35
|
+
|
|
36
|
+
// Create your store with structured actions
|
|
37
|
+
export const useStore = create<StructuredStore>()(
|
|
38
|
+
devtools(
|
|
39
|
+
createStructuredStore({
|
|
40
|
+
onFilterUpdate: (apiParams: QueryParams) => {
|
|
41
|
+
console.log("Filters updated:", apiParams);
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
{ name: "inresi-store" }
|
|
45
|
+
)
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
export const useUnitState = createUseUnitState()(useStore);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 2. Initialize in Your App
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// main.tsx or App.tsx
|
|
55
|
+
import { useStore } from './stores/myStore';
|
|
56
|
+
|
|
57
|
+
async function initializeApp() {
|
|
58
|
+
await useStore.getState()._initialize();
|
|
59
|
+
await useStore.getState()._hydrate();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
initializeApp().then(() => {
|
|
63
|
+
// Render your app
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 3. Use Structured Actions
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
function MyComponent() {
|
|
71
|
+
const store = useStore();
|
|
72
|
+
|
|
73
|
+
// Property actions
|
|
74
|
+
const toggleFavorite = async (unitId: string) => {
|
|
75
|
+
await store.property.unit.favorites.toggle(unitId);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const markViewed = async (unitId: string, slug: string) => {
|
|
79
|
+
await store.property.unit.viewed.mark(unitId, slug);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Filter actions
|
|
83
|
+
const updateFilters = async () => {
|
|
84
|
+
await store.filters.set({ bedrooms: [1, 2] });
|
|
85
|
+
await store.filters.submit();
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<div>
|
|
90
|
+
<button onClick={() => toggleFavorite("unit-123")}>
|
|
91
|
+
Toggle Favorite
|
|
92
|
+
</button>
|
|
93
|
+
<button onClick={() => markViewed("unit-123", "property-slug")}>
|
|
94
|
+
Mark as Viewed
|
|
95
|
+
</button>
|
|
96
|
+
<button onClick={updateFilters}>
|
|
97
|
+
Update Filters
|
|
98
|
+
</button>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 🏗️ Architecture
|
|
105
|
+
|
|
106
|
+
### Core Components
|
|
107
|
+
|
|
108
|
+
- **Dexie Database**: IndexedDB abstraction layer
|
|
109
|
+
- **Zod Schemas**: Runtime type validation and TypeScript inference
|
|
110
|
+
- **Unified Store**: Single source of truth combining property and app state
|
|
111
|
+
- **Structured Actions**: Organized API with nested action groups
|
|
112
|
+
- **Zustand Integration**: React state management with devtools support
|
|
113
|
+
|
|
114
|
+
### Data Flow
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
React Components
|
|
118
|
+
↓
|
|
119
|
+
Structured Store Actions
|
|
120
|
+
↓
|
|
121
|
+
Unified Store (Zustand)
|
|
122
|
+
↓
|
|
123
|
+
ORM Layer (Validation)
|
|
124
|
+
↓
|
|
125
|
+
IndexedDB (Dexie)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 📚 API Reference
|
|
129
|
+
|
|
130
|
+
### Structured Store Actions
|
|
131
|
+
|
|
132
|
+
#### Property Actions
|
|
133
|
+
```typescript
|
|
134
|
+
// Unit favorites
|
|
135
|
+
store.property.unit.favorites.toggle(unitId: string)
|
|
136
|
+
|
|
137
|
+
// Unit viewing
|
|
138
|
+
store.property.unit.viewed.mark(unitId: string, slug: string)
|
|
139
|
+
|
|
140
|
+
// Questionnaire
|
|
141
|
+
store.property.questionnaire.setResults(results: unknown)
|
|
142
|
+
|
|
143
|
+
// Tour scheduling
|
|
144
|
+
store.property.tour.setContactedOn()
|
|
145
|
+
store.property.tour.getContactedOn()
|
|
146
|
+
store.property.tour.setContactData(data: TourContactData)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### Filter Actions
|
|
150
|
+
```typescript
|
|
151
|
+
// Filter management
|
|
152
|
+
store.filters.set(filters: Partial<Filters>)
|
|
153
|
+
store.filters.setTemp(filters: Partial<Filters>)
|
|
154
|
+
store.filters.setToDefault()
|
|
155
|
+
store.filters.commitTemp(key, defaultValue)
|
|
156
|
+
store.filters.commitAvailability()
|
|
157
|
+
store.filters.submit()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Store State
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
// Property data
|
|
164
|
+
const currentPropertyId = useStore(state => state.currentPropertyId);
|
|
165
|
+
const properties = useStore(state => state.properties);
|
|
166
|
+
|
|
167
|
+
// App data
|
|
168
|
+
const filters = useStore(state => state.filters);
|
|
169
|
+
const unitResults = useStore(state => state.unitResults);
|
|
170
|
+
const resultsMode = useStore(state => state.resultsMode);
|
|
171
|
+
|
|
172
|
+
// Unit state helper
|
|
173
|
+
const unitState = useUnitState("unit-123");
|
|
174
|
+
// Returns: { isFavorite: boolean, viewedDate: string }
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Direct Store Methods
|
|
178
|
+
|
|
179
|
+
For advanced use cases, all original store methods are available:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// Property operations
|
|
183
|
+
await store.getCurrentProperty()
|
|
184
|
+
await store.setCurrentProperty(propertyId, slug)
|
|
185
|
+
await store.getPropertyData(propertyId)
|
|
186
|
+
|
|
187
|
+
// Unit results
|
|
188
|
+
await store.setUnitResults(transformedUnits.hits)
|
|
189
|
+
await store.clearUnitResults()
|
|
190
|
+
|
|
191
|
+
// Filter operations
|
|
192
|
+
await store.loadPersistedFilters()
|
|
193
|
+
await store.handleFilterCommitIndexDB(newFilters)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## 🛠️ Development
|
|
197
|
+
|
|
198
|
+
### Local Development Setup
|
|
199
|
+
|
|
200
|
+
1. **Environment Configuration**
|
|
201
|
+
|
|
202
|
+
Create `.env` in your consuming app:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
VITE_USE_LOCAL_ORM_LIBRARY=true
|
|
206
|
+
VITE_LOCAL_ORM_LIBRARY_PATH=/path/to/indexeddb-orm-starter-with-playground
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
2. **Vite Configuration**
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
// vite.config.ts
|
|
213
|
+
const alias: Record<string, string> = {};
|
|
214
|
+
if (useLocalORM && ormPath) {
|
|
215
|
+
alias["@superbright/indexeddb-orm"] = resolve(ormPath, "./dist");
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### 🎮 Interactive Playground
|
|
220
|
+
|
|
221
|
+
The ORM includes a comprehensive interactive playground for testing and exploring functionality:
|
|
12
222
|
|
|
13
|
-
## Dev / Playground
|
|
14
223
|
```bash
|
|
15
224
|
pnpm i
|
|
16
225
|
pnpm dev
|
|
17
226
|
# Visit http://localhost:5173 (or printed URL)
|
|
18
|
-
# Use the buttons to write/dump/export, then open DevTools → Application → IndexedDB → inresi-orm
|
|
19
227
|
```
|
|
20
228
|
|
|
21
|
-
|
|
229
|
+
#### Playground Features
|
|
230
|
+
|
|
231
|
+
- **🗄️ Database Operations**: Initialize, dump state, export JSON, and reset database
|
|
232
|
+
- **🏠 Property Management**: Create properties, set current property, retrieve property data
|
|
233
|
+
- **⭐ Unit Actions**: Toggle favorites, mark units as viewed, get unit state
|
|
234
|
+
- **🔍 Filter Operations**: Set filters, reset to defaults, submit filter updates
|
|
235
|
+
- **📝 Questionnaire & Tours**: Set questionnaire results, manage tour contact data
|
|
236
|
+
- **📊 Real-time State View**: Live view of database state and action logs
|
|
237
|
+
- **🛠️ Developer Tools Integration**: Inspect IndexedDB directly in DevTools → Application → IndexedDB → `inresi-orm`
|
|
238
|
+
|
|
239
|
+
#### How to Use
|
|
240
|
+
|
|
241
|
+
1. **Start with Database Operations**: Click "Initialize Database" to set up the ORM
|
|
242
|
+
2. **Create a Property**: Enter a property ID and slug, then click "Initialize Property"
|
|
243
|
+
3. **Test Unit Actions**: Enter a unit ID and try toggling favorites or marking as viewed
|
|
244
|
+
4. **Experiment with Filters**: Set bedroom counts and cost filters, then submit them
|
|
245
|
+
5. **View State Changes**: Watch the real-time state updates and action logs
|
|
246
|
+
6. **Inspect Database**: Open browser DevTools to see the actual IndexedDB storage
|
|
247
|
+
|
|
248
|
+
The playground demonstrates all structured store actions and provides immediate feedback, making it perfect for learning the API and testing integrations.
|
|
249
|
+
|
|
250
|
+
### Build Scripts
|
|
251
|
+
|
|
22
252
|
```bash
|
|
23
|
-
|
|
24
|
-
pnpm
|
|
253
|
+
# Development
|
|
254
|
+
pnpm run dev # Start playground with hot reload
|
|
255
|
+
pnpm run watch # Watch mode for types and bundle
|
|
256
|
+
|
|
257
|
+
# Building
|
|
258
|
+
pnpm run build # Production build
|
|
259
|
+
pnpm run clean # Clean dist folder
|
|
260
|
+
|
|
261
|
+
# Testing
|
|
262
|
+
pnpm run test # Run tests
|
|
263
|
+
pnpm run test:watch # Watch mode testing
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Package Structure
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
dist/
|
|
270
|
+
├── index.d.ts # Main type definitions
|
|
271
|
+
├── index.es.js # ES module build
|
|
272
|
+
├── index.cjs.js # CommonJS build
|
|
273
|
+
├── adapters/ # Store adapters
|
|
274
|
+
├── api/ # API modules
|
|
275
|
+
└── stores/ # Store implementations
|
|
25
276
|
```
|
|
26
277
|
|
|
27
|
-
##
|
|
278
|
+
## 🎯 TypeScript Support
|
|
279
|
+
|
|
280
|
+
Full TypeScript support with proper type inference:
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
import type {
|
|
284
|
+
StructuredStore,
|
|
285
|
+
StructuredStoreActions,
|
|
286
|
+
Filters,
|
|
287
|
+
QueryParams,
|
|
288
|
+
TourContactData,
|
|
289
|
+
UserPropertyState,
|
|
290
|
+
Unit,
|
|
291
|
+
ZustandUnifiedStoreState,
|
|
292
|
+
} from "@superbright/indexeddb-orm";
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## 📋 Schema Validation
|
|
296
|
+
|
|
297
|
+
Built-in Zod schemas ensure data integrity:
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
// Example schema usage
|
|
301
|
+
import { FiltersSchema, UnitSchema } from "@superbright/indexeddb-orm";
|
|
302
|
+
|
|
303
|
+
// Validate data at runtime
|
|
304
|
+
const validatedFilters = FiltersSchema.parse(userInput);
|
|
305
|
+
const validatedUnit = UnitSchema.parse(transformedUnit);
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## 🔧 Configuration
|
|
309
|
+
|
|
310
|
+
### Store Configuration
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
createStructuredStore({
|
|
314
|
+
onFilterUpdate?: (apiParams: QueryParams) => void;
|
|
315
|
+
// Add more configuration options as needed
|
|
316
|
+
})
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Validation Configuration
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
import { configureValidation } from "@superbright/indexeddb-orm";
|
|
323
|
+
|
|
324
|
+
// Configure validation mode
|
|
325
|
+
configureValidation("strict"); // "strict" | "warn" | "off"
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## 🚀 Production
|
|
329
|
+
|
|
330
|
+
### Package Exports
|
|
331
|
+
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"exports": {
|
|
335
|
+
".": {
|
|
336
|
+
"types": "./dist/index.d.ts",
|
|
337
|
+
"import": "./dist/index.mjs",
|
|
338
|
+
"require": "./dist/index.cjs"
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Bundle Optimization
|
|
345
|
+
|
|
346
|
+
- Tree-shakable ES modules
|
|
347
|
+
- Separate type definitions
|
|
348
|
+
- Optimized for Vite and Webpack
|
|
349
|
+
- Source maps included
|
|
350
|
+
|
|
351
|
+
## 📖 Documentation
|
|
352
|
+
|
|
353
|
+
- [Consuming App Guide](./CONSUMING_APP_GUIDE.md) - Complete integration guide
|
|
354
|
+
- [Migration Summary](./MIGRATION_SUMMARY.md) - Migration from legacy stores
|
|
355
|
+
- [Property Store Guide](./docs/property-store.md) - Property-specific usage
|
|
356
|
+
- [App Store Guide](./docs/app-store-guide.md) - App state management
|
|
357
|
+
|
|
358
|
+
## 🔧 Legacy API
|
|
359
|
+
|
|
360
|
+
For backward compatibility, the original API is still available:
|
|
361
|
+
|
|
28
362
|
```ts
|
|
29
363
|
import {
|
|
30
364
|
getDB,
|
|
@@ -32,7 +366,7 @@ import {
|
|
|
32
366
|
getPreferences, setPreferences,
|
|
33
367
|
upsertUser, getUser,
|
|
34
368
|
debugDump, exportJSON
|
|
35
|
-
} from "indexeddb-orm
|
|
369
|
+
} from "@superbright/indexeddb-orm";
|
|
36
370
|
|
|
37
371
|
await getDB();
|
|
38
372
|
await setFavouritedUnits(["u1","u2"]);
|
|
@@ -40,6 +374,22 @@ console.log(await getFavouritedUnits());
|
|
|
40
374
|
await exportJSON();
|
|
41
375
|
```
|
|
42
376
|
|
|
43
|
-
##
|
|
44
|
-
|
|
45
|
-
|
|
377
|
+
## 🤝 Contributing
|
|
378
|
+
|
|
379
|
+
1. Fork the repository
|
|
380
|
+
2. Create a feature branch
|
|
381
|
+
3. Make your changes
|
|
382
|
+
4. Add tests if applicable
|
|
383
|
+
5. Ensure type checking passes: `pnpm run build`
|
|
384
|
+
6. Submit a pull request
|
|
385
|
+
|
|
386
|
+
## 📝 License
|
|
387
|
+
|
|
388
|
+
UNLICENSED - Proprietary software for internal use
|
|
389
|
+
|
|
390
|
+
## 🔗 Related Projects
|
|
391
|
+
|
|
392
|
+
- [Dexie](https://dexie.org/) - IndexedDB wrapper
|
|
393
|
+
- [Zod](https://zod.dev/) - TypeScript schema validation
|
|
394
|
+
- [Zustand](https://zustand-demo.pmnd.rs/) - React state management
|
|
395
|
+
- [Vite](https://vitejs.dev/) - Build tool and dev server
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("zod"),at=require("dexie");var U=typeof document<"u"?document.currentScript:null;class B extends Error{constructor(t,e){super(t),this.detail=e,this.name="SchemaMismatchError"}}class Q extends Error{constructor(t,e){super(t),this.detail=e,this.name="OpenDBError"}}class R extends at{constructor(t="inresi-orm"){super(t),this.version(m).stores({users:"uuid",kv:"key"}),this.users=this.table("users"),this.kv=this.table("kv")}}let O="strict",b;function x(a){a.mode&&(O=a.mode),b=a.onIssue}function D(a,t,e){const r=a.safeParse(t);if(r.success)return r.data;const s=r.error.flatten();if(b==null||b(e,s),O==="strict")throw new B(`ORM schema mismatch in ${e}`,s);return O==="warn"&&console.warn(`ORM schema mismatch in ${e}`,s),null}const it={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1},I="manifest",nt=n.z.object({schemaVersion:n.z.number().int()});let h=null,f=null;const L=Symbol("validationInstalled");function C(a,t){const e=a;if(e[L])return;if(e[L]=!0,((i,o,c)=>{i.hook("creating",(u,y)=>{const p=D(o,y,`${c}.creating`);if(!p)throw new Error(`Rejected invalid ${c} on create`);return p}),i.hook("updating",(u,y,p)=>{const d={...p,...u};return D(o,d,`${c}.updating`)?u:{}})})(a.users,g,"users"),(t==null?void 0:t.validateReads)??!0){const i=(t==null?void 0:t.dropInvalidOnRead)??!0;((c,u,y)=>{c.hook("reading",p=>{const d=D(u,p,`${y}.reading`);return d||(i?void 0:p)})})(a.users,g,"users")}}function st(){try{if(typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:U&&U.tagName.toUpperCase()==="SCRIPT"&&U.src||new URL("index.cjs",document.baseURI).href}<"u"&&it)return!1}catch{}try{if(typeof process<"u"&&process.env)return process.env.NODE_ENV!=="production"}catch{}return!1}async function w(a={}){if(h)return h;if(f)return f;const t=a.dbName??"inresi-orm";return f=(async()=>{var e,r,s,i;try{const o=st()?"warn":"strict";x({mode:((e=a.validation)==null?void 0:e.mode)??o,onIssue:(r=a.validation)==null?void 0:r.onIssue});const c=new R(t);c.on("versionchange",()=>{var d;try{c.close()}finally{(d=a.onReset)==null||d.call(a,"versionchange")}}),c.on("blocked",()=>{var d;(d=a.onReset)==null||d.call(a,"blocked")}),await c.open();const u=await c.kv.get(I),y=(u==null?void 0:u.value)??null;if(!y)return await c.transaction("rw",c.kv,async()=>{await c.kv.put({key:I,value:{schemaVersion:m}})}),C(c,a.validation),h=c,c;const p=nt.safeParse(y);if(!p.success||p.data.schemaVersion!==m){await c.delete();const d=new R(t);return d.on("versionchange",()=>{var S;try{d.close()}finally{(S=a.onReset)==null||S.call(a,"versionchange")}}),d.on("blocked",()=>{var S;(S=a.onReset)==null||S.call(a,"blocked")}),await d.open(),await d.kv.put({key:I,value:{schemaVersion:m}}),C(d,a.validation),(s=a.onReset)==null||s.call(a,"incompatible"),h=d,d}return C(c,a.validation),h=c,c}catch(o){throw(i=a.onError)==null||i.call(a,o),new Q("Failed to open IndexedDB",o)}finally{f=null}})(),f}async function ot(a){const t=a??"inresi-orm";if(h)try{await h.close()}catch{}await new R(t).delete(),h=null}async function A(a){const e=await(await w()).kv.get(a);return(e==null?void 0:e.value)??null}async function E(a,t){await(await w()).kv.put({key:a,value:t})}async function ct(a){await(await w()).kv.delete(a)}function lt(a){const t=new Map,e=(a==null?void 0:a.prefix)??"",r=s=>`${e}${s}`;return{async getItem(s){try{const o=await(await w()).kv.get(r(s));return o?JSON.stringify(o.value):null}catch(i){if(a!=null&&a.fallbackToMemory)return t.get(r(s))??null;throw i}},async setItem(s,i){try{await(await w()).kv.put({key:r(s),value:JSON.parse(i)})}catch(o){if(a!=null&&a.fallbackToMemory){t.set(r(s),i);return}throw o}},async removeItem(s){try{await(await w()).kv.delete(r(s))}catch(i){if(a!=null&&a.fallbackToMemory){t.delete(r(s));return}throw i}}}}const N=n.z.object({unitId:n.z.string(),viewedDate:n.z.string()}),H=n.z.object({timezone:n.z.string(),favouriteUnits:n.z.array(n.z.string()).optional(),preferences:n.z.record(n.z.unknown())}),q=n.z.object({id:n.z.string(),slug:n.z.string(),favoritedUnits:n.z.array(n.z.string()),tourContactedOn:n.z.string().nullable(),viewedUnits:n.z.array(N),questionnaireResults:n.z.unknown().nullable().optional(),tourContactData:H.nullable().optional()}),ut=n.z.object({data:n.z.record(q),propertySlug:n.z.string().nullable(),propertyId:n.z.string().nullable(),hasPreviouslySearched:n.z.array(n.z.string())}),dt={data:{},propertySlug:null,propertyId:null,hasPreviouslySearched:[]};class J{async getState(){return await A("property")??dt}async setState(t){const e=await this.getState(),r=t(e);await E("property",r)}async setData(t){await this.setState(e=>({...e,data:t}))}async setPropertySlug(t){await this.setState(e=>({...e,propertySlug:t}))}async setPropertyId(t){await this.setState(e=>({...e,propertyId:t}))}async removeData(t){await this.setState(e=>({...e,data:Object.entries(e.data).filter(([r])=>r!==t).reduce((r,[s,i])=>({...r,[s]:i}),{})}))}async clearData(){await this.setState(t=>({...t,data:{}}))}async setHasPreviouslySearched(t){await this.setState(e=>({...e,hasPreviouslySearched:Array.from(new Set([...e.hasPreviouslySearched,t]))}))}async setTourContactedOn(){await this.setState(t=>{const e=t.propertyId;if(!e)return t;const r=t.data[e];return r?{...t,data:{...t.data,[e]:{...r,tourContactedOn:new Date().toISOString()}}}:t})}async getTourContactedOn(){var r;const t=await this.getState(),e=t.propertyId;return e?((r=t.data[e])==null?void 0:r.tourContactedOn)??null:null}async setQuestionnaireResults(t){await this.setState(e=>{const r=e.propertyId;if(!r)return e;const s=e.data[r];return s?{...e,data:{...e.data,[r]:{...s,questionnaireResults:t}}}:e})}async setTourContactData(t){await this.setState(e=>{const r=e.propertyId;if(!r)return e;const s=e.data[r];return s?{...e,data:{...e.data,[r]:{...s,tourContactData:t}}}:e})}async toggleFavorite(t){await this.setState(e=>{const r=e.propertyId;if(!r)return e;const s=e.data[r];if(!s)return e;const o=s.favoritedUnits.includes(t)?s.favoritedUnits.filter(c=>c!==t):[...s.favoritedUnits,t];return{...e,data:{...e.data,[r]:{...s,favoritedUnits:o}}}})}async markUnitAsViewed(t,e){const r=new Date,s=`${String(r.getMonth()+1).padStart(2,"0")}/${String(r.getDate()).padStart(2,"0")}`;await this.setState(i=>{const o=i.propertyId;if(!o)return i;const c=i.data[o];if(!c)return i;const u=[...c.viewedUnits.filter(y=>y.unitId!==t),{unitId:t,viewedDate:s}];return{...i,data:{...i.data,[o]:{...c,viewedUnits:u}}}}),typeof window<"u"&&window.open(`//${e}`,"_blank")}async getUnitState(t){var s;const e=await this.getState(),r=e.propertyId?e.data[e.propertyId]:null;return{isFavorite:(r==null?void 0:r.favoritedUnits.includes(t))??!1,viewedDate:((s=r==null?void 0:r.viewedUnits.find(i=>i.unitId===t))==null?void 0:s.viewedDate)??""}}async getPropertyData(t){const e=await this.getState(),r=t??e.propertyId;return r?e.data[r]??null:null}async getCurrentProperty(){const t=await this.getState();return t.propertyId?t.data[t.propertyId]??null:null}async getFullState(){return this.getState()}async initializeProperty(t,e){await this.setState(r=>r.data[t]?{...r,propertyId:t,propertySlug:e}:{...r,propertyId:t,propertySlug:e,data:{...r.data,[t]:{id:t,slug:e,favoritedUnits:[],tourContactedOn:null,viewedUnits:[],questionnaireResults:null,tourContactData:null}}})}}const yt=new J,G=n.z.object({isFavorite:n.z.boolean().optional(),viewedDate:n.z.string().optional()}),V=n.z.object({availability:n.z.union([n.z.string(),n.z.array(n.z.string())]).nullable().optional(),bedrooms:n.z.array(n.z.number()).nullable().optional(),cost:n.z.number().nullable().optional(),highlights:n.z.array(n.z.string()).optional()}),K=n.z.object({limit:n.z.number().default(10),page:n.z.number().default(1),availability:n.z.array(n.z.string()).optional(),bedrooms:n.z.array(n.z.number()).optional(),cost:n.z.number().nullable().optional(),highlights:n.z.array(n.z.string()).optional()}),pt=n.z.object({data:n.z.record(G),filters:V,tempFilters:V,apiFilters:K,resultsMode:n.z.enum(["all","bestFit","closestMatch","favorites"]),propertySlug:n.z.string().nullable(),resolvedQuestionnaireValues:n.z.record(n.z.array(n.z.string())),sortBy:n.z.enum(["relevance","newest","priceLowToHigh","priceHighToLow"]),filtersLoaded:n.z.boolean()});n.z.object({isFavorite:n.z.boolean().optional(),viewedDate:n.z.string().optional()});const wt=n.z.object({unitId:n.z.string(),viewedDate:n.z.string()}),ht=n.z.object({timezone:n.z.string(),favouriteUnits:n.z.array(n.z.string()).optional(),preferences:n.z.record(n.z.unknown())}),gt=n.z.object({id:n.z.string(),slug:n.z.string(),favoritedUnits:n.z.array(n.z.string()),tourContactedOn:n.z.string().nullable(),viewedUnits:n.z.array(wt),questionnaireResults:n.z.unknown().nullable().optional(),tourContactData:ht.nullable().optional()}),_=n.z.object({availability:n.z.union([n.z.string(),n.z.array(n.z.string())]).nullable().optional(),bedrooms:n.z.array(n.z.number()).nullable().optional(),cost:n.z.number().nullable().optional(),highlights:n.z.array(n.z.string()).optional()}),St=n.z.object({limit:n.z.number().default(10),page:n.z.number().default(1),availability:n.z.array(n.z.string()).optional(),bedrooms:n.z.array(n.z.number()).optional(),cost:n.z.number().nullable().optional(),highlights:n.z.array(n.z.string()).optional()}),ft=n.z.object({properties:n.z.record(gt),currentPropertyId:n.z.string().nullable(),currentPropertySlug:n.z.string().nullable(),hasPreviouslySearched:n.z.array(n.z.string()),filters:_,tempFilters:_,apiFilters:St,resultsMode:n.z.enum(["all","bestFit","closestMatch","favorites"]),resolvedQuestionnaireValues:n.z.record(n.z.array(n.z.string())),sortBy:n.z.enum(["relevance","newest","priceLowToHigh","priceHighToLow"]),filtersLoaded:n.z.boolean()}),M={availability:void 0,bedrooms:void 0,cost:void 0,highlights:void 0},k={properties:{},currentPropertyId:null,currentPropertySlug:null,hasPreviouslySearched:[],filters:M,tempFilters:M,apiFilters:{limit:10,page:1},resultsMode:"all",resolvedQuestionnaireValues:{},sortBy:"relevance",filtersLoaded:!1};class Z{async getState(){const t=await A("app");return t?{...k,...t,properties:t.properties??{}}:k}async setState(t){const e=await this.getState(),r=t(e);await E("app",r)}async initializeProperty(t,e){await this.setState(r=>r.properties&&r.properties[t]?{...r,currentPropertyId:t,currentPropertySlug:e}:{...r,currentPropertyId:t,currentPropertySlug:e,properties:{...r.properties,[t]:{id:t,slug:e,favoritedUnits:[],tourContactedOn:null,viewedUnits:[],questionnaireResults:null,tourContactData:null}}})}async setCurrentProperty(t,e){await this.setState(r=>({...r,currentPropertyId:t,currentPropertySlug:e||r.currentPropertySlug}))}async setCurrentPropertySlug(t){await this.setState(e=>({...e,currentPropertySlug:t}))}async setHasPreviouslySearched(t){await this.setState(e=>({...e,hasPreviouslySearched:Array.from(new Set([...e.hasPreviouslySearched,t]))}))}async toggleFavorite(t){await this.setState(e=>{const r=e.currentPropertyId;if(!r)return e;const s=e.properties[r];if(!s)return e;const o=s.favoritedUnits.includes(t)?s.favoritedUnits.filter(c=>c!==t):[...s.favoritedUnits,t];return{...e,properties:{...e.properties,[r]:{...s,favoritedUnits:o}}}})}async markUnitAsViewed(t,e){const r=new Date,s=`${String(r.getMonth()+1).padStart(2,"0")}/${String(r.getDate()).padStart(2,"0")}`;await this.setState(i=>{const o=i.currentPropertyId;if(!o)return i;const c=i.properties[o];if(!c)return i;const u=[...c.viewedUnits.filter(y=>y.unitId!==t),{unitId:t,viewedDate:s}];return{...i,properties:{...i.properties,[o]:{...c,viewedUnits:u}}}}),typeof window<"u"&&window.open(`//${e}`,"_blank")}async setTourContactedOn(){await this.setState(t=>{const e=t.currentPropertyId;if(!e)return t;const r=t.properties[e];return r?{...t,properties:{...t.properties,[e]:{...r,tourContactedOn:new Date().toISOString()}}}:t})}async getTourContactedOn(){var r;const t=await this.getState(),e=t.currentPropertyId;return e?((r=t.properties[e])==null?void 0:r.tourContactedOn)??null:null}async setQuestionnaireResults(t){await this.setState(e=>{const r=e.currentPropertyId;if(!r)return e;const s=e.properties[r];return s?{...e,properties:{...e.properties,[r]:{...s,questionnaireResults:t}}}:e})}async setTourContactData(t){await this.setState(e=>{const r=e.currentPropertyId;if(!r)return e;const s=e.properties[r];return s?{...e,properties:{...e.properties,[r]:{...s,tourContactData:t}}}:e})}async setFilters(t){await this.setState(e=>({...e,filters:{...e.filters,...t}}))}async setTempFilters(t){await this.setState(e=>({...e,tempFilters:{...e.tempFilters,...t}}))}async setFiltersToDefault(){await this.setState(t=>({...t,filters:M}))}async setApiFilters(t){await this.setState(e=>({...e,apiFilters:{...e.apiFilters,...t}}))}async handleTempFilterChange(t,e){await this.setState(r=>({...r,tempFilters:{...r.tempFilters,[t]:e}}))}async commitTempFilterChange(t,e){const s=(await this.getState()).tempFilters[t]??e;await this.handleTempFilterChange(t,s),await this.submitFilterUpdate()}async handleFilterCommitIndexDB(t){await this.setState(e=>{const r={...e.apiFilters,availability:t.availability||[],bedrooms:t.bedrooms||[],cost:t.cost||null,highlights:t.highlights||[]};return{...e,filters:{...e.filters,...t},apiFilters:r}})}async commitAvailabilityChange(){await this.submitFilterUpdate()}async submitFilterUpdate(){await this.setState(t=>{const e={...t.apiFilters,availability:t.filters.availability||[],bedrooms:t.filters.bedrooms||[],cost:t.filters.cost||null,highlights:t.filters.highlights||[]};return{...t,apiFilters:e}})}async setResultsMode(t){await this.setState(e=>({...e,resultsMode:t}))}async setSortBy(t){await this.setState(e=>({...e,sortBy:t}))}async setResolvedQuestionnaireValues(t,e){await this.setState(r=>({...r,resolvedQuestionnaireValues:{...r.resolvedQuestionnaireValues,[t]:e}}))}async getUnitState(t){var s;const e=await this.getState(),r=e.currentPropertyId?e.properties[e.currentPropertyId]:null;return{isFavorite:(r==null?void 0:r.favoritedUnits.includes(t))??!1,viewedDate:((s=r==null?void 0:r.viewedUnits.find(i=>i.unitId===t))==null?void 0:s.viewedDate)??""}}async getResultsUrl(){const t=await this.getState();return t.currentPropertySlug?`/${t.currentPropertySlug}/results`:null}async getCurrentProperty(){const t=await this.getState();return t.currentPropertyId?t.properties[t.currentPropertyId]??null:null}async getPropertyData(t){const e=await this.getState(),r=t??e.currentPropertyId;return r?e.properties[r]??null:null}async getFullState(){return this.getState()}async initialize(){const t=await this.getState();Object.keys(t.properties).length===0&&!t.filtersLoaded&&await this.setState(e=>({...k,...e,filtersLoaded:!0}))}async loadPersistedFilters(){await this.setState(t=>({...t,filtersLoaded:!0}))}async setData(t){await this.setState(e=>({...e,properties:t}))}async setPropertySlug(t){await this.setCurrentPropertySlug(t)}async setPropertyId(t){await this.setCurrentProperty(t)}async removeData(t){await this.setState(e=>{const{[t]:r,...s}=e.properties;return{...e,properties:s}})}async clearData(){await this.setState(t=>({...t,properties:{}}))}}const l=new Z,m=1,g=n.z.object({uuid:n.z.string().uuid()}),z=n.z.object({propertyId:n.z.string()||n.z.number(),unitIds:n.z.array(n.z.string())}),v="user",Y=()=>{var a;return typeof((a=globalThis.crypto)==null?void 0:a.randomUUID)=="function"?globalThis.crypto.randomUUID():(()=>{var r,s;const t=((s=(r=globalThis.crypto)==null?void 0:r.getRandomValues)==null?void 0:s.call(r,new Uint8Array(16)))??Uint8Array.from({length:16},()=>Math.random()*256|0);t[6]=t[6]&15|64,t[8]=t[8]&63|128;const e=[...t].map(i=>i.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`})()},T=a=>{var t,e;return((t=a==null?void 0:a.value)==null?void 0:t.useruuid)??((e=a==null?void 0:a.value)==null?void 0:e.uuid)};async function P(a=Y){const t=await w(),e=T(await t.kv.get(v));if(e){const r=await t.users.get(e);if(r)return g.parse(r)}try{return await t.transaction("rw",t.kv,t.users,async()=>{const r=T(await t.kv.get(v));if(r){const o=await t.users.get(r);if(o)return g.parse(o)}const s=a();await t.kv.add({key:v,value:{useruuid:s}});const i=g.parse({uuid:s,createdAt:new Date().toISOString()});return await t.users.add(i),i})}catch(r){if((r==null?void 0:r.name)==="ConstraintError"){const s=T(await t.kv.get(v));if(s){const i=await t.users.get(s);if(i)return g.parse(i)}}throw r}}const mt=async a=>(await P(a)).uuid;async function W(){const a=await w(),t={};for(const e of a.tables)t[e.name]=await e.toArray();return t}async function vt(a="inresi-orm-export.json"){if(typeof window>"u"||typeof document>"u")throw new Error("exportJSON can only run in a browser.");const t=await W(),e=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),r=document.createElement("a");r.href=URL.createObjectURL(e),r.download=a,document.body.appendChild(r),r.click(),r.remove(),URL.revokeObjectURL(r.href)}const X=(a,t)=>`favorites:${a}:${t}`;async function F(a){const t=await w(),{uuid:e}=await P(),r=X(e,String(a)),s=await t.kv.get(r),i=s?z.safeParse(s.value):null;return i!=null&&i.success?i.data.unitIds:[]}async function j(a,t,e){const r=await w(),{uuid:s}=await P(),i=X(s,String(a));return r.transaction("rw",r.kv,async()=>{const o=await r.kv.get(i),c=o&&z.safeParse(o.value).success?o.value:{unitIds:[],updatedAt:new Date().toISOString()},u=new Set(c.unitIds);e?u.add(t):u.delete(t);const y={unitIds:[...u],updatedAt:new Date().toISOString()},p=z.parse(y);return await r.kv.put({key:i,value:p}),p.unitIds})}async function tt(a,t){const r=!(await F(a)).includes(t);return j(a,t,r)}async function et(a,t){return(await F(a)).includes(t)}function $(a){return(t,e)=>{const r=async()=>{const i=await l.getFullState();t({properties:i.properties,currentPropertyId:i.currentPropertyId,currentPropertySlug:i.currentPropertySlug,hasPreviouslySearched:i.hasPreviouslySearched,filters:i.filters,tempFilters:i.tempFilters,apiFilters:i.apiFilters,resultsMode:i.resultsMode,resolvedQuestionnaireValues:i.resolvedQuestionnaireValues,sortBy:i.sortBy,filtersLoaded:i.filtersLoaded})},s=async()=>{if(a!=null&&a.onFilterUpdate){const i=(await l.getFullState()).apiFilters;a.onFilterUpdate(i)}};return{properties:{},currentPropertyId:null,currentPropertySlug:null,hasPreviouslySearched:[],units:{},filters:{availability:void 0,bedrooms:void 0,cost:void 0,highlights:void 0},tempFilters:{availability:void 0,bedrooms:void 0,cost:void 0,highlights:void 0},apiFilters:{limit:10,page:1},resultsMode:"all",resolvedQuestionnaireValues:{},sortBy:"relevance",filtersLoaded:!1,async initializeProperty(i,o){await l.initializeProperty(i,o),await r()},async setCurrentProperty(i,o){await l.setCurrentProperty(i,o),t({currentPropertyId:i,...o&&{currentPropertySlug:o}})},async setCurrentPropertySlug(i){await l.setCurrentPropertySlug(i),t({currentPropertySlug:i})},async setHasPreviouslySearched(i){await l.setHasPreviouslySearched(i),await r()},async toggleFavorite(i){await l.toggleFavorite(i),await r()},async markUnitAsViewed(i,o){await l.markUnitAsViewed(i,o),await r()},async setTourContactedOn(){await l.setTourContactedOn(),await r()},getTourContactedOn:l.getTourContactedOn.bind(l),async setQuestionnaireResults(i){await l.setQuestionnaireResults(i),await r()},async setTourContactData(i){await l.setTourContactData(i),await r()},async setFilters(i){await l.setFilters(i);const o=e();t({filters:{...o.filters,...i}})},async setTempFilters(i){await l.setTempFilters(i);const o=e();t({tempFilters:{...o.tempFilters,...i}})},async setFiltersToDefault(){await l.setFiltersToDefault(),t({filters:{availability:void 0,bedrooms:void 0,cost:void 0,highlights:void 0}})},async setApiFilters(i){await l.setApiFilters(i);const o=e();t({apiFilters:{...o.apiFilters,...i}})},async handleTempFilterChange(i,o){await l.handleTempFilterChange(i,o);const c=e();t({tempFilters:{...c.tempFilters,[i]:o}})},async commitTempFilterChange(i,o){await l.commitTempFilterChange(i,o),await r(),await s()},async handleFilterCommitIndexDB(i){await l.handleFilterCommitIndexDB(i),await r(),await s()},async commitAvailabilityChange(){await l.commitAvailabilityChange(),await r(),await s()},async submitFilterUpdate(){await l.submitFilterUpdate(),await r(),await s()},async setResultsMode(i){await l.setResultsMode(i),t({resultsMode:i})},async setSortBy(i){await l.setSortBy(i),t({sortBy:i})},async setResolvedQuestionnaireValues(i,o){await l.setResolvedQuestionnaireValues(i,o);const c=e();t({resolvedQuestionnaireValues:{...c.resolvedQuestionnaireValues,[i]:o}})},getUnitState(i){var u;const o=e(),c=o.currentPropertyId?o.properties[o.currentPropertyId]:null;return{isFavorite:(c==null?void 0:c.favoritedUnits.includes(i))??!1,viewedDate:((u=c==null?void 0:c.viewedUnits.find(y=>y.unitId===i))==null?void 0:u.viewedDate)??""}},getResultsUrl:l.getResultsUrl.bind(l),getCurrentProperty:l.getCurrentProperty.bind(l),getPropertyData:l.getPropertyData.bind(l),async setData(i){await l.setData(i),t({properties:i})},async setPropertySlug(i){await l.setPropertySlug(i),t({currentPropertySlug:i})},async setPropertyId(i){await l.setPropertyId(i),t({currentPropertyId:i})},async removeData(i){await l.removeData(i),await r()},async clearData(){await l.clearData(),t({properties:{}})},async loadPersistedFilters(){await l.loadPersistedFilters(),t({filtersLoaded:!0})},async _hydrate(){await r()},async _initialize(){await l.initialize(),await r()}}}}function bt(){return a=>t=>a(e=>e.getUnitState(t))}function rt(a){return{property:{unit:{favorites:{toggle:a.toggleFavorite.bind(a)},viewed:{mark:a.markUnitAsViewed.bind(a)}},questionnaire:{setResults:a.setQuestionnaireResults.bind(a)},tour:{setContactedOn:a.setTourContactedOn.bind(a),getContactedOn:a.getTourContactedOn.bind(a),setContactData:a.setTourContactData.bind(a)}},filters:{set:a.setFilters.bind(a),setTemp:a.setTempFilters.bind(a),setToDefault:a.setFiltersToDefault.bind(a),commitTemp:a.commitTempFilterChange.bind(a),commitAvailability:a.commitAvailabilityChange.bind(a),submit:a.submitFilterUpdate.bind(a)}}}function zt(a){return(t,e)=>{const r=$(a)(t,e),s=rt(r);return{...r,...s}}}const Pt={async isFavorite(a,t){return et(a,t)},async toggle(a,t){return tt(a,t)},async set(a,t,e){return j(a,t,e)},async getAll(a){return F(a)}};exports.AppStoreDataSchema=pt;exports.FavoritesSchema=z;exports.FiltersSchema=V;exports.OpenDBError=Q;exports.PropertyDataSchema=q;exports.PropertyStore=J;exports.PropertyStoreDataSchema=ut;exports.QueryParamsSchema=K;exports.SCHEMA_VERSION=m;exports.SchemaMismatchError=B;exports.TourContactDataSchema=H;exports.UnifiedStore=Z;exports.UnifiedStoreDataSchema=ft;exports.UnitDataSchema=G;exports.UserSchema=g;exports.ViewedUnitSchema=N;exports.configureValidation=x;exports.createORMStringStorage=lt;exports.createStructuredStore=zt;exports.createStructuredStoreActions=rt;exports.createUseUnitState=bt;exports.createZustandPropertyStore=$;exports.createZustandUnifiedStore=$;exports.debugDump=W;exports.defaultIdGenerator=Y;exports.ensureUser=P;exports.exportJSON=vt;exports.favorites=Pt;exports.getDB=w;exports.getFavoritedUnitsForProperty=F;exports.getUserUUID=mt;exports.isUnitFavorited=et;exports.kvGet=A;exports.kvRemove=ct;exports.kvSet=E;exports.propertyStore=yt;exports.resetDB=ot;exports.setFavoriteUnit=j;exports.store=l;exports.toggleFavoriteUnit=tt;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("zod"),bt=require("dexie");var N=typeof document<"u"?document.currentScript:null;class it extends Error{constructor(t,e){super(t),this.detail=e,this.name="SchemaMismatchError"}}class st extends Error{constructor(t,e){super(t),this.detail=e,this.name="OpenDBError"}}const z=1,f=n.z.object({uuid:n.z.string().uuid(),createdAt:n.z.string().datetime().optional()}),ot=n.z.object({isFavorite:n.z.boolean().optional(),viewedDate:n.z.string().optional()}),lt=ot,T=n.z.union([n.z.string(),n.z.number(),n.z.boolean(),n.z.record(n.z.unknown())]),zt=n.z.union([T,n.z.array(T)]),U=n.z.object({availability:zt.nullable().optional(),bedrooms:n.z.union([n.z.array(T),n.z.null()]).optional(),cost:n.z.number().nullable().optional(),highlights:n.z.array(T).optional()}),G=n.z.object({limit:n.z.number().default(10),page:n.z.number().default(1),availability:n.z.array(n.z.string()).optional(),bedrooms:n.z.array(n.z.number()).optional(),cost:n.z.number().nullable().optional(),highlights:n.z.array(n.z.string()).optional()}),J=n.z.enum(["all","bestFit","closestMatch","favorites","loading"]),Z=n.z.enum(["relevance","newest","priceLowToHigh","priceHighToLow"]),Ut=n.z.object({data:n.z.record(lt),filters:U,tempFilters:U,apiFilters:G,resultsMode:J,propertySlug:n.z.string().nullable(),resolvedQuestionnaireValues:n.z.record(n.z.array(n.z.string())),sortBy:Z}),v=n.z.object({id:n.z.union([n.z.number().int(),n.z.string()]).optional(),title:n.z.string(),slug:n.z.string().nullable().optional(),bedrooms:n.z.coerce.number().nullable().optional(),bathrooms:n.z.coerce.number().nullable().optional(),cost:n.z.coerce.number().nullable().optional(),totalSqFt:n.z.coerce.number().nullable().optional(),propertyId:n.z.union([n.z.number().int(),n.z.string()]).optional(),isAvailable:n.z.boolean().optional(),createdAt:n.z.string().datetime().optional(),updatedAt:n.z.string().datetime().optional(),availability:n.z.string().datetime().nullable().optional(),unitSetAvailableOn:n.z.string().datetime().nullable().optional(),floorPlanId:n.z.union([n.z.number().int(),n.z.string()]).nullable().optional(),property:n.z.unknown().optional(),amenities:n.z.array(n.z.unknown()).optional(),highlights:n.z.array(n.z.unknown()).optional(),floorPlan:n.z.unknown().nullable().optional(),renderedStyle:n.z.array(n.z.unknown()).optional(),video:n.z.unknown().nullable().optional(),videoThumbnail:n.z.unknown().nullable().optional(),embedGif:n.z.unknown().nullable().optional(),userId:n.z.union([n.z.number().int(),n.z.string()]).optional(),user:n.z.unknown().optional(),status:n.z.string().optional(),externalId:n.z.string().nullable().optional(),unitRenderedStyles:n.z.array(n.z.unknown()).optional()}),w=n.z.object({id:n.z.union([n.z.number().int(),n.z.string()]),createdAt:n.z.string().datetime(),updatedAt:n.z.string().datetime(),title:n.z.string(),slug:n.z.string().nullable().optional(),description:n.z.string(),contactName:n.z.string().nullable().optional(),contactEmail:n.z.string().optional(),contactPhone:n.z.string().nullable().optional(),notificationEmail:n.z.string().nullable().optional(),logo:n.z.unknown().nullable().optional(),leadMedia:n.z.unknown().nullable().optional(),overviewImages:n.z.array(n.z.unknown()).optional(),amenityImages:n.z.array(n.z.unknown()).optional(),street:n.z.string().optional(),city:n.z.string().optional(),state:n.z.string().nullable().optional(),ingestionFileName:n.z.string().nullable().optional(),zip:n.z.string().optional(),country:n.z.string().optional(),units:n.z.array(v).optional(),amenities:n.z.array(n.z.unknown()).optional(),highlights:n.z.array(n.z.unknown()).optional(),externalServices:n.z.array(n.z.unknown()).optional(),userId:n.z.union([n.z.number().int(),n.z.string()]).optional(),user:n.z.unknown().optional(),status:n.z.string().optional(),floorPlans:n.z.array(n.z.unknown()).optional()}),Pt=n.z.object({id:n.z.union([n.z.number().int(),n.z.string()]).optional(),email:n.z.string().email().optional(),firstName:n.z.string().optional(),lastName:n.z.string().optional(),password:n.z.string().optional(),salt:n.z.string().optional(),role:n.z.string().optional(),Property:n.z.array(w).optional(),Unit:n.z.array(v).optional(),floorPlans:n.z.array(n.z.unknown()).optional(),createdAt:n.z.string().datetime().optional(),updatedAt:n.z.string().datetime().optional()}),ct=n.z.object({unitId:n.z.string(),viewedDate:n.z.string()}),ut=n.z.object({timezone:n.z.string().optional(),favouriteUnits:n.z.array(n.z.coerce.string()).optional(),preferences:n.z.record(n.z.unknown()).optional()}),P=n.z.object({id:n.z.coerce.string(),slug:n.z.string(),favoritedUnits:n.z.array(n.z.string()),tourContactedOn:n.z.string().nullable(),viewedUnits:n.z.array(ct),questionnaireResults:n.z.unknown().nullable().optional(),tourContactData:ut.nullable().optional(),data:w.optional()}),R=n.z.object({data:n.z.record(P),propertySlug:n.z.string().nullable(),propertyId:n.z.string().nullable(),hasPreviouslySearched:n.z.array(n.z.string())}),Ft=n.z.object({id:n.z.number().int(),userId:n.z.number().int(),unitId:n.z.number().int(),createdAt:n.z.string().datetime()}),E=n.z.object({unitIds:n.z.array(n.z.string()),updatedAt:n.z.string().datetime()}),k=n.z.object({properties:n.z.record(P),currentPropertyId:n.z.string().nullable(),currentPropertySlug:n.z.string().nullable(),hasPreviouslySearched:n.z.array(n.z.string()),unitResults:n.z.array(v),filters:U,tempFilters:U,apiFilters:G,resultsMode:J,resolvedQuestionnaireValues:n.z.record(n.z.array(n.z.string())),sortBy:Z});class L extends bt{constructor(t="inresi-orm"){super(t),this.version(z).stores({users:"uuid",kv:"key"}),this.users=this.table("users"),this.kv=this.table("kv")}}let Q="strict",A;function dt(r){r.mode&&(Q=r.mode),A=r.onIssue}function m(r,t,e){const a=r.safeParse(t);if(a.success)return a.data;const s=a.error.flatten();if(A==null||A(e,s),Q==="strict")throw new it(`ORM schema mismatch in ${e}`,s);return Q==="warn"&&console.warn(`ORM schema mismatch in ${e}`,s),null}const It={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1},j="manifest",Dt=n.z.object({schemaVersion:n.z.number().int()});let h=null,b=null;const at=Symbol("validationInstalled");function $(r,t){const e=r;if(e[at])return;if(e[at]=!0,((i,o,l)=>{i.hook("creating",(u,d)=>{const y=m(o,d,`${l}.creating`);if(!y)throw new Error(`Rejected invalid ${l} on create`);return y}),i.hook("updating",(u,d,y)=>{const p={...y,...u};return m(o,p,`${l}.updating`)?u:{}})})(r.users,f,"users"),(t==null?void 0:t.validateReads)??!0){const i=(t==null?void 0:t.dropInvalidOnRead)??!0;((l,u,d)=>{l.hook("reading",y=>{const p=m(u,y,`${d}.reading`);return p||(i?void 0:y)})})(r.users,f,"users")}}function Rt(){try{if(typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:N&&N.tagName.toUpperCase()==="SCRIPT"&&N.src||new URL("index.cjs",document.baseURI).href}<"u"&&It)return!1}catch{}try{if(typeof process<"u"&&process.env)return process.env.NODE_ENV!=="production"}catch{}return!1}async function S(r={}){if(h)return h;if(b)return b;const t=r.dbName??"inresi-orm";return b=(async()=>{var e,a,s,i;try{const o=Rt()?"warn":"strict";dt({mode:((e=r.validation)==null?void 0:e.mode)??o,onIssue:(a=r.validation)==null?void 0:a.onIssue});const l=new L(t);l.on("versionchange",()=>{var p;try{l.close()}finally{(p=r.onReset)==null||p.call(r,"versionchange")}}),l.on("blocked",()=>{var p;(p=r.onReset)==null||p.call(r,"blocked")}),await l.open();const u=await l.kv.get(j),d=(u==null?void 0:u.value)??null;if(!d)return await l.transaction("rw",l.kv,async()=>{await l.kv.put({key:j,value:{schemaVersion:z}})}),$(l,r.validation),h=l,l;const y=Dt.safeParse(d);if(!y.success||y.data.schemaVersion!==z){await l.delete();const p=new L(t);return p.on("versionchange",()=>{var g;try{p.close()}finally{(g=r.onReset)==null||g.call(r,"versionchange")}}),p.on("blocked",()=>{var g;(g=r.onReset)==null||g.call(r,"blocked")}),await p.open(),await p.kv.put({key:j,value:{schemaVersion:z}}),$(p,r.validation),(s=r.onReset)==null||s.call(r,"incompatible"),h=p,p}return $(l,r.validation),h=l,l}catch(o){throw(i=r.onError)==null||i.call(r,o),new st("Failed to open IndexedDB",o)}finally{b=null}})(),b}async function kt(r){const t=r??"inresi-orm";if(h)try{await h.close()}catch{}await new L(t).delete(),h=null}const F="user",pt=()=>{var r;return typeof((r=globalThis.crypto)==null?void 0:r.randomUUID)=="function"?globalThis.crypto.randomUUID():(()=>{var a,s;const t=((s=(a=globalThis.crypto)==null?void 0:a.getRandomValues)==null?void 0:s.call(a,new Uint8Array(16)))??Uint8Array.from({length:16},()=>Math.random()*256|0);t[6]=t[6]&15|64,t[8]=t[8]&63|128;const e=[...t].map(i=>i.toString(16).padStart(2,"0")).join("");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20)}`})()},x=r=>{var t,e;return((t=r==null?void 0:r.value)==null?void 0:t.useruuid)??((e=r==null?void 0:r.value)==null?void 0:e.uuid)};async function M(r=pt){const t=await S(),e=x(await t.kv.get(F));if(e){const a=await t.users.get(e);if(a)return f.parse(a)}try{return await t.transaction("rw",t.kv,t.users,async()=>{const a=x(await t.kv.get(F));if(a){const o=await t.users.get(a);if(o)return f.parse(o)}const s=r();await t.kv.add({key:F,value:{useruuid:s}});const i=f.parse({uuid:s,createdAt:new Date().toISOString()});return await t.users.add(i),i})}catch(a){if((a==null?void 0:a.name)==="ConstraintError"){const s=x(await t.kv.get(F));if(s){const i=await t.users.get(s);if(i)return f.parse(i)}}throw a}}const At=async r=>(await M(r)).uuid;async function yt(){const r=await S(),t={};for(const e of r.tables)t[e.name]=await e.toArray();return t}async function Ct(r="inresi-orm-export.json"){if(typeof window>"u"||typeof document>"u")throw new Error("exportJSON can only run in a browser.");const t=await yt(),e=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),a=document.createElement("a");a.href=URL.createObjectURL(e),a.download=r,document.body.appendChild(a),a.click(),a.remove(),URL.revokeObjectURL(a.href)}async function K(r){const e=await(await S()).kv.get(r);return(e==null?void 0:e.value)??null}async function W(r,t){await(await S()).kv.put({key:r,value:t})}async function Ot(r){await(await S()).kv.delete(r)}function Tt(r){const t=new Map,e=(r==null?void 0:r.prefix)??"",a=s=>`${e}${s}`;return{async getItem(s){try{const o=await(await S()).kv.get(a(s));return o?JSON.stringify(o.value):null}catch(i){if(r!=null&&r.fallbackToMemory)return t.get(a(s))??null;throw i}},async setItem(s,i){try{await(await S()).kv.put({key:a(s),value:JSON.parse(i)})}catch(o){if(r!=null&&r.fallbackToMemory){t.set(a(s),i);return}throw o}},async removeItem(s){try{await(await S()).kv.delete(a(s))}catch(i){if(r!=null&&r.fallbackToMemory){t.delete(a(s));return}throw i}}}}const gt=(r,t)=>`favorites:${r}:${t}`;async function V(r){const t=await S(),{uuid:e}=await M(),a=gt(e,String(r)),s=await t.kv.get(a),i=s?E.safeParse(s.value):null;return i!=null&&i.success?i.data.unitIds:[]}async function Y(r,t,e){const a=await S(),{uuid:s}=await M(),i=gt(s,String(r));return a.transaction("rw",a.kv,async()=>{const o=await a.kv.get(i),l=o&&E.safeParse(o.value).success?o.value:{unitIds:[],updatedAt:new Date().toISOString()},u=new Set(l.unitIds);e?u.add(t):u.delete(t);const d={unitIds:[...u],updatedAt:new Date().toISOString()},y=E.parse(d);return await a.kv.put({key:i,value:y}),y.unitIds})}async function St(r,t){const a=!(await V(r)).includes(t);return Y(r,t,a)}async function mt(r,t){return(await V(r)).includes(t)}const B={data:{},propertySlug:null,propertyId:null,hasPreviouslySearched:[]};class ht{async getState(){const t=await K("property");if(!t)return B;const e={...t,propertyId:t.propertyId==null?null:String(t.propertyId),propertySlug:t.propertySlug??null,hasPreviouslySearched:Array.isArray(t.hasPreviouslySearched)?t.hasPreviouslySearched.map(String):[]},a=R.safeParse(e);if(a.success)return a.data;const s=Object.entries(e.data??{}).reduce((l,[u,d])=>{const y=P.safeParse(d);return y.success&&(l[u]=y.data),l},{}),i={...B,...e,data:s},o=R.safeParse(i);return o.success?o.data:B}async setState(t){const e=await this.getState(),a=t(e),s=R.parse(a);await W("property",s)}async setData(t){await this.setState(e=>({...e,data:t}))}async setPropertySlug(t){await this.setState(e=>({...e,propertySlug:t}))}async setPropertyId(t){await this.setState(e=>({...e,propertyId:String(t)}))}async removeData(t){const e=String(t);await this.setState(a=>({...a,data:Object.entries(a.data).filter(([s])=>s!==e).reduce((s,[i,o])=>({...s,[i]:o}),{})}))}async clearData(){await this.setState(t=>({...t,data:{}}))}async setHasPreviouslySearched(t){await this.setState(e=>({...e,hasPreviouslySearched:Array.from(new Set([...e.hasPreviouslySearched,t]))}))}async setTourContactedOn(){await this.setState(t=>{const e=t.propertyId;if(!e)return t;const a=t.data[e];return a?{...t,data:{...t.data,[e]:{...a,tourContactedOn:new Date().toISOString()}}}:t})}async getTourContactedOn(){var a;const t=await this.getState(),e=t.propertyId;return e?((a=t.data[e])==null?void 0:a.tourContactedOn)??null:null}async setQuestionnaireResults(t){await this.setState(e=>{const a=e.propertyId;if(!a)return e;const s=e.data[a];return s?{...e,data:{...e.data,[a]:{...s,questionnaireResults:t}}}:e})}async setTourContactData(t){await this.setState(e=>{const a=e.propertyId;if(!a)return e;const s=e.data[a];return s?{...e,data:{...e.data,[a]:{...s,tourContactData:t}}}:e})}async toggleFavorite(t){await this.setState(e=>{const a=e.propertyId;if(!a)return e;const s=e.data[a];if(!s)return e;const o=s.favoritedUnits.includes(t)?s.favoritedUnits.filter(l=>l!==t):[...s.favoritedUnits,t];return{...e,data:{...e.data,[a]:{...s,favoritedUnits:o}}}})}async markUnitAsViewed(t,e){const a=new Date,s=`${String(a.getMonth()+1).padStart(2,"0")}/${String(a.getDate()).padStart(2,"0")}`;await this.setState(i=>{const o=i.propertyId;if(!o)return i;const l=i.data[o];if(!l)return i;const u=[...l.viewedUnits.filter(d=>d.unitId!==t),{unitId:t,viewedDate:s}];return{...i,data:{...i.data,[o]:{...l,viewedUnits:u}}}}),typeof window<"u"&&window.open(`//${e}`,"_blank")}async getUnitState(t){var s;const e=await this.getState(),a=e.propertyId?e.data[e.propertyId]:null;return{isFavorite:(a==null?void 0:a.favoritedUnits.includes(t))??!1,viewedDate:((s=a==null?void 0:a.viewedUnits.find(i=>i.unitId===t))==null?void 0:s.viewedDate)??""}}async getPropertyData(t){const e=await this.getState(),a=t==null?e.propertyId:String(t);return a?e.data[a]??null:null}async getCurrentProperty(){const t=await this.getState();return t.propertyId?t.data[t.propertyId]??null:null}async getFullState(){return this.getState()}async initializeProperty(t,e){const a=String(t);await this.setState(s=>s.data[a]?{...s,propertyId:a,propertySlug:e}:{...s,propertyId:a,propertySlug:e,data:{...s.data,[a]:{id:a,slug:e,favoritedUnits:[],tourContactedOn:null,viewedUnits:[],questionnaireResults:null,tourContactData:null}}})}}const Et=new ht,H={availability:void 0,bedrooms:void 0,cost:void 0,highlights:void 0},I={properties:{},currentPropertyId:null,currentPropertySlug:null,hasPreviouslySearched:[],unitResults:[],filters:H,tempFilters:H,apiFilters:{limit:10,page:1},resultsMode:"all",resolvedQuestionnaireValues:{},sortBy:"relevance"},Mt=r=>r==null?[]:Array.isArray(r)?r:[r],ft=r=>Mt(r).flatMap(t=>{if(t==null)return[];if(Array.isArray(t))return t;if(typeof t=="object"&&"value"in t){const e=t.value;return Array.isArray(e)?e:e!=null?[e]:[]}return[t]}),D=r=>ft(r).flatMap(t=>Array.isArray(t)?t:[t]).map(t=>String(t)).map(t=>t.trim()).filter(t=>t.length>0),nt=r=>ft(r).map(t=>{if(typeof t=="number"&&Number.isFinite(t))return t;const e=Number(t);return Number.isFinite(e)?e:null}).filter(t=>t!==null),q=r=>{if(r==null)return null;if(typeof r=="number")return Number.isFinite(r)?r:null;if(typeof r=="object"&&"value"in r)return q(r.value);const t=Number(r);return Number.isFinite(t)?t:null};class X{async getState(){const t=await K("app");if(!t)return I;const e={...I,...t,properties:t.properties??{},unitResults:t.unitResults??[],currentPropertyId:t.currentPropertyId==null?null:String(t.currentPropertyId),currentPropertySlug:t.currentPropertySlug??null,hasPreviouslySearched:Array.isArray(t.hasPreviouslySearched)?t.hasPreviouslySearched.map(String):[]},a=k.safeParse(e);if(a.success)return a.data;const s=Object.entries(e.properties??{}).reduce((d,[y,p])=>{const g=P.safeParse(p);return g.success&&(d[y]=g.data),d},{}),o=(Array.isArray(e.unitResults)?e.unitResults:e.unitResults&&typeof e.unitResults=="object"?Object.values(e.unitResults):[]).reduce((d,y)=>{const p=v.safeParse(y);return p.success&&d.push(p.data),d},[]),l={...e,properties:s,unitResults:o},u=k.safeParse(l);return u.success?u.data:I}async setState(t){const e=await this.getState(),a=t(e),s=k.parse(a);await W("app",s)}async initializeProperty(t,e){const a=String(t);await this.setState(s=>s.properties&&s.properties[a]?{...s,currentPropertyId:a,currentPropertySlug:e}:{...s,currentPropertyId:a,currentPropertySlug:e,properties:{...s.properties,[a]:{id:a,slug:e,favoritedUnits:[],tourContactedOn:null,viewedUnits:[],questionnaireResults:null,tourContactData:null}}})}async setUnitResults(t,e){console.log(t);const a=e??v,s=[];(Array.isArray(t)?t:t&&typeof t=="object"?Object.values(t):[]).forEach((o,l)=>{const u=m(a,o,`unitResults[${l}]`);u&&s.push(u)}),await this.setState(o=>({...o,unitResults:s}))}async clearUnitResults(){await this.setState(t=>({...t,unitResults:[]}))}async setPropertyData(t,e,a){const s=String(t),i=a??w;await this.setState(o=>{const l=o.properties[s];if(!l)return o;const u=m(i,e,`properties.${s}.data`);return u?{...o,properties:{...o.properties,[s]:{...l,data:u}}}:o})}async mergePropertyData(t,e,a){const s=String(t),i=a??w;await this.setState(o=>{const l=o.properties[s];if(!l)return o;const u=l.data;if(!u){const g=m(i,e,`properties.${s}.data`);return g?{...o,properties:{...o.properties,[s]:{...l,data:g}}}:o}const d=i.partial(),y=m(d,e,`properties.${s}.data.partial`);if(!y)return o;const p=m(i,{...u,...y},`properties.${s}.data`);return p?{...o,properties:{...o.properties,[s]:{...l,data:p}}}:o})}async upsertPropertyFromApi(t,e){const s=(e??w).parse(t),i=s.id??s.propertyId;if(i==null)throw new Error("upsertPropertyFromApi: property id is required");const o=String(i),l=s.slug??void 0;await this.setState(u=>{const d=u.properties[o],y=d?{...d,...l?{slug:l}:{},data:s}:{id:o,slug:l??"",favoritedUnits:[],tourContactedOn:null,viewedUnits:[],questionnaireResults:null,tourContactData:null,data:s};return{...u,properties:{...u.properties,[o]:y}}})}async setCurrentProperty(t,e){const a=String(t);await this.setState(s=>({...s,currentPropertyId:a,currentPropertySlug:e||s.currentPropertySlug}))}async setCurrentPropertySlug(t){await this.setState(e=>({...e,currentPropertySlug:t}))}async setHasPreviouslySearched(t){await this.setState(e=>({...e,hasPreviouslySearched:Array.from(new Set([...e.hasPreviouslySearched,t]))}))}async toggleFavorite(t){await this.setState(e=>{const a=e.currentPropertyId;if(!a)return e;const s=e.properties[a];if(!s)return e;const o=s.favoritedUnits.includes(t)?s.favoritedUnits.filter(l=>l!==t):[...s.favoritedUnits,t];return{...e,properties:{...e.properties,[a]:{...s,favoritedUnits:o}}}})}async markUnitAsViewed(t,e){const a=new Date,s=`${String(a.getMonth()+1).padStart(2,"0")}/${String(a.getDate()).padStart(2,"0")}`;await this.setState(i=>{const o=i.currentPropertyId;if(!o)return i;const l=i.properties[o];if(!l)return i;const u=[...l.viewedUnits.filter(d=>d.unitId!==t),{unitId:t,viewedDate:s}];return{...i,properties:{...i.properties,[o]:{...l,viewedUnits:u}}}}),typeof window<"u"&&window.open(`//${e}`,"_blank")}async setTourContactedOn(){await this.setState(t=>{const e=t.currentPropertyId;if(!e)return t;const a=t.properties[e];return a?{...t,properties:{...t.properties,[e]:{...a,tourContactedOn:new Date().toISOString()}}}:t})}async getTourContactedOn(){var a;const t=await this.getState(),e=t.currentPropertyId;return e?((a=t.properties[e])==null?void 0:a.tourContactedOn)??null:null}async setQuestionnaireResults(t){await this.setState(e=>{const a=e.currentPropertyId;if(!a)return e;const s=e.properties[a];return s?{...e,properties:{...e.properties,[a]:{...s,questionnaireResults:t}}}:e})}async setTourContactData(t){await this.setState(e=>{const a=e.currentPropertyId;if(!a)return e;const s=e.properties[a];return s?{...e,properties:{...e.properties,[a]:{...s,tourContactData:t}}}:e})}async setFilters(t){await this.setState(e=>({...e,filters:{...e.filters,...t}}))}async setTempFilters(t){await this.setState(e=>({...e,tempFilters:{...e.tempFilters,...t}}))}async setFiltersToDefault(){await this.setState(t=>({...t,filters:H}))}async setApiFilters(t){await this.setState(e=>({...e,apiFilters:{...e.apiFilters,...t}}))}async handleTempFilterChange(t,e){await this.setState(a=>({...a,tempFilters:{...a.tempFilters,[t]:e}}))}async commitTempFilterChange(t,e){const s=(await this.getState()).tempFilters[t]??e;await this.handleTempFilterChange(t,s),await this.submitFilterUpdate()}async handleFilterCommitIndexDB(t){await this.setState(e=>{const a={...e.apiFilters,availability:D(t.availability),bedrooms:nt(t.bedrooms),cost:q(t.cost),highlights:D(t.highlights)};return{...e,filters:{...e.filters,...t},apiFilters:a}})}async commitAvailabilityChange(){await this.submitFilterUpdate()}async submitFilterUpdate(){await this.setState(t=>{const e={...t.apiFilters,availability:D(t.filters.availability),bedrooms:nt(t.filters.bedrooms),cost:q(t.filters.cost),highlights:D(t.filters.highlights)};return{...t,apiFilters:e}})}async setResultsMode(t){await this.setState(e=>({...e,resultsMode:t}))}async setSortBy(t){await this.setState(e=>({...e,sortBy:t}))}async setResolvedQuestionnaireValues(t,e){await this.setState(a=>({...a,resolvedQuestionnaireValues:{...a.resolvedQuestionnaireValues,[t]:e}}))}async getUnitState(t){var s;const e=await this.getState(),a=e.currentPropertyId?e.properties[e.currentPropertyId]:null;return{isFavorite:(a==null?void 0:a.favoritedUnits.includes(t))??!1,viewedDate:((s=a==null?void 0:a.viewedUnits.find(i=>i.unitId===t))==null?void 0:s.viewedDate)??""}}async getResultsUrl(){const t=await this.getState();return t.currentPropertySlug?`/${t.currentPropertySlug}/results`:null}async getCurrentProperty(){const t=await this.getState();return t.currentPropertyId?t.properties[t.currentPropertyId]??null:null}async getPropertyData(t){const e=await this.getState(),a=t==null?e.currentPropertyId:String(t);return a?e.properties[a]??null:null}async getFullState(){return this.getState()}async initialize(){await this.setState(t=>({...I,...t}))}async loadPersistedFilters(){}async setData(t){await this.setState(e=>({...e,properties:t}))}async setPropertySlug(t){await this.setCurrentPropertySlug(t)}async setPropertyId(t){await this.setCurrentProperty(t)}async removeData(t){const e=String(t);await this.setState(a=>{const{[e]:s,...i}=a.properties;return{...a,properties:i}})}async clearData(){await this.setState(t=>({...t,properties:{}}))}}const c=new X;function _(r){return(t,e)=>{const a=async()=>{const i=await c.getFullState();t({properties:i.properties,currentPropertyId:i.currentPropertyId,currentPropertySlug:i.currentPropertySlug,hasPreviouslySearched:i.hasPreviouslySearched,unitResults:i.unitResults,filters:i.filters,tempFilters:i.tempFilters,apiFilters:i.apiFilters,resultsMode:i.resultsMode,resolvedQuestionnaireValues:i.resolvedQuestionnaireValues,sortBy:i.sortBy})},s=async()=>{if(r!=null&&r.onFilterUpdate){const i=(await c.getFullState()).apiFilters;r.onFilterUpdate(i)}};return{properties:{},currentPropertyId:null,currentPropertySlug:null,hasPreviouslySearched:[],unitResults:[],filters:{availability:void 0,bedrooms:void 0,cost:void 0,highlights:void 0},tempFilters:{availability:void 0,bedrooms:void 0,cost:void 0,highlights:void 0},apiFilters:{limit:10,page:1},resultsMode:"all",resolvedQuestionnaireValues:{},sortBy:"relevance",filtersLoaded:!1,async initializeProperty(i,o){await c.initializeProperty(i,o),await a()},async setCurrentProperty(i,o){await c.setCurrentProperty(i,o),t({currentPropertyId:i,...o&&{currentPropertySlug:o}})},async setCurrentPropertySlug(i){await c.setCurrentPropertySlug(i),t({currentPropertySlug:i})},async setHasPreviouslySearched(i){await c.setHasPreviouslySearched(i),await a()},async toggleFavorite(i){await c.toggleFavorite(i),await a()},async markUnitAsViewed(i,o){await c.markUnitAsViewed(i,o),await a()},async setTourContactedOn(){await c.setTourContactedOn(),await a()},getTourContactedOn:c.getTourContactedOn.bind(c),async setQuestionnaireResults(i){await c.setQuestionnaireResults(i),await a()},async setTourContactData(i){await c.setTourContactData(i),await a()},async setUnitResults(i){await c.setUnitResults(i),await a()},async clearUnitResults(){await c.clearUnitResults(),await a()},async setFilters(i){await c.setFilters(i);const o=e();t({filters:{...o.filters,...i}})},async setTempFilters(i){await c.setTempFilters(i);const o=e();t({tempFilters:{...o.tempFilters,...i}})},async setFiltersToDefault(){await c.setFiltersToDefault(),t({filters:{availability:void 0,bedrooms:void 0,cost:void 0,highlights:void 0}})},async setApiFilters(i){await c.setApiFilters(i);const o=e();t({apiFilters:{...o.apiFilters,...i}})},async handleTempFilterChange(i,o){await c.handleTempFilterChange(i,o);const l=e();t({tempFilters:{...l.tempFilters,[i]:o}})},async commitTempFilterChange(i,o){await c.commitTempFilterChange(i,o),await a(),await s()},async handleFilterCommitIndexDB(i){await c.handleFilterCommitIndexDB(i),await a(),await s()},async commitAvailabilityChange(){await c.commitAvailabilityChange(),await a(),await s()},async submitFilterUpdate(){await c.submitFilterUpdate(),await a(),await s()},async setResultsMode(i){await c.setResultsMode(i),t({resultsMode:i})},async setSortBy(i){await c.setSortBy(i),t({sortBy:i})},async setResolvedQuestionnaireValues(i,o){await c.setResolvedQuestionnaireValues(i,o);const l=e();t({resolvedQuestionnaireValues:{...l.resolvedQuestionnaireValues,[i]:o}})},getUnitState(i){var u;const o=e(),l=o.currentPropertyId?o.properties[o.currentPropertyId]:null;return{isFavorite:(l==null?void 0:l.favoritedUnits.includes(i))??!1,viewedDate:((u=l==null?void 0:l.viewedUnits.find(d=>d.unitId===i))==null?void 0:u.viewedDate)??""}},getResultsUrl:c.getResultsUrl.bind(c),getCurrentProperty:c.getCurrentProperty.bind(c),getPropertyData:c.getPropertyData.bind(c),async setData(i){await c.setData(i),t({properties:i})},async setPropertySlug(i){await c.setPropertySlug(i),t({currentPropertySlug:i})},async setPropertyId(i){await c.setPropertyId(i),t({currentPropertyId:i})},async removeData(i){await c.removeData(i),await a()},async clearData(){await c.clearData(),t({properties:{}})},async loadPersistedFilters(){await c.loadPersistedFilters(),t({filtersLoaded:!0})},async _hydrate(){await a()},async _initialize(){await c.initialize(),await a(),t({filtersLoaded:!0})}}}}function Vt(){return r=>t=>r(e=>e.getUnitState(t))}function wt(r){return{property:{unit:{favorites:{toggle:r.toggleFavorite.bind(r)},viewed:{mark:r.markUnitAsViewed.bind(r)}},questionnaire:{setResults:r.setQuestionnaireResults.bind(r)},tour:{setContactedOn:r.setTourContactedOn.bind(r),getContactedOn:r.getTourContactedOn.bind(r),setContactData:r.setTourContactData.bind(r)}},filters:{set:r.setFilters.bind(r),setTemp:r.setTempFilters.bind(r),setToDefault:r.setFiltersToDefault.bind(r),commitTemp:r.commitTempFilterChange.bind(r),commitAvailability:r.commitAvailabilityChange.bind(r),submit:r.submitFilterUpdate.bind(r)}}}function _t(r){return(t,e)=>{const a=_(r)(t,e),s=wt(a);return{...a,...s}}}const Nt={async isFavorite(r,t){return mt(r,t)},async toggle(r,t){return St(r,t)},async set(r,t,e){return Y(r,t,e)},async getAll(r){return V(r)}},tt="https://web.inresiapp.com",et="/placeholder.jpg",jt=r=>r?r.startsWith("?")?r:`?${r}`:"",vt=(r,t,e=tt)=>`${e}/${t}/unit/${r}/explore`,C=(r,t=et)=>!(r!=null&&r.CFURL)||!(r!=null&&r.name)||!(r!=null&&r.signature)?t:`${r.CFURL}${r.name}${jt(r.signature)}`;function $t(r){return{data:r}}function xt(r,t,e){var o,l;const a=(e==null?void 0:e.origin)??tt,s=(e==null?void 0:e.placeholderImage)??et,i=((o=r.hits)==null?void 0:o.map(u=>{var g,rt;const d=u._source??{},y=typeof d.name=="string"?d.name:typeof d.title=="string"?d.title:"";return{...d,title:y,slug:vt(String(d.slug??""),t,a),imageUrl:C(d.image,s),secondaryImageUrl:C((g=d.additionalImages)==null?void 0:g[0],s),tertiaryImageUrl:C((rt=d.additionalImages)==null?void 0:rt[1],s)}}))??[];return{total:((l=r.total)==null?void 0:l.value)??i.length,maxScore:r.max_score??null,type:r.type??"units",hits:i}}const Bt={asap:"ASAP",next_month:"Next Month","2_3_months":"2-3 Months",all:"Just Browsing"},O={0:"Studio",1:"1 Bed",2:"2 Bed",3:"3+ Bed"},Lt=new Set(Object.values(O)),Qt=r=>{if(!r||r.length===0)return;const t=new Set;for(const e of r){if(typeof e=="number"){const s=O[e];s&&t.add(s);continue}const a=e.split(",").map(s=>s.trim());for(const s of a){const i=Number.parseInt(s,10);!Number.isNaN(i)&&O[i]?t.add(O[i]):Lt.has(s)&&t.add(s)}}return t.size>0?Array.from(t):void 0},Ht=r=>({availability:r.availability&&r.availability.length>0?r.availability.map(e=>Bt[e]??e):void 0,bedrooms:Qt(r.bedrooms),cost:r.cost??void 0,highlights:r.highlights??[]});exports.ApiUserSchema=Pt;exports.AppStoreDataSchema=Ut;exports.DEFAULT_PLACEHOLDER_IMAGE=et;exports.DEFAULT_WEB_ORIGIN=tt;exports.FavoritesSchema=E;exports.FiltersSchema=U;exports.OpenDBError=st;exports.PropertySchema=w;exports.PropertyStore=ht;exports.PropertyStoreDataSchema=R;exports.QueryParamsSchema=G;exports.ResultsModeEnum=J;exports.SCHEMA_VERSION=z;exports.SchemaMismatchError=it;exports.SortByEnum=Z;exports.Store=X;exports.TourContactDataSchema=ut;exports.UnifiedStore=X;exports.UnifiedStoreDataSchema=k;exports.UnitDataSchema=lt;exports.UnitFavoriteSchema=Ft;exports.UnitSchema=v;exports.UserPropertyStateSchema=P;exports.UserSchema=f;exports.UserUnitDataSchema=ot;exports.ViewedUnitSchema=ct;exports.buildExploreUrl=vt;exports.buildImageUrl=C;exports.configureValidation=dt;exports.createORMStringStorage=Tt;exports.createStructuredStore=_t;exports.createStructuredStoreActions=wt;exports.createUseUnitState=Vt;exports.createZustandPropertyStore=_;exports.createZustandStore=_;exports.createZustandUnifiedStore=_;exports.debugDump=yt;exports.defaultIdGenerator=pt;exports.ensureUser=M;exports.exportJSON=Ct;exports.favorites=Nt;exports.getDB=S;exports.getFavoritedUnitsForProperty=V;exports.getUserUUID=At;exports.isUnitFavorited=mt;exports.kvGet=K;exports.kvRemove=Ot;exports.kvSet=W;exports.propertyStore=Et;exports.resetDB=kt;exports.setFavoriteUnit=Y;exports.store=c;exports.toggleFavoriteUnit=St;exports.transformUnitsApiResponse=$t;exports.transformUnitsApiResponseToClient=xt;exports.transformUnitsApiResponseToClientFilters=Ht;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|