UNPKG

respond-framework

Version:
113 lines (109 loc) 3.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _utils = require("../utils.js"); var _fetch2 = require("../helpers/fetch.js"); var _revive = require("./helpers/revive.js"); var _createApiHandler = require("./createApiHandler.js"); var _inferArgName = require("./helpers/inferArgName.js"); const createDb = (respond, Respond) => { Respond.prototype.apiHandler ??= _utils.isDev && (0, _createApiHandler.default)({ db: respond.top.db }); // create only once for all respond instances -- only dev needs apiHandler on client const get = (_, table) => { const get = (_, method) => callDatabase(respond, table, method); return new Proxy({}, { get }); }; return new Proxy({}, { get }); }; var _default = exports.default = createDb; const callDatabase = (respond, table, method) => { if (method === 'make') return respond.models[table].make; if (method === 'create') return respond.models[table].create; const url = respond.options.apiUrl ?? respond.topState.respond.options.apiUrl; const getter = async (...args) => { const body = createBody(table, method, args, respond); const response = await fetch(url, body, getter, respond); return createResponse(respond, body, response); }; getter.cache = (...args) => (getter.useCache = true) && getter(...args); getter.server = (...args) => (getter.useServer = true) && getter(...args); return getter; }; const fetch = async (apiUrl, body, getter, respond) => { const cached = respond.dbCache.get(body); if (cached) return cached; _utils.isDev && (await respond.simulateLatency()); const r = _utils.isProd || getter.useServer ? await (0, _fetch2.default)(apiUrl, body, respond) : await respond.apiHandler({ body }, { json: r => JSON.parse(JSON.stringify(r)) }); // the magic: call server-side api handler directly on the client during development + simulate json stringification const response = r === _fetch2.__undefined__ ? undefined : r ? (0, _revive.reviveApiClient)(respond, body.branch)(r) : r; if (getter.useCache) respond.dbCache.set(body, response); return response; }; const createBody = (table, method, argsRaw, respond) => { const { token, userId, adminUserId, basename, basenameFull, __dbFirstCall } = respond.topState; const { state, focusedBranch, replays } = respond; const branch = respond.moduleName === 'replayTools' ? 'replayTools' : replays.db.branchAbsolute; // replayTools always at top even when child branch focused : db may be inherited, so we actually need to pass the branch inherited from const args = (0, _fetch2.argsIn)(argsRaw); const body = respond.options.getBody?.call(state, table, method, args); // additional body data for api calls const first = !__dbFirstCall; return { branch, table, method, args, token, userId, adminUserId, basename, basenameFull, focusedBranch, first, ...body }; }; const createResponse = (respond, body, response) => { const { branch, table, method, args } = body; respond.topState.__dbFirstCall = true; respond.devtools.sendNotification({ branch, table, method, args, response }); const proto = respond.models[table]?.prototype; if (!proto) { return response; } else if (response?.__branchType) { (0, _inferArgName.inferArgName)(response, proto._name); // eg: 'user' -> dispatched as arg = { user: response } } else if (Array.isArray(response)) { (0, _inferArgName.inferArgName)(response, proto._namePlural); // eg: 'users' -> dispatched as arg = { users: [...response] } } return response; };