From 5ef5d3226b90fae161ddb7a76add0a3b517307c9 Mon Sep 17 00:00:00 2001 From: Nikolay Aleshkovskiy Date: Thu, 7 Dec 2023 21:34:11 +0700 Subject: [PATCH 01/25] feat: Add example and Meteor v.3 support, add types --- example/.gitignore | 1 + example/.meteor/.finished-upgraders | 19 + example/.meteor/.gitignore | 1 + example/.meteor/.id | 7 + example/.meteor/packages | 23 + example/.meteor/platforms | 2 + example/.meteor/release | 1 + example/.meteor/versions | 72 ++ example/client/main.css | 4 + example/client/main.html | 8 + example/client/main.tsx | 10 + example/imports/api/links.ts | 10 + example/imports/ui/App.tsx | 83 ++ .../ui/react-meteor-method-hooks/types.d.ts | 16 + .../useMeteorCall.js | 59 ++ example/package-lock.json | 900 ++++++++++++++++++ example/package.json | 30 + example/server/main.ts | 59 ++ example/tests/main.ts | 21 + example/tsconfig.json | 45 + index.js | 37 - package.json | 9 +- 22 files changed, 1378 insertions(+), 39 deletions(-) create mode 100644 example/.gitignore create mode 100644 example/.meteor/.finished-upgraders create mode 100644 example/.meteor/.gitignore create mode 100644 example/.meteor/.id create mode 100644 example/.meteor/packages create mode 100644 example/.meteor/platforms create mode 100644 example/.meteor/release create mode 100644 example/.meteor/versions create mode 100644 example/client/main.css create mode 100644 example/client/main.html create mode 100644 example/client/main.tsx create mode 100644 example/imports/api/links.ts create mode 100644 example/imports/ui/App.tsx create mode 100644 example/imports/ui/react-meteor-method-hooks/types.d.ts create mode 100644 example/imports/ui/react-meteor-method-hooks/useMeteorCall.js create mode 100644 example/package-lock.json create mode 100644 example/package.json create mode 100644 example/server/main.ts create mode 100644 example/tests/main.ts create mode 100644 example/tsconfig.json delete mode 100644 index.js diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/example/.meteor/.finished-upgraders b/example/.meteor/.finished-upgraders new file mode 100644 index 0000000..c07b6ff --- /dev/null +++ b/example/.meteor/.finished-upgraders @@ -0,0 +1,19 @@ +# This file contains information which helps Meteor properly upgrade your +# app when you run 'meteor update'. You should check it into version control +# with your project. + +notices-for-0.9.0 +notices-for-0.9.1 +0.9.4-platform-file +notices-for-facebook-graph-api-2 +1.2.0-standard-minifiers-package +1.2.0-meteor-platform-split +1.2.0-cordova-changes +1.2.0-breaking-changes +1.3.0-split-minifiers-package +1.4.0-remove-old-dev-bundle-link +1.4.1-add-shell-server-package +1.4.3-split-account-service-packages +1.5-add-dynamic-import-package +1.7-split-underscore-from-meteor-base +1.8.3-split-jquery-from-blaze diff --git a/example/.meteor/.gitignore b/example/.meteor/.gitignore new file mode 100644 index 0000000..4083037 --- /dev/null +++ b/example/.meteor/.gitignore @@ -0,0 +1 @@ +local diff --git a/example/.meteor/.id b/example/.meteor/.id new file mode 100644 index 0000000..16dd92f --- /dev/null +++ b/example/.meteor/.id @@ -0,0 +1,7 @@ +# This file contains a token that is unique to your project. +# Check it into your repository along with the rest of this directory. +# It can be used for purposes such as: +# - ensuring you don't accidentally deploy one app on top of another +# - providing package authors with aggregated statistics + +mwteyo9y63m.nsvo9ukypcz7 diff --git a/example/.meteor/packages b/example/.meteor/packages new file mode 100644 index 0000000..9c99a40 --- /dev/null +++ b/example/.meteor/packages @@ -0,0 +1,23 @@ +# Meteor packages used by this project, one per line. +# Check this file (and the other files in this directory) into your repository. +# +# 'meteor add' and 'meteor remove' will edit this file for you, +# but you can also edit it by hand. + +meteor-base@1.5.1 # Packages every Meteor app needs to have +mobile-experience@1.1.0 # Packages for a great mobile UX +mongo@1.16.7 # The database Meteor supports right now +reactive-var@1.0.12 # Reactive variable for tracker + +standard-minifier-css@1.9.2 # CSS minifier run for production mode +standard-minifier-js@2.8.1 # JS minifier run for production mode +es5-shim@4.8.0 # ECMAScript 5 compatibility for older browsers +ecmascript@0.16.7 # Enable ECMAScript2015+ syntax in app code +typescript@4.9.4 # Enable TypeScript syntax in .ts and .tsx modules +shell-server@0.5.0 # Server-side component of the `meteor shell` command +hot-module-replacement@0.5.3 # Update client in development without reloading the page + + +static-html@1.3.2 # Define static page content in .html files +react-meteor-data # React higher-order component for reactively tracking Meteor data +zodern:types # Pull in type declarations from other Meteor packages diff --git a/example/.meteor/platforms b/example/.meteor/platforms new file mode 100644 index 0000000..efeba1b --- /dev/null +++ b/example/.meteor/platforms @@ -0,0 +1,2 @@ +server +browser diff --git a/example/.meteor/release b/example/.meteor/release new file mode 100644 index 0000000..6641d04 --- /dev/null +++ b/example/.meteor/release @@ -0,0 +1 @@ +METEOR@2.13.3 diff --git a/example/.meteor/versions b/example/.meteor/versions new file mode 100644 index 0000000..4727c55 --- /dev/null +++ b/example/.meteor/versions @@ -0,0 +1,72 @@ +allow-deny@1.1.1 +autoupdate@1.8.0 +babel-compiler@7.10.4 +babel-runtime@1.5.1 +base64@1.0.12 +binary-heap@1.0.11 +blaze-tools@1.1.3 +boilerplate-generator@1.7.1 +caching-compiler@1.2.2 +caching-html-compiler@1.2.1 +callback-hook@1.5.1 +check@1.3.2 +ddp@1.4.1 +ddp-client@2.6.1 +ddp-common@1.4.0 +ddp-server@2.6.2 +diff-sequence@1.1.2 +dynamic-import@0.7.3 +ecmascript@0.16.7 +ecmascript-runtime@0.8.1 +ecmascript-runtime-client@0.12.1 +ecmascript-runtime-server@0.11.0 +ejson@1.1.3 +es5-shim@4.8.0 +fetch@0.1.3 +geojson-utils@1.0.11 +hot-code-push@1.0.4 +hot-module-replacement@0.5.3 +html-tools@1.1.3 +htmljs@1.1.1 +id-map@1.1.1 +inter-process-messaging@0.1.1 +launch-screen@1.3.0 +logging@1.3.2 +meteor@1.11.3 +meteor-base@1.5.1 +minifier-css@1.6.4 +minifier-js@2.7.5 +minimongo@1.9.3 +mobile-experience@1.1.0 +mobile-status-bar@1.1.0 +modern-browsers@0.1.9 +modules@0.19.0 +modules-runtime@0.13.1 +modules-runtime-hot@0.14.2 +mongo@1.16.7 +mongo-decimal@0.1.3 +mongo-dev-server@1.1.0 +mongo-id@1.0.8 +npm-mongo@4.16.0 +ordered-dict@1.1.0 +promise@0.12.2 +random@1.2.1 +react-fast-refresh@0.2.7 +react-meteor-data@2.7.2 +reactive-var@1.0.12 +reload@1.3.1 +retry@1.1.0 +routepolicy@1.1.1 +shell-server@0.5.0 +socket-stream-client@0.5.1 +spacebars-compiler@1.3.1 +standard-minifier-css@1.9.2 +standard-minifier-js@2.8.1 +static-html@1.3.2 +templating-tools@1.2.2 +tracker@1.3.2 +typescript@4.9.4 +underscore@1.0.13 +webapp@1.13.5 +webapp-hashing@1.1.1 +zodern:types@1.0.10 diff --git a/example/client/main.css b/example/client/main.css new file mode 100644 index 0000000..7f354f0 --- /dev/null +++ b/example/client/main.css @@ -0,0 +1,4 @@ +body { + padding: 10px; + font-family: sans-serif; +} diff --git a/example/client/main.html b/example/client/main.html new file mode 100644 index 0000000..1fd6699 --- /dev/null +++ b/example/client/main.html @@ -0,0 +1,8 @@ + + example + + + + +
+ diff --git a/example/client/main.tsx b/example/client/main.tsx new file mode 100644 index 0000000..523141b --- /dev/null +++ b/example/client/main.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { Meteor } from 'meteor/meteor'; +import { App } from '/imports/ui/App'; + +Meteor.startup(() => { + const container = document.getElementById('react-target'); + const root = createRoot(container!); + root.render(); +}); diff --git a/example/imports/api/links.ts b/example/imports/api/links.ts new file mode 100644 index 0000000..ec0bf46 --- /dev/null +++ b/example/imports/api/links.ts @@ -0,0 +1,10 @@ +import { Mongo } from 'meteor/mongo'; + +export interface Link { + _id?: string; + title: string; + url: string; + createdAt: Date; +} + +export const LinksCollection = new Mongo.Collection('links'); diff --git a/example/imports/ui/App.tsx b/example/imports/ui/App.tsx new file mode 100644 index 0000000..73c401f --- /dev/null +++ b/example/imports/ui/App.tsx @@ -0,0 +1,83 @@ +import React, { useEffect } from 'react'; + +import { useMeteorCall } from './react-meteor-method-hooks/useMeteorCall'; + +export const App = () => { + const [ + methodWithResult, + methodWithResultLoading, + methodWithResultError, + methodWithResultResult, + ] = useMeteorCall( + 'methodWithResult', + { param: 'This is param' }, + (error, result) => { + console.log('methodWithResult callback', { error, result }); + } + ); + + const [ + methodWithError, + methodWithErrorLoading, + methodWithErrorError, + methodWithErrorResult, + ] = useMeteorCall('methodWithError', {}, (error, result) => { + console.log('methodWithError callback', { error, result }); + }); + + useEffect(() => { + methodWithResult(); + methodWithError(); + }, []); + + useEffect(() => { + console.log({ + methodWithResultLoading, + methodWithResultError, + methodWithResultResult, + methodWithErrorLoading, + methodWithErrorError, + methodWithErrorResult, + }); + }, [ + methodWithResultLoading, + methodWithResultError, + methodWithResultResult, + methodWithErrorLoading, + methodWithErrorError, + methodWithErrorResult, + ]); + + return ( +
+
+

methodWithResult

+
+          {JSON.stringify(
+            {
+              methodWithResultLoading,
+              methodWithResultError,
+              methodWithResultResult,
+            },
+            undefined,
+            2
+          )}
+        
+
+
+

methodWithError

+
+          {JSON.stringify(
+            {
+              methodWithErrorLoading,
+              methodWithErrorError,
+              methodWithErrorResult,
+            },
+            undefined,
+            2
+          )}
+        
+
+
+ ); +}; diff --git a/example/imports/ui/react-meteor-method-hooks/types.d.ts b/example/imports/ui/react-meteor-method-hooks/types.d.ts new file mode 100644 index 0000000..25e2adb --- /dev/null +++ b/example/imports/ui/react-meteor-method-hooks/types.d.ts @@ -0,0 +1,16 @@ +type UseMeteorCallHook = ( + name: string, + params: object, + cb: (error: object | undefined, result: any) => void +) => [ + methodHandler: () => Promise, + loading: boolean, + error: object | undefined, + result: any +]; + +type UseMeteorCallHookInitialState = { + loading: boolean; + error: object | undefined; + result: any; +} diff --git a/example/imports/ui/react-meteor-method-hooks/useMeteorCall.js b/example/imports/ui/react-meteor-method-hooks/useMeteorCall.js new file mode 100644 index 0000000..3dee1ca --- /dev/null +++ b/example/imports/ui/react-meteor-method-hooks/useMeteorCall.js @@ -0,0 +1,59 @@ +import { Meteor } from 'meteor/meteor'; +import { useState, useCallback } from 'react'; + +/// + +/** @type {UseMeteorCallHookInitialState} */ +const initialState = { + loading: false, + error: undefined, + result: undefined, +}; + +/** @type {UseMeteorCallHook} */ +const useMeteorCall = (name, params = {}, cb) => { + if (!name) { + console.error('Name is required to call Meteor method'); + } + + const [loading, setLoading] = useState(initialState.loading); + const [error, setError] = useState(initialState.error); + const [result, setResult] = useState(initialState.result); + + const methodHandler = useCallback(async () => { + setLoading(true); + setError(initialState.error); + setResult(initialState.result); + + // Meteor 3.0 + if (typeof Meteor.callAsync === 'function') { + try { + const result = await Meteor.callAsync(name, params); + setLoading(false); + setResult(result); + + if (typeof cb === 'function') { + cb(error, result); + } + } catch (error) { + setError(error); + } + } + // Meteor 2.x + else { + Meteor.call(name, params, (error, result) => { + setLoading(false); + setError(error); + setResult(result); + + if (typeof cb === 'function') { + cb(error, result); + } + }); + } + }, [name, params, cb]); + + return [methodHandler, loading, error, result]; +}; + +export { useMeteorCall }; diff --git a/example/package-lock.json b/example/package-lock.json new file mode 100644 index 0000000..1e5ca38 --- /dev/null +++ b/example/package-lock.json @@ -0,0 +1,900 @@ +{ + "name": "example", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@babel/runtime": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz", + "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==", + "requires": { + "regenerator-runtime": "^0.14.0" + } + }, + "@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true + }, + "@types/node": { + "version": "18.19.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.3.tgz", + "integrity": "sha512-k5fggr14DwAytoA/t8rPrIz++lXK7/DqckthCmoZOKNsEbJkId4Z//BqgApXBUGrGddrigYa1oqheo/7YmW4rg==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", + "dev": true + }, + "@types/react": { + "version": "18.2.42", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.42.tgz", + "integrity": "sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "18.2.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", + "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", + "dev": true + }, + "csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "meteor-node-stubs": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-1.2.7.tgz", + "integrity": "sha512-20bAFUhEIOD/Cos2nmvhqf2NOKpTf63WVQ+nwuaX2OFj31sU6GL4KkNylkWum8McwsH0LsMr/F+UHhduTX7KRg==", + "requires": { + "assert": "^2.0.0", + "browserify-zlib": "^0.2.0", + "buffer": "^5.7.1", + "console-browserify": "^1.2.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.12.0", + "domain-browser": "^4.22.0", + "elliptic": "^6.5.4", + "events": "^3.3.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "^1.0.0", + "process": "^0.11.10", + "punycode": "^1.4.1", + "querystring-es3": "^0.2.1", + "readable-stream": "^3.6.0", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", + "string_decoder": "^1.3.0", + "timers-browserify": "^2.0.12", + "tty-browserify": "0.0.1", + "url": "^0.11.0", + "util": "^0.12.4", + "vm-browserify": "^1.1.2" + }, + "dependencies": { + "asn1.js": { + "version": "5.4.1", + "bundled": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "assert": { + "version": "2.0.0", + "bundled": true, + "requires": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, + "available-typed-arrays": { + "version": "1.0.4", + "bundled": true + }, + "base64-js": { + "version": "1.5.1", + "bundled": true + }, + "bn.js": { + "version": "5.2.0", + "bundled": true + }, + "brorand": { + "version": "1.1.0", + "bundled": true + }, + "browserify-aes": { + "version": "1.2.0", + "bundled": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "bundled": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "bundled": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "bundled": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "bundled": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "bundled": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "5.7.1", + "bundled": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-xor": { + "version": "1.0.3", + "bundled": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "bundled": true + }, + "call-bind": { + "version": "1.0.2", + "bundled": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "cipher-base": { + "version": "1.0.4", + "bundled": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "console-browserify": { + "version": "1.2.0", + "bundled": true + }, + "constants-browserify": { + "version": "1.0.0", + "bundled": true + }, + "create-ecdh": { + "version": "4.0.4", + "bundled": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "bundled": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "bundled": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "bundled": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "define-properties": { + "version": "1.1.3", + "bundled": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "des.js": { + "version": "1.0.1", + "bundled": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "diffie-hellman": { + "version": "5.0.3", + "bundled": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "domain-browser": { + "version": "4.22.0", + "bundled": true + }, + "elliptic": { + "version": "6.5.4", + "bundled": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "es-abstract": { + "version": "1.18.3", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "bundled": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-object-assign": { + "version": "1.1.0", + "bundled": true + }, + "events": { + "version": "3.3.0", + "bundled": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "bundled": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "foreach": { + "version": "2.0.5", + "bundled": true + }, + "function-bind": { + "version": "1.1.1", + "bundled": true + }, + "get-intrinsic": { + "version": "1.1.1", + "bundled": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "has": { + "version": "1.0.3", + "bundled": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "bundled": true + }, + "has-symbols": { + "version": "1.0.2", + "bundled": true + }, + "hash-base": { + "version": "3.1.0", + "bundled": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "bundled": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "https-browserify": { + "version": "1.0.0", + "bundled": true + }, + "ieee754": { + "version": "1.2.1", + "bundled": true + }, + "inherits": { + "version": "2.0.4", + "bundled": true + }, + "is-arguments": { + "version": "1.1.0", + "bundled": true, + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-bigint": { + "version": "1.0.2", + "bundled": true + }, + "is-boolean-object": { + "version": "1.1.1", + "bundled": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-callable": { + "version": "1.2.3", + "bundled": true + }, + "is-date-object": { + "version": "1.0.4", + "bundled": true + }, + "is-generator-function": { + "version": "1.0.9", + "bundled": true + }, + "is-nan": { + "version": "1.3.2", + "bundled": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "bundled": true + }, + "is-number-object": { + "version": "1.0.5", + "bundled": true + }, + "is-regex": { + "version": "1.1.3", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.6", + "bundled": true + }, + "is-symbol": { + "version": "1.0.4", + "bundled": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.5", + "bundled": true, + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + } + }, + "md5.js": { + "version": "1.3.5", + "bundled": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "bundled": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "bundled": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "bundled": true + }, + "object-inspect": { + "version": "1.10.3", + "bundled": true + }, + "object-is": { + "version": "1.1.5", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "bundled": true + }, + "object.assign": { + "version": "4.1.2", + "bundled": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "os-browserify": { + "version": "0.3.0", + "bundled": true + }, + "pako": { + "version": "1.0.11", + "bundled": true + }, + "parse-asn1": { + "version": "5.1.6", + "bundled": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "1.0.1", + "bundled": true + }, + "pbkdf2": { + "version": "3.1.2", + "bundled": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "process": { + "version": "0.11.10", + "bundled": true + }, + "public-encrypt": { + "version": "4.0.3", + "bundled": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "punycode": { + "version": "1.4.1", + "bundled": true + }, + "querystring": { + "version": "0.2.0", + "bundled": true + }, + "querystring-es3": { + "version": "0.2.1", + "bundled": true + }, + "randombytes": { + "version": "2.1.0", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "bundled": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "ripemd160": { + "version": "2.0.2", + "bundled": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "bundled": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true + }, + "setimmediate": { + "version": "1.0.5", + "bundled": true + }, + "sha.js": { + "version": "2.4.11", + "bundled": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "stream-browserify": { + "version": "3.0.0", + "bundled": true, + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "stream-http": { + "version": "3.2.0", + "bundled": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "timers-browserify": { + "version": "2.0.12", + "bundled": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tty-browserify": { + "version": "0.0.1", + "bundled": true + }, + "unbox-primitive": { + "version": "1.0.1", + "bundled": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "url": { + "version": "0.11.0", + "bundled": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "bundled": true + } + } + }, + "util": { + "version": "0.12.4", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, + "vm-browserify": { + "version": "1.1.2", + "bundled": true + }, + "which-boxed-primitive": { + "version": "1.0.2", + "bundled": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.4", + "bundled": true, + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + } + }, + "xtend": { + "version": "4.0.2", + "bundled": true + } + } + }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + } + }, + "regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + } + } +} diff --git a/example/package.json b/example/package.json new file mode 100644 index 0000000..7b0ab58 --- /dev/null +++ b/example/package.json @@ -0,0 +1,30 @@ +{ + "name": "example", + "private": true, + "scripts": { + "start": "meteor run", + "test": "meteor test --once --driver-package meteortesting:mocha", + "test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha", + "visualize": "meteor --production --extra-packages bundle-visualizer" + }, + "dependencies": { + "@babel/runtime": "^7.20.7", + "meteor-node-stubs": "^1.2.5", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/mocha": "^8.2.3", + "@types/node": "^18.13.0", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.10", + "typescript": "^4.9.4" + }, + "meteor": { + "mainModule": { + "client": "client/main.tsx", + "server": "server/main.ts" + }, + "testModule": "tests/main.ts" + } +} diff --git a/example/server/main.ts b/example/server/main.ts new file mode 100644 index 0000000..aa1345f --- /dev/null +++ b/example/server/main.ts @@ -0,0 +1,59 @@ +import { Meteor } from 'meteor/meteor'; +import { Link, LinksCollection } from '/imports/api/links'; + +async function insertLink({ title, url }: Pick) { + await LinksCollection.insertAsync({ title, url, createdAt: new Date() }); +} + +Meteor.startup(async () => { + // If the Links collection is empty, add some data. + if ((await LinksCollection.find().countAsync()) === 0) { + await insertLink({ + title: 'Do the Tutorial', + url: 'https://www.meteor.com/tutorials/react/creating-an-app', + }); + + await insertLink({ + title: 'Follow the Guide', + url: 'https://guide.meteor.com', + }); + + await insertLink({ + title: 'Read the Docs', + url: 'https://docs.meteor.com', + }); + + await insertLink({ + title: 'Discussions', + url: 'https://forums.meteor.com', + }); + } + + // We publish the entire Links collection to all clients. + // In order to be fetched in real-time to the clients + Meteor.publish('links', function () { + return LinksCollection.find(); + }); + + Meteor.methods({ + methodWithResult: async function (params) { + this.unblock(); + Meteor._sleepForMs(1500); + + return { + date: new Date(), + value: 'Good night', + params, + }; + }, + methodWithError: function () { + this.unblock(); + Meteor._sleepForMs(3000); + + throw new Meteor.Error( + 500, + 'Something is wrong on a server. Debug please!' + ); + }, + }); +}); diff --git a/example/tests/main.ts b/example/tests/main.ts new file mode 100644 index 0000000..2f021ee --- /dev/null +++ b/example/tests/main.ts @@ -0,0 +1,21 @@ +import { Meteor } from 'meteor/meteor'; +import assert from 'assert'; + +describe('example', function () { + it('package.json has correct name', async function () { + const { name } = await import('../package.json'); + assert.strictEqual(name, 'example'); + }); + + if (Meteor.isClient) { + it('client is not server', function () { + assert.strictEqual(Meteor.isServer, false); + }); + } + + if (Meteor.isServer) { + it('server is not client', function () { + assert.strictEqual(Meteor.isClient, false); + }); + } +}); diff --git a/example/tsconfig.json b/example/tsconfig.json new file mode 100644 index 0000000..5806f49 --- /dev/null +++ b/example/tsconfig.json @@ -0,0 +1,45 @@ +{ + "compilerOptions": { + /* Basic Options */ + "target": "es2018", + "module": "esNext", + "lib": ["esnext", "dom"], + "allowJs": true, + "checkJs": false, + "jsx": "preserve", + "incremental": true, + "noEmit": true, + + /* Strict Type-Checking Options */ + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + + /* Additional Checks */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": false, + "noFallthroughCasesInSwitch": false, + + /* Module Resolution Options */ + "baseUrl": ".", + "paths": { + /* Support absolute /imports/* with a leading '/' */ + "/*": ["*"], + /* Pull in type declarations for Meteor packages from either zodern:types or @types/meteor packages */ + "meteor/*": [ + "node_modules/@types/meteor/*", + ".meteor/local/types/packages.d.ts" + ] + }, + "moduleResolution": "node", + "resolveJsonModule": true, + "types": ["node", "mocha"], + "esModuleInterop": true, + "preserveSymlinks": true + }, + "exclude": [ + "./.meteor/**", + "./packages/**" + ] +} diff --git a/index.js b/index.js deleted file mode 100644 index 85c0096..0000000 --- a/index.js +++ /dev/null @@ -1,37 +0,0 @@ -import { useState, useCallback } from 'react'; - -const initialState = { - loading: false, - error: null, - result: null, -}; - -const useMeteorCall = (name, params = {}, cb) => { - if (!name) { - console.error('Name is required for Meteor methods'); - } - - const [loading, setLoading] = useState(initialState.loading); - const [error, setError] = useState(initialState.error); - const [result, setResult] = useState(initialState.result); - - const methodHandler = useCallback(() => { - setLoading(true); - setError(initialState.error); - setResult(initialState.result); - - Meteor.call(name, params, (error, result) => { - setLoading(false); - setError(error); - setResult(result); - - if (typeof cb === 'function') { - cb(error, result); - } - }); - }, [name, params, cb]); - - return [methodHandler, loading, error, result]; -}; - -export { useMeteorCall }; diff --git a/package.json b/package.json index d21b0ba..bcb1c42 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,13 @@ { "name": "react-meteor-method-hooks", - "version": "0.0.1", + "version": "0.0.2-beta.1", "description": "", - "main": "index.js", + "main": "./example/imports/ui/react-meteor-method-hooks/useMeteorCall.js", + "types": "./example/imports/ui/react-meteor-method-hooks/types.d.ts", + "files": [ + "./example/imports/ui/react-meteor-method-hooks/useMeteorCall.js", + "./example/imports/ui/react-meteor-method-hooks/types.d.ts" + ], "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, From 60e26488315eadb69e3ec3370f9df15da9009ab6 Mon Sep 17 00:00:00 2001 From: Nikolay Aleshkovskiy Date: Thu, 7 Dec 2023 21:46:26 +0700 Subject: [PATCH 02/25] feat: Move code to ./src before publish --- package.json | 12 ++++----- pre-publish.sh | 10 ++++++++ src/types.d.ts | 16 ++++++++++++ src/useMeteorCall.js | 59 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 pre-publish.sh create mode 100644 src/types.d.ts create mode 100644 src/useMeteorCall.js diff --git a/package.json b/package.json index bcb1c42..3b033c4 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,15 @@ { "name": "react-meteor-method-hooks", - "version": "0.0.2-beta.1", + "version": "0.0.2-beta.2", "description": "", - "main": "./example/imports/ui/react-meteor-method-hooks/useMeteorCall.js", - "types": "./example/imports/ui/react-meteor-method-hooks/types.d.ts", + "main": "./src/useMeteorCall.js", + "types": "./src/types.d.ts", "files": [ - "./example/imports/ui/react-meteor-method-hooks/useMeteorCall.js", - "./example/imports/ui/react-meteor-method-hooks/types.d.ts" + "./src/useMeteorCall.js", + "./src/types.d.ts" ], "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "prepublishOnly": "sh ./pre-publish.sh" }, "repository": { "type": "git", diff --git a/pre-publish.sh b/pre-publish.sh new file mode 100644 index 0000000..2b8dd01 --- /dev/null +++ b/pre-publish.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Script to prepare the package structure before npm publish + +# Remove existing files and directories +rm -rf ./src + +# Create a new directory structure +mkdir ./src +cp ./example/imports/ui/react-meteor-method-hooks/* ./src diff --git a/src/types.d.ts b/src/types.d.ts new file mode 100644 index 0000000..25e2adb --- /dev/null +++ b/src/types.d.ts @@ -0,0 +1,16 @@ +type UseMeteorCallHook = ( + name: string, + params: object, + cb: (error: object | undefined, result: any) => void +) => [ + methodHandler: () => Promise, + loading: boolean, + error: object | undefined, + result: any +]; + +type UseMeteorCallHookInitialState = { + loading: boolean; + error: object | undefined; + result: any; +} diff --git a/src/useMeteorCall.js b/src/useMeteorCall.js new file mode 100644 index 0000000..3dee1ca --- /dev/null +++ b/src/useMeteorCall.js @@ -0,0 +1,59 @@ +import { Meteor } from 'meteor/meteor'; +import { useState, useCallback } from 'react'; + +/// + +/** @type {UseMeteorCallHookInitialState} */ +const initialState = { + loading: false, + error: undefined, + result: undefined, +}; + +/** @type {UseMeteorCallHook} */ +const useMeteorCall = (name, params = {}, cb) => { + if (!name) { + console.error('Name is required to call Meteor method'); + } + + const [loading, setLoading] = useState(initialState.loading); + const [error, setError] = useState(initialState.error); + const [result, setResult] = useState(initialState.result); + + const methodHandler = useCallback(async () => { + setLoading(true); + setError(initialState.error); + setResult(initialState.result); + + // Meteor 3.0 + if (typeof Meteor.callAsync === 'function') { + try { + const result = await Meteor.callAsync(name, params); + setLoading(false); + setResult(result); + + if (typeof cb === 'function') { + cb(error, result); + } + } catch (error) { + setError(error); + } + } + // Meteor 2.x + else { + Meteor.call(name, params, (error, result) => { + setLoading(false); + setError(error); + setResult(result); + + if (typeof cb === 'function') { + cb(error, result); + } + }); + } + }, [name, params, cb]); + + return [methodHandler, loading, error, result]; +}; + +export { useMeteorCall }; From 0a3bad4c417f34cd6140fc1b9079c0153aa69b38 Mon Sep 17 00:00:00 2001 From: Nikolay Aleshkovskiy Date: Sat, 9 Dec 2023 11:39:49 +0700 Subject: [PATCH 03/25] feat: Update code, add logging and params, update docs --- README.md | 25 +++++--- example/imports/ui/App.tsx | 8 +++ .../ui/react-meteor-method-hooks/types.d.ts | 9 ++- .../useMeteorCall.js | 60 ++++++++++++++++++- 4 files changed, 90 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index f66dd4d..7df912d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # react-meteor-method-hooks -Simple hook to handle `Meteor.call` requests. +Updated to work with `Meteor.callAsync()` method. + +Simple hook to handle `Meteor.callAsync()` or `Meteor.call()` requests. Usage example: @@ -11,13 +13,13 @@ import { useMeteorCall } from 'react-meteor-method-hooks'; const MyComponent = () => { const [ - calculateSomething, - calculateSomethingLoading, - calculateSomethingError, + calculateSomething, + calculateSomethingLoading, + calculateSomethingError, calculateSomethingResult ] = useMeteorCall( 'calculateSomethingMethodName', - {}, + { methodParam: 'Test string' }, (error, result) => { if (error) { alert(error.reason); @@ -25,11 +27,20 @@ const MyComponent = () => { console.log(result); } }, + { + // Forces to use Meteor.call() instead of Meteor.callAsync() + forceSyncCall: true, + // Adds some logging in console + logging: true, + // By default the package writes console.error for all incoming errors + // This behaviour can be disabled by the setting + suppressErrorLogging: true + } ); return ( -