Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC] - Support dependencies in modules #27

Closed
wants to merge 13 commits into from
70 changes: 54 additions & 16 deletions gulpHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ const MANIFEST = 'package.json';
const through = require('through2');
const _ = require('lodash');
const gutil = require('gulp-util');
const submodules = require('./modules/.submodules.json');
const dependencyMap = require('./modules/.submodules.json');
const submodules = dependencyMap.parentModules;
const libraries = dependencyMap.libraries;

const MODULE_PATH = './modules';
const LIBRARY_PATH = './libraries';
const BUILD_PATH = './build/dist';
const DEV_PATH = './build/dev';
const ANALYTICS_PATH = '../analytics';
Expand Down Expand Up @@ -68,39 +71,74 @@ module.exports = {
}
});

Object.keys(libraries).forEach(library => {
if (!modules.includes(library) && modules.some(module => libraries[library].dependants.includes(module))) {
modules.unshift(library);
}
});

return modules;
},
getParentLibraries(moduleName) {
const libraryNames = [];
Object.keys(libraries).forEach(libraryName => {
const library = libraries[libraryName];
if (library.dependants.includes(moduleName)) {
libraryNames.push(libraryName);
}
});
return libraryNames;
},
getLibraryFiles(name) {
const library = libraries[name];
const files = library.files.map(file => require.resolve(file, {paths: ['./libraries/' + name + '/']}));
return files;
},
isLibrary(name) {
return !!libraries[name];
},
getModules: _.memoize(function(externalModules) {
externalModules = externalModules || [];
var internalModules;
try {
var getInternalModules = function(absolutePath) {
return fs.readdirSync(absolutePath)
.filter(file => (/^[^\.]+(\.js)?$/).test(file))
.reduce((memo, file) => {
var moduleName = file.split(new RegExp('[.\\' + path.sep + ']'))[0];
var modulePath = path.join(absolutePath, file);
if (fs.lstatSync(modulePath).isDirectory()) {
modulePath = path.join(modulePath, 'index.js')
}
if (fs.existsSync(modulePath)) {
memo[modulePath] = moduleName;
}
return memo;
}, {});
};

var absoluteModulePath = path.join(__dirname, MODULE_PATH);
internalModules = fs.readdirSync(absoluteModulePath)
.filter(file => (/^[^\.]+(\.js)?$/).test(file))
.reduce((memo, file) => {
var moduleName = file.split(new RegExp('[.\\' + path.sep + ']'))[0];
var modulePath = path.join(absoluteModulePath, file);
if (fs.lstatSync(modulePath).isDirectory()) {
modulePath = path.join(modulePath, 'index.js')
}
if (fs.existsSync(modulePath)) {
memo[modulePath] = moduleName;
}
return memo;
}, {});
var absoluteLibraryPath = path.join(__dirname, LIBRARY_PATH);

internalModules = getInternalModules(absoluteModulePath);
var internalLibraries = getInternalModules(absoluteLibraryPath);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the right logic to use for libraries - because the dependencies on them will not work unless they are explicitly declared in .submodules.json, I think this should just return the list of libraries as it's defined in there.
Otherwise this allows inconsistencies when the library does not use index.js in the way we expect here, or the compilation of files that are not used by anyone.

Object.assign(internalModules, internalLibraries);
} catch (err) {
internalModules = {};
}
return Object.assign(externalModules.reduce((memo, module) => {
try {
// prefer internal project modules before looking at project dependencies
var modulePath = require.resolve(module, {paths: ['./modules']});
if (modulePath === '') modulePath = require.resolve(module);
var modulePath = require.resolve(module, {paths: [MODULE_PATH, LIBRARY_PATH]});
if (modulePath === '') {
modulePath = require.resolve(module);
}

memo[modulePath] = module;
} catch (err) {
// do something
}

return memo;
}, internalModules));
}),
Expand Down
1 change: 1 addition & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ function lint(done) {
return gulp.src([
'src/**/*.js',
'modules/**/*.js',
'libraries/**/*.js',
'test/**/*.js',
'plugins/**/*.js',
'!plugins/**/node_modules/**',
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
158 changes: 84 additions & 74 deletions modules/.submodules.json
Original file line number Diff line number Diff line change
@@ -1,76 +1,86 @@
{
"userId": [
"33acrossIdSystem",
"admixerIdSystem",
"adtelligentIdSystem",
"akamaiDAPIdSystem",
"amxIdSystem",
"britepoolIdSystem",
"connectIdSystem",
"cpexIdSystem",
"criteoIdSystem",
"dacIdSystem",
"deepintentDpesIdSystem",
"dmdIdSystem",
"fabrickIdSystem",
"flocIdSystem",
"hadronIdSystem",
"haloIdSystem",
"id5IdSystem",
"ftrackIdSystem",
"identityLinkIdSystem",
"idxIdSystem",
"imuIdSystem",
"intentIqIdSystem",
"justIdSystem",
"kinessoIdSystem",
"liveIntentIdSystem",
"lotamePanoramaIdSystem",
"merkleIdSystem",
"mwOpenLinkIdSystem",
"naveggIdSystem",
"netIdSystem",
"nextrollIdSystem",
"novatiqIdSystem",
"parrableIdSystem",
"pubProvidedIdSystem",
"publinkIdSystem",
"quantcastIdSystem",
"sharedIdSystem",
"tapadIdSystem",
"trustpidSystem",
"uid2IdSystem",
"unifiedIdSystem",
"verizonMediaIdSystem",
"zeotapIdPlusIdSystem",
"adqueryIdSystem"
],
"adpod": [
"freeWheelAdserverVideo",
"dfpAdServerVideo"
],
"rtdModule": [
"airgridRtdProvider",
"browsiRtdProvider",
"dgkeywordRtdProvider",
"geoedgeRtdProvider",
"hadronRtdProvider",
"haloRtdProvider",
"iasRtdProvider",
"jwplayerRtdProvider",
"medianetRtdProvider",
"optimeraRtdProvider",
"permutiveRtdProvider",
"reconciliationRtdProvider",
"sirdataRtdProvider",
"timeoutRtdProvider",
"weboramaRtdProvider"
],
"fpdModule": [
"enrichmentFpdModule",
"validationFpdModule"
],
"videoModule": [
"jwplayerVideoProvider"
]
"parentModules": {
"userId": [
"33acrossIdSystem",
"admixerIdSystem",
"adtelligentIdSystem",
"akamaiDAPIdSystem",
"amxIdSystem",
"britepoolIdSystem",
"connectIdSystem",
"cpexIdSystem",
"criteoIdSystem",
"dacIdSystem",
"deepintentDpesIdSystem",
"dmdIdSystem",
"fabrickIdSystem",
"flocIdSystem",
"hadronIdSystem",
"haloIdSystem",
"id5IdSystem",
"ftrackIdSystem",
"identityLinkIdSystem",
"idxIdSystem",
"imuIdSystem",
"intentIqIdSystem",
"justIdSystem",
"kinessoIdSystem",
"liveIntentIdSystem",
"lotamePanoramaIdSystem",
"merkleIdSystem",
"mwOpenLinkIdSystem",
"naveggIdSystem",
"netIdSystem",
"nextrollIdSystem",
"novatiqIdSystem",
"parrableIdSystem",
"pubProvidedIdSystem",
"publinkIdSystem",
"quantcastIdSystem",
"sharedIdSystem",
"tapadIdSystem",
"trustpidSystem",
"uid2IdSystem",
"unifiedIdSystem",
"verizonMediaIdSystem",
"zeotapIdPlusIdSystem",
"adqueryIdSystem"
],
"adpod": [
"freeWheelAdserverVideo",
"dfpAdServerVideo"
],
"rtdModule": [
"airgridRtdProvider",
"browsiRtdProvider",
"dgkeywordRtdProvider",
"geoedgeRtdProvider",
"hadronRtdProvider",
"haloRtdProvider",
"iasRtdProvider",
"jwplayerRtdProvider",
"medianetRtdProvider",
"optimeraRtdProvider",
"permutiveRtdProvider",
"reconciliationRtdProvider",
"sirdataRtdProvider",
"timeoutRtdProvider",
"weboramaRtdProvider"
],
"fpdModule": [
"enrichmentFpdModule",
"validationFpdModule"
]
},
"libraries": {
"video": {
"files": [
"./index.js", "./constants/ortb.js", "./constants/enums.js"
],
"dependants": [
"jwplayerVideoProvider",
"testVideoProvider"
]
}
}
}
51 changes: 25 additions & 26 deletions modules/jwplayerVideoProvider.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import {
PROTOCOLS, API_FRAMEWORKS, VIDEO_MIME_TYPE, PLAYBACK_METHODS, PLACEMENT, VPAID_MIME_TYPE
} from './videoModule/constants/ortb.js';
import { PLAYBACK_MODE } from './videoModule/constants/enums.js';
import stateFactory from './videoModule/shared/state.js';
import { JWPLAYER_VENDOR } from './videoModule/constants/vendorCodes.js';
} from '../libraries/video/constants/ortb.js';
import { PLAYBACK_MODE } from '../libraries/video/constants/enums.js';
import {
SETUP_COMPLETE, SETUP_FAILED, DESTROYED, AD_REQUEST, AD_BREAK_START, AD_LOADED, AD_STARTED, AD_IMPRESSION, AD_PLAY,
AD_TIME, AD_PAUSE, AD_CLICK, AD_SKIPPED, AD_ERROR, AD_COMPLETE, AD_BREAK_END, PLAYLIST, PLAYBACK_REQUEST,
AUTOSTART_BLOCKED, PLAY_ATTEMPT_FAILED, CONTENT_LOADED, PLAY, PAUSE, BUFFER, TIME, SEEK_START, SEEK_END, MUTE, VOLUME,
RENDITION_UPDATE, ERROR, COMPLETE, PLAYLIST_COMPLETE, FULLSCREEN, PLAYER_RESIZE, VIEWABLE, CAST
} from '../libraries/video/constants/events.js';
import stateFactory from '../libraries/video/shared/state.js';
import { JWPLAYER_VENDOR } from '../libraries/video/constants/vendorCodes.js';
import { submodule } from '../src/hook.js';

/**
Expand All @@ -30,13 +36,6 @@ export function JWPlayerProvider(config, jwplayer_, adState_, timeState_, callba
let minimumSupportedPlayerVersion = '8.20.1';
let setupCompleteCallback = null;
let setupFailedCallback = null;
const prebidVideoEvents = sharedUtils.videoEvents;
const {
SETUP_COMPLETE, SETUP_FAILED, DESTROYED, AD_REQUEST, AD_BREAK_START, AD_LOADED, AD_STARTED, AD_IMPRESSION, AD_PLAY,
AD_TIME, AD_PAUSE, AD_CLICK, AD_SKIPPED, AD_ERROR, AD_COMPLETE, AD_BREAK_END, PLAYLIST, PLAYBACK_REQUEST,
AUTOSTART_BLOCKED, PLAY_ATTEMPT_FAILED, CONTENT_LOADED, PLAY, PAUSE, BUFFER, TIME, SEEK_START, SEEK_END, MUTE, VOLUME,
RENDITION_UPDATE, ERROR, COMPLETE, PLAYLIST_COMPLETE, FULLSCREEN, PLAYER_RESIZE, VIEWABLE, CAST
} = prebidVideoEvents;
const MEDIA_TYPES = [
VIDEO_MIME_TYPE.MP4,
VIDEO_MIME_TYPE.OGG,
Expand Down Expand Up @@ -194,7 +193,7 @@ export function JWPlayerProvider(config, jwplayer_, adState_, timeState_, callba

function offEvents(events, callback) {
events.forEach(event => {
const jwEvent = utils.getJwEvent(event, prebidVideoEvents);
const jwEvent = utils.getJwEvent(event);
if (!callback) {
player.off(jwEvent);
return;
Expand Down Expand Up @@ -720,42 +719,42 @@ export const utils = {
return jwConfig;
},

getJwEvent: function(eventName, prebidVideoEvents) {
getJwEvent: function(eventName) {
switch (eventName) {
case prebidVideoEvents.SETUP_COMPLETE:
case SETUP_COMPLETE:
return 'ready';

case prebidVideoEvents.SETUP_FAILED:
case SETUP_FAILED:
return 'setupError';

case prebidVideoEvents.DESTROYED:
case DESTROYED:
return 'remove';

case prebidVideoEvents.AD_STARTED:
return prebidVideoEvents.AD_IMPRESSION;
case AD_STARTED:
return AD_IMPRESSION;

case prebidVideoEvents.AD_IMPRESSION:
case AD_IMPRESSION:
return 'adViewableImpression';

case prebidVideoEvents.PLAYBACK_REQUEST:
case PLAYBACK_REQUEST:
return 'playAttempt';

case prebidVideoEvents.AUTOSTART_BLOCKED:
case AUTOSTART_BLOCKED:
return 'autostartNotAllowed';

case prebidVideoEvents.CONTENT_LOADED:
case CONTENT_LOADED:
return 'playlistItem';

case prebidVideoEvents.SEEK_START:
case SEEK_START:
return 'seek';

case prebidVideoEvents.SEEK_END:
case SEEK_END:
return 'seeked';

case prebidVideoEvents.RENDITION_UPDATE:
case RENDITION_UPDATE:
return 'visualQuality';

case prebidVideoEvents.PLAYER_RESIZE:
case PLAYER_RESIZE:
return 'resize';

default:
Expand Down
26 changes: 26 additions & 0 deletions modules/testVideoProvider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
PROTOCOLS, API_FRAMEWORKS, VIDEO_MIME_TYPE, PLAYBACK_METHODS, PLACEMENT, VPAID_MIME_TYPE
} from '../libraries/video/constants/ortb.js';
import { PLAYBACK_MODE } from '../libraries/video/constants/enums.js';
import {
SETUP_COMPLETE, SETUP_FAILED, DESTROYED, AD_REQUEST, AD_BREAK_START, AD_LOADED, AD_STARTED, AD_IMPRESSION, AD_PLAY,
AD_TIME, AD_PAUSE, AD_CLICK, AD_SKIPPED, AD_ERROR, AD_COMPLETE, AD_BREAK_END, PLAYLIST, PLAYBACK_REQUEST,
AUTOSTART_BLOCKED, PLAY_ATTEMPT_FAILED, CONTENT_LOADED, PLAY, PAUSE, BUFFER, TIME, SEEK_START, SEEK_END, MUTE, VOLUME,
RENDITION_UPDATE, ERROR, COMPLETE, PLAYLIST_COMPLETE, FULLSCREEN, PLAYER_RESIZE, VIEWABLE, CAST
} from '../libraries/video/constants/events.js';
import stateFactory from '../libraries/video/shared/state.js';
import { VIDEO_JS_VENDOR } from '../libraries/video/constants/vendorCodes.js';
import { submodule } from '../src/hook.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';

export function testProvider() {
const state = stateFactory();
state.updateState(PROTOCOLS, API_FRAMEWORKS, VIDEO_MIME_TYPE, PLAYBACK_METHODS, PLACEMENT, VPAID_MIME_TYPE, SETUP_COMPLETE, SETUP_FAILED, DESTROYED, AD_REQUEST, AD_BREAK_START, AD_LOADED, AD_STARTED, AD_IMPRESSION, AD_PLAY,
AD_TIME, AD_PAUSE, AD_CLICK, AD_SKIPPED, AD_ERROR, AD_COMPLETE, AD_BREAK_END, PLAYLIST, PLAYBACK_REQUEST,
AUTOSTART_BLOCKED, PLAY_ATTEMPT_FAILED, CONTENT_LOADED, PLAY, PAUSE, BUFFER, TIME, SEEK_START, SEEK_END, MUTE, VOLUME,
RENDITION_UPDATE, ERROR, COMPLETE, PLAYLIST_COMPLETE, FULLSCREEN, PLAYER_RESIZE, VIEWABLE, CAST, registerBidder, PLAYBACK_MODE);
}

testProvider.code = VIDEO_JS_VENDOR;

submodule('videoModule', testProvider);
Loading