diff --git a/.github/workflows/release-workflow.yaml b/.github/workflows/release-workflow.yaml index 9ecfa159..c4bfb230 100644 --- a/.github/workflows/release-workflow.yaml +++ b/.github/workflows/release-workflow.yaml @@ -19,7 +19,7 @@ jobs: node-version: "16.x" registry-url: "https://registry.npmjs.org" - run: npm ci - - run: npm run build + - run: npm run build-prod - run: npm publish --access public env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/tag-workflow.yaml b/.github/workflows/tag-workflow.yaml index d2b5a9c7..00b19a9d 100644 --- a/.github/workflows/tag-workflow.yaml +++ b/.github/workflows/tag-workflow.yaml @@ -43,7 +43,7 @@ jobs: - name: Build SPS Frontend run: | cd ./examples/typescript - npm run build-all + npm run build-all-prod # Build the Scalable Pixel Streaming Frontend Docker image from the dist directories of the packages - name: Build the Scalable Pixel Streaming Frontend Docker image and push to Docker diff --git a/.github/workflows/test-pull-request.yaml b/.github/workflows/test-pull-request.yaml index 6dde6116..8e964bbc 100644 --- a/.github/workflows/test-pull-request.yaml +++ b/.github/workflows/test-pull-request.yaml @@ -1,4 +1,4 @@ -# The following workflow will run when a pull request is opened, synched or reopened +# The following workflow will run when a pull request is opened, synced or reopened # It's intent is to run a build of the package against the PR to ensure that it passes a code build check name: test-build @@ -26,10 +26,30 @@ jobs: with: node-version: "16.x" - # install deps for frontend and library and build both - - name: Install library and frontend deps and build + # install deps for Library and build for development + - name: Install and build library for development + working-directory: ./library + run: | + npm ci + npm run build-dev + + # install deps for Library and build for production + - name: Install and build library for production + working-directory: ./library + run: | + npm ci + npm run build-prod + + # install deps for Frontend and Library and build both for development + - name: Install and build library and Frontend for development + working-directory: ./examples/typescript + run: | + npm ci + npm run build-all-dev + + # install deps for Frontend and Library for and build both for production + - name: Install and build library and Frontend for production working-directory: ./examples/typescript - id: npm run: | npm ci - npm run build-all \ No newline at end of file + npm run build-all-prod \ No newline at end of file diff --git a/.gitignore b/.gitignore index 07bca9dd..86e183a7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ dist/ node_modules/ types/ .vscode +!.env.example +.env diff --git a/examples/typescript/.env.example b/examples/typescript/.env.example new file mode 100644 index 00000000..f018a2a5 --- /dev/null +++ b/examples/typescript/.env.example @@ -0,0 +1 @@ +WEBSOCKET_URL=ws://example.com/your/ws \ No newline at end of file diff --git a/examples/typescript/package-lock.json b/examples/typescript/package-lock.json index e4945e1c..c2aa7fa9 100644 --- a/examples/typescript/package-lock.json +++ b/examples/typescript/package-lock.json @@ -16,6 +16,7 @@ "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.7.3", "declaration-bundler-webpack-plugin": "^1.0.3", + "dotenv": "^16.0.3", "html-loader": "^4.2.0", "html-webpack-plugin": "^5.5.0", "style-loader": "^3.3.1", @@ -2602,6 +2603,15 @@ "tslib": "^2.0.3" } }, + "node_modules/dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -10463,6 +10473,12 @@ "tslib": "^2.0.3" } }, + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "dev": true + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", diff --git a/examples/typescript/package.json b/examples/typescript/package.json index f826d6ca..fac53ffd 100644 --- a/examples/typescript/package.json +++ b/examples/typescript/package.json @@ -2,13 +2,17 @@ "name": "spstypescriptexample", "version": "1.0.0", "description": "The typescript example for consuming the Scalable Pixel Streaming Frontend", - "main": "index.ts", + "main": "./src/index.ts", "scripts": { - "build": "npx webpack", + "build-dev": "npx webpack --config webpack.dev.js", + "build-prod": "npx webpack --config webpack.prod.js", "watch": "npx webpack --watch", "start": "npx webpack && open-cli ./dist/index.html", - "serve": "webpack serve", - "build-all": "cd ../../library && npm install && npm run build && cd ../examples/typescript && npm install && npm link ../../library && npm run build" + "serve-dev": "webpack serve --config webpack.dev.js", + "serve-prod": "webpack serve --config webpack.prod.js", + "symlink": "npm link ../../library", + "build-all-dev": "cd ../../library && npm install && npm run build-dev && cd ../examples/typescript && npm run symlink && npm run build-dev", + "build-all-prod": "cd ../../library && npm install && npm run build-prod && cd ../examples/typescript && npm run symlink && npm run build-prod" }, "author": "TensorWorks Pty Ltd", "keywords": [], @@ -21,14 +25,15 @@ "copy-webpack-plugin": "^11.0.0", "css-loader": "^6.7.3", "declaration-bundler-webpack-plugin": "^1.0.3", + "dotenv": "^16.0.3", + "html-loader": "^4.2.0", "html-webpack-plugin": "^5.5.0", "style-loader": "^3.3.1", "ts-loader": "^9.4.2", - "html-loader": "^4.2.0", "typescript": "^4.9.5", "webpack": "^5.76.1", "webpack-cli": "^5.0.1", "webpack-dev-server": "^4.11.1", "wepack-cli": "^0.0.1-security" } -} \ No newline at end of file +} diff --git a/examples/typescript/src/index.ts b/examples/typescript/src/index.ts index 9215c092..e2337471 100644 --- a/examples/typescript/src/index.ts +++ b/examples/typescript/src/index.ts @@ -1,18 +1,27 @@ -import * as spsFrontend from "@tensorworks/libspsfrontend"; +import {Config, PixelStreaming, SPSApplication, TextParameters, PixelStreamingApplicationStyle} from "@tensorworks/libspsfrontend"; -// Apply default styling from Epic's frontend -export const PixelStreamingApplicationStyles = new spsFrontend.PixelStreamingApplicationStyle(); +// Apply default styling from Epic Games Pixel Streaming Frontend +export const PixelStreamingApplicationStyles = new PixelStreamingApplicationStyle(); PixelStreamingApplicationStyles.applyStyleSheet(); +// websocket url env +declare var WEBSOCKET_URL: string; + document.body.onload = function () { // Create a config object. // Note: This config is extremely important, SPS only supports the browser sending the offer. - const config = new spsFrontend.Config({ useUrlParams: true, initialSettings: { OfferToReceive: true, TimeoutIfIdle: true } }); + const config = new Config({ useUrlParams: true, initialSettings: { OfferToReceive: true, TimeoutIfIdle: true } }); + + // make usage of WEBSOCKET_URL if it is not empty + let webSocketAddress = WEBSOCKET_URL; + if(webSocketAddress != ""){ + config.setTextSetting(TextParameters.SignallingServerUrl, webSocketAddress) + } - // Create a Native DOM delegate instance that implements the Delegate interface class - const stream = new spsFrontend.PixelStreaming(config); - const spsApplication = new spsFrontend.SPSApplication({ + // Create stream and spsApplication instances that implement the Epic Games Pixel Streaming Frontend PixelStreaming and Application types + const stream = new PixelStreaming(config); + const spsApplication = new SPSApplication({ stream, onColorModeChanged: (isLightMode) => PixelStreamingApplicationStyles.setColorMode(isLightMode) /* Light/Dark mode support. */ }); diff --git a/examples/typescript/webpack.common.js b/examples/typescript/webpack.common.js new file mode 100644 index 00000000..d8d4bb3c --- /dev/null +++ b/examples/typescript/webpack.common.js @@ -0,0 +1,72 @@ +const path = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const webpack = require('webpack'); +require('dotenv').config({ path: './.env' }); + +module.exports = { + entry: { + index: './src/index.ts', + }, + plugins: [ + new webpack.DefinePlugin({ + WEBSOCKET_URL: JSON.stringify((process.env.WEBSOCKET_URL !== undefined) ? process.env.WEBSOCKET_URL : '') + }), + new HtmlWebpackPlugin({ + title: 'Scalable Pixel Streaming Frontend', + template: './src/index.html', + filename: 'index.html' + }), + ], + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: [ + /node_modules/, + ], + }, + { + test: /\.html$/i, + use: 'html-loader' + }, + { + test: /\.css$/, + type: 'asset/resource', + generator: { + filename: '[name][ext]' + } + }, + { + test: /\.(png|svg)$/i, + type: 'asset/resource', + generator: { + filename: 'images/[name][ext]' + } + }, + ], + }, + resolve: { + extensions: ['.tsx', '.ts', '.js', '.svg'], + }, + output: { + filename: '[name].js', + library: 'spstypescriptexample', + libraryTarget: 'umd', + path: path.resolve(__dirname, 'dist'), + clean: true, + globalObject: 'this', + hashFunction: 'xxhash64' + }, + experiments: { + futureDefaults: true + }, + optimization: { + minimize: false + }, + devServer: { + static: { + directory: path.join(__dirname, 'dist'), + }, + }, +}; \ No newline at end of file diff --git a/examples/typescript/webpack.config.js b/examples/typescript/webpack.config.js deleted file mode 100644 index 9deb0a8b..00000000 --- a/examples/typescript/webpack.config.js +++ /dev/null @@ -1,77 +0,0 @@ -const path = require('path'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -//const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const webpack = require('webpack'); - -module.exports = (env) => { - return { - mode: "development", - entry: { - index: './src/index.ts', - }, - plugins: [ - new webpack.DefinePlugin({ - WEBSOCKET_URL: JSON.stringify((env.WEBSOCKET_URL !== undefined) ? env.WEBSOCKET_URL : '') - }), - - new HtmlWebpackPlugin({ - title: 'Development', - template: './src/index.html', - filename: 'index.html' - }), - ], - // turn off so we can see the source map for dom delegate so we can debug the library - devtool: 'inline-source-map', - module: { - rules: [ - { - test: /\.tsx?$/, - loader: 'ts-loader', - exclude: [ - /node_modules/, - ], - }, - { - test: /\.html$/i, - use: 'html-loader' - }, - { - test: /\.css$/, - type: 'asset/resource', - generator: { - filename: '[name][ext]' - } - }, - { - test: /\.(png|svg)$/i, - type: 'asset/resource', - generator: { - filename: 'images/[name][ext]' - } - }, - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js', '.svg'], - }, - output: { - filename: '[name].js', - library: 'spstypescriptexample', - libraryTarget: 'umd', - path: path.resolve(__dirname, 'dist'), - clean: true, - globalObject: 'this' - }, - experiments: { - futureDefaults: true - }, - optimization: { - minimize: false - }, - devServer: { - static: { - directory: path.join(__dirname, 'dist'), - }, - }, - }; -}; \ No newline at end of file diff --git a/examples/typescript/webpack.dev.js b/examples/typescript/webpack.dev.js new file mode 100644 index 00000000..09b07928 --- /dev/null +++ b/examples/typescript/webpack.dev.js @@ -0,0 +1,8 @@ +const { merge } = require('webpack-merge'); +const common = require('./webpack.common.js'); +const path = require('path'); + +module.exports = merge(common, { + mode: 'development', + devtool: 'inline-source-map', +}); \ No newline at end of file diff --git a/examples/typescript/webpack.prod.js b/examples/typescript/webpack.prod.js new file mode 100644 index 00000000..132f8a8b --- /dev/null +++ b/examples/typescript/webpack.prod.js @@ -0,0 +1,14 @@ +const { merge } = require('webpack-merge'); +const common = require('./webpack.common.js'); + +module.exports = merge(common, { + mode: 'production', + optimization: { + usedExports: true, + minimize: true + }, + stats: 'errors-only', + performance: { + hints: false + } +}); diff --git a/library/package.json b/library/package.json index cd17d3d0..37b297e2 100644 --- a/library/package.json +++ b/library/package.json @@ -4,7 +4,8 @@ "description": "The Scalable Pixel Streaming Frontend Library consuming Epic Games' Pixel Streaming Frontend", "main": "src/index.ts", "scripts": { - "build": "npx webpack", + "build-prod": "npx webpack --config webpack.prod.js", + "build-dev": "npx webpack --config webpack.dev.js", "watch": "npx webpack --watch", "serve": "webpack serve" }, diff --git a/library/webpack.common.js b/library/webpack.common.js new file mode 100644 index 00000000..59df1393 --- /dev/null +++ b/library/webpack.common.js @@ -0,0 +1,26 @@ +const package = require('./package.json'); +const path = require('path'); +const webpack = require('webpack'); + +module.exports = { + entry: { + index: './src/index.ts' + }, + module: { + rules: [ + { + test: /\.tsx?$/, + loader: 'ts-loader', + exclude: [/node_modules/] + } + ] + }, + resolve: { + extensions: ['.tsx', '.ts', '.js'] + }, + plugins: [], + output: { + path: path.resolve(__dirname, 'dist'), + globalObject: 'this' + } +}; \ No newline at end of file diff --git a/library/webpack.config.js b/library/webpack.config.js deleted file mode 100644 index 01017f6f..00000000 --- a/library/webpack.config.js +++ /dev/null @@ -1,51 +0,0 @@ -const path = require('path'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -//const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const webpack = require('webpack'); - -module.exports = (env) => { - return { - mode: 'development', - entry: { - index: './src/index.ts', - }, - plugins: [ - ], - // turn off so we can see the source map for dom delegate so we can debug the library - devtool: 'inline-source-map', - module: { - rules: [ - { - test: /\.tsx?$/, - loader: 'ts-loader', - exclude: [ - /node_modules/, - ], - }, - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js', '.svg'], - }, - output: { - filename: '[name].js', - library: 'libspsfrontend', - libraryTarget: 'umd', - path: path.resolve(__dirname, 'dist'), - clean: true, - globalObject: 'this', - hashFunction: 'xxhash64', - }, - experiments: { - futureDefaults: true - }, - optimization: { - minimize: false - }, - devServer: { - static: { - directory: path.join(__dirname, 'dist'), - }, - } - }; -} \ No newline at end of file diff --git a/library/webpack.dev.js b/library/webpack.dev.js new file mode 100644 index 00000000..39a7eb09 --- /dev/null +++ b/library/webpack.dev.js @@ -0,0 +1,33 @@ +const { merge } = require('webpack-merge'); +const common = require('./webpack.common.js'); + +const devCommon = { + mode: 'development', + devtool: 'inline-source-map', + devServer: { + static: './dist', + } +}; + +module.exports = [ + merge(common, devCommon, { + output: { + filename: 'libspsfrontend.js', + library: { + name: 'libspsfrontend', // exposed variable that will provide access to the library classes + type: 'umd' + }, + }, + }), + merge(common, devCommon, { + output: { + filename: 'libspsfrontend.esm.js', + library: { + type: 'module' + }, + }, + experiments: { + outputModule: true + } + }) +]; diff --git a/library/webpack.prod.js b/library/webpack.prod.js new file mode 100644 index 00000000..d59b0f26 --- /dev/null +++ b/library/webpack.prod.js @@ -0,0 +1,34 @@ +const { merge } = require('webpack-merge'); +const common = require('./webpack.common.js'); + +const prodCommon = { + mode: 'production', + optimization: { + usedExports: true, + minimize: true + }, + stats: 'errors-only', +}; + +module.exports = [ + merge(common, prodCommon, { + output: { + filename: 'libspsfrontend.js', + library: { + name: 'libspsfrontend', // exposed variable that will provide access to the library classes + type: 'umd' + }, + }, + }), + merge(common, prodCommon, { + output: { + filename: 'libspsfrontend.esm.js', + library: { + type: 'module' + }, + }, + experiments: { + outputModule: true + } + }) +];