From 3a6e835cd2329a3ead7c7b2b57c4208f1cff42b3 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 7 Mar 2023 17:01:02 +0000 Subject: [PATCH 01/13] Add feature flag for 'same session in multiple tabs' --- src/domain/session/settings/FeaturesViewModel.ts | 9 +++++++-- src/features.ts | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/domain/session/settings/FeaturesViewModel.ts b/src/domain/session/settings/FeaturesViewModel.ts index b0ee359869..707138a0f3 100644 --- a/src/domain/session/settings/FeaturesViewModel.ts +++ b/src/domain/session/settings/FeaturesViewModel.ts @@ -28,12 +28,17 @@ export class FeaturesViewModel extends ViewModel { new FeatureViewModel(this.childOptions({ name: this.i18n`Audio/video calls`, description: this.i18n`Allows starting and participating in A/V calls compatible with Element Call (MSC3401). Look for the start call option in the room menu ((...) in the right corner) to start a call.`, - feature: FeatureFlag.Calls + feature: FeatureFlag.Calls, })), new FeatureViewModel(this.childOptions({ name: this.i18n`Cross-Signing`, description: this.i18n`Allows verifying the identity of people you chat with. This feature is still evolving constantly, expect things to break.`, - feature: FeatureFlag.CrossSigning + feature: FeatureFlag.CrossSigning, + })), + new FeatureViewModel(this.childOptions({ + name: this.i18n`Open the same session in multiple tabs`, + description: this.i18n`Allows having the same session open in multiple browser tabs or windows. This feature is currently not functional and is intended only for usage by Hydrogen developers. Do not enable.`, + feature: FeatureFlag.SameSessionInMultipleTabs, })), ]; } diff --git a/src/features.ts b/src/features.ts index 6fa5dd432a..84c9eecc46 100644 --- a/src/features.ts +++ b/src/features.ts @@ -18,7 +18,8 @@ import type {SettingsStorage} from "./platform/web/dom/SettingsStorage"; export enum FeatureFlag { Calls = 1 << 0, - CrossSigning = 1 << 1 + CrossSigning = 1 << 1, + SameSessionInMultipleTabs = 1 << 2, } export class FeatureSet { @@ -44,6 +45,10 @@ export class FeatureSet { return this.isFeatureEnabled(FeatureFlag.CrossSigning); } + get sameSessionInMultipleTabs(): boolean { + return this.isFeatureEnabled(FeatureFlag.SameSessionInMultipleTabs); + } + static async load(settingsStorage: SettingsStorage): Promise { const flags = await settingsStorage.getInt("enabled_features") || 0; return new FeatureSet(flags); From ced4d257f45b724658ac33fade540aae627316f8 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Wed, 8 Mar 2023 11:16:05 +0000 Subject: [PATCH 02/13] Load features in platform init instead of main So that features are available through the Platform. I think logically it makes sense to have the Platform load the features, as where features are coming from depends on the Platform. On Web they come from localStorage, on other platforms they might come from elsewhere. This will allow us to inject the FeatureSet into a SyncFactory class in next commits. --- src/platform/web/Platform.js | 2 ++ src/platform/web/main.js | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platform/web/Platform.js b/src/platform/web/Platform.js index be8c997078..f77c2cdd1b 100644 --- a/src/platform/web/Platform.js +++ b/src/platform/web/Platform.js @@ -43,6 +43,7 @@ import {MediaDevicesWrapper} from "./dom/MediaDevices"; import {DOMWebRTC} from "./dom/WebRTC"; import {ThemeLoader} from "./theming/ThemeLoader"; import {TimeFormatter} from "./dom/TimeFormatter"; +import {FeatureSet} from "../../features"; function addScript(src) { return new Promise(function (resolve, reject) { @@ -201,6 +202,7 @@ export class Platform { log.log({ l: "Active theme", name: themeName, variant: themeVariant }); await this._themeLoader.setTheme(themeName, themeVariant, log); } + this.features = await FeatureSet.load(this.settingsStorage); }); } catch (err) { this._container.innerText = err.message; diff --git a/src/platform/web/main.js b/src/platform/web/main.js index d9c6fe8a94..d48b442dd7 100644 --- a/src/platform/web/main.js +++ b/src/platform/web/main.js @@ -35,7 +35,6 @@ export async function main(platform) { // const request = recorder.request; // window.getBrawlFetchLog = () => recorder.log(); await platform.init(); - const features = await FeatureSet.load(platform.settingsStorage); const navigation = createNavigation(); platform.setNavigation(navigation); const urlRouter = createRouter({navigation, history: platform.history}); @@ -46,7 +45,7 @@ export async function main(platform) { // so we call it that in the view models urlRouter: urlRouter, navigation, - features + features: platform.features, }); await vm.load(); platform.createAndMountRootView(vm); From fb5a4e222f615582896e95766a3494a8f468fd70 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 7 Mar 2023 16:23:31 +0000 Subject: [PATCH 03/13] Extract interface from Sync --- src/matrix/ISync.ts | 9 +++++++++ src/matrix/Sync.js | 1 + 2 files changed, 10 insertions(+) create mode 100644 src/matrix/ISync.ts diff --git a/src/matrix/ISync.ts b/src/matrix/ISync.ts new file mode 100644 index 0000000000..eab854d01d --- /dev/null +++ b/src/matrix/ISync.ts @@ -0,0 +1,9 @@ +import {ObservableValue} from "../observable/value"; +import {SyncStatus} from "./Sync"; + +export interface ISync { + get status(): ObservableValue; + get error(): Error | null; + start(): void; + stop(): void; +} diff --git a/src/matrix/Sync.js b/src/matrix/Sync.js index d335336d29..90743ba3e1 100644 --- a/src/matrix/Sync.js +++ b/src/matrix/Sync.js @@ -51,6 +51,7 @@ function timelineIsEmpty(roomResponse) { * await room.afterSyncCompleted(changes); * ``` */ +// TODO: When this file gets converted to Typescript, Sync must implement ISync. export class Sync { constructor({hsApi, session, storage, logger}) { this._hsApi = hsApi; From fb7d4e0761fdfb9eb627adf1b618c0ac976f291e Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 7 Mar 2023 16:30:08 +0000 Subject: [PATCH 04/13] Make the start() method async When sync is running in a worker, the start() method will need to be async, as we will need to send messages to the worker to start the sync. --- src/matrix/Client.js | 4 ++-- src/matrix/ISync.ts | 2 +- src/matrix/Sync.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/matrix/Client.js b/src/matrix/Client.js index fabb489b67..205b55146b 100644 --- a/src/matrix/Client.js +++ b/src/matrix/Client.js @@ -298,7 +298,7 @@ export class Client { this._platform.logger.runDetached("reconnect", async log => { // needs to happen before sync and session or it would abort all requests this._requestScheduler.start(); - this._sync.start(); + await this._sync.start(); this._sessionStartedByReconnector = true; const d = dehydratedDevice; dehydratedDevice = undefined; @@ -329,7 +329,7 @@ export class Client { } async _waitForFirstSync() { - this._sync.start(); + await this._sync.start(); this._status.set(LoadStatus.FirstSync); // only transition into Ready once the first sync has succeeded this._waitForFirstSyncHandle = this._sync.status.waitFor(s => { diff --git a/src/matrix/ISync.ts b/src/matrix/ISync.ts index eab854d01d..99c456db85 100644 --- a/src/matrix/ISync.ts +++ b/src/matrix/ISync.ts @@ -4,6 +4,6 @@ import {SyncStatus} from "./Sync"; export interface ISync { get status(): ObservableValue; get error(): Error | null; - start(): void; + start(): Promise; stop(): void; } diff --git a/src/matrix/Sync.js b/src/matrix/Sync.js index 90743ba3e1..f244476b71 100644 --- a/src/matrix/Sync.js +++ b/src/matrix/Sync.js @@ -72,7 +72,7 @@ export class Sync { return this._error; } - start() { + async start() { // not already syncing? if (this._status.get() !== SyncStatus.Stopped) { return; @@ -84,7 +84,7 @@ export class Sync { } else { this._status.set(SyncStatus.InitialSync); } - this._syncLoop(syncToken); + void this._syncLoop(syncToken); } async _syncLoop(syncToken) { From 6c78eef48bdb430fdd63bd67883a2e52c1c406ca Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Wed, 8 Mar 2023 11:30:05 +0000 Subject: [PATCH 05/13] Use a SyncFactory to make instances of Sync I think it makes sense to not have the logic of whether sync runs in a worker in Client, as that is platform-specific, so that logic should not be in the matrix layer. --- src/matrix/Client.js | 6 ++++- src/platform/web/Platform.js | 2 ++ src/platform/web/sync/SyncFactory.ts | 36 ++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/platform/web/sync/SyncFactory.ts diff --git a/src/matrix/Client.js b/src/matrix/Client.js index 205b55146b..a8ced4abc2 100644 --- a/src/matrix/Client.js +++ b/src/matrix/Client.js @@ -291,7 +291,11 @@ export class Client { await log.wrap("createIdentity", log => this._session.createIdentity(log)); } - this._sync = new Sync({hsApi: this._requestScheduler.hsApi, storage: this._storage, session: this._session, logger: this._platform.logger}); + this._sync = this._platform.syncFactory.make({ + scheduler: this._requestScheduler, + storage: this._storage, + session: this._session, + }); // notify sync and session when back online this._reconnectSubscription = this._reconnector.connectionStatus.subscribe(state => { if (state === ConnectionStatus.Online) { diff --git a/src/platform/web/Platform.js b/src/platform/web/Platform.js index f77c2cdd1b..3622751826 100644 --- a/src/platform/web/Platform.js +++ b/src/platform/web/Platform.js @@ -44,6 +44,7 @@ import {DOMWebRTC} from "./dom/WebRTC"; import {ThemeLoader} from "./theming/ThemeLoader"; import {TimeFormatter} from "./dom/TimeFormatter"; import {FeatureSet} from "../../features"; +import {SyncFactory} from "./sync/SyncFactory"; function addScript(src) { return new Promise(function (resolve, reject) { @@ -203,6 +204,7 @@ export class Platform { await this._themeLoader.setTheme(themeName, themeVariant, log); } this.features = await FeatureSet.load(this.settingsStorage); + this.syncFactory = new SyncFactory({logger: this.logger}); }); } catch (err) { this._container.innerText = err.message; diff --git a/src/platform/web/sync/SyncFactory.ts b/src/platform/web/sync/SyncFactory.ts new file mode 100644 index 0000000000..6cd5522345 --- /dev/null +++ b/src/platform/web/sync/SyncFactory.ts @@ -0,0 +1,36 @@ +import {ISync} from "../../../matrix/ISync"; +import {Sync} from "../../../matrix/Sync"; +import {RequestScheduler} from "../../../matrix/net/RequestScheduler"; +import {Session} from "../../../matrix/Session"; +import {Logger} from "../../../logging/Logger"; +import {Storage} from "../../../matrix/storage/idb/Storage"; + +type Options = { + logger: Logger; +} + +type MakeOptions = { + scheduler: RequestScheduler; + storage: Storage; + session: Session; +} + +export class SyncFactory { + private readonly _logger: Logger; + + constructor(options: Options) { + const {logger} = options; + this._logger = logger; + } + + make(options: MakeOptions): ISync { + const {scheduler, storage, session} = options; + + return new Sync({ + logger: this._logger, + hsApi: scheduler.hsApi, + storage, + session, + }); + } +} From da09121229a70ab1eaad4ed6633aab0a5de35e73 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 7 Mar 2023 16:42:51 +0000 Subject: [PATCH 06/13] Add SyncProxy Will proxy calls to a worker. Doesn't do anything yet. --- src/platform/web/sync/SyncProxy.ts | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/platform/web/sync/SyncProxy.ts diff --git a/src/platform/web/sync/SyncProxy.ts b/src/platform/web/sync/SyncProxy.ts new file mode 100644 index 0000000000..48e0d30c96 --- /dev/null +++ b/src/platform/web/sync/SyncProxy.ts @@ -0,0 +1,35 @@ +import {ISync} from "../../../matrix/ISync"; +import {ObservableValue} from "../../../observable/value"; +import {SyncStatus} from "../../../matrix/Sync"; +import {Session} from "../../../matrix/Session"; + +type Options = { + session: Session; +} + +export class SyncProxy implements ISync { + private _session: Session; + private readonly _status: ObservableValue = new ObservableValue(SyncStatus.Stopped); + private _error: Error | null = null; + + constructor(options: Options) { + const {session} = options; + this._session = session; + } + + get status(): ObservableValue { + return this._status; + } + + get error(): Error | null { + return this._error; + } + + async start(): Promise { + // TODO + } + + stop(): void { + // TODO + } +} From 5c6343cb3d228ad5dd1efbeb1bf7bc42efaad9ba Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Wed, 8 Mar 2023 11:53:25 +0000 Subject: [PATCH 07/13] Return a SyncProxy when feature flag is enabled ... and the browser supports SharedWorkers. --- src/platform/web/Platform.js | 2 +- src/platform/web/sync/SyncFactory.ts | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/platform/web/Platform.js b/src/platform/web/Platform.js index 3622751826..a5a7c5fac0 100644 --- a/src/platform/web/Platform.js +++ b/src/platform/web/Platform.js @@ -204,7 +204,7 @@ export class Platform { await this._themeLoader.setTheme(themeName, themeVariant, log); } this.features = await FeatureSet.load(this.settingsStorage); - this.syncFactory = new SyncFactory({logger: this.logger}); + this.syncFactory = new SyncFactory({logger: this.logger, features: this.features}); }); } catch (err) { this._container.innerText = err.message; diff --git a/src/platform/web/sync/SyncFactory.ts b/src/platform/web/sync/SyncFactory.ts index 6cd5522345..d98eac5707 100644 --- a/src/platform/web/sync/SyncFactory.ts +++ b/src/platform/web/sync/SyncFactory.ts @@ -4,9 +4,12 @@ import {RequestScheduler} from "../../../matrix/net/RequestScheduler"; import {Session} from "../../../matrix/Session"; import {Logger} from "../../../logging/Logger"; import {Storage} from "../../../matrix/storage/idb/Storage"; +import {FeatureSet} from "../../../features"; +import {SyncProxy} from "./SyncProxy"; type Options = { logger: Logger; + features: FeatureSet; } type MakeOptions = { @@ -17,14 +20,25 @@ type MakeOptions = { export class SyncFactory { private readonly _logger: Logger; + private readonly _features: FeatureSet; constructor(options: Options) { - const {logger} = options; + const {logger, features} = options; this._logger = logger; + this._features = features; } make(options: MakeOptions): ISync { const {scheduler, storage, session} = options; + let runSyncInWorker = this._features.sameSessionInMultipleTabs; + + if (typeof SharedWorker === "undefined") { + runSyncInWorker = false; + } + + if (runSyncInWorker) { + return new SyncProxy({session}); + } return new Sync({ logger: this._logger, From 70749842764ae3979ad5293f56c8de2c869c5b96 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Wed, 8 Mar 2023 15:27:45 +0000 Subject: [PATCH 08/13] Spawn sync worker Doesn't do anything yet. --- src/platform/web/sync/SyncProxy.ts | 7 ++++++- src/platform/web/sync/sync-worker.js | 7 +++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/platform/web/sync/sync-worker.js diff --git a/src/platform/web/sync/SyncProxy.ts b/src/platform/web/sync/SyncProxy.ts index 48e0d30c96..8d96ce5d4e 100644 --- a/src/platform/web/sync/SyncProxy.ts +++ b/src/platform/web/sync/SyncProxy.ts @@ -11,6 +11,7 @@ export class SyncProxy implements ISync { private _session: Session; private readonly _status: ObservableValue = new ObservableValue(SyncStatus.Stopped); private _error: Error | null = null; + private _worker?: SharedWorker; constructor(options: Options) { const {session} = options; @@ -26,7 +27,11 @@ export class SyncProxy implements ISync { } async start(): Promise { - // TODO + this._worker = new SharedWorker(new URL("./sync-worker", import.meta.url)); + this._worker.port.onmessage = (event: MessageEvent) => { + // TODO + console.log(event); + }; } stop(): void { diff --git a/src/platform/web/sync/sync-worker.js b/src/platform/web/sync/sync-worker.js new file mode 100644 index 0000000000..c70e4e233b --- /dev/null +++ b/src/platform/web/sync/sync-worker.js @@ -0,0 +1,7 @@ +// TODO + +self.onconnect = (event) => { + const port = event.ports[0]; + port.postMessage("hello from sync worker"); + console.log("hello from sync worker"); +} From 952eccde285d1aebc675004919e09af530c7378e Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Wed, 8 Mar 2023 15:28:09 +0000 Subject: [PATCH 09/13] Don't precache sync worker in service worker Without this the build fails. --- scripts/build-plugins/service-worker.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/scripts/build-plugins/service-worker.js b/scripts/build-plugins/service-worker.js index 856195453a..8dad6064f8 100644 --- a/scripts/build-plugins/service-worker.js +++ b/scripts/build-plugins/service-worker.js @@ -72,6 +72,21 @@ const NON_PRECACHED_JS = [ function isPreCached(asset) { const {name, fileName} = asset; + + // For sync-worker.js and sync-worker.js.map, `name` isn't set, so we must rely on `fileName` only. + if (!name && fileName.includes("sync-worker")) { + // Don't precache sourcemap. + if (fileName.endsWith(".js.map")) { + return false; + } + + // sync-worker.js is only used when the SameSessionInMultipleTabs feature is enabled, so we don't precache it. + // TODO: Once the SameSessionInMultipleTabs feature is removed, we should probably precache sync-worker.js by returning true below. + if (fileName.endsWith(".js")) { + return false; + } + } + return name.endsWith(".svg") || name.endsWith(".png") || name.endsWith(".css") || From 67153dd97d249a0f46e12631ee52d4e94dde2744 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Wed, 8 Mar 2023 16:57:34 +0000 Subject: [PATCH 10/13] Convert sync worker to a module, and to typescript --- src/platform/web/sync/SyncProxy.ts | 4 +++- src/platform/web/sync/sync-worker.js | 7 ------- src/platform/web/sync/sync-worker.ts | 12 ++++++++++++ 3 files changed, 15 insertions(+), 8 deletions(-) delete mode 100644 src/platform/web/sync/sync-worker.js create mode 100644 src/platform/web/sync/sync-worker.ts diff --git a/src/platform/web/sync/SyncProxy.ts b/src/platform/web/sync/SyncProxy.ts index 8d96ce5d4e..bd5d422983 100644 --- a/src/platform/web/sync/SyncProxy.ts +++ b/src/platform/web/sync/SyncProxy.ts @@ -27,7 +27,9 @@ export class SyncProxy implements ISync { } async start(): Promise { - this._worker = new SharedWorker(new URL("./sync-worker", import.meta.url)); + this._worker = new SharedWorker(new URL("./sync-worker", import.meta.url), { + type: "module", + }); this._worker.port.onmessage = (event: MessageEvent) => { // TODO console.log(event); diff --git a/src/platform/web/sync/sync-worker.js b/src/platform/web/sync/sync-worker.js deleted file mode 100644 index c70e4e233b..0000000000 --- a/src/platform/web/sync/sync-worker.js +++ /dev/null @@ -1,7 +0,0 @@ -// TODO - -self.onconnect = (event) => { - const port = event.ports[0]; - port.postMessage("hello from sync worker"); - console.log("hello from sync worker"); -} diff --git a/src/platform/web/sync/sync-worker.ts b/src/platform/web/sync/sync-worker.ts new file mode 100644 index 0000000000..be7a1f6751 --- /dev/null +++ b/src/platform/web/sync/sync-worker.ts @@ -0,0 +1,12 @@ +/// + +// The empty export makes this a module. It can be removed once there's at least one import. +export {} + +declare let self: SharedWorkerGlobalScope; + +self.onconnect = (event: MessageEvent) => { + const port = event.ports[0]; + port.postMessage("hello from sync worker"); + console.log("hello from sync worker"); +} From 9a2674a6d8d824146f3c6762fed797ea595eb832 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Thu, 9 Mar 2023 15:07:40 +0000 Subject: [PATCH 11/13] Disable typescript checks on the sync worker Will address this in a follow-up PR as it's not trivial to fix. --- src/platform/web/sync/sync-worker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/platform/web/sync/sync-worker.ts b/src/platform/web/sync/sync-worker.ts index be7a1f6751..28f85d275c 100644 --- a/src/platform/web/sync/sync-worker.ts +++ b/src/platform/web/sync/sync-worker.ts @@ -1,4 +1,5 @@ -/// +// TODO: Figure out how to get WebWorkers Typescript lib working. For now we just disable checks on the whole file. +// @ts-nocheck // The empty export makes this a module. It can be removed once there's at least one import. export {} From 721543a0c6438d05a0a5c69f309074cdfce5b24a Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 14 Mar 2023 15:27:20 +0000 Subject: [PATCH 12/13] Remove sync worker from SDK build --- scripts/sdk/build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/sdk/build.sh b/scripts/sdk/build.sh index 5e1632d3ee..62b9a32859 100755 --- a/scripts/sdk/build.sh +++ b/scripts/sdk/build.sh @@ -10,6 +10,9 @@ shopt -s extglob rm -rf target/* yarn run vite build -c vite.sdk-assets-config.js yarn run vite build -c vite.sdk-lib-config.js +# Remove sync-worker.js from SDK build. +# TODO: Once SameSessionInMultipleTabs feature flag is globally enabled, remove the following line. +rm -rf target/lib-build/assets yarn tsc -p tsconfig-declaration.json ./scripts/sdk/create-manifest.js ./target/package.json mkdir target/paths From 2b64cd59239a3ac1113fc51f26a23c652e4ec5cc Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 14 Mar 2023 15:29:26 +0000 Subject: [PATCH 13/13] Add copyright notices --- src/matrix/ISync.ts | 16 ++++++++++++++++ src/platform/web/sync/SyncFactory.ts | 16 ++++++++++++++++ src/platform/web/sync/SyncProxy.ts | 16 ++++++++++++++++ src/platform/web/sync/sync-worker.ts | 16 ++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/src/matrix/ISync.ts b/src/matrix/ISync.ts index 99c456db85..f035a6a904 100644 --- a/src/matrix/ISync.ts +++ b/src/matrix/ISync.ts @@ -1,3 +1,19 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +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. +*/ + import {ObservableValue} from "../observable/value"; import {SyncStatus} from "./Sync"; diff --git a/src/platform/web/sync/SyncFactory.ts b/src/platform/web/sync/SyncFactory.ts index d98eac5707..037662643e 100644 --- a/src/platform/web/sync/SyncFactory.ts +++ b/src/platform/web/sync/SyncFactory.ts @@ -1,3 +1,19 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +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. +*/ + import {ISync} from "../../../matrix/ISync"; import {Sync} from "../../../matrix/Sync"; import {RequestScheduler} from "../../../matrix/net/RequestScheduler"; diff --git a/src/platform/web/sync/SyncProxy.ts b/src/platform/web/sync/SyncProxy.ts index bd5d422983..7e59edcc61 100644 --- a/src/platform/web/sync/SyncProxy.ts +++ b/src/platform/web/sync/SyncProxy.ts @@ -1,3 +1,19 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +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. +*/ + import {ISync} from "../../../matrix/ISync"; import {ObservableValue} from "../../../observable/value"; import {SyncStatus} from "../../../matrix/Sync"; diff --git a/src/platform/web/sync/sync-worker.ts b/src/platform/web/sync/sync-worker.ts index 28f85d275c..559c77d742 100644 --- a/src/platform/web/sync/sync-worker.ts +++ b/src/platform/web/sync/sync-worker.ts @@ -1,3 +1,19 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +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. +*/ + // TODO: Figure out how to get WebWorkers Typescript lib working. For now we just disable checks on the whole file. // @ts-nocheck