UNPKG

convex

Version:

Client for the Convex Cloud

250 lines (249 loc) 8.75 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var react_exports = {}; __export(react_exports, { ConvexProvider: () => ConvexProvider, ConvexReactClient: () => ConvexReactClient, useActionGeneric: () => useActionGeneric, useConvexGeneric: () => useConvexGeneric, useMutationGeneric: () => useMutationGeneric, useQueriesGeneric: () => import_use_queries.useQueriesGeneric, useQueryGeneric: () => useQueryGeneric }); module.exports = __toCommonJS(react_exports); var import_browser = require("../browser/index.js"); var import_react = __toESM(require("react")); var import_values = require("../values/index.js"); var import_react_dom = __toESM(require("react-dom")); var import_use_subscription = require("./use_subscription.js"); __reExport(react_exports, require("./use_paginated_query.js"), module.exports); var import_use_queries = require("./use_queries.js"); if (typeof import_react.default === "undefined") { throw new Error("Required dependency 'react' not installed"); } if (typeof import_react_dom.default === "undefined") { throw new Error("Required dependency 'react-dom' not installed"); } function createMutation(name, sync, update = null) { function mutation(...args) { assertNotAccidentalArgument(args); return sync().mutate(name, args, update); } mutation.withOptimisticUpdate = function withOptimisticUpdate(optimisticUpdate) { if (update !== null) { throw new Error( `Already specified optimistic update for mutation ${name}` ); } return createMutation(name, sync, optimisticUpdate); }; return mutation; } function createAction(name, sync) { return function(...args) { return sync().action(name, args); }; } const DEFAULT_OPTIONS = { unsavedChangesWarning: true }; class ConvexReactClient { constructor(clientConfig, options) { this.closed = false; this.clientConfig = clientConfig; this.listeners = /* @__PURE__ */ new Map(); this.options = { ...DEFAULT_OPTIONS, ...options }; } get sync() { if (this.closed) { throw new Error("ConvexReactClient has already been closed."); } if (this.cachedSync) { return this.cachedSync; } this.cachedSync = new import_browser.InternalConvexClient( this.clientConfig, (updatedQueries) => this.transition(updatedQueries), this.options ); if (this.adminAuth) { this.cachedSync.setAdminAuth(this.adminAuth); } return this.cachedSync; } setAuth(token) { this.sync.setAuth(token); } clearAuth() { this.sync.clearAuth(); } setAdminAuth(token) { this.adminAuth = token; if (this.closed) { throw new Error("ConvexReactClient has already been closed."); } if (this.cachedSync) { this.sync.setAdminAuth(token); } } watchQuery(name, args, journal) { if (!Array.isArray(args)) { throw new Error( `Query arguments to \`ConvexReactClient.watchQuery\` must be an array. Received ${args}.` ); } return { onUpdate: (callback) => { const { queryToken, unsubscribe } = this.sync.subscribe( name, args, journal ); const currentListeners = this.listeners.get(queryToken); if (currentListeners !== void 0) { currentListeners.add(callback); } else { this.listeners.set(queryToken, /* @__PURE__ */ new Set([callback])); } return () => { if (this.closed) { return; } const currentListeners2 = this.listeners.get(queryToken); currentListeners2.delete(callback); if (currentListeners2.size == 0) { this.listeners.delete(queryToken); } unsubscribe(); }; }, localQueryResult: () => { if (this.cachedSync) { return this.cachedSync.localQueryResult(name, args); } return void 0; }, journal: () => { if (this.cachedSync) { return this.cachedSync.queryJournal(name, args); } return void 0; } }; } mutation(name) { return createMutation(name, () => this.sync); } action(name) { return createAction(name, () => this.sync); } connectionState() { return this.sync.connectionState(); } async close() { this.closed = true; this.listeners = /* @__PURE__ */ new Map(); if (this.cachedSync) { const sync = this.cachedSync; this.cachedSync = void 0; await sync.close(); } } transition(updatedQueries) { import_react_dom.default.unstable_batchedUpdates(() => { for (const queryToken of updatedQueries) { const callbacks = this.listeners.get(queryToken); if (callbacks) { for (const callback of callbacks) { callback(); } } } }); } } const ConvexContext = import_react.default.createContext( void 0 ); function useConvexGeneric() { return (0, import_react.useContext)(ConvexContext); } const ConvexProvider = ({ client, children }) => { return import_react.default.createElement( ConvexContext.Provider, { value: client }, children ); }; function useQueryGeneric(name, ...args) { const convex = (0, import_react.useContext)(ConvexContext); if (convex === void 0) { throw new Error( "Could not find Convex client! `useQuery` must be used in the React component tree under `ConvexProvider`. Did you forget it? See https://docs.convex.dev/quick-start#set-up-convex-in-your-react-app" ); } const subscription = (0, import_react.useMemo)( () => { const watch = convex.watchQuery(name, args); return { getCurrentValue: () => watch.localQueryResult(), subscribe: (callback) => watch.onUpdate(callback) }; }, [name, convex, JSON.stringify((0, import_values.convexToJson)(args))] ); const queryResult = (0, import_use_subscription.useSubscription)(subscription); return queryResult; } function useMutationGeneric(name) { const convex = (0, import_react.useContext)(ConvexContext); if (convex === void 0) { throw new Error( "Could not find Convex client! `useMutation` must be used in the React component tree under `ConvexProvider`. Did you forget it? See https://docs.convex.dev/quick-start#set-up-convex-in-your-react-app" ); } return (0, import_react.useMemo)(() => convex.mutation(name), [convex, name]); } function useActionGeneric(name) { const convex = (0, import_react.useContext)(ConvexContext); if (convex === void 0) { throw new Error( "Could not find Convex client! `useAction` must be used in the React component tree under `ConvexProvider`. Did you forget it? See https://docs.convex.dev/quick-start#set-up-convex-in-your-react-app" ); } return (0, import_react.useMemo)(() => convex.action(name), [convex, name]); } function assertNotAccidentalArgument(args) { if (args.length !== 1) return; const [value] = args; if (typeof value === "object" && "bubbles" in value && "persist" in value && "isDefaultPrevented" in value) { throw new Error( `Convex function called with SyntheticEvent object. Did you use a Convex function as an event handler directly? Event handlers like onClick receive an event object as their first argument. These SyntheticEvent objects are not valid Convex values. Try wrapping the function like \`const handler = () => myMutation();\` and using \`handler\` in the event handler.` ); } } //# sourceMappingURL=index.js.map