Skip to content

Commit 578d858

Browse files
Jake ChampionJakeChampion
authored andcommitted
feat: Add KVStore.prototype.delete method
1 parent f5cefbb commit 578d858

File tree

3 files changed

+100
-2
lines changed

3 files changed

+100
-2
lines changed

runtime/js-compute-runtime/builtins/kv-store.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,89 @@ bool parse_and_validate_key(JSContext *cx, const char *key, size_t len) {
183183

184184
} // namespace
185185

186+
bool KVStore::has_pending_delete_handle(JSObject *self) {
187+
MOZ_ASSERT(KVStore::is_instance(self));
188+
189+
JS::Value handle_val =
190+
JS::GetReservedSlot(self, static_cast<uint32_t>(Slots::PendingDeleteHandle));
191+
return handle_val.isInt32() &&
192+
handle_val.toInt32() != host_api::ObjectStorePendingDelete::invalid;
193+
}
194+
195+
host_api::ObjectStorePendingDelete KVStore::pending_delete_handle(JSObject *self) {
196+
MOZ_ASSERT(KVStore::is_instance(self));
197+
host_api::ObjectStorePendingDelete res;
198+
199+
JS::Value handle_val =
200+
JS::GetReservedSlot(self, static_cast<uint32_t>(Slots::PendingDeleteHandle));
201+
if (handle_val.isInt32()) {
202+
res = host_api::ObjectStorePendingDelete(handle_val.toInt32());
203+
}
204+
205+
return res;
206+
}
207+
208+
bool KVStore::process_pending_kv_store_delete(JSContext *cx, JS::HandleObject self) {
209+
MOZ_ASSERT(KVStore::is_instance(self));
210+
211+
auto pending_promise_value =
212+
JS::GetReservedSlot(self, static_cast<uint32_t>(Slots::PendingDeletePromise));
213+
MOZ_ASSERT(pending_promise_value.isObject());
214+
JS::RootedObject result_promise(cx, &pending_promise_value.toObject());
215+
216+
auto res = builtins::KVStore::pending_delete_handle(self).wait();
217+
218+
if (auto *err = res.to_err()) {
219+
HANDLE_ERROR(cx, *err);
220+
return RejectPromiseWithPendingError(cx, result_promise);
221+
}
222+
223+
JS::ResolvePromise(cx, result_promise, JS::UndefinedHandleValue);
224+
225+
return true;
226+
}
227+
228+
bool KVStore::delete_(JSContext *cx, unsigned argc, JS::Value *vp) {
229+
METHOD_HEADER_WITH_NAME(1, "delete");
230+
231+
JS::RootedObject result_promise(cx, JS::NewPromiseObject(cx, nullptr));
232+
if (!result_promise) {
233+
return ReturnPromiseRejectedWithPendingError(cx, args);
234+
}
235+
236+
JS::RootedValue key(cx, args.get(0));
237+
238+
// Convert the key argument into a String following https://tc39.es/ecma262/#sec-tostring
239+
auto key_chars = core::encode(cx, key);
240+
if (!key_chars) {
241+
return ReturnPromiseRejectedWithPendingError(cx, args);
242+
}
243+
244+
if (!parse_and_validate_key(cx, key_chars.begin(), key_chars.len)) {
245+
return ReturnPromiseRejectedWithPendingError(cx, args);
246+
}
247+
248+
auto res = kv_store_handle(self).delete_async(key_chars);
249+
250+
if (auto *err = res.to_err()) {
251+
HANDLE_ERROR(cx, *err);
252+
return ReturnPromiseRejectedWithPendingError(cx, args);
253+
}
254+
auto ret = res.unwrap();
255+
256+
JS::SetReservedSlot(self, static_cast<uint32_t>(Slots::PendingDeleteHandle),
257+
JS::Int32Value(ret.handle));
258+
JS::SetReservedSlot(self, static_cast<uint32_t>(Slots::PendingDeletePromise),
259+
JS::ObjectValue(*result_promise));
260+
261+
if (!core::EventLoop::queue_async_task(self)) {
262+
return ReturnPromiseRejectedWithPendingError(cx, args);
263+
}
264+
265+
args.rval().setObject(*result_promise);
266+
return true;
267+
}
268+
186269
host_api::ObjectStorePendingLookup KVStore::pending_lookup_handle(JSObject *self) {
187270
MOZ_ASSERT(KVStore::is_instance(self));
188271
host_api::ObjectStorePendingLookup res;
@@ -399,6 +482,7 @@ const JSPropertySpec KVStore::static_properties[] = {
399482
};
400483

401484
const JSFunctionSpec KVStore::methods[] = {
485+
JS_FN("delete", delete_, 1, JSPROP_ENUMERATE),
402486
JS_FN("get", get, 1, JSPROP_ENUMERATE),
403487
JS_FN("put", put, 1, JSPROP_ENUMERATE),
404488
JS_FS_END,

runtime/js-compute-runtime/builtins/kv-store.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class KVStoreEntry final : public BuiltinImpl<KVStoreEntry> {
3131
};
3232

3333
class KVStore final : public BuiltinImpl<KVStore> {
34+
static bool delete_(JSContext *cx, unsigned argc, JS::Value *vp);
3435
static bool get(JSContext *cx, unsigned argc, JS::Value *vp);
3536
static bool put(JSContext *cx, unsigned argc, JS::Value *vp);
3637

@@ -40,6 +41,8 @@ class KVStore final : public BuiltinImpl<KVStore> {
4041
KVStore,
4142
PendingLookupPromise,
4243
PendingLookupHandle,
44+
PendingDeletePromise,
45+
PendingDeleteHandle,
4346
Count,
4447
};
4548
static const JSFunctionSpec static_methods[];
@@ -53,6 +56,9 @@ class KVStore final : public BuiltinImpl<KVStore> {
5356
static bool constructor(JSContext *cx, unsigned argc, JS::Value *vp);
5457
static host_api::ObjectStorePendingLookup pending_lookup_handle(JSObject *self);
5558
static bool process_pending_kv_store_lookup(JSContext *cx, JS::HandleObject self);
59+
static host_api::ObjectStorePendingDelete pending_delete_handle(JSObject *self);
60+
static bool process_pending_kv_store_delete(JSContext *cx, JS::HandleObject self);
61+
static bool has_pending_delete_handle(JSObject *self);
5662
};
5763

5864
} // namespace builtins

runtime/js-compute-runtime/core/event_loop.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,11 @@ bool EventLoop::process_pending_async_tasks(JSContext *cx) {
260260
if (builtins::Request::is_instance(pending_obj)) {
261261
handles.push_back(builtins::Request::pending_handle(pending_obj).async_handle());
262262
} else if (builtins::KVStore::is_instance(pending_obj)) {
263-
handles.push_back(builtins::KVStore::pending_lookup_handle(pending_obj).async_handle());
263+
if (builtins::KVStore::has_pending_delete_handle(pending_obj)) {
264+
handles.push_back(builtins::KVStore::pending_delete_handle(pending_obj).async_handle());
265+
} else {
266+
handles.push_back(builtins::KVStore::pending_lookup_handle(pending_obj).async_handle());
267+
}
264268
} else {
265269
MOZ_ASSERT(builtins::NativeStreamSource::is_instance(pending_obj));
266270
JS::RootedObject owner(cx, builtins::NativeStreamSource::owner(pending_obj));
@@ -301,7 +305,11 @@ bool EventLoop::process_pending_async_tasks(JSContext *cx) {
301305
if (builtins::Request::is_instance(ready_obj)) {
302306
ok = process_pending_request(cx, ready_obj, host_api::HttpPendingReq{ready_handle});
303307
} else if (builtins::KVStore::is_instance(ready_obj)) {
304-
ok = builtins::KVStore::process_pending_kv_store_lookup(cx, ready_obj);
308+
if (builtins::KVStore::has_pending_delete_handle(ready_obj)) {
309+
ok = builtins::KVStore::process_pending_kv_store_delete(cx, ready_obj);
310+
} else {
311+
ok = builtins::KVStore::process_pending_kv_store_lookup(cx, ready_obj);
312+
}
305313
} else {
306314
MOZ_ASSERT(builtins::NativeStreamSource::is_instance(ready_obj));
307315
ok = process_body_read(cx, ready_obj, host_api::HttpBody{ready_handle});

0 commit comments

Comments
 (0)