From a2c544de543343ad4135f0419f1548ed1cf502cb Mon Sep 17 00:00:00 2001 From: Idan Amit Date: Thu, 19 Jul 2018 12:05:50 +0300 Subject: sdc-pubsub first commit Committed sdc-pubsub code for the first time to LF repo Change-Id: I1e26f7fe8b2f1747169e3101e0705d1c89d3f56b Issue-ID: SDC-1537 Signed-off-by: Idan Amit --- .gitattributes | 2 + .gitignore | 7 +++ .gitreview | 4 ++ .npmignore | 5 ++ LICENSE.TXT | 19 ++++++++ README.md | 70 ++++++++++++++++++++++++++++ index.ts | 4 ++ lib/base-pubsub.ts | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/plugin-pubsub.ts | 29 ++++++++++++ package.json | 25 ++++++++++ tsconfig.json | 18 ++++++++ version.properties | 13 ++++++ webpack.config.js | 68 +++++++++++++++++++++++++++ 13 files changed, 391 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .gitreview create mode 100644 .npmignore create mode 100644 LICENSE.TXT create mode 100644 README.md create mode 100644 index.ts create mode 100644 lib/base-pubsub.ts create mode 100644 lib/plugin-pubsub.ts create mode 100644 package.json create mode 100644 tsconfig.json create mode 100644 version.properties create mode 100644 webpack.config.js 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= +//parentUrl= +//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; + eventsCallbacks: Array; + clientId: string; + eventsToWait: Map>; + lastEventNotified: string; + + constructor(pluginId: string) { + this.subscribers = new Map(); + this.eventsCallbacks = []; + this.eventsToWait = new Map>(); + 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) => + 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) { + super(pluginId); + this.register('sdc-hub', window.parent, parentUrl); + this.subscribe(eventsToWait); + } + + public subscribe(eventsToWait?: Array) { + 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 -- cgit 1.2.3-korg