Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@buildable/messages

Package Overview
Dependencies
Maintainers
5
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@buildable/messages - npm Package Compare versions

Comparing version
1.0.0
to
1.0.1
+25
LICENSE
MIT License
-----------
Copyright (c) 2022 Buildable Technologies Inc (https://www.buildable.dev/)
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
+22
-52

@@ -15,3 +15,3 @@ "use strict";

const emitPath = "/emit";
const SEPERATOR = process.env.BLD_LISTENER_SEPARATOR || "---";
const SEPERATOR = "---";
function createClient(secret) {

@@ -22,14 +22,8 @@ if (!secret) {

let listeners = {};
let fullEventNameCache = {};
const getFullEventName = ({ eventName, platform, label }) => {
return fullEventNameCache[eventName + platform + label];
const getListenerId = ({ eventName, txKey }) => {
return eventName + SEPERATOR + txKey;
};
const getListenerId = ({ eventName, txKey, platform, label }) => {
const fullEventName = getFullEventName({ eventName, platform, label });
return fullEventName + SEPERATOR + txKey;
};
const runTransactions = async ({ eventName, txKey, since = Date.now(), sleepTime = 3000, platform, label }) => {
var _a, _b, _c, _d, _e, _f;
const runTransactions = async ({ eventName, txKey, since = Date.now(), sleepTime = 3000 }) => {
try {
const listener = listeners[getListenerId({ eventName, txKey, platform, label })];
const listener = listeners[getListenerId({ eventName, txKey })];
if (!listener) {

@@ -53,4 +47,2 @@ return; //deregistered

txKey,
platform,
label,
since,

@@ -72,6 +64,6 @@ txState: "does-not-exist",

hasMorePages = false;
console.error("Error fetching events for ", { eventName, txKey }, { data: (_a = e === null || e === void 0 ? void 0 : e.response) === null || _a === void 0 ? void 0 : _a.data, status: (_b = e === null || e === void 0 ? void 0 : e.response) === null || _b === void 0 ? void 0 : _b.status });
console.error("Error fetching events for ", { eventName, txKey }, e === null || e === void 0 ? void 0 : e.response);
}
for (const event of events) {
const { headers, query, payload, key, eventName } = event;
const { headers, query, payload, key } = event;
try {

@@ -91,3 +83,3 @@ await (0, axios_1.default)({

catch (e) {
console.error(`Error initializing transaction for event: ${eventName}, with key: ${key} and txKey: ${txKey}`, { data: (_c = e === null || e === void 0 ? void 0 : e.response) === null || _c === void 0 ? void 0 : _c.data, status: (_d = e === null || e === void 0 ? void 0 : e.response) === null || _d === void 0 ? void 0 : _d.status });
console.error(`Error initializing transaction for event: ${event.eventName}`, e === null || e === void 0 ? void 0 : e.response);
continue;

@@ -118,3 +110,3 @@ }

txKey,
output: error,
output: (0, utils_1.stringify)(error),
state: "failed"

@@ -134,3 +126,3 @@ }

txKey,
output: output || "{}",
output: (0, utils_1.stringify)(output),
state: "finished"

@@ -144,8 +136,8 @@ }

catch (e) {
console.error("Error occurred in query interval", (e === null || e === void 0 ? void 0 : e.response) ? { data: (_e = e === null || e === void 0 ? void 0 : e.response) === null || _e === void 0 ? void 0 : _e.data, status: (_f = e === null || e === void 0 ? void 0 : e.response) === null || _f === void 0 ? void 0 : _f.status } : e);
console.error("Error occurred in query interval", e);
}
await (0, utils_1.sleep)(sleepTime);
const listener = listeners[getListenerId({ eventName, txKey, platform, label })];
const listener = listeners[getListenerId({ eventName, txKey })];
if (listener && listener.interval) {
listener.interval.then(() => runTransactions({ eventName, txKey, since, sleepTime, platform, label })); // doesn't affect stack size
listener.interval.then(() => runTransactions({ eventName, txKey, since })); // doesn't affect stack size
}

@@ -174,42 +166,20 @@ };

},
on: async (eventName, handler, options = {}) => {
let fullEventName = getFullEventName({ eventName, platform: options.platform, label: options.label });
if (!fullEventName) {
const { data } = await (0, axios_1.default)({
method: "post",
url: baseURL + "/get-full-event-name",
headers: {
"X-BUILDABLE-SECRET": secret
},
data: {
eventName,
platform: options.platform,
label: options.platform
}
});
if (!data || !data.fullEventName) {
throw new Error("Could not grab required fullEventName from the server");
}
const [, , ...splitEventName] = data.fullEventName.split(".");
fullEventName = splitEventName.join(".");
fullEventNameCache[eventName + options.platform + options.label] = fullEventName;
}
const txKey = options.txKey || `js-sdk.${fullEventName}`;
const id = getListenerId({ eventName, txKey, platform: options.platform, label: options.label });
on: (eventName, handler, options = {}) => {
const txKey = options.txKey || `js-sdk.${eventName}`;
const id = getListenerId({ eventName, txKey });
if (listeners[id]) {
throw new Error(`Listener already exists with for ${fullEventName} with txKey: ${txKey}`);
throw new Error(`Listener already exists with eventName: ${eventName}, txKey: ${txKey}`);
}
listeners[id] = { eventName, handler, txKey, options, id };
listeners[id].interval = runTransactions({ eventName, txKey, since: options.since, platform: options.platform, label: options.label });
listeners[id].interval = runTransactions({ eventName, txKey, since: options.since });
return { eventName, handler, txKey, options, id };
},
deregister: async ({ eventName, txKey, platform, label }) => {
deregister: ({ eventName, txKey }) => {
const removeKeys = Object.keys(listeners).filter(id => {
const [_fullEventName, _txKey] = id.split(SEPERATOR);
const fullEventName = getFullEventName({ eventName, platform, label });
const [_eventName, _txKey] = id.split(SEPERATOR);
if (eventName && txKey) {
return _fullEventName === fullEventName && _txKey === txKey;
return _eventName === eventName && _txKey === txKey;
}
if (eventName) {
return _fullEventName === fullEventName;
return _eventName === eventName;
}

@@ -216,0 +186,0 @@ if (txKey) {

{
"name": "@buildable/messages",
"version": "1.0.0",
"description": "Custom Events for Buildable",
"version": "1.0.1",
"description": "A fully managed messaging service that lets you easily exchange event data across any app or resource.",
"main": "dist/src/index.js",

@@ -13,5 +13,10 @@ "types": "dist/src/index.d.ts",

"buildable",
"low code"
"events",
"messages",
"message-broker",
"event-broker",
"event-pipeline",
"transactions"
],
"author": "@Buildable Team",
"author": "@buildable",
"license": "MIT",

@@ -18,0 +23,0 @@ "dependencies": {

@@ -5,3 +5,3 @@ # `@buildable/messages`

[Buildable](https://www.buildable.dev/messages) is the easiest way to collect, transform, send and action your backend system messages. Buildable simplifies the process of collecting message data from your disparate systems and connecting new tools to action those messages, allowing you to spend more of your engineering time on things that matter.
[Buildable](https://www.buildable.dev/messages) is the easiest way to collect, transform, send and action your backend system events. Buildable simplifies the process of communicating between services or cloud apps, via Messages.

@@ -33,2 +33,6 @@ **This library allows you to quickly and easily emit and listen on messages via Node.js.**

A message contains:
1. `event` - The name of the event
2. `payload` - The data of the event
Once a message is emitted, it will be visible immediately in the Messages Stream on your Buildable account.

@@ -43,4 +47,4 @@

client.emit("my-message", {
salutation: "Hello world ⚡️"
client.emit("user.created", {
name: "John Doe"
});

@@ -55,5 +59,5 @@ ```

--data-raw '{
"event": "my-message",
"event": "user.created",
"payload": {
"salutation": "Hello world ⚡️"
"name": "John Doe"
}

@@ -65,2 +69,5 @@ }'

### What is a transaction?
A transaction is an action that can be triggered when a message is received. A message can have multiple transactions. Each transaction has a unique transaction key (`txKey`) per message.
There are two cases for transacting on messages:

@@ -78,4 +85,4 @@

// Listen on `my-message`
client.on("my-message", async ({ event, payload }) => {
// Transact on `user.created`
client.on("user.created", async ({ event, payload }) => {
console.log("Receieved message with payload: ", payload);

@@ -87,3 +94,3 @@ });

All [Connections](https://hub.buildable.dev/fundamentals/emitting-messages#emit-using-connections) act as a source of events, leveraging the power of WebHooks. Once you’ve created a Connection in Buildable and subscribed to at least 1 message type, messages will continually enter the Messages Stream. In most cases, once you create a Connection once, you can forget about it!
All [Connections](https://hub.buildable.dev/fundamentals/emitting-messages#emit-using-connections) act as a source of events, leveraging the power of WebHooks. Once you’ve created a Connection in Buildable and subscribed to at least 1 event, messages will continually enter the Messages Stream. In most cases, once you create a Connection once, you can forget about it!

@@ -106,2 +113,48 @@ When listening on messages from cloud apps, simply add two additional options to the listener:

### Multiple transactions on a message
In order to trigger multiple transactions on the same message, you must specify a custom transaction key (`txKey`). For example, if two services need to listen on the same message and trigger different custom logic, each service must pass a unique txKey to the listener.
```javascript
const { createClient } = require('@buildable/messages');
const client = createClient(process.env.BUILDABLE_SECRET_KEY);
// Transaction #1 on `user.created` from service A
client.on("user.created", async ({ event, payload }) => {
// Set the notification.sent transaction output
return await sendNotification(payload);
}, {
txKey: "notification.sent"
});
// Transaction #2 on `user.created` from service B
client.on("user.created", async ({ event, payload }) => {
// Set the salesforce.customer.created transaction output
return await createCustomerOnSalesForce(payload);
}, {
txKey: "salesforce.customer.created"
});
```
*By default, the `txKey` is set to `sdk.{{EVENT_NAME}}`
### Transacting on older messages
In order to transact on messages that have already been emitted, simply pass in the additional configuration argument `since`. For example, to transact on messages from 10 days ago:
```javascript
client.on("user.created", async ({ event, payload }) => {
// Set the notification.sent transaction output
return await sendNotification(payload);
}, {
txKey: "notification.sent",
since: Date.now() - (10 * 24 * 60 * 60 * 1000) // Since 10 days ago
});
```
## API
Alternatively, you can use the `Messages API`. Learn more about it at [hub.buildable.dev](https://hub.buildable.dev/using-the-api)
## Need More Help?

@@ -108,0 +161,0 @@

{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 80,
"useTabs": true
}
export declare const getFullEventName: ({ secret, eventName, platform, label, baseURL }: {
secret: string;
eventName: string;
platform?: string | undefined;
label?: string | undefined;
baseURL: string;
}) => Promise<any>;
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getFullEventName = void 0;
const axios_1 = __importDefault(require("axios"));
const getFullEventName = async ({ secret, eventName, platform, label, baseURL }) => {
let fullEventName;
try {
const { data } = await (0, axios_1.default)({
method: "post",
url: baseURL + "/get-full-event-name",
headers: {
"X-BUILDABLE-SECRET": secret
},
data: {
eventName,
platform: platform,
label: label
}
});
fullEventName = data.fullEventName;
}
catch (e) {
console.error((e === null || e === void 0 ? void 0 : e.response) ? { data: e.response.data, status: e.response.status } : e);
throw new Error("Error retreiving fullEventName");
}
if (fullEventName) {
throw new Error("Could not grab required fullEventName from the server");
}
const [, , ...splitEventName] = fullEventName.split(".");
return splitEventName.join(".");
};
exports.getFullEventName = getFullEventName;