### Setup for Running Tests Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/CONTRIBUTING.md This snippet shows the commands to set up a new Meteor project and install necessary dependencies for running tests. It creates a bare Meteor project, navigates into it, and installs Puppeteer, simpl-schema, and chai. ```bash meteor create --release 1.12.2 --bare test cd test meteor npm i --save puppeteer@1.18.1 simpl-schema chai ``` -------------------------------- ### Install Picker Meteor Package Source: https://github.com/quavedev/meteor-packages/blob/main/picker/README.md Installs the Picker package for Meteor using the Meteor command-line interface. ```sh meteor add quave:picker ``` -------------------------------- ### Install quave:migrations Source: https://github.com/quavedev/meteor-packages/blob/main/migrations/README.md Installs the quave:migrations package using the Meteor package manager. ```sh meteor add quave:migrations ``` -------------------------------- ### Install quave:react-data Source: https://github.com/quavedev/meteor-packages/blob/main/react-data/README.md Installs the quave:react-data Meteor package using the Meteor package manager. ```sh meteor add quave:react-data ``` -------------------------------- ### Install quave:email-postmark Source: https://github.com/quavedev/meteor-packages/blob/main/email-postmark/README.md Installs the quave:email-postmark Meteor package using the Meteor command-line interface. ```sh meteor add quave:email-postmark ``` -------------------------------- ### Install quave:collections and simpl-schema Source: https://github.com/quavedev/meteor-packages/blob/main/collections/README.md Installs the quave:collections package and the simpl-schema library using the Meteor and npm package managers. ```sh meteor add quave:collections meteor npm install simpl-schema ``` -------------------------------- ### Run Package Tests Source: https://github.com/quavedev/meteor-packages/blob/main/migrations/README.md Starts the test runner for the quave:migrations package from its local directory. ```sh meteor test-packages ./ ``` -------------------------------- ### Install react-meteor-data Source: https://github.com/quavedev/meteor-packages/blob/main/react-meteor-data/README.md Installs the react-meteor-data package using the Meteor package manager. It also requires installing React separately if it's not already part of the project. ```bash meteor add react-meteor-data meteor npm install react ``` -------------------------------- ### Install Meteor CPU Profiler Source: https://github.com/quavedev/meteor-packages/blob/main/profile/README.md Installs the Meteor CPU Profiler package using the Meteor CLI. This command is essential for adding the profiling functionality to your Meteor application. ```sh meteor add quave:profile ``` -------------------------------- ### Start Tests with Meteor Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/CONTRIBUTING.md This command initiates the test runner for Meteor packages. It specifies the package directory, the browser driver to use (Puppeteer), and the package to test, along with raw logs and a single run. ```bash METEOR_PACKAGE_DIRS="../" TEST_BROWSER_DRIVER=puppeteer meteor test-packages --raw-logs --once --driver-package meteortesting:mocha ../ ``` -------------------------------- ### Meteor Publication Example Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/how_it_works.md Provides an example of a Meteor publication that returns a cursor from a collection. This publication will subscribe to relevant Redis channels to receive changes. ```javascript Meteor.publish('my_items', function () { return Items.find({userId: this.userId}); }) ``` -------------------------------- ### Install Redis Oplog and Disable Oplog Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/README.md Commands to install the quave-oplog package and the disable-oplog package, which are often used together with Redis Oplog. ```bash meteor add cultofcoders:quave-oplog meteor add disable-oplog ``` -------------------------------- ### Configure Redis Oplog Settings Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/README.md Example JSON configurations for Meteor settings, showing default and full options for Redis Oplog, including Redis connection details and mutation defaults. ```json // settings.json { ... "redisOplog": {} } ``` ```json // default full configuration { ... "redisOplog": { "redis": { "port": 6379, // Redis port "host": "127.0.0.1" // Redis host }, "retryIntervalMs": 10000, // Retries in 10 seconds to reconnect to redis if the connection failed "mutationDefaults": { "optimistic": true, // Does not do a sync processing on the diffs. But it works by default with client-side mutations. "pushToRedis": true // Pushes to redis the changes by default }, "debug": false, // Will show timestamp and activity of redis-oplog. } } ``` -------------------------------- ### Install and Migrate Redis Oplog Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/README.md Commands to remove the old cultofcoders:redis-oplog package and add the quave:redis-oplog package for Meteor 3.0 compatibility. ```shell meteor remove cultofcoders:redis-oplog && meteor add quave:redis-oplog ``` -------------------------------- ### Example of Soft Removal and Querying Source: https://github.com/quavedev/meteor-packages/blob/main/collections/README.md Demonstrates how to use the soft removal functionality. It shows inserting a document, performing a soft remove, and then querying for the document both with and without the soft removal flag. ```javascript // Example of soft removal const user = await UsersCollection.insertAsync({ name: 'John Doe' }); await UsersCollection.removeAsync(user._id); // The user is not actually removed, but marked as removed (using option includeSoftRemoved) const removedUser = await UsersCollection.findOneAsync( { _id: user._id }, { includeSoftRemoved: true } ); console.log(removedUser); // { _id: ..., name: 'John Doe', isRemoved: true } // The user seems to be removed in normal queries const removedUser2 = await UsersCollection.findOneAsync({ _id: user._id }); console.log(removedUser2); // null ``` -------------------------------- ### Install quave:email-sendgrid Source: https://github.com/quavedev/meteor-packages/blob/main/email-sendgrid/README.md Command to add the quave:email-sendgrid package to your Meteor project. ```sh meteor add quave:email-sendgrid ``` -------------------------------- ### Install quave:logged-user-react Source: https://github.com/quavedev/meteor-packages/blob/main/logged-user-react/README.md This command installs the `quave:logged-user-react` Meteor package using the Meteor package manager. ```sh meteor add quave:logged-user-react ``` -------------------------------- ### Install quave:synced-cron Source: https://github.com/quavedev/meteor-packages/blob/main/synced-cron/README.md Installs the synced-cron package into your Meteor project using the Meteor package manager. ```sh meteor add quave:synced-cron ``` -------------------------------- ### Install Meteor Collection Hooks Source: https://github.com/quavedev/meteor-packages/blob/main/meteor-collection-hooks/README.md Installs the Meteor Collection Hooks package using the Meteor package manager. This command should be run in your Meteor project's root directory. ```bash meteor add quave:collection-hooks ``` -------------------------------- ### Install Quave Aggregate Package Source: https://github.com/quavedev/meteor-packages/blob/main/meteor-aggregate/README.md This snippet shows how to remove the old sakulstra:aggregate package and install the quave:aggregate package using the Meteor command line interface. This is the recommended migration path for users of the older package. ```shell meteor remove sakulstra:aggregate && meteor add quave:aggregate ``` -------------------------------- ### Meteor Collection Insert Example Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/how_it_works.md Demonstrates inserting a document into a Meteor collection. This action triggers a publish to a Redis channel. ```javascript const Items = new Mongo.Collection('items') Items.insert({text: 'Hello'}) ``` -------------------------------- ### Install meteor-slingshot Source: https://github.com/quavedev/meteor-packages/blob/main/meteor-slingshot/README.md This command removes the older edgee:slingshot package and adds the compatible quave:slingshot package, ensuring compatibility with Meteor 3.0 and later. ```shell meteor remove edgee:slingshot && meteor add quave:slingshot ``` -------------------------------- ### Aggregation with Explain Option Source: https://github.com/quavedev/meteor-packages/blob/main/meteor-aggregate/README.md Illustrates how to use the `.aggregate` function with the `explain: true` option. This allows you to get detailed information about the execution plan of the aggregation query. The output is then logged to the console in a formatted JSON string. ```javascript const metrics = new Mongo.Collection('metrics'); const pipeline = [{ $group: { _id: null, resTime: { $sum: '$resTime' } } }]; const result = await metrics.aggregate(pipeline, { explain: true }); console.log('Explain Report:', JSON.stringify(result[0]), null, 2); ``` -------------------------------- ### Install quave:alert-react-tailwind Source: https://github.com/quavedev/meteor-packages/blob/main/alert-react-tailwind/README.md Command to add the quave:alert-react-tailwind Meteor package to your project. Ensure you have the necessary npm dependencies like react, react-dom, and react-router-dom installed. ```sh meteor add quave:alert-react-tailwind ``` -------------------------------- ### Custom Logger Implementation Source: https://github.com/quavedev/meteor-packages/blob/main/migrations/README.md Provides an example of how to implement a custom logger function for the Migrations package, allowing for custom logging behavior. ```javascript var MyLogger = function(opts) { console.log('Level', opts.level); console.log('Message', opts.message); console.log('Tag', opts.tag); } Migrations.config({ logger: MyLogger }); Migrations.add({ name: 'Test Job', ... }); ``` -------------------------------- ### Meteor React Suspense useTracker Example Source: https://github.com/quavedev/meteor-packages/blob/main/react-meteor-data/README.md Demonstrates the usage of `useTracker` from `meteor/react-meteor-data/suspense` within a React component. It shows how to subscribe to data and fetch user and task data asynchronously, leveraging Suspense for data loading. ```jsx import { useTracker } from 'meteor/react-meteor-data/suspense' import { useSubscribe } from 'meteor/react-meteor-data/suspense' function Tasks() { // this component will suspend useSubscribe("tasks"); const { username } = useTracker("user", () => Meteor.user()) // Meteor.user() is async meteor 3.0 const tasksByUser = useTracker("tasksByUser", () => TasksCollection.find({username}, { sort: { createdAt: -1 } }).fetchAsync() // async call ); // render the tasks } ``` -------------------------------- ### Disable Reactivity for a Collection Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md This example illustrates how to completely disable reactivity for a specific Meteor collection by setting `pushToRedis` to `false` within the mutation configuration. ```javascript const Tasks = new Mongo.Collection('tasks'); Tasks.configureRedisOplog({ mutation(options) { options.pushToRedis = false; }, }); ``` -------------------------------- ### useFind: Accelerate List Rendering Source: https://github.com/quavedev/meteor-packages/blob/main/react-meteor-data/README.md The `useFind` hook optimizes the rendering of lists derived from MongoDB queries by controlling document object references. It utilizes the `Cursor.observe` API to efficiently update only changed object references during DDP updates, enhancing performance. This hook requires the factory function to return a `Mongo.Cursor` object or `null` for conditional setup; calling `.fetch()` is not recommended. Memoization of list items is also demonstrated for further optimization. ```jsx import React, { memo } from 'react' import { useFind } from 'meteor/react-meteor-data' import TestDocs from '/imports/api/collections/TestDocs' // Memoize the list item const ListItem = memo(({doc}) => { return (
  • {doc.id},{doc.updated}
  • ) }) const Test = () => { const docs = useFind(() => TestDocs.find(), []) return ( ) } // Later on, update a single document - notice only that single component is updated in the DOM TestDocs.update({ id: 2 }, { $inc: { someProp: 1 } }) ``` ```jsx const docs = useFind(() => { if (props.skip) { return null } return TestDocs.find() }, []) ``` -------------------------------- ### ESLint Configuration for useTracker Dependencies Source: https://github.com/quavedev/meteor-packages/blob/main/react-meteor-data/README.md Provides an example ESLint configuration to enforce the correct usage of the dependencies array for the useTracker hook, similar to how it's done for built-in React hooks. ```json "react-hooks/exhaustive-deps": ["warn", { "additionalHooks": "useTracker|useSomeOtherHook|..." }] ``` -------------------------------- ### Meteor Collection Update Example Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/how_it_works.md Shows how to update a document in a Meteor collection. This triggers publishes to both a general collection channel and a specific document channel. ```javascript Items.update(itemId, { $set: { text: 'Hello World!' } }) ``` -------------------------------- ### Create a Paginable Collection Composer Source: https://github.com/quavedev/meteor-packages/blob/main/collections/README.md Provides an example of creating a custom composer to paginate data fetched from a collection. The `paginable` composer includes a `getPaginated` method for fetching items with pagination details. ```javascript import { createCollection } from 'meteor/quave:collections'; const LIMIT = 7; export const paginable = (collection) => Object.assign({}, collection, { getPaginated({ selector, options = {}, paginationAction }) { const { skip, limit } = paginationAction || { skip: 0, limit: LIMIT }; const items = this.find(selector, { ...options, skip, limit, }).fetch(); const total = this.find(selector).count(); const nextSkip = skip + limit; const previousSkip = skip - limit; return { items, pagination: { total, totalPages: parseInt(total / limit, 10) + (total % limit > 0 ? 1 : 0), currentPage: parseInt(skip / limit, 10) + (skip % limit > 0 ? 1 : 0) + 1, ...(nextSkip < total ? { next: { skip: nextSkip, limit } } : {}), ...(previousSkip >= 0 ? { previous: { skip: previousSkip, limit } } : {}), }, }; }, }); export const StoresCollection = createCollection({ name: 'stores', composers: [paginable], }); // This probably will come from the client, using Methods, REST, or GraphQL // const paginationAction = {skip: XXX, limit: YYY}; const { items, pagination } = StoresCollection.getPaginated({ selector: { ...(search ? { name: { $regex: search, $options: 'i' } } : {}), }, options: { sort: { updatedAt: -1 } }, paginationAction, }); ``` -------------------------------- ### SyntheticMutator with Namespaced Collections Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md This example demonstrates the correct usage of `SyntheticMutator.update` when dealing with namespaced collections. It highlights the need to specify the direct processing channel if listening to a document by `_id` without passing the collection instance directly. ```javascript // Be very careful here! // If you perform an update to a channeled, namespaced collection SyntheticMutator.update(`company::{companyId}::threads`, threadId, {}); // This will not work if you listen to a document by _id, you will have to specify direct processing channel: SyntheticMutator.update( [`company::{companyId}::threads`, `threads::${threadId}`], threadId, {} ); // If you pass-in the collection instance as argument, this will be automatically done. ``` -------------------------------- ### Configure AlertProvider in React App Source: https://github.com/quavedev/meteor-packages/blob/main/alert-react-tailwind/README.md Example of setting up the AlertProvider in a React application, typically placed within the BrowserRouter. This enables the alert system's context. The Alert component itself also needs to be rendered. ```jsx import React from 'react'; import { BrowserRouter as Router } from 'react-router-dom'; import { Routes } from './Routes'; import { AlertProvider, Alert } from 'meteor/quave:alert-react-tailwind'; export const App = () => (
    ); ``` -------------------------------- ### Meteor Direct Processing Example Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/how_it_works.md Demonstrates the 'Direct Processing' method for Meteor publications that filter by specific document _ids. This method listens to individual document channels instead of the general collection channel. ```javascript Meteor.publish('items', function () { return Items.find({_id: {$in: ids}}); // this has the same behavior when you have a selector like {_id: 'XXX'} }) ``` -------------------------------- ### Create Slingshot Directive Example in JavaScript Source: https://github.com/quavedev/meteor-packages/blob/main/meteor-slingshot/README.md This JavaScript code demonstrates how to create a Slingshot directive named 'myUploads' using a custom storage service. It specifies the storage service to be used and provides directive-specific options such as an access key and a custom function 'foo' that processes file and meta context. ```JavaScript Slingshot.createDirective("myUploads", MyStorageService, { accessKey: "a12345xyz", foo: function (file, metaContext) { return "bar"; } }); ``` -------------------------------- ### Rackspace Cloud Files CORS Setup Source: https://github.com/quavedev/meteor-packages/blob/main/meteor-slingshot/README.md Configures Cross-Origin Resource Sharing (CORS) for Rackspace Cloud Files using a curl command. Requires an Auth-Token and specifies access control headers for public accessibility. ```Bash curl -I -X POST -H 'X-Auth-Token: yourAuthToken' \ -H 'X-Container-Meta-Access-Control-Allow-Origin: *' \ -H 'X-Container-Meta-Access-Expose-Headers: etag location x-timestamp x-trans-id Access-Control-Allow-Origin' \ https://storage101.containerRegion.clouddrive.com/v1/MossoCloudFS_yourAccoountNumber/yourContainer ``` -------------------------------- ### Run Meteor with Settings Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/README.md Command to run a Meteor application using a specified settings file. ```bash meteor run --settings settings.json ``` -------------------------------- ### Start SyncedCron Source: https://github.com/quavedev/meteor-packages/blob/main/synced-cron/README.md Starts the SyncedCron service, enabling it to begin executing scheduled jobs. This should be called once in your application's startup sequence. ```javascript SyncedCron.start(); ``` -------------------------------- ### Migrate from communitypackages:picker Source: https://github.com/quavedev/meteor-packages/blob/main/picker/README.md Provides instructions to migrate from the communitypackages:picker to quave:picker by removing the old package and adding the new one. ```sh meteor remove communitypackages:picker && meteor add quave:picker ``` -------------------------------- ### Configure Redis Oplog for Mutations and Cursors Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md This snippet demonstrates how to configure Redis Oplog for both mutation and cursor events at the collection level. It shows how to dynamically set namespaces based on the logged-in user's company ID for mutations and cursor subscriptions. ```javascript const Tasks = new Mongo.Collection('tasks'); Tasks.configureRedisOplog({ mutation(options, { event, selector, modifier, doc }) { const userId = Meteor.userId(); const companyId = getCompany(userId); Object.assign(options, { namespace: `company::${companyId}`, }); }, cursor(options, selector) { const companyId = getCompany(this.userId); Object.assign(options, { namespace: `company::${companyId}`, }); }, shouldIncludePrevDocument: false, protectAgainstRaceConditions: true, }); ``` -------------------------------- ### Allowed Cursor Options for RedisOplog Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md Lists the available options for configuring cursors in RedisOplog, including specifying single channels, multiple channels, namespaces, and multiple namespaces for fine-grained reactivity control. ```javascript { channel: 'customChannel'; // it will only listen to customChannel channel channels: []; // array of strings, it will listen to those channels only namespace: 'namespaceString'; // it will listen to namespaceString::actualCollectionName channel namespaces: []; // array of strings, it will listen to those namespaces only } ``` -------------------------------- ### Get Current Migration Version Source: https://github.com/quavedev/meteor-packages/blob/main/migrations/README.md Retrieves the current version of the database migrations. ```javascript await Migrations.getVersion(); ``` -------------------------------- ### Mutating Data with Namespace (Meteor JS) Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md Shows how to insert data into a collection while specifying a namespace. This ensures that the reactivity updates are routed correctly in a multi-tenant environment, targeting the relevant company's data. ```javascript // sample mutation that applies to the namespace Users.insert(data, { namespace: 'company::' + companyId, }); ``` -------------------------------- ### Import Redis Oplog Events Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md This code shows how to import the `Events` object from the `meteor/quave:redis-oplog` package, which is necessary for using event types within mutation configurations. ```javascript import { Events } from 'meteor/quave:redis-oplog'; ``` -------------------------------- ### Get Next Scheduled Date Source: https://github.com/quavedev/meteor-packages/blob/main/synced-cron/README.md Retrieves the Date object for the next scheduled execution of a given job. ```javascript SyncedCron.nextScheduledAtDate(jobName); ``` -------------------------------- ### Publish Users with Namespace for Multi-Tenancy (Meteor JS) Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md Publishes user data with a namespace based on the company ID. This approach is ideal for multi-tenant applications, allowing data to be isolated and reactivity to be focused on specific company data. ```javascript Meteor.publish('users', function () { // get the company for this.userId return Users.find({ companyId }, { namespace: 'company::' + companyId }); }); ``` -------------------------------- ### Emulate Database Writes with SyntheticMutator Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md This snippet shows how to use `SyntheticMutator` to simulate database updates, inserts, and removes. It's useful for real-time features where data doesn't need to be persisted, like showing typing indicators in a chat application. The `update` method requires a specific `_id` and supports Minimongo modifiers. ```javascript import { SyntheticMutator } from 'meteor/quave:redis-oplog'; // If you put the Mongo.Collection object as first argument, it will transform itself to "messages" (the collection name) Meteor.methods({ 'messages.start_typing'(threadId) { // you can use any modifier supported by minimongo // only works with specific _id's, not selectors! SyntheticMutator.update(ThreadsCollection, threadId, { $addToSet: { currentlyTyping: this.userId, }, }); }, }); // And in the client, you will instantly get access to the updated `doc.currentlyTyping` // Even if it's not stored in the database, imagine the potential of this in real-time games. // if data does not have an '_id' set, it will generate it with a Random.id() SyntheticMutator.insert(MessagesCollection, data); // synthetic deletion, like update, only works with specific _ids SyntheticMutator.remove(MessagesCollection, _id); ``` -------------------------------- ### Basic Migration Definition and Execution Source: https://github.com/quavedev/meteor-packages/blob/main/migrations/README.md Defines a simple migration with a version and an 'up' function, and then executes migrations to the latest version on application startup. Includes error handling for the migration process. ```javascript Migrations.add({ version: 1, up: async function() { //code to migrate up to version 1 } }); Meteor.startup(() => { Migrations.migrateTo('latest').catch((e) => console.error(`Error running migrations`, e) ); }); ``` -------------------------------- ### Publish Meteor Package Source: https://github.com/quavedev/meteor-packages/blob/main/collections/README.md Instructions for publishing a Meteor package. This involves updating the version in `package.js`, generating TypeScript definitions, and then publishing the package using the Meteor CLI. ```shell meteor publish ``` -------------------------------- ### Include Previous Document State in Updates Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md This example shows how to configure `shouldIncludePrevDocument` to `true` to include the previous state of a document in Redis event messages during updates. This is useful for tracking changes. ```javascript { u: 'event_id', f: [ 'fieldModified' ], e: 'u', d: { _id: 'document_id', fieldModified: 'oldValue' } } ``` -------------------------------- ### Define Collection Transform Function Source: https://github.com/quavedev/meteor-packages/blob/main/collections/README.md Illustrates how to define a transform function for a collection, which modifies documents before they are returned from queries. This example adds a `user` getter to each document. ```javascript const transform = (doc) => ({ ...doc, get user() { return Meteor.users.findOne(this.userId); }, }); export const PlayersCollection = createCollection({ name: 'players', schema, options: { transform, }, }); ``` -------------------------------- ### Meteor Collection Multi-Update Example Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/how_it_works.md Illustrates updating multiple documents in a Meteor collection based on a selector. This results in multiple messages being sent to Redis for each updated document. ```javascript Items.update({archived: false}, { $set: {archived: true} }, {multi: true}) ``` -------------------------------- ### Allowed Mutation Options for RedisOplog Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/finetuning.md Details the options available when performing mutations with RedisOplog, such as specifying channels, namespaces, controlling optimistic updates, and disabling reactivity for batch operations. ```javascript // channel: String // will only reach the cursors that listen to this channel // channels: [String] // will reach all cursors that listen to any of these channels // namespace: String // namespaces: [String] // optimistic: Boolean // default is true. This is wether or not to do the diff computation in sync so latency compensation works // pushToRedis: Boolean // default is true, use false if you don't want reactivity at all. Useful when doing large batch inserts/updates. ``` -------------------------------- ### Declare AWS S3 Directive (JavaScript) Source: https://github.com/quavedev/meteor-packages/blob/main/meteor-slingshot/README.md A basic example of how to declare a Meteor Slingshot directive for uploading files to AWS S3. This requires AWS credentials to be configured in Meteor settings. ```JavaScript Slingshot.createDirective("aws-s3-example", Slingshot.S3Storage, { //... }); ``` -------------------------------- ### Default Configuration Options Source: https://github.com/quavedev/meteor-packages/blob/main/migrations/README.md Shows the default configuration settings for the Migrations package, including logging behavior and the collection name. ```javascript Migrations.config({ // Log job run details to console log: true, // Use a custom logger function (defaults to Meteor's logging package) logger: null, // Enable/disable logging "Not migrating, already at version {number}" logIfLatest: true, // migrations collection name to use in the database collectionName: "migrations" }); ``` -------------------------------- ### Direct Query Processing with Namespaces Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/outside_mutations.md Demonstrates that namespaces do not affect direct query processing when subscribing by document ID. It shows an example where a subscription bypasses namespacing, listening only to the specific task channel. ```javascript return Tasks.find( { _id: taskId }, { namespace: `group::${groupId}`, } ); ``` -------------------------------- ### Customizing the Persistable Composer Source: https://github.com/quavedev/meteor-packages/blob/main/collections/README.md Demonstrates how to customize the 'persistable' composer with options like `shouldFetchFullDoc`, `beforeInsert`, `beforeUpdate`, `afterInsert`, and `afterUpdate` hooks for advanced control over document persistence. ```javascript const customPersistable = persistable({ shouldFetchFullDoc: true, // When true, fetches the full document for updates beforeInsert: ({ doc }) => { // Modify the document before insertion return { ...doc, customField: 'value' }; }, beforeUpdate: ({ doc }) => { // Modify the document before update return { ...doc, lastModified: new Date() }; }, afterInsert: ({ doc }) => { // Any action after the document has been inserted }, afterUpdate: ({ doc, oldDoc }) => { // Any action after the document has been updated // When shouldFetchFullDoc is true, oldDoc contains the full previous document }, }); export const CustomUsersCollection = createCollection({ name: 'customUsers', composers: [customPersistable], }); ``` -------------------------------- ### Declare Google Cloud Storage Directive (JavaScript) Source: https://github.com/quavedev/meteor-packages/blob/main/meteor-slingshot/README.md A basic example of how to declare a Meteor Slingshot directive for uploading files to Google Cloud Storage. This requires the Google Cloud secret key to be configured. ```JavaScript Slingshot.createDirective("google-cloud-example", Slingshot.GoogleCloud, { //... }); ``` -------------------------------- ### Use useMethod Hook for Async Method Calls Source: https://github.com/quavedev/meteor-packages/blob/main/react-data/README.md Demonstrates how to use the `useMethod` hook from `quave:react-data` to asynchronously call a Meteor method. It shows how to pass arguments and handle the response, including options for error and success callbacks. ```jsx import { useMethod } from 'meteor/quave:react-data'; export const Snapshot = () => { const { method } = useMethod(); const save = async () => { const snapshot = await method('saveSnapshot', { snapshot: { _id: snapshotId, items, }, }); clear(); }; // continue to render... }; ``` -------------------------------- ### Migrate to Specific Version or Undo Source: https://github.com/quavedev/meteor-packages/blob/main/migrations/README.md Demonstrates how to migrate directly to a specified version (e.g., version 2) or undo all migrations by migrating to version 0. Also shows how to rerun a specific migration. ```javascript await Migrations.migrateTo(2); await Migrations.migrateTo(0); await Migrations.migrateTo('3,rerun'); ``` -------------------------------- ### Extend Meteor.users Collection Source: https://github.com/quavedev/meteor-packages/blob/main/collections/README.md Demonstrates extending the built-in `Meteor.users` collection using `createCollection`. This includes adding custom methods, helpers, composers, and applying lifecycle hooks. ```javascript import { createCollection } from 'meteor/quave:collections'; export const UsersCollection = createCollection({ instance: Meteor.users, schema: UserTypeDef, collection: { isAdmin(userId) { const user = userId && this.findOne(userId, { fields: { profiles: 1 } }); return ( user && user.profiles && user.profiles.includes(UserProfile.ADMIN.name) ); }, }, helpers: { toPaymentGatewayJson() { return { country: 'us', external_id: this._id, name: this.name, type: 'individual', email: this.email, }; }, }, composers: [paginable], apply(coll) { coll.after.insert(userAfterInsert(coll), { fetchPrevious: false }); coll.after.update(userAfterUpdate); }, }); ``` -------------------------------- ### Integrate Connect/Express Middlewares Source: https://github.com/quavedev/meteor-packages/blob/main/picker/README.md Shows how to integrate existing Connect and Express middlewares, such as body-parser for JSON and URL-encoded data, into Picker routes. ```javascript import bodyParser from 'body-parser'; // Add two middleware calls. The first attempting to parse the request body as // JSON data and the second as URL encoded data. Picker.middleware(bodyParser.json()); Picker.middleware(bodyParser.urlencoded({ extended: false })); ``` -------------------------------- ### Client: Subscribe and Listen to Redis Vent Events Source: https://github.com/quavedev/meteor-packages/blob/main/redis-oplog/docs/vent.md Shows how to subscribe to a Redis Vent publication on the client and listen for incoming events. It uses Vent.subscribe to establish the connection and handler.listen to process received messages. The handler object also provides ready() and stop() methods. Dependencies include the 'meteor/quave:redis-oplog' package. ```javascript import { Vent } from 'meteor/quave:redis-oplog'; // same handler from Meteor.subscribe, extended with a listen() function const handler = Vent.subscribe('threadMessage', { threadId }); handler.listen(function ({ message }) { // handle it // the object receives is the one returned from the 'on' function }); // returns boolean if the subscription has been marked as ready handler.ready(); // stops all the listeners and the subscription handler.stop(); ```