From 3eb52c647bbfab2bf9246f20e11beb31f09d157d Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 13 Sep 2021 23:03:19 +0200 Subject: [PATCH 1/9] adding functionality to detect user download speed --- ui/analytics.js | 11 ++++++++- ui/redux/actions/app.js | 1 + ui/util/detect-user-bandwidth.js | 38 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 ui/util/detect-user-bandwidth.js diff --git a/ui/analytics.js b/ui/analytics.js index 495535dcc..505fb1180 100644 --- a/ui/analytics.js +++ b/ui/analytics.js @@ -10,6 +10,13 @@ import ElectronCookies from '@exponent/electron-cookies'; import { generateInitialUrl } from 'util/url'; // @endif import { MATOMO_ID, MATOMO_URL } from 'config'; +import getConnectionSpeed from 'util/detect-user-bandwidth'; + +let downloadSpeed; +getConnectionSpeed(function(speedInMbps){ + downloadSpeed = speedInMbps; + console.log(downloadSpeed); +}); const isProduction = process.env.NODE_ENV === 'production'; const devInternalApis = process.env.LBRY_API_URL && process.env.LBRY_API_URL.includes('dev'); @@ -202,8 +209,10 @@ async function sendWatchmanData(body) { } const analytics: Analytics = { - // receive buffer events from tracking plugin and jklj + // receive buffer events from tracking plugin and save buffer amounts and times for backend call videoBufferEvent: async (claim, data) => { + console.log('running here!'); + console.log(data); amountOfBufferEvents = amountOfBufferEvents + 1; amountOfBufferTimeInMS = amountOfBufferTimeInMS + data.bufferDuration; }, diff --git a/ui/redux/actions/app.js b/ui/redux/actions/app.js index 67a00c4a0..cb0b81332 100644 --- a/ui/redux/actions/app.js +++ b/ui/redux/actions/app.js @@ -505,6 +505,7 @@ export function doAnalyticsBuffer(uri, bufferData) { const fileSizeInBits = fileSize * 8; const bitRate = parseInt(fileSizeInBits / fileDurationInSeconds); const userId = user && user.id.toString(); + // if there's a logged in user, send buffer event data to watchman if (userId) { analytics.videoBufferEvent(claim, { timeAtBuffer, diff --git a/ui/util/detect-user-bandwidth.js b/ui/util/detect-user-bandwidth.js new file mode 100644 index 000000000..f14c82523 --- /dev/null +++ b/ui/util/detect-user-bandwidth.js @@ -0,0 +1,38 @@ +var startTime; +var endTime; + +var testConnectionSpeed = { + imageAddr: 'https://upload.wikimedia.org/wikipedia/commons/a/a6/Brandenburger_Tor_abends.jpg', // this is just an example, you rather want an image hosted on your server + downloadSize: 2707459, // this must match with the image above + + getConnectionSpeed: function(callback) { + testConnectionSpeed.InitiateSpeedDetection(); + testConnectionSpeed.callback = callback; + }, + InitiateSpeedDetection: function() { + window.setTimeout(testConnectionSpeed.MeasureConnectionSpeed, 1); + }, + result: function() { + var duration = (endTime - startTime) / 1000; + var bitsLoaded = testConnectionSpeed.downloadSize * 8; + var speedBps = (bitsLoaded / duration).toFixed(2); + var speedKbps = (speedBps / 1024).toFixed(2); + var speedMbps = (speedKbps / 1024).toFixed(2); + testConnectionSpeed.callback(speedMbps); + }, + MeasureConnectionSpeed: function() { + var download = new Image(); + download.onload = function() { + endTime = (new Date()).getTime(); + testConnectionSpeed.result(); + }; + startTime = (new Date()).getTime(); + var cacheBuster = '?nnn=' + startTime; + download.src = testConnectionSpeed.imageAddr + cacheBuster; + }, +}; + +// start test immediatly, you could also call this on any event or whenever you want +// testConnectionSpeed.getConnectionSpeed(function(time) { console.log(time) }); + +module.exports = testConnectionSpeed.getConnectionSpeed; -- 2.45.2 From 594d419fc381781261ae8298cbd3a4c41203cecd Mon Sep 17 00:00:00 2001 From: Anthony Date: Tue, 21 Sep 2021 18:42:31 +0300 Subject: [PATCH 2/9] calculating bandwidth speed more intelligently --- ui/util/detect-user-bandwidth.js | 42 ++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/ui/util/detect-user-bandwidth.js b/ui/util/detect-user-bandwidth.js index f14c82523..bc41d3e62 100644 --- a/ui/util/detect-user-bandwidth.js +++ b/ui/util/detect-user-bandwidth.js @@ -1,5 +1,5 @@ -var startTime; -var endTime; +// var startTime; +// var endTime; var testConnectionSpeed = { imageAddr: 'https://upload.wikimedia.org/wikipedia/commons/a/a6/Brandenburger_Tor_abends.jpg', // this is just an example, you rather want an image hosted on your server @@ -12,6 +12,7 @@ var testConnectionSpeed = { InitiateSpeedDetection: function() { window.setTimeout(testConnectionSpeed.MeasureConnectionSpeed, 1); }, + result: function() { var duration = (endTime - startTime) / 1000; var bitsLoaded = testConnectionSpeed.downloadSize * 8; @@ -20,6 +21,7 @@ var testConnectionSpeed = { var speedMbps = (speedKbps / 1024).toFixed(2); testConnectionSpeed.callback(speedMbps); }, + MeasureConnectionSpeed: function() { var download = new Image(); download.onload = function() { @@ -32,6 +34,42 @@ var testConnectionSpeed = { }, }; +function timeout(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +const imageAddr = 'https://upload.wikimedia.org/wikipedia/commons/a/a6/Brandenburger_Tor_abends.jpg'; +const downloadSize = 2707459; // this must match with the image above + +let startTime, endTime; +function measureConnectionSpeed() { + startTime = (new Date()).getTime(); + var cacheBuster = '?nnn=' + startTime; + + var download = new Image(); + download.src = imageAddr + cacheBuster; + + download.onload = function() { + endTime = (new Date()).getTime(); + var duration = (endTime - startTime) / 1000; + var bitsLoaded = downloadSize * 8; + var speedBps = (bitsLoaded / duration).toFixed(2); + var speedKbps = (speedBps / 1024).toFixed(2); + var speedMbps = (speedKbps / 1024).toFixed(2); + console.log(speedMbps); + return new Promise(resolve => resolve(speedMbps)); + // return speedMbps; + }; + + +} + +async function getDownloadSpeed() { + await timeout(1); + const downloadSpeed = await measureConnectionSpeed(); + console.log(downloadSpeed); +} + // start test immediatly, you could also call this on any event or whenever you want // testConnectionSpeed.getConnectionSpeed(function(time) { console.log(time) }); -- 2.45.2 From 43e96004d3cc1d6545127d45d78a0cd8fb481f4a Mon Sep 17 00:00:00 2001 From: Anthony Date: Tue, 21 Sep 2021 19:07:57 +0300 Subject: [PATCH 3/9] saving download speed and updating it every 30s --- ui/analytics.js | 12 +++-- ui/util/detect-user-bandwidth.js | 80 ++++++-------------------------- 2 files changed, 20 insertions(+), 72 deletions(-) diff --git a/ui/analytics.js b/ui/analytics.js index 505fb1180..ec96f4bbf 100644 --- a/ui/analytics.js +++ b/ui/analytics.js @@ -12,11 +12,13 @@ import { generateInitialUrl } from 'util/url'; import { MATOMO_ID, MATOMO_URL } from 'config'; import getConnectionSpeed from 'util/detect-user-bandwidth'; -let downloadSpeed; -getConnectionSpeed(function(speedInMbps){ - downloadSpeed = speedInMbps; - console.log(downloadSpeed); -}); +let userDownloadBandwidth; +async function getUserBandwidth() { + userDownloadBandwidth = await getConnectionSpeed(); +} + +getUserBandwidth(); +setInterval(getUserBandwidth, 1000 * 30); const isProduction = process.env.NODE_ENV === 'production'; const devInternalApis = process.env.LBRY_API_URL && process.env.LBRY_API_URL.includes('dev'); diff --git a/ui/util/detect-user-bandwidth.js b/ui/util/detect-user-bandwidth.js index bc41d3e62..353579ee3 100644 --- a/ui/util/detect-user-bandwidth.js +++ b/ui/util/detect-user-bandwidth.js @@ -1,76 +1,22 @@ -// var startTime; -// var endTime; - -var testConnectionSpeed = { - imageAddr: 'https://upload.wikimedia.org/wikipedia/commons/a/a6/Brandenburger_Tor_abends.jpg', // this is just an example, you rather want an image hosted on your server - downloadSize: 2707459, // this must match with the image above - - getConnectionSpeed: function(callback) { - testConnectionSpeed.InitiateSpeedDetection(); - testConnectionSpeed.callback = callback; - }, - InitiateSpeedDetection: function() { - window.setTimeout(testConnectionSpeed.MeasureConnectionSpeed, 1); - }, - - result: function() { - var duration = (endTime - startTime) / 1000; - var bitsLoaded = testConnectionSpeed.downloadSize * 8; - var speedBps = (bitsLoaded / duration).toFixed(2); - var speedKbps = (speedBps / 1024).toFixed(2); - var speedMbps = (speedKbps / 1024).toFixed(2); - testConnectionSpeed.callback(speedMbps); - }, - - MeasureConnectionSpeed: function() { - var download = new Image(); - download.onload = function() { - endTime = (new Date()).getTime(); - testConnectionSpeed.result(); - }; - startTime = (new Date()).getTime(); - var cacheBuster = '?nnn=' + startTime; - download.src = testConnectionSpeed.imageAddr + cacheBuster; - }, -}; - -function timeout(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - const imageAddr = 'https://upload.wikimedia.org/wikipedia/commons/a/a6/Brandenburger_Tor_abends.jpg'; const downloadSize = 2707459; // this must match with the image above let startTime, endTime; -function measureConnectionSpeed() { +async function measureConnectionSpeed() { startTime = (new Date()).getTime(); - var cacheBuster = '?nnn=' + startTime; + const cacheBuster = '?nnn=' + startTime; - var download = new Image(); + const download = new Image(); download.src = imageAddr + cacheBuster; - - download.onload = function() { - endTime = (new Date()).getTime(); - var duration = (endTime - startTime) / 1000; - var bitsLoaded = downloadSize * 8; - var speedBps = (bitsLoaded / duration).toFixed(2); - var speedKbps = (speedBps / 1024).toFixed(2); - var speedMbps = (speedKbps / 1024).toFixed(2); - console.log(speedMbps); - return new Promise(resolve => resolve(speedMbps)); - // return speedMbps; - }; - - + // this returns when the image is finished downloading + await download.decode(); + endTime = (new Date()).getTime(); + const duration = (endTime - startTime) / 1000; + const bitsLoaded = downloadSize * 8; + const speedBps = (bitsLoaded / duration).toFixed(2); + const speedKbps = (speedBps / 1024).toFixed(2); + const speedMbps = (speedKbps / 1024).toFixed(2); + return speedMbps; } -async function getDownloadSpeed() { - await timeout(1); - const downloadSpeed = await measureConnectionSpeed(); - console.log(downloadSpeed); -} - -// start test immediatly, you could also call this on any event or whenever you want -// testConnectionSpeed.getConnectionSpeed(function(time) { console.log(time) }); - -module.exports = testConnectionSpeed.getConnectionSpeed; +module.exports = measureConnectionSpeed; -- 2.45.2 From 9702ee8144ccf5eae88db42051cbfeef5d740d1d Mon Sep 17 00:00:00 2001 From: Anthony Date: Tue, 21 Sep 2021 20:36:59 +0300 Subject: [PATCH 4/9] all the functionality should be done needs testing --- ui/analytics.js | 13 +++++++------ ui/component/viewers/videoViewer/view.jsx | 10 +++++++++- ui/util/detect-user-bandwidth.js | 4 +--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ui/analytics.js b/ui/analytics.js index ec96f4bbf..49cc48653 100644 --- a/ui/analytics.js +++ b/ui/analytics.js @@ -12,9 +12,9 @@ import { generateInitialUrl } from 'util/url'; import { MATOMO_ID, MATOMO_URL } from 'config'; import getConnectionSpeed from 'util/detect-user-bandwidth'; -let userDownloadBandwidth; +let userDownloadBandwidthInBitsPerSecond; async function getUserBandwidth() { - userDownloadBandwidth = await getConnectionSpeed(); + userDownloadBandwidthInBitsPerSecond = await getConnectionSpeed(); } getUserBandwidth(); @@ -120,7 +120,7 @@ function getDeviceType() { // variables initialized for watchman let amountOfBufferEvents = 0; let amountOfBufferTimeInMS = 0; -let videoType, userId, claimUrl, playerPoweredBy, videoPlayer; +let videoType, userId, claimUrl, playerPoweredBy, videoPlayer, bitrateAsBitsPerSecond; let lastSentTime; // calculate data for backend, send them, and reset buffer data for next interval @@ -161,6 +161,8 @@ async function sendAndResetWatchmanData() { user_id: userId.toString(), position: Math.round(positionInVideo), rel_position: Math.round((positionInVideo / (totalDurationInSeconds * 1000)) * 100), + ...(userDownloadBandwidthInBitsPerSecond && {bandwidth: userDownloadBandwidthInBitsPerSecond}), // add bandwidth if populated + ...(bitrateAsBitsPerSecond && {bitrate: bitrateAsBitsPerSecond}), // add bitrate if video (audio doesn't work) }; // post to watchman @@ -213,8 +215,6 @@ async function sendWatchmanData(body) { const analytics: Analytics = { // receive buffer events from tracking plugin and save buffer amounts and times for backend call videoBufferEvent: async (claim, data) => { - console.log('running here!'); - console.log(data); amountOfBufferEvents = amountOfBufferEvents + 1; amountOfBufferTimeInMS = amountOfBufferTimeInMS + data.bufferDuration; }, @@ -251,7 +251,7 @@ const analytics: Analytics = { startWatchmanIntervalIfNotRunning(); } }, - videoStartEvent: (claimId, duration, poweredBy, passedUserId, canonicalUrl, passedPlayer) => { + videoStartEvent: (claimId, duration, poweredBy, passedUserId, canonicalUrl, passedPlayer, videoBitrate) => { // populate values for watchman when video starts userId = passedUserId; claimUrl = canonicalUrl; @@ -259,6 +259,7 @@ const analytics: Analytics = { videoType = passedPlayer.currentSource().type; videoPlayer = passedPlayer; + bitrateAsBitsPerSecond = videoBitrate; sendPromMetric('time_to_start', duration); sendMatomoEvent('Media', 'TimeToStart', claimId, duration); diff --git a/ui/component/viewers/videoViewer/view.jsx b/ui/component/viewers/videoViewer/view.jsx index efe534dd1..5619065f9 100644 --- a/ui/component/viewers/videoViewer/view.jsx +++ b/ui/component/viewers/videoViewer/view.jsx @@ -168,9 +168,17 @@ function VideoViewer(props: Props) { } analytics.playerStartedEvent(embedded); + // convert bytes to bits, and then divide by seconds + const contentInBits = Number(claim.value.source.size) * 8; + const durationInSeconds = claim.value.video && claim.value.video.duration; + let bitrateAsBitsPerSecond; + if (durationInSeconds) { + bitrateAsBitsPerSecond = Math.round(contentInBits / durationInSeconds); + } + fetch(source, { method: 'HEAD', cache: 'no-store' }).then((response) => { let playerPoweredBy = response.headers.get('x-powered-by') || ''; - analytics.videoStartEvent(claimId, timeToStart, playerPoweredBy, userId, claim.canonical_url, this); + analytics.videoStartEvent(claimId, timeToStart, playerPoweredBy, userId, claim.canonical_url, this, bitrateAsBitsPerSecond); }); doAnalyticsView(uri, timeToStart).then(() => { diff --git a/ui/util/detect-user-bandwidth.js b/ui/util/detect-user-bandwidth.js index 353579ee3..0610190fe 100644 --- a/ui/util/detect-user-bandwidth.js +++ b/ui/util/detect-user-bandwidth.js @@ -14,9 +14,7 @@ async function measureConnectionSpeed() { const duration = (endTime - startTime) / 1000; const bitsLoaded = downloadSize * 8; const speedBps = (bitsLoaded / duration).toFixed(2); - const speedKbps = (speedBps / 1024).toFixed(2); - const speedMbps = (speedKbps / 1024).toFixed(2); - return speedMbps; + return Math.round(Number(speedBps)); } module.exports = measureConnectionSpeed; -- 2.45.2 From 1e7c2c26a278d5e7c0bf1a9c43cfd665f21a1b3f Mon Sep 17 00:00:00 2001 From: Anthony Date: Wed, 22 Sep 2021 18:46:49 +0300 Subject: [PATCH 5/9] fix linting --- ui/analytics.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/analytics.js b/ui/analytics.js index 49cc48653..de25c7f5f 100644 --- a/ui/analytics.js +++ b/ui/analytics.js @@ -49,7 +49,7 @@ type Analytics = { tagFollowEvent: (string, boolean, ?string) => void, playerLoadedEvent: (?boolean) => void, playerStartedEvent: (?boolean) => void, - videoStartEvent: (string, number, string, number, string, any) => void, + videoStartEvent: (string, number, string, number, string, any, number) => void, videoIsPlaying: (boolean, any) => void, videoBufferEvent: ( StreamClaim, -- 2.45.2 From 1cc591b247b9c46ef51d0d2066a90db9f919be4b Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 27 Sep 2021 16:43:26 +0300 Subject: [PATCH 6/9] use a 1mb file for calculating bandwidth --- ui/analytics.js | 5 +++-- ui/util/detect-user-bandwidth.js | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ui/analytics.js b/ui/analytics.js index de25c7f5f..39ec740af 100644 --- a/ui/analytics.js +++ b/ui/analytics.js @@ -17,8 +17,8 @@ async function getUserBandwidth() { userDownloadBandwidthInBitsPerSecond = await getConnectionSpeed(); } -getUserBandwidth(); -setInterval(getUserBandwidth, 1000 * 30); +// get user bandwidth every minute, starting after an initial one minute wait +setInterval(getUserBandwidth, 1000 * 60); const isProduction = process.env.NODE_ENV === 'production'; const devInternalApis = process.env.LBRY_API_URL && process.env.LBRY_API_URL.includes('dev'); @@ -136,6 +136,7 @@ async function sendAndResetWatchmanData() { let timeSinceLastIntervalSend = new Date() - lastSentTime; lastSentTime = new Date(); + // TODO: hook into here to calculate bandwidth let protocol; if (videoType === 'application/x-mpegURL') { protocol = 'hls'; diff --git a/ui/util/detect-user-bandwidth.js b/ui/util/detect-user-bandwidth.js index 0610190fe..fd3f0d187 100644 --- a/ui/util/detect-user-bandwidth.js +++ b/ui/util/detect-user-bandwidth.js @@ -1,5 +1,5 @@ -const imageAddr = 'https://upload.wikimedia.org/wikipedia/commons/a/a6/Brandenburger_Tor_abends.jpg'; -const downloadSize = 2707459; // this must match with the image above +const imageAddr = 'https://upload.wikimedia.org/wikipedia/commons/b/b9/Pizigani_1367_Chart_1MB.jpg'; +const downloadSize = 1093957; // this must match with the image above let startTime, endTime; async function measureConnectionSpeed() { -- 2.45.2 From a26558a336f496eb37dd74d9df1efa601a014a02 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 27 Sep 2021 17:02:45 +0300 Subject: [PATCH 7/9] add optional chaining plugin to babel and get bitrate from texttrack --- package.json | 1 + ui/analytics.js | 3 ++- web/webpack.config.js | 2 +- yarn.lock | 36 +++++++++++++++++++++++++++++++++++- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index f1545afa3..6826b3296 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-decorators": "^7.3.0", "@babel/plugin-proposal-object-rest-spread": "^7.6.2", + "@babel/plugin-proposal-optional-chaining": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-transform-flow-strip-types": "^7.2.3", "@babel/plugin-transform-runtime": "^7.4.3", diff --git a/ui/analytics.js b/ui/analytics.js index 39ec740af..47eaa8d12 100644 --- a/ui/analytics.js +++ b/ui/analytics.js @@ -136,10 +136,11 @@ async function sendAndResetWatchmanData() { let timeSinceLastIntervalSend = new Date() - lastSentTime; lastSentTime = new Date(); - // TODO: hook into here to calculate bandwidth let protocol; if (videoType === 'application/x-mpegURL') { protocol = 'hls'; + // get bandwidth if it exists from the texttrack (so it's accurate if user changes quality) + bitrateAsBitsPerSecond = videoPlayer.textTracks?.().tracks_[0]?.activeCues[0]?.value?.bandwidth; } else { protocol = 'stb'; } diff --git a/web/webpack.config.js b/web/webpack.config.js index f483c6217..120747802 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -149,7 +149,7 @@ const webConfig = { test: /\.jsx?$/, options: { presets: ['@babel/env', '@babel/react', '@babel/flow'], - plugins: ['@babel/plugin-proposal-object-rest-spread', '@babel/plugin-proposal-class-properties'], + plugins: ['@babel/plugin-proposal-optional-chaining', '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-proposal-class-properties'], }, }, { diff --git a/yarn.lock b/yarn.lock index 96aee291f..0234b1a2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -329,6 +329,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== +"@babel/helper-plugin-utils@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" + integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== + "@babel/helper-remap-async-to-generator@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd" @@ -390,6 +395,13 @@ dependencies: "@babel/types" "^7.12.1" +"@babel/helper-skip-transparent-expression-wrappers@^7.14.5": + version "7.15.4" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz#707dbdba1f4ad0fa34f9114fc8197aec7d5da2eb" + integrity sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A== + dependencies: + "@babel/types" "^7.15.4" + "@babel/helper-split-export-declaration@^7.10.1": version "7.10.1" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz#c6f4be1cbc15e3a868e4c64a17d5d31d754da35f" @@ -426,6 +438,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== +"@babel/helper-validator-identifier@^7.14.9": + version "7.15.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" + integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== + "@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f" @@ -590,6 +607,15 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-syntax-optional-chaining" "^7.8.0" +"@babel/plugin-proposal-optional-chaining@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz#fa83651e60a360e3f13797eef00b8d519695b603" + integrity sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-proposal-private-methods@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz#86814f6e7a21374c980c10d38b4493e703f4a389" @@ -694,7 +720,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-chaining@^7.8.0": +"@babel/plugin-syntax-optional-chaining@^7.8.0", "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== @@ -1230,6 +1256,14 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.15.4": + version "7.15.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" + integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== + dependencies: + "@babel/helper-validator-identifier" "^7.14.9" + to-fast-properties "^2.0.0" + "@datapunt/matomo-tracker-js@^0.1.4": version "0.1.4" resolved "https://registry.yarnpkg.com/@datapunt/matomo-tracker-js/-/matomo-tracker-js-0.1.4.tgz#1226f0964d2c062bf9392e9c2fd89838262b10df" -- 2.45.2 From bb9f7b350da3799a55a64b2f032b4c1b9f48d678 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 27 Sep 2021 17:59:03 +0300 Subject: [PATCH 8/9] allow optional chaining for flow --- .flowconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.flowconfig b/.flowconfig index 2c6b8839f..3c406f19c 100644 --- a/.flowconfig +++ b/.flowconfig @@ -42,6 +42,7 @@ module.name_mapper='^web\/effects\(.*\)$' -> '/web/effects\1' module.name_mapper='^web\/page\(.*\)$' -> '/web/page\1' module.name_mapper='^homepage\(.*\)$' -> '/ui/util/homepage\1' module.name_mapper='^scss\/component\(.*\)$' -> '/ui/scss/component/\1' +esproposal.optional_chaining=enable ; Extensions module.file_ext=.js @@ -50,5 +51,4 @@ module.file_ext=.json module.file_ext=.css module.file_ext=.scss - [strict] -- 2.45.2 From 29b4e0a76cd6770f627826dbffd8b6ee7b3e50ed Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 1 Oct 2021 20:31:47 +0300 Subject: [PATCH 9/9] bump flow version --- package.json | 3 ++- yarn.lock | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 6826b3296..408ff91e8 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "flow": "flow", "lint": "eslint 'ui/**/*.{js,jsx}' && eslint 'web/**/*.{js,jsx}' && eslint 'electron/**/*.js' && flow", "lint-fix": "eslint --fix --quiet 'ui/**/*.{js,jsx}' && eslint --fix --quiet 'web/**/*.{js,jsx}' && eslint --fix --quiet 'electron/**/*.js'", + "flow": "flow", "format": "prettier 'src/**/*.{js,jsx,scss,json}' --write", "flow-defs": "flow-typed install", "precommit": "lint-staged", @@ -148,7 +149,7 @@ "eslint-plugin-react-hooks": "^1.6.0", "eslint-plugin-standard": "^4.0.1", "file-loader": "^4.2.0", - "flow-bin": "^0.97.0", + "flow-bin": "^0.112.0", "flow-typed": "^2.3.0", "formik": "^0.10.4", "hast-util-sanitize": "^3.0.2", diff --git a/yarn.lock b/yarn.lock index 0234b1a2c..63c08fd6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7490,9 +7490,10 @@ flatten@^1.0.2: resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== -flow-bin@^0.97.0: - version "0.97.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.97.0.tgz#036ffcfc27503367a9d906ec9d843a0aa6f6bb83" +flow-bin@^0.112.0: + version "0.112.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.112.0.tgz#6a21c31937c4a2f23a750056a364c598a95ea216" + integrity sha512-vdcuKv0UU55vjv0e2EVh1ZxlU+TSNT19SkE+6gT1vYzTKtzYE6dLuAmBIiS3Rg2N9D9HOI6TKSyl53zPtqZLrA== flow-typed@^2.3.0: version "2.6.2" -- 2.45.2