nuxt-surrealdb
Version:
A Nuxt module aimed to simplify the use of SurrealDB
260 lines (259 loc) • 5.41 kB
JavaScript
import { useWebSocket } from "@vueuse/core";
import { joinURL } from "ufo";
import { destr } from "destr";
import {
computed,
reactive,
ref,
toValue,
useRuntimeConfig,
useSurrealAuth,
watch
} from "#imports";
export function useSurrealWS(options) {
const {
auth: { database: authDatabase },
databases
} = useRuntimeConfig().public.surrealdb;
const { token: userToken } = useSurrealAuth();
const { database, onDisconnected: _onDisconnected, ...opts } = options || {};
const _database = computed(() => {
if (database !== void 0) {
if (typeof database !== "string" && typeof database !== "number" && typeof database !== "symbol") {
return database;
} else {
return databases[database];
}
} else {
return databases["default"];
}
});
const useId = 0;
const authId = 1;
const idCounter = ref(2);
const isReady = reactive({
db: false,
auth: false
});
const queue = [];
const isAuthDatabase = !!(options?.auth !== false && _database.value === databases[authDatabase]);
const {
close,
data: _data,
open,
send: _send,
status,
ws
} = useWebSocket(joinURL(_database.value.ws, "rpc"), {
onDisconnected(ws2, event) {
idCounter.value = 2;
_onDisconnected?.(ws2, event);
},
...opts
});
const stopInitWatcher = watch(_data, (newData) => {
const _newData = destr(newData);
if (_newData && _newData.id === useId) {
isReady.db = true;
} else if (_newData && _newData.id === authId) {
isReady.auth = true;
_sendQueue();
stopInitWatcher();
}
if (!userToken.value || !isAuthDatabase) {
_sendQueue();
stopInitWatcher();
}
});
function _init() {
_send(JSON.stringify({
id: useId,
method: "use",
params: [_database.value.NS, _database.value.DB]
}));
if (userToken.value && isAuthDatabase) {
_send(JSON.stringify({
id: authId,
method: "query",
params: [userToken.value]
}));
} else if (options?.auth) {
_send(JSON.stringify({
id: authId,
method: "query",
params: [options.auth]
}));
}
}
function _sendQueue() {
if (!queue.length) return;
for (const message of queue) {
_send(JSON.stringify(message));
}
}
const data = computed(() => {
const res = destr(_data.value);
if (res && !res.error) {
return res.result;
} else {
return res;
}
});
function send(data2, useBuffer = true) {
if (!isReady.db || isAuthDatabase && !isReady.auth) {
queue.push(data2);
_init();
return false;
} else {
return _send(JSON.stringify(data2), useBuffer);
}
}
function rpc(req) {
return send({
id: idCounter.value++,
...req
});
}
function authenticate(token) {
return rpc({
method: "query",
params: [toValue(token)]
});
}
function create(thing, data2) {
return rpc({
method: "create",
params: [toValue(thing), toValue(data2)]
});
}
function info() {
return rpc({
method: "info"
});
}
function insert(thing, data2) {
return rpc({
method: "insert",
params: [toValue(thing), toValue(data2)]
});
}
function invalidate() {
return rpc({
method: "invalidate"
});
}
function kill(thing) {
return rpc({
method: "kill",
params: [toValue(thing)]
});
}
function set(name, value) {
return rpc({
method: "let",
params: [toValue(name), toValue(value)]
});
}
function live(table, diff) {
return rpc({
method: "live",
params: [toValue(table), toValue(diff)]
});
}
function merge(thing, data2) {
return rpc({
method: "merge",
params: [toValue(thing), toValue(data2)]
});
}
function patch(thing, patches, diff) {
return rpc({
method: "patch",
params: [toValue(thing), toValue(patches), toValue(diff)]
});
}
function query(sql, vars) {
return rpc({
method: "query",
params: [toValue(sql), toValue(vars)]
});
}
function remove(thing) {
return rpc({
method: "delete",
params: [toValue(thing)]
});
}
function select(thing) {
return rpc({
method: "select",
params: [toValue(thing)]
});
}
function signin(auth) {
return rpc({
method: "signin",
params: [toValue(auth)]
});
}
function signup(auth) {
return rpc({
method: "signup",
params: [toValue(auth)]
});
}
function unset(name) {
return rpc({
method: "unset",
params: [toValue(name)]
});
}
function update(thing, data2) {
return rpc({
method: "update",
params: [toValue(thing), toValue(data2)]
});
}
function use(NS, DB) {
if (!NS && !DB) {
NS = _database.value.NS;
DB = _database.value.DB;
}
return rpc({
method: "use",
params: [toValue(NS), toValue(DB)]
});
}
return {
authenticate,
close,
create,
_data,
data,
delete: remove,
info,
insert,
invalidate,
kill,
let: set,
live,
merge,
open,
patch,
query,
remove,
rpc,
select,
_send,
send,
set,
signin,
signup,
sql: query,
status,
unset,
update,
use,
ws
};
}