diff --git a/.changeset/lucky-wolves-nail.md b/.changeset/lucky-wolves-nail.md
new file mode 100644
index 00000000..c66a2188
--- /dev/null
+++ b/.changeset/lucky-wolves-nail.md
@@ -0,0 +1,5 @@
+---
+"@theoplayer/nielsen-connector-web": minor
+---
+
+Updated to be compatible with THEOplayer `6.X`.
diff --git a/.gitignore b/.gitignore
index c2658d7d..c28de259 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
node_modules/
+
+# Generated by MacOS
+.DS_Store
diff --git a/.idea/web-connectors.iml b/.idea/web-connectors.iml
index 23928731..4e0bc000 100644
--- a/.idea/web-connectors.iml
+++ b/.idea/web-connectors.iml
@@ -7,6 +7,7 @@
+
diff --git a/conviva/BUILD.md b/conviva/BUILD.md
deleted file mode 100644
index b75f4716..00000000
--- a/conviva/BUILD.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# conviva-connector-web
-
-A connector implementing Conviva for web.
-
-## Getting started
-
-```
-npm install
-```
-
-## Testing and code quality
-
-A test stack is set up and can be used by adding tests to the `test/unit/` folder. Run these tests with
-
-```
-npm run test
-```
-
-This project is set up with [ESLint](https://eslint.org/) and [Prettier](https://prettier.io/). You can run these checks with
-
-```
-npm run lint
-npm run prettier
-```
-
-but it's a good idea to set up the necessary IDE integration for both.
-
-CI will automatically verify whether the code passes all necessary quality gates.
-
-## Manual testing
-
-- Run `npm run serve` to start `http-server` in the root folder by running.
-- Run `npm run build` to create the integrations library `conviva-connector.umd.js` under `dist/`.
-- Navigate to `localhost:8080/test/pages/main_umd.html` or add an alternative test page.
-
-## Release process
-
-This release process is based on the assumption that the `master` branch is the default branch, and working branches are branched off from it and PR's back to it.
-It is mostly automated by creating tags with a specific format on the `master` branch.
-
-### Prerequisites
-
-- All the necesary code for the release is present on the `master` branch.
-- The `README.md` file contains the necessary information for an external developer to use the connector. This will be published along with the code.
-- Bitbucket Pipelines has been correctly enabled for the repository.
- - Github Actions integration is on the roadmap.
-- The necessary variables have been configured for Bitbucket Pipelines:
- - `NPMRC_CONTENT`: the full content of an `.npmrc` file to be used during publishing. Linebreaks in the file can be substituted by `\n` in the variable.
- - `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`: The AWS credentials necessary to publish a bundle to CDN.
- - This might be replaced with a Github release artifact later.
-
-### Creating a release
-
-These steps assume that the new release version is `X.Y.Z`.
-
-- Create a new version bump commit on the `master` branch to bump the project version to the release version.
-- Create a tag on the version bump commit of the format `vX.Y.Z`.
-- Verify that the release pipeline correctly runs for your new tag.
-- Verify that the correct artifacts have been published once the pipeline has completed.
diff --git a/conviva/LICENSE b/conviva/LICENSE.md
similarity index 100%
rename from conviva/LICENSE
rename to conviva/LICENSE.md
diff --git a/conviva/package.json b/conviva/package.json
index 622067df..c257b7de 100644
--- a/conviva/package.json
+++ b/conviva/package.json
@@ -30,6 +30,7 @@
"dist/",
"CHANGELOG.md",
"README.md",
+ "LICENSE.md",
"package.json"
],
"dependencies": {
diff --git a/nielsen/.gitignore b/nielsen/.gitignore
new file mode 100644
index 00000000..92b3d00f
--- /dev/null
+++ b/nielsen/.gitignore
@@ -0,0 +1,10 @@
+# Node artifact files
+node_modules/
+lib/
+dist/
+
+# Generated by MacOS
+.DS_Store
+
+# Generated by Windows
+Thumbs.db
diff --git a/nielsen/CHANGELOG.md b/nielsen/CHANGELOG.md
new file mode 100644
index 00000000..219f3188
--- /dev/null
+++ b/nielsen/CHANGELOG.md
@@ -0,0 +1,7 @@
+# @theoplayer/nielsen-connector-web
+
+## 1.0.0
+
+### ✨ Features
+
+- Initial release
diff --git a/yospace/LICENSE b/nielsen/LICENSE.md
similarity index 100%
rename from yospace/LICENSE
rename to nielsen/LICENSE.md
diff --git a/nielsen/README.md b/nielsen/README.md
new file mode 100644
index 00000000..d598a24f
--- /dev/null
+++ b/nielsen/README.md
@@ -0,0 +1,50 @@
+# Nielsen Web Connector
+
+A connector implementing Nielsen with THEOplayer.
+
+## Installation
+
+```sh
+npm install @theoplayer/nielsen-connector-web
+```
+
+## Usage
+
+### Configuring the connector
+
+Create the connector by providing the `THEOplayer` instance, the Nielsen App ID, the channelName for the asset
+and optionally some Nielsen configuration.
+
+```js
+import {NielsenConnector} from "../../dist/THEOplayerNielsenConnector";
+
+const appId = '';
+const channelName = '';
+// Optional
+const options: NielsenOptions = {
+ containerId: 'THEOplayer',
+ optout: false
+}
+const nielsenConnector = new NielsenConnector(player, appId, channelName, options);
+```
+
+The `NielsenOptions` can have the following fields:
+
+| Key | Value |
+|-----------------|-----------------------------------------------------------------|
+| ` containerId ` | HTML DOM element id of the player container. |
+| ` nol_sdkDebug` | Enables Debug Mode which allows output to be viewed in console. |
+| ` optout ` | Whether to opt-out of Nielsen Measurement. |
+
+### Passing metadata dynamically
+
+The connector allows updating the current asset's metadata at any time:
+
+```js
+const metadata = {
+ ['channelName']: 'newChannelName',
+ ['customTag1']: 'customValue1',
+ ['customTag2']: 'customValue2'
+}
+nielsenConnector.updateMetadata(metadata);
+```
diff --git a/nielsen/jest.config.js b/nielsen/jest.config.js
new file mode 100644
index 00000000..78e93fe8
--- /dev/null
+++ b/nielsen/jest.config.js
@@ -0,0 +1,4 @@
+module.exports = {
+ preset: "ts-jest",
+ testEnvironment: "node"
+};
diff --git a/nielsen/package.json b/nielsen/package.json
new file mode 100644
index 00000000..c7e12c08
--- /dev/null
+++ b/nielsen/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "@theoplayer/nielsen-connector-web",
+ "version": "1.0.0",
+ "description": "A connector implementing Nielsen with THEOplayer.",
+ "main": "dist/THEOplayerNielsenConnector.umd.js",
+ "module": "dist/THEOplayerNielsenConnector.esm.js",
+ "types": "dist/THEOplayerNielsenConnector.d.ts",
+ "exports": {
+ ".": {
+ "types": "./dist/THEOplayerNielsenConnector.d.ts",
+ "import": "./dist/THEOplayerNielsenConnector.esm.js",
+ "require": "./dist/THEOplayerNielsenConnector.umd.js"
+ },
+ "./dist/*": "./dist/*",
+ "./package": "./package.json",
+ "./package.json": "./package.json"
+ },
+ "scripts": {
+ "clean": "rimraf lib dist",
+ "bundle": "rollup -c rollup.config.mjs",
+ "build": "npm run clean && npm run bundle",
+ "serve": "http-server",
+ "test": "jest"
+ },
+ "author": "THEO Technologies NV",
+ "license": "MIT",
+ "files": [
+ "dist/",
+ "CHANGELOG.md",
+ "README.md",
+ "LICENSE.md",
+ "package.json"
+ ],
+ "peerDependencies": {
+ "theoplayer": "^5.0.0 || ^6.0.0"
+ }
+}
diff --git a/nielsen/rollup.config.mjs b/nielsen/rollup.config.mjs
new file mode 100644
index 00000000..30a21542
--- /dev/null
+++ b/nielsen/rollup.config.mjs
@@ -0,0 +1,14 @@
+import {getSharedBuildConfiguration} from "../tools/build.mjs";
+import fs from "node:fs";
+
+const {version} = JSON.parse(fs.readFileSync("./package.json", "utf8"));
+
+const fileName = "nielsen-connector";
+const globalName = "THEOplayerNielsenConnector";
+
+const banner = `
+/**
+ * Nielsen Web Connector v${version}
+ */`.trim();
+
+export default getSharedBuildConfiguration(fileName, globalName, banner);
diff --git a/nielsen/src/index.ts b/nielsen/src/index.ts
new file mode 100644
index 00000000..ee3d9c68
--- /dev/null
+++ b/nielsen/src/index.ts
@@ -0,0 +1,2 @@
+export { NielsenConnector } from './integration/NielsenConnector';
+export { NielsenOptions } from './nielsen/Types';
diff --git a/nielsen/src/integration/NielsenConnector.ts b/nielsen/src/integration/NielsenConnector.ts
new file mode 100644
index 00000000..aae4305b
--- /dev/null
+++ b/nielsen/src/integration/NielsenConnector.ts
@@ -0,0 +1,27 @@
+import { ChromelessPlayer } from 'theoplayer';
+import { NielsenOptions } from '../nielsen/Types';
+import { NielsenHandler } from './NielsenHandler';
+
+export class NielsenConnector {
+ private nielsenHandler: NielsenHandler;
+
+ /**
+ * Create NielsenConnector
+ *
+ * @param player THEOplayer instance.
+ * @param appId UniqueID assigned to player/site.
+ * @param instanceName User-defined string value for describing the player/site.
+ * @param options Additional options.
+ */
+ constructor(player: ChromelessPlayer, appId: string, instanceName: string, options?: NielsenOptions) {
+ this.nielsenHandler = new NielsenHandler(player, appId, instanceName, options);
+ }
+
+ updateMetadata(metadata: { [key: string]: string }): void {
+ this.nielsenHandler.updateMetadata(metadata);
+ }
+
+ destroy() {
+ this.nielsenHandler.destroy();
+ }
+}
diff --git a/nielsen/src/integration/NielsenHandler.ts b/nielsen/src/integration/NielsenHandler.ts
new file mode 100644
index 00000000..fc544919
--- /dev/null
+++ b/nielsen/src/integration/NielsenHandler.ts
@@ -0,0 +1,151 @@
+import { Ad, AddTrackEvent, ChromelessPlayer, TextTrack, TextTrackEnterCueEvent, VolumeChangeEvent } from 'theoplayer';
+import { loadNielsenLibrary } from '../nielsen/NOLBUNDLE';
+import { AdMetadata, ContentMetadata, NielsenOptions } from '../nielsen/Types';
+import { getAdType } from '../utils/Util';
+
+export class NielsenHandler {
+ private player: ChromelessPlayer;
+
+ private nSdkInstance: any;
+
+ private sessionInProgress: boolean = false;
+
+ private duration: number = NaN;
+
+ constructor(player: ChromelessPlayer, appId: string, instanceName: string, options?: NielsenOptions) {
+ this.player = player;
+ this.nSdkInstance = loadNielsenLibrary(appId, instanceName, options);
+
+ this.addEventListeners();
+ }
+
+ updateMetadata(metadata: { [key: string]: string }): void {
+ this.nSdkInstance.ggPM('updateMetadata', metadata);
+ }
+
+ private addEventListeners(): void {
+ this.player.addEventListener('play', this.onPlay);
+ this.player.addEventListener('ended', this.onEnd);
+ this.player.addEventListener('sourcechange', this.onSourceChange);
+ this.player.addEventListener('volumechange', this.onVolumeChange);
+ this.player.addEventListener('loadedmetadata', this.onLoadMetadata);
+ this.player.addEventListener('durationchange', this.onDurationChange);
+
+ this.player.textTracks.addEventListener('addtrack', this.onAddTrack);
+
+ if (this.player.ads) {
+ this.player.ads.addEventListener('adbegin', this.onAdBegin);
+ }
+
+ window.addEventListener('beforeunload', this.onEnd);
+ }
+
+ private removeEventListeners(): void {
+ this.player.removeEventListener('play', this.onPlay);
+ this.player.removeEventListener('ended', this.onEnd);
+ this.player.removeEventListener('sourcechange', this.onSourceChange);
+ this.player.removeEventListener('volumechange', this.onVolumeChange);
+ this.player.removeEventListener('loadedmetadata', this.onLoadMetadata);
+ this.player.removeEventListener('durationchange', this.onDurationChange);
+
+ this.player.textTracks.removeEventListener('addtrack', this.onAddTrack);
+
+ if (this.player.ads) {
+ this.player.ads.removeEventListener('adbegin', this.onAdBegin);
+ }
+
+ window.removeEventListener('beforeunload', this.onEnd);
+ }
+
+ private onPlay = () => {
+ this.maybeSendPlayEvent();
+ };
+
+ private onEnd = () => {
+ this.endSession();
+ };
+
+ private onSourceChange = () => {
+ this.duration = NaN;
+ this.endSession();
+ };
+
+ private onVolumeChange = (event: VolumeChangeEvent) => {
+ const volumeLevel = this.player.muted ? 0 : event.volume * 100;
+ this.nSdkInstance.ggPM('setVolume', volumeLevel);
+ };
+
+ private onDurationChange = () => {
+ this.duration = this.player.duration;
+ this.maybeSendPlayEvent();
+ };
+
+ private onLoadMetadata = () => {
+ const data: ContentMetadata = {
+ type: 'content',
+ adModel: '1' // Always '1' for DTVR
+ };
+ this.nSdkInstance.ggPM('loadMetadata', data);
+ };
+
+ private onAddTrack = (event: AddTrackEvent) => {
+ if (event.track.kind === 'metadata') {
+ const track = event.track as TextTrack;
+ if (track.type === 'id3') {
+ // || track.type === 'emsg') {
+ if (track.mode === 'disabled') {
+ track.mode = 'hidden';
+ }
+ track.addEventListener('entercue', this.onEnterCue);
+ }
+ }
+ };
+
+ private onEnterCue = (event: TextTrackEnterCueEvent) => {
+ const { cue } = event;
+ if (cue.track.type === 'id3') {
+ if (cue.content.id === 'PRIV' && cue.content.ownerIdentifier.indexOf('www.nielsen.com') !== -1) {
+ this.nSdkInstance.ggPM('sendID3', cue.content.ownerIdentifier);
+ }
+ } else {
+ // TODO emsg is not supported for now
+ }
+ };
+
+ private onAdBegin = () => {
+ const currentAd = this.player.ads!.currentAds.filter((ad: Ad) => ad.type === 'linear');
+ const type = getAdType(this.player.ads!.currentAdBreak!);
+ const adMetadata: AdMetadata = {
+ type,
+ assetid: currentAd[0].id!
+ };
+ this.nSdkInstance.ggPM('loadMetadata', adMetadata);
+ };
+
+ private maybeSendPlayEvent(): void {
+ if (!this.sessionInProgress && !Number.isNaN(this.duration)) {
+ this.sessionInProgress = true;
+ const metadataObject = {
+ channelName: this.player.src,
+ length: this.duration
+ };
+ this.nSdkInstance.ggPM('play', metadataObject);
+ }
+ }
+
+ private endSession(): void {
+ if (this.sessionInProgress) {
+ this.sessionInProgress = false;
+ this.nSdkInstance.ggPM('end', this.getPlayHeadPosition());
+ }
+ }
+
+ private getPlayHeadPosition(): string {
+ return Math.floor(this.player.currentTime).toString();
+ }
+
+ destroy() {
+ this.removeEventListeners();
+ this.endSession();
+ }
+}
diff --git a/nielsen/src/nielsen/NOLBUNDLE.ts b/nielsen/src/nielsen/NOLBUNDLE.ts
new file mode 100644
index 00000000..87d67c1a
--- /dev/null
+++ b/nielsen/src/nielsen/NOLBUNDLE.ts
@@ -0,0 +1,44 @@
+/* eslint-disable */
+import { NielsenOptions } from './Types';
+
+export function loadNielsenLibrary(appId: string, instanceName: string, options?: NielsenOptions) {
+ // https://engineeringportal.nielsen.com/docs/DTVR_Browser_SDK
+ // Add Static Queue Snippet to initialize a Nielsen SDK Instance.
+ // @ts-ignore
+ !(function (t: Window, n: any) {
+ t[n] = t[n] || {
+ nlsQ: function (e: any, o: any, c?: any, r?: any, s?: any, i?: any) {
+ // @ts-ignore
+ return (
+ (s = t.document),
+ (r = s.createElement('script')),
+ (r.async = 1),
+ (r.src =
+ ('http:' === t.location.protocol ? 'http:' : 'https:') +
+ '//cdn-gl.imrworldwide.com/conf/' +
+ e +
+ '.js#name=' +
+ o +
+ '&ns=' +
+ n),
+ (i = s.getElementsByTagName('script')[0]),
+ i.parentNode.insertBefore(r, i),
+ (t[n][o] = t[n][o] || {
+ g: c || {},
+ ggPM: function (e: any, c: any, r?: any, s?: any, i?: any) {
+ // @ts-ignore
+ (t[n][o].q = t[n][o].q || []).push([e, c, r, s, i]);
+ }
+ }),
+ t[n][o]
+ );
+ }
+ };
+ })(window, 'NOLBUNDLE');
+
+ if (options) {
+ return (window as any).NOLBUNDLE.nlsQ(appId, instanceName, options);
+ } else {
+ return (window as any).NOLBUNDLE.nlsQ(appId, instanceName);
+ }
+}
diff --git a/nielsen/src/nielsen/Types.ts b/nielsen/src/nielsen/Types.ts
new file mode 100644
index 00000000..f2ffe88a
--- /dev/null
+++ b/nielsen/src/nielsen/Types.ts
@@ -0,0 +1,25 @@
+export type AdType = 'preroll' | 'midroll' | 'postroll' | 'ad';
+
+export type NielsenOptions = {
+ // HTML DOM element id of the player container
+ containerId?: string;
+
+ // Enables Debug Mode which allows output to be viewed in console.
+ nol_sdkDebug?: string;
+
+ // Set the ability to optout on initialization of the SDK
+ optout?: boolean;
+};
+
+/**
+ * adModel: 1) - Linear – matches TV ad load * 2) Dynamic – Dynamic Ad Insertion (DAI)
+ */
+export type ContentMetadata = {
+ type: 'content';
+ adModel: '1' | '2';
+} & { [key: string]: string };
+
+export type AdMetadata = {
+ type: AdType;
+ assetid: any; // TODO string? or can be anything?
+} & { [key: string]: string };
diff --git a/nielsen/src/utils/Util.ts b/nielsen/src/utils/Util.ts
new file mode 100644
index 00000000..f3b89d0d
--- /dev/null
+++ b/nielsen/src/utils/Util.ts
@@ -0,0 +1,15 @@
+import { AdBreak } from 'theoplayer';
+import { AdType } from '../nielsen/Types';
+
+export function getAdType(adBreak: AdBreak): AdType {
+ const currentAdBreakTimeOffset = adBreak.timeOffset;
+ let currentAdBreakPosition: AdType = 'ad';
+ if (currentAdBreakTimeOffset === 0) {
+ currentAdBreakPosition = 'preroll';
+ } else if (currentAdBreakTimeOffset < 0) {
+ currentAdBreakPosition = 'postroll';
+ } else if (currentAdBreakTimeOffset > 0) {
+ currentAdBreakPosition = 'midroll';
+ }
+ return currentAdBreakPosition;
+}
diff --git a/nielsen/test/pages/main.html b/nielsen/test/pages/main.html
new file mode 100644
index 00000000..7e9b6f65
--- /dev/null
+++ b/nielsen/test/pages/main.html
@@ -0,0 +1,43 @@
+
+
+
+
+ Connector test page
+
+
+
+
+
+
+
+
+
diff --git a/nielsen/test/unit/example.spec.ts b/nielsen/test/unit/example.spec.ts
new file mode 100644
index 00000000..6ddb9eac
--- /dev/null
+++ b/nielsen/test/unit/example.spec.ts
@@ -0,0 +1,6 @@
+describe('My connector code', () => {
+ it('should be decently tested', () => {
+ const a: number = 3;
+ expect(a).toBe(3);
+ });
+});
diff --git a/nielsen/tsconfig.json b/nielsen/tsconfig.json
new file mode 100644
index 00000000..5fd53772
--- /dev/null
+++ b/nielsen/tsconfig.json
@@ -0,0 +1,13 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "commonjs",
+ "strict": true,
+ "baseUrl": "./",
+ "rootDir": ".",
+ "paths": { "THEOplayer": ["./src/THEOplayer"] },
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true
+ }
+}
diff --git a/package-lock.json b/package-lock.json
index 6f1f0d5b..59808251 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,8 @@
"license": "MIT",
"workspaces": [
"yospace",
- "conviva"
+ "conviva",
+ "nielsen"
],
"devDependencies": {
"@changesets/cli": "^2.27.1",
@@ -42,13 +43,13 @@
},
"conviva": {
"name": "@theoplayer/conviva-connector-web",
- "version": "1.3.0",
+ "version": "2.0.0",
"license": "MIT",
"dependencies": {
"@convivainc/conviva-js-coresdk": "^4.6.1"
},
"peerDependencies": {
- "@theoplayer/yospace-connector-web": "^2.0.0",
+ "@theoplayer/yospace-connector-web": "^2.1.0",
"theoplayer": "^5.0.0 || ^6.0.0"
},
"peerDependenciesMeta": {
@@ -57,6 +58,20 @@
}
}
},
+ "nielsen": {
+ "name": "@theoplayer/nielsen-connector-web",
+ "version": "1.0.0",
+ "license": "MIT",
+ "peerDependencies": {
+ "theoplayer": "^5.0.0 || ^6.0.0"
+ }
+ },
+ "nielsen/node_modules/theoplayer": {
+ "version": "5.11.0",
+ "resolved": "https://registry.npmjs.org/theoplayer/-/theoplayer-5.11.0.tgz",
+ "integrity": "sha512-Ywn3nnTPiyh0cckO3FGIvXfhr3BR16D967voMthnQlwY5jITEJq6pKYAt9qHEXyWNafULKVhY0X///61Wxm7lw==",
+ "peer": true
+ },
"node_modules/@aashutoshrathi/word-wrap": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
@@ -2526,6 +2541,10 @@
"resolved": "conviva",
"link": true
},
+ "node_modules/@theoplayer/nielsen-connector-web": {
+ "resolved": "nielsen",
+ "link": true
+ },
"node_modules/@theoplayer/yospace-connector-web": {
"resolved": "yospace",
"link": true
@@ -9401,7 +9420,7 @@
},
"yospace": {
"name": "@theoplayer/yospace-connector-web",
- "version": "2.0.0",
+ "version": "2.1.0",
"license": "MIT",
"peerDependencies": {
"theoplayer": "^5.0.0 || ^6.0.0"
diff --git a/package.json b/package.json
index 5fa7b0ba..12d23c2f 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,8 @@
"license": "MIT",
"workspaces": [
"yospace",
- "conviva"
+ "conviva",
+ "nielsen"
],
"scripts": {
"changeset:version": "changeset version && node .changeset/post-process.js",
diff --git a/yospace/BUILD.md b/yospace/BUILD.md
deleted file mode 100644
index d3319306..00000000
--- a/yospace/BUILD.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# yospace-connector-web
-
-A connector implementing Yospace for web.
-
-## Getting started
-
-- `npm install`
-
-## Testing and code quality
-
-A test stack is set up and can be used by adding tests to the `test/unit/` folder. Run these tests with
-
-```
-npm run test
-```
-
-This project is set up with [ESLint](https://eslint.org/) and [Prettier](https://prettier.io/). You can run these checks with
-
-```
-npm run lint
-npm run prettier
-```
-
-but it's a good idea to set up the necessary IDE integration for both.
-
-CI will automatically verify whether the code passes all necessary quality gates.
-
-## Manual testing
-
-- Run `npm run serve` to start `http-server` in the root folder by running.
-- Run `npm run build` to create the integrations library `yospace-connector.umd.js` under `dist/`.
-- Navigate to `localhost:8080/test/pages/main.html` or add an alternative test page.
-
-## Release process
-
-This release process is based on the assumption that the `master` branch is the default branch, and working branches are branched off from it and PR's back to it.
-It is mostly automated by creating tags with a specific format on the `master` branch.
-
-### Prerequisites
-
-- All the necesary code for the release is present on the `master` branch.
-- The `README.md` file contains the necessary information for an external developer to use the connector. This will be published along with the code.
-- Bitbucket Pipelines has been correctly enabled for the repository.
- - Github Actions integration is on the roadmap.
-- The necessary variables have been configured for Bitbucket Pipelines:
- - `NPMRC_CONTENT`: the full content of an `.npmrc` file to be used during publishing. Linebreaks in the file can be substituted by `\n` in the variable.
- - `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`: The AWS credentials necessary to publish a bundle to CDN.
- - This might be replaced with a Github release artifact later.
-
-### Creating a release
-
-These steps assume that the new release version is `X.Y.Z`.
-
-- Create a new version bump commit on the `master` branch to bump the project version to the release version.
-- Create a tag on the version bump commit of the format `vX.Y.Z`.
-- Verify that the release pipeline correctly runs for your new tag.
-- Verify that the correct artifacts have been published once the pipeline has completed.
diff --git a/yospace/LICENSE.md b/yospace/LICENSE.md
new file mode 100644
index 00000000..146db44c
--- /dev/null
+++ b/yospace/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 THEO Technologies NV
+
+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/yospace/package.json b/yospace/package.json
index 45661e43..6205e117 100644
--- a/yospace/package.json
+++ b/yospace/package.json
@@ -32,7 +32,9 @@
"license": "MIT",
"files": [
"dist/",
+ "CHANGELOG.md",
"README.md",
+ "LICENSE.md",
"package.json"
],
"peerDependencies": {