This commit is contained in:
2026-03-13 16:41:55 +04:00
parent 1f8c076051
commit 90b7b1cf01
4 changed files with 200 additions and 3 deletions

118
dist/places.js vendored
View File

@@ -27,9 +27,33 @@ const placeSchema = {
},
required: ['id', 'title', 'lat', 'lon', 'geohash', 'createdAt'],
};
const listSchema = {
type: 'object',
properties: {
id: { type: 'string' },
title: { type: 'string' },
color: { type: 'string' },
placeRefs: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'string' },
geohash: { type: 'string' },
},
required: ['id', 'geohash'],
},
default: [],
},
createdAt: { type: 'string', format: 'date-time' },
updatedAt: { type: 'string', format: 'date-time' },
},
required: ['id', 'title', 'placeRefs', 'createdAt'],
};
const Places = function (privateClient /*, publicClient: BaseClient */) {
// Define Schema
privateClient.declareType('place', placeSchema);
privateClient.declareType('list', listSchema);
// Helper to normalize place object
function preparePlace(data) {
const now = new Date().toISOString();
@@ -67,7 +91,91 @@ const Places = function (privateClient /*, publicClient: BaseClient */) {
const p2 = geohash.substring(2, 4);
return `${p1}/${p2}/${id}`;
}
const lists = {
async getAll() {
const result = await privateClient.getAll('_lists/');
if (!result)
return [];
// Normalize result: remoteStorage.getAll returns { 'slug': object }
return Object.values(result);
},
async get(id) {
const path = `_lists/${id}`;
return privateClient.getObject(path);
},
async create(id, title, color) {
const path = `_lists/${id}`;
let list = (await privateClient.getObject(path));
const now = new Date().toISOString();
if (list) {
// Update existing
list.title = title;
if (color)
list.color = color;
list.updatedAt = now;
}
else {
// Create new
list = {
id,
title,
color,
placeRefs: [],
createdAt: now,
updatedAt: now,
};
}
await privateClient.storeObject('list', path, list);
return list;
},
async delete(id) {
await privateClient.remove(`_lists/${id}`);
},
async addPlace(listId, placeId, geohash) {
const path = `_lists/${listId}`;
const list = (await privateClient.getObject(path));
if (!list) {
throw new Error(`List not found: ${listId}`);
}
const index = list.placeRefs.findIndex((ref) => ref.id === placeId);
if (index === -1) {
// Add only if not present
list.placeRefs.push({ id: placeId, geohash });
list.updatedAt = new Date().toISOString();
await privateClient.storeObject('list', path, list);
}
return list;
},
async removePlace(listId, placeId) {
const path = `_lists/${listId}`;
const list = (await privateClient.getObject(path));
if (!list) {
throw new Error(`List not found: ${listId}`);
}
const index = list.placeRefs.findIndex((ref) => ref.id === placeId);
if (index !== -1) {
// Remove only if present
list.placeRefs.splice(index, 1);
list.updatedAt = new Date().toISOString();
await privateClient.storeObject('list', path, list);
}
return list;
},
async initDefaults() {
const defaults = [
{ id: 'to-go', title: 'Want to go', color: '#2e9e4f' }, // Green
{ id: 'to-do', title: 'To do', color: '#2a7fff' }, // Blue
];
for (const def of defaults) {
const existing = await this.get(def.id);
if (!existing) {
await this.create(def.id, def.title, def.color);
}
}
},
};
const places = {
lists,
/**
* Store a place.
* Generates ID and Geohash if missing.
@@ -87,6 +195,16 @@ const Places = function (privateClient /*, publicClient: BaseClient */) {
if (!id || !geohash) {
throw new Error('Both id and geohash are required to remove a place');
}
// Cleanup: Remove this place from all lists
const allLists = await lists.getAll();
await Promise.all(allLists.map(async (list) => {
const index = list.placeRefs.findIndex((ref) => ref.id === id);
if (index !== -1) {
list.placeRefs.splice(index, 1);
list.updatedAt = new Date().toISOString();
await privateClient.storeObject('list', `_lists/${list.id}`, list);
}
}));
const path = getPath(geohash, id);
return privateClient.remove(path);
},