Skip to content

Commit a8f3f0e

Browse files
committed
Optimize pragmatic solution
1 parent b32ba47 commit a8f3f0e

File tree

1 file changed

+52
-62
lines changed

1 file changed

+52
-62
lines changed

Pragmatic/static/storage.js

Lines changed: 52 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@ class Database {
2222
resolve();
2323
};
2424
request.onerror = (event) => {
25-
reject(
26-
event.target.error ??
27-
new Error(`IndexedDB: can't open ${this.#name}`),
28-
);
25+
let { error } = event.target;
26+
if (!error) error = new Error(`IndexedDB: can't open ${this.#name}`);
27+
reject(error);
2928
};
3029
});
3130
return this;
@@ -61,79 +60,70 @@ class Database {
6160
}
6261

6362
insert({ store, record }) {
64-
return this.#exec(store, (s) => s.add(record));
63+
return this.#exec(store, (objectStore) => objectStore.add(record));
6564
}
6665

6766
update({ store, record }) {
68-
return this.#exec(store, (s) => s.put(record));
67+
return this.#exec(store, (objectStore) => objectStore.put(record));
6968
}
7069

7170
delete({ store, id }) {
72-
return this.#exec(store, (s) => s.delete(id));
71+
return this.#exec(store, (objectStore) => objectStore.delete(id));
7372
}
7473

7574
get({ store, id }) {
76-
return this.#exec(
77-
store,
78-
(s) => {
79-
const req = s.get(id);
80-
return new Promise((resolve, reject) => {
81-
req.onsuccess = () => resolve(req.result);
82-
req.onerror = () => reject(req.error ?? new Error(`Can't get ${id}`));
83-
});
84-
},
85-
'readonly',
86-
);
75+
const op = (objectStore) => {
76+
const req = objectStore.get(id);
77+
return new Promise((resolve, reject) => {
78+
req.onsuccess = () => resolve(req.result);
79+
req.onerror = () => reject(req.error ?? new Error(`Can't get ${id}`));
80+
});
81+
};
82+
return this.#exec(store, op, 'readonly');
8783
}
8884

8985
select({ store, where, limit, offset, order, filter, sort }) {
90-
return this.#exec(
91-
store,
92-
(s) => {
93-
const results = [];
94-
let skipped = 0;
95-
return new Promise((resolve, reject) => {
96-
const req = s.openCursor();
97-
req.onerror = () => reject(req.error);
98-
req.onsuccess = (event) => {
99-
const cursor = event.target.result;
100-
if (!cursor) {
101-
const filtered = filter ? results.filter(filter) : results;
102-
return void resolve(
103-
sort
104-
? filtered.toSorted(sort)
105-
: Database.#order(filtered, order),
106-
);
107-
}
108-
const record = cursor.value;
109-
const match =
110-
!where ||
111-
Object.entries(where).every(([k, v]) => record[k] === v);
112-
if (match) {
113-
if (!offset || skipped >= offset) {
114-
results.push(record);
115-
if (limit && results.length >= limit) {
116-
return void resolve(results);
117-
}
118-
} else {
119-
skipped++;
120-
}
121-
}
122-
cursor.continue();
123-
};
124-
});
125-
},
126-
'readonly',
127-
);
86+
const op = (objectStore) => {
87+
const result = [];
88+
let skipped = 0;
89+
return new Promise((resolve, reject) => {
90+
const reply = () => {
91+
if (sort) result.sort(sort);
92+
if (order) Database.#sort(result, order);
93+
resolve(result);
94+
};
95+
const req = objectStore.openCursor();
96+
req.onerror = () => reject(req.error);
97+
req.onsuccess = (event) => {
98+
const cursor = event.target.result;
99+
if (!cursor) return void reply();
100+
const record = cursor.value;
101+
const check = ([key, val]) => record[key] === val;
102+
const match = !where || Object.entries(where).every(check);
103+
const valid = !filter || filter(record);
104+
if (match && valid) {
105+
if (!offset || skipped >= offset) result.push(record);
106+
else skipped++;
107+
if (limit && result.length >= limit) return void reply();
108+
}
109+
cursor.continue();
110+
};
111+
});
112+
};
113+
return this.#exec(store, op, 'readonly');
128114
}
129115

130-
static #order(arr, order) {
131-
if (!order || typeof order !== 'object') return arr;
132-
const [[field, dir = 'asc']] = Object.entries(order);
116+
static #sort(arr, order) {
117+
if (typeof order !== 'object') return;
118+
const rule = Object.entries(order)[0];
119+
if (!Array.isArray(rule)) return;
120+
const [field, dir = 'asc'] = rule;
133121
const sign = dir === 'desc' ? -1 : 1;
134-
return [...arr].sort((a, b) => {
135-
if (a[field] === b[field]) return 0;
136-
return a[field] > b[field] ? sign : -sign;
122+
arr.sort((a, b) => {
123+
const x = a[field];
124+
const y = b[field];
125+
if (x === y) return 0;
126+
return x > y ? sign : -sign;
137127
});
138128
}
139129
}

0 commit comments

Comments
 (0)