diff --git a/packages/pubsub/.babelrc.js b/packages/pubsub/.babelrc.js new file mode 100644 index 00000000000..7cdc243c30a --- /dev/null +++ b/packages/pubsub/.babelrc.js @@ -0,0 +1 @@ +module.exports = require("../../.babel.node")({ path: __dirname }); diff --git a/packages/pubsub/LICENSE b/packages/pubsub/LICENSE new file mode 100644 index 00000000000..f772d04d4db --- /dev/null +++ b/packages/pubsub/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Webiny + +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. diff --git a/packages/pubsub/README.md b/packages/pubsub/README.md new file mode 100644 index 00000000000..bfaebecea4d --- /dev/null +++ b/packages/pubsub/README.md @@ -0,0 +1,20 @@ +# @webiny/pubsub + +[![](https://img.shields.io/npm/dw/@webiny/pubsub.svg)](https://www.npmjs.com/package/@webiny/pubsub) +[![](https://img.shields.io/npm/v/@webiny/pubsub.svg)](https://www.npmjs.com/package/@webiny/pubsub) +[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) + +## Install + +``` +yarn add @webiny/pubsub +``` + + +## Testing + +### Command +```` +yarn test packages/pubsub +```` \ No newline at end of file diff --git a/packages/pubsub/__tests__/pubsub.test.ts b/packages/pubsub/__tests__/pubsub.test.ts new file mode 100644 index 00000000000..97160b194a8 --- /dev/null +++ b/packages/pubsub/__tests__/pubsub.test.ts @@ -0,0 +1,21 @@ +import { createTopic } from "../src"; + +describe("pubsub", () => { + test("create a topic, subscribe to it, and publish an event", async () => { + const topic = createTopic(); + + const values = []; + + topic.subscribe(eventValue => { + values.push(eventValue); + }); + + topic.subscribe(eventValue => { + values.push(eventValue); + }); + + await topic.publish(1); + + expect(values).toEqual([1, 1]); + }); +}); diff --git a/packages/pubsub/jest.config.js b/packages/pubsub/jest.config.js new file mode 100644 index 00000000000..cc5ac2bb64f --- /dev/null +++ b/packages/pubsub/jest.config.js @@ -0,0 +1,5 @@ +const base = require("../../jest.config.base"); + +module.exports = { + ...base({ path: __dirname }) +}; diff --git a/packages/pubsub/package.json b/packages/pubsub/package.json new file mode 100644 index 00000000000..c71df59f374 --- /dev/null +++ b/packages/pubsub/package.json @@ -0,0 +1,29 @@ +{ + "name": "@webiny/pubsub", + "version": "5.14.0", + "main": "index.js", + "repository": { + "type": "git", + "url": "https://github.com/webiny/webiny-js.git", + "directory": "packages/pubsub" + }, + "description": "A simple implementation of publish-subscribe pattern based on topic objects instead of strings.", + "license": "MIT", + "publishConfig": { + "access": "public", + "directory": "dist" + }, + "devDependencies": { + "@babel/cli": "^7.12.10", + "@babel/core": "^7.5.5", + "@webiny/cli": "^5.13.0", + "@webiny/project-utils": "^5.13.0", + "rimraf": "^3.0.2", + "ttypescript": "^1.5.12", + "typescript": "^4.1.3" + }, + "scripts": { + "build": "yarn webiny run build", + "watch": "yarn webiny run watch" + } +} diff --git a/packages/pubsub/src/index.ts b/packages/pubsub/src/index.ts new file mode 100644 index 00000000000..f5ab2c85b1e --- /dev/null +++ b/packages/pubsub/src/index.ts @@ -0,0 +1,22 @@ +import { Subscriber, Topic } from "~/types"; + +export const createTopic = (topicName?: string): Topic => { + const subscribers: Subscriber[] = []; + + return { + getTopicName() { + return topicName || "unknown"; + }, + subscribe(cb: Subscriber) { + subscribers.push(cb); + }, + getSubscribers() { + return subscribers; + }, + async publish(event) { + for (const cb of subscribers) { + await cb(event); + } + } + }; +}; diff --git a/packages/pubsub/src/types.ts b/packages/pubsub/src/types.ts new file mode 100644 index 00000000000..0d197518442 --- /dev/null +++ b/packages/pubsub/src/types.ts @@ -0,0 +1,15 @@ +export interface Subscriber { + (event: TEvent): void | Promise; +} + +export type Event = Record; + +export interface Topic { + getTopicName(): string; + + subscribe(cb: (event: TEvent) => void | Promise): void; + + getSubscribers(): Subscriber[]; + + publish(event?: TEvent): Promise; +} diff --git a/packages/pubsub/tsconfig.build.json b/packages/pubsub/tsconfig.build.json new file mode 100644 index 00000000000..4615d573cc6 --- /dev/null +++ b/packages/pubsub/tsconfig.build.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.build.json", + "include": ["./src"], + "exclude": ["node_modules", "./dist"], + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "declarationDir": "./dist", + "paths": { + "~/*": ["./src/*"] + }, + "baseUrl": "." + }, + "references": [] +} diff --git a/packages/pubsub/tsconfig.json b/packages/pubsub/tsconfig.json new file mode 100644 index 00000000000..be13e36b4df --- /dev/null +++ b/packages/pubsub/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig", + "references": [], + "include": ["./src", "./__tests__"], + "compilerOptions": { + "paths": { + "~/*": ["./src/*"] + }, + "baseUrl": "." + } +} diff --git a/packages/pubsub/webiny.config.js b/packages/pubsub/webiny.config.js new file mode 100644 index 00000000000..d2680341ca2 --- /dev/null +++ b/packages/pubsub/webiny.config.js @@ -0,0 +1,8 @@ +const { watchPackage, buildPackage } = require("@webiny/project-utils"); + +module.exports = { + commands: { + build: buildPackage, + watch: watchPackage + } +}; diff --git a/yarn.lock b/yarn.lock index c238c647eb8..3c7e4ce55dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10235,7 +10235,7 @@ __metadata: languageName: unknown linkType: soft -"@webiny/cli@^5.14.0, @webiny/cli@workspace:packages/cli": +"@webiny/cli@^5.13.0, @webiny/cli@^5.14.0, @webiny/cli@workspace:packages/cli": version: 0.0.0-use.local resolution: "@webiny/cli@workspace:packages/cli" dependencies: @@ -10611,7 +10611,7 @@ __metadata: languageName: unknown linkType: soft -"@webiny/project-utils@^5.14.0, @webiny/project-utils@workspace:packages/project-utils": +"@webiny/project-utils@^5.13.0, @webiny/project-utils@^5.14.0, @webiny/project-utils@workspace:packages/project-utils": version: 0.0.0-use.local resolution: "@webiny/project-utils@workspace:packages/project-utils" dependencies: @@ -10676,6 +10676,20 @@ __metadata: languageName: unknown linkType: soft +"@webiny/pubsub@workspace:packages/pubsub": + version: 0.0.0-use.local + resolution: "@webiny/pubsub@workspace:packages/pubsub" + dependencies: + "@babel/cli": ^7.12.10 + "@babel/core": ^7.5.5 + "@webiny/cli": ^5.13.0 + "@webiny/project-utils": ^5.13.0 + rimraf: ^3.0.2 + ttypescript: ^1.5.12 + typescript: ^4.1.3 + languageName: unknown + linkType: soft + "@webiny/pulumi-sdk@^5.14.0, @webiny/pulumi-sdk@workspace:packages/pulumi-sdk": version: 0.0.0-use.local resolution: "@webiny/pulumi-sdk@workspace:packages/pulumi-sdk"