diff options
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | .gitreview | 4 | ||||
-rw-r--r-- | .npmignore | 5 | ||||
-rw-r--r-- | LICENSE.TXT | 19 | ||||
-rw-r--r-- | README.md | 70 | ||||
-rw-r--r-- | index.ts | 4 | ||||
-rw-r--r-- | lib/base-pubsub.ts | 127 | ||||
-rw-r--r-- | lib/plugin-pubsub.ts | 29 | ||||
-rw-r--r-- | package.json | 25 | ||||
-rw-r--r-- | tsconfig.json | 18 | ||||
-rw-r--r-- | version.properties | 13 | ||||
-rw-r--r-- | webpack.config.js | 68 |
13 files changed, 391 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a3439c3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Git will always convert line endings to LF on checkout. You should use this for files that must keep LF endings, even on Windows. +text eol=lf
\ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93d5f49 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.idea/ +dist/ +node_modules/ +**/*.d.ts +**/*.js.map +**/*.js +!webpack.config.js
\ No newline at end of file diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000..346d41c --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=gerrit.onap.org +port=29418 +project=sdc-pubsub.git
\ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..2622b1d --- /dev/null +++ b/.npmignore @@ -0,0 +1,5 @@ +**/*.ts +!**/*.d.ts +**/*.js.map +node_modules/ +tsconfig.json
\ No newline at end of file diff --git a/LICENSE.TXT b/LICENSE.TXT new file mode 100644 index 0000000..4ab2a6d --- /dev/null +++ b/LICENSE.TXT @@ -0,0 +1,19 @@ +/* +* ============LICENSE_START========================================== +* =================================================================== +* Copyright © 2018 AT&T Intellectual Property. +* All rights reserved. +* =================================================================== +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* ============LICENSE_END============================================ +*/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..5047828 --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +## sdc-pubsub + +sdc-pubsub [npm](https://www.npmjs.com/package/sdc-pubsub) package. + +### Installation + +Installing using npm: + +``` +npm install sdc-pubsub +``` + +### Loading It Up +#### ES6 +```javascript +import {PluginPubSub} from 'sdc-pubsub' +``` +#### ES5 + +```javascript +var pluginPubSub = require('PluginPubSub') +``` + +### Usage +#### Initialize a pubsub client +```javascript +//eventsClientId=<received from query params> +//parentUrl=<received from query params> +//eventsToWaitFor = [ “CHECK_IN” ] + +var client = new PluginPubSub('eventsClientId, parentUrl, eventsToWaitFor') +``` + +#### Notify about events +```javascript +client.notify(“READY”) +``` + +#### Register for an event +```javascript +client.on((eventData,event) => { + if(eventData.type == ”WINDOW_OUT”) { + //do logic + } + } +) +``` + +### Dependencies + +* None. + +### Tests + +None. + +### Authors + +* Idan Amit: [https://wiki.onap.org/display/~idanamit](hhttps://wiki.onap.org/display/~idanamit) + + +### Links + +sdc onap wiki [https://wiki.onap.org/x/_TX0](https://wiki.onap.org/x/_TX0) + +### License + +Copyright 2018 AT&T, Inc. + +Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..69e923c --- /dev/null +++ b/index.ts @@ -0,0 +1,4 @@ +import { BasePubSub, IPubSubEvent, ISubscriber } from './lib/base-pubsub'; +import { PluginPubSub } from './lib/plugin-pubsub'; + +export { BasePubSub, PluginPubSub, IPubSubEvent, ISubscriber }; diff --git a/lib/base-pubsub.ts b/lib/base-pubsub.ts new file mode 100644 index 0000000..41e8039 --- /dev/null +++ b/lib/base-pubsub.ts @@ -0,0 +1,127 @@ +declare const window: Window; + +export class BasePubSub { + + subscribers: Map<string, ISubscriber>; + eventsCallbacks: Array<Function>; + clientId: string; + eventsToWait: Map<string, Array<string>>; + lastEventNotified: string; + + constructor(pluginId: string) { + this.subscribers = new Map<string, ISubscriber>(); + this.eventsCallbacks = []; + this.eventsToWait = new Map<string, Array<string>>(); + this.clientId = pluginId; + this.lastEventNotified = ""; + this.onMessage = this.onMessage.bind(this); + + window.addEventListener("message", this.onMessage); + } + + public register(subscriberId: string, subscriberWindow: Window, subscriberUrl: string) { + const subscriber = { + window: subscriberWindow, + locationUrl: subscriberUrl || subscriberWindow.location.href + } as ISubscriber; + + this.subscribers.set(subscriberId, subscriber); + } + + public unregister(subscriberId: string) { + this.subscribers.delete(subscriberId); + } + + public on(callback: Function) { + let functionExists = this.eventsCallbacks.find((func: Function) => { + return callback.toString() == func.toString() + }); + + if (!functionExists) { + this.eventsCallbacks.push(callback); + } + } + + public off(callback: Function) { + let index = this.eventsCallbacks.indexOf(callback); + this.eventsCallbacks.splice(index, 1) + } + + public notify(eventType:string, eventData?:any) { + let eventObj = { + type: eventType, + data: eventData, + originId: this.clientId + } as IPubSubEvent; + + this.subscribers.forEach( (subscriber: ISubscriber, subscriberId: string) => { + subscriber.window.postMessage(eventObj, subscriber.locationUrl); + }); + + this.lastEventNotified = eventType; + + return { + subscribe: function(callbackFn) { + + if(this.subscribers.size !== 0) { + let subscribersToNotify = Array.from(this.subscribers.keys()); + + const checkNotifyComplete = (subscriberId: string) => { + + let index = subscribersToNotify.indexOf(subscriberId); + subscribersToNotify.splice(index, 1); + + if (subscribersToNotify.length === 0) { + callbackFn(); + } + }; + + this.subscribers.forEach((subscriber: ISubscriber, subscriberId: string) => { + if (this.eventsToWait.has(subscriberId) && this.eventsToWait.get(subscriberId).indexOf(eventType) !== -1) { + + const actionCompletedFunction = (eventData, subId = subscriberId) => { + if (eventData.type == "ACTION_COMPLETED") { + checkNotifyComplete(subId); + } + this.off(actionCompletedFunction); + + }; + this.on(actionCompletedFunction); + } + else { + checkNotifyComplete(subscriberId); + } + }); + } + else { + callbackFn(); + } + }.bind(this) + } + } + + public isWaitingForEvent(eventName: string) : boolean { + return Array.from(this.eventsToWait.values()).some((eventsList: Array<string>) => + eventsList.indexOf(eventName) !== -1 + ); + } + + protected onMessage(event: any) { + if (this.subscribers.has(event.data.originId)) { + this.eventsCallbacks.forEach((callback: Function) => { + callback(event.data, event); + }) + } + } +} + +export interface IPubSubEvent { + type: string; + originId: string; + data: any; +} + +export interface ISubscriber { + window: Window; + locationUrl: string; +} diff --git a/lib/plugin-pubsub.ts b/lib/plugin-pubsub.ts new file mode 100644 index 0000000..3a34de9 --- /dev/null +++ b/lib/plugin-pubsub.ts @@ -0,0 +1,29 @@ +import {BasePubSub} from "./base-pubsub"; + +declare const window: Window; + +export class PluginPubSub extends BasePubSub { + + constructor(pluginId: string, parentUrl: string, eventsToWait?: Array<string>) { + super(pluginId); + this.register('sdc-hub', window.parent, parentUrl); + this.subscribe(eventsToWait); + } + + public subscribe(eventsToWait?: Array<string>) { + const registerData = { + pluginId: this.clientId, + eventsToWait: eventsToWait || [] + }; + + this.notify('PLUGIN_REGISTER', registerData); + } + + public unsubscribe() { + const unregisterData = { + pluginId: this.clientId + }; + + this.notify('PLUGIN_UNREGISTER', unregisterData); + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..9bbe3d0 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "sdc-pubsub", + "version": "1.0.15", + "description": "Publish Subscribe library using post message for sdc plugins", + "main": "index.js", + "author": "Idan Amit", + "license": "Apache-2.0", + "scripts": { + "clean": "rimraf dist && rimraf lib", + "build": "webpack --mode development" + }, + "keywords": [ + "sdc", + "pubsub", + "sdc-pubsub", + "onap" + ], + "devDependencies": { + "awesome-typescript-loader": "^3.1.3", + "typescript": "2.7.2", + "webpack": "4.12.0", + "webpack-cli": "^3.1.0", + "rimraf": "^2.6.2" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..0031264 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "module": "commonjs", + "target": "es5", + "lib": [ "es2015", "dom" ], + "allowSyntheticDefaultImports": true, + "suppressImplicitAnyIndexErrors": true, + "forceConsistentCasingInFileNames": true, + "sourceMap": true, + "declaration": true + }, + "files": [ + "./index.ts" + ], + "compileOnSave": false, + "buildOnSave": false +}
\ No newline at end of file diff --git a/version.properties b/version.properties new file mode 100644 index 0000000..66914f1 --- /dev/null +++ b/version.properties @@ -0,0 +1,13 @@ +########################################################### +# Versioning variables +# Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... ) +# because they are used in Jenkins, whose plug-in doesn't support + +major=1 +minor=0 +patch=14 + +base_version=${major}.${minor}.${patch} + +release_version=${base_version} +snapshot_version=${base_version}-SNAPSHOT diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..73c10dd --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,68 @@ +var path = require("path"); +var webpack = require("webpack"); +var UglifyJsPlugin = require("uglifyjs-webpack-plugin"); + +var PATHS = { + entryPoint: path.resolve(__dirname, 'index.ts'), + bundles: path.resolve(__dirname, 'dist'), +} + +var config = { + // These are the entry point of our library. We tell webpack to use + // the name we assign later, when creating the bundle. We also use + // the name to filter the second entry point for applying code + // minification via UglifyJS + entry: { + 'sdc-pubsub': [PATHS.entryPoint], + 'sdc-pubsub.min': [PATHS.entryPoint] + }, + // The output defines how and where we want the bundles. The special + // value `[name]` in `filename` tell Webpack to use the name we defined above. + // We target a UMD and name it MyLib. When including the bundle in the browser + // it will be accessible at `window.MyLib` + output: { + path: PATHS.bundles, + filename: '[name].js', + libraryTarget: 'umd', + library: 'sdcPubSub', + umdNamedDefine: true + }, + // Add resolve for `tsx` and `ts` files, otherwise Webpack would + // only look for common JavaScript file extension (.js) + resolve: { + extensions: ['.ts', '.js'] + }, + // Activate source maps for the bundles in order to preserve the original + // source when the user debugs the application + devtool: 'source-map', + plugins: [ + // Apply minification only on the second bundle by + // using a RegEx on the name, which must end with `.min.js` + // NB: Remember to activate sourceMaps in UglifyJsPlugin + // since they are disabled by default! + new UglifyJsPlugin({ + sourceMap: true, + include: /\.min\.js$/, + }) + ], + module: { + // Webpack doesn't understand TypeScript files and a loader is needed. + // `node_modules` folder is excluded in order to prevent problems with + // the library dependencies, as well as `__tests__` folders that + // contain the tests for the library + rules: [ + { + test: /\.ts?$/, + use: [ + { + loader: 'awesome-typescript-loader', + options: { + configFileName: 'tsconfig.json' + } + } + ] + }] + } +} + +module.exports = config;
\ No newline at end of file |