From b3095112cd9409eded425695bebc0ce1eb4c4596 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Sun, 23 Jun 2019 23:38:30 +0200 Subject: [PATCH 01/11] build bundled version no es6 modules on lumia --- index-build.html | 13 ++++ package.json | 4 +- rollup.config.js | 8 ++ yarn.lock | 197 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 index-build.html create mode 100644 rollup.config.js create mode 100644 yarn.lock diff --git a/index-build.html b/index-build.html new file mode 100644 index 00000000..30725164 --- /dev/null +++ b/index-build.html @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/package.json b/package.json index f0a8ab93..d6ecacbc 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ }, "scripts": { "test": "node_modules/.bin/impunity --entryPoint src/main.js --force-esm", - "start": "node scripts/serve-local.js" + "start": "node scripts/serve-local.js", + "build": "node_modules/rollup/bin/rollup -c" }, "repository": { "type": "git", @@ -23,6 +24,7 @@ "devDependencies": { "finalhandler": "^1.1.1", "impunity": "^0.0.7", + "rollup": "^1.15.6", "serve-static": "^1.13.2" } } diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 00000000..ebaa9ff0 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,8 @@ +export default { + input: 'src/main.js', + output: { + file: 'bundle.js', + format: 'iife', + name: 'main' + } +}; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..c926d2a4 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,197 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/node@^12.0.8": + version "12.0.8" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.8.tgz#551466be11b2adc3f3d47156758f610bd9f6b1d8" + integrity sha512-b8bbUOTwzIY3V5vDTY1fIJ+ePKDUBqt2hC2woVGotdQQhG/2Sh62HOKHrT7ab+VerXAcPyAiTEipPu/FsreUtg== + +acorn@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== + +colors@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" + integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== + +commander@^2.19.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +finalhandler@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +http-errors@~1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +impunity@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/impunity/-/impunity-0.0.7.tgz#15b8aaafcc98dcf3a4b5bcfa0beea4eea63d760f" + integrity sha512-+DhzXSWrzqI1KNroKt3y1LkLTn/aoJpt4DzxWN+hair+Jfb+iJAbTEsSFkYUG7kASP9TF9GvI0hIBUul6PjpKg== + dependencies: + colors "^1.3.3" + commander "^2.19.0" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +rollup@^1.15.6: + version "1.15.6" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.15.6.tgz#caf0ed28d2d78e3a59c1398e5a3695fb600a0ef0" + integrity sha512-s3Vn3QJQ5YVFfIG4nXoG9VdL1I37IZsft+4ZyeBhxE0df1kCFz9e+4bEAbR4mKH3pvBO9e9xjdxWPhhIp0r9ow== + dependencies: + "@types/estree" "0.0.39" + "@types/node" "^12.0.8" + acorn "^6.1.1" + +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-static@^1.13.2: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" + +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= From ca4361248f1e4996ea5885d8071ee25397d2e778 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 19:49:49 +0200 Subject: [PATCH 02/11] fallback for platforms missing AbortController --- src/matrix/hs-api.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/matrix/hs-api.js b/src/matrix/hs-api.js index 4c6ebf86..cc2e60f4 100644 --- a/src/matrix/hs-api.js +++ b/src/matrix/hs-api.js @@ -6,8 +6,21 @@ import { class RequestWrapper { constructor(promise, controller) { - this._promise = promise; - this._controller = controller; + if (!controller) { + const abortPromise = new Promise((_, reject) => { + this._controller = { + abort() { + const err = new Error("fetch request aborted"); + err.name = "AbortError"; + reject(err); + } + }; + }); + this._promise = Promise.race([promise, abortPromise]); + } else { + this._promise = promise; + this._controller = controller; + } } abort() { @@ -47,13 +60,13 @@ export default class HomeServerApi { headers.append("Content-Type", "application/json"); bodyString = JSON.stringify(body); } - const controller = new AbortController(); + const controller = typeof AbortController === "function" ? new AbortController() : null; // TODO: set authenticated headers with second arguments, cache them let promise = fetch(url, { method, headers, body: bodyString, - signal: controller.signal + signal: controller && controller.signal }); promise = promise.then(async (response) => { if (response.ok) { From 106146660ccdbcb7c97177f84629031c96cf5ca1 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 21:49:42 +0200 Subject: [PATCH 03/11] define storage keys to be 32bit for idb / web platform as a preparation to serialize the eventIndex and fragmentId as a 8 character string, part of a concatenated string PK, as lumia doesn't support array keys. --- src/Platform.js | 5 +++++ src/matrix/room/timeline/EventKey.js | 13 +++++-------- .../timeline/entries/FragmentBoundaryEntry.js | 5 +++-- .../storage/idb/stores/TimelineEventStore.js | 5 +++-- .../storage/idb/stores/TimelineFragmentStore.js | 6 ++++-- src/ui/web/WebPlatform.js | 16 ++++++++++++++++ 6 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 src/Platform.js create mode 100644 src/ui/web/WebPlatform.js diff --git a/src/Platform.js b/src/Platform.js new file mode 100644 index 00000000..c3ce381f --- /dev/null +++ b/src/Platform.js @@ -0,0 +1,5 @@ +// #ifdef PLATFORM_GNOME +// export {default} from "./ui/gnome/GnomePlatform.js"; +// #else +export {default} from "./ui/web/WebPlatform.js"; +// #endif diff --git a/src/matrix/room/timeline/EventKey.js b/src/matrix/room/timeline/EventKey.js index e05c38f4..7b8460d1 100644 --- a/src/matrix/room/timeline/EventKey.js +++ b/src/matrix/room/timeline/EventKey.js @@ -1,7 +1,4 @@ -const DEFAULT_LIVE_FRAGMENT_ID = 0; -const MIN_EVENT_INDEX = Number.MIN_SAFE_INTEGER + 1; -const MAX_EVENT_INDEX = Number.MAX_SAFE_INTEGER - 1; -const MID_EVENT_INDEX = 0; +import Platform from "../../../Platform.js"; // key for events in the timelineEvents store export default class EventKey { @@ -12,7 +9,7 @@ export default class EventKey { nextFragmentKey() { // could take MIN_EVENT_INDEX here if it can't be paged back - return new EventKey(this.fragmentId + 1, MID_EVENT_INDEX); + return new EventKey(this.fragmentId + 1, Platform.middleStorageKey); } nextKeyForDirection(direction) { @@ -32,15 +29,15 @@ export default class EventKey { } static get maxKey() { - return new EventKey(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER); + return new EventKey(Platform.maxStorageKey, Platform.maxStorageKey); } static get minKey() { - return new EventKey(Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER); + return new EventKey(Platform.minStorageKey, Platform.minStorageKey); } static get defaultLiveKey() { - return new EventKey(DEFAULT_LIVE_FRAGMENT_ID, MID_EVENT_INDEX); + return new EventKey(Platform.minStorageKey, Platform.middleStorageKey); } toString() { diff --git a/src/matrix/room/timeline/entries/FragmentBoundaryEntry.js b/src/matrix/room/timeline/entries/FragmentBoundaryEntry.js index 5eb772f3..4dc0ab61 100644 --- a/src/matrix/room/timeline/entries/FragmentBoundaryEntry.js +++ b/src/matrix/room/timeline/entries/FragmentBoundaryEntry.js @@ -1,6 +1,7 @@ import BaseEntry from "./BaseEntry.js"; import Direction from "../Direction.js"; import {isValidFragmentId} from "../common.js"; +import Platform from "../../../../Platform.js"; export default class FragmentBoundaryEntry extends BaseEntry { constructor(fragment, isFragmentStart, fragmentIdComparer) { @@ -36,9 +37,9 @@ export default class FragmentBoundaryEntry extends BaseEntry { get entryIndex() { if (this.started) { - return Number.MIN_SAFE_INTEGER; + return Platform.minStorageKey; } else { - return Number.MAX_SAFE_INTEGER; + return Platform.maxStorageKey; } } diff --git a/src/matrix/storage/idb/stores/TimelineEventStore.js b/src/matrix/storage/idb/stores/TimelineEventStore.js index 7c333245..e53f6e70 100644 --- a/src/matrix/storage/idb/stores/TimelineEventStore.js +++ b/src/matrix/storage/idb/stores/TimelineEventStore.js @@ -1,4 +1,5 @@ import EventKey from "../../../room/timeline/EventKey.js"; +import Platform from "../../../../Platform.js"; class Range { constructor(only, lower, upper, lowerOpen, upperOpen) { @@ -19,7 +20,7 @@ class Range { if (this._lower && !this._upper) { return IDBKeyRange.bound( [roomId, this._lower.fragmentId, this._lower.eventIndex], - [roomId, this._lower.fragmentId, EventKey.maxKey.eventIndex], + [roomId, this._lower.fragmentId, Platform.maxStorageKey], this._lowerOpen, false ); @@ -28,7 +29,7 @@ class Range { // also bound as we don't want to move into another roomId if (!this._lower && this._upper) { return IDBKeyRange.bound( - [roomId, this._upper.fragmentId, EventKey.minKey.eventIndex], + [roomId, this._upper.fragmentId, Platform.minStorageKey], [roomId, this._upper.fragmentId, this._upper.eventIndex], false, this._upperOpen diff --git a/src/matrix/storage/idb/stores/TimelineFragmentStore.js b/src/matrix/storage/idb/stores/TimelineFragmentStore.js index 86bd243f..1e08bbec 100644 --- a/src/matrix/storage/idb/stores/TimelineFragmentStore.js +++ b/src/matrix/storage/idb/stores/TimelineFragmentStore.js @@ -1,3 +1,5 @@ +import Platform from "../../../../Platform.js"; + export default class RoomFragmentStore { constructor(store) { this._store = store; @@ -5,8 +7,8 @@ export default class RoomFragmentStore { _allRange(roomId) { return IDBKeyRange.bound( - [roomId, Number.MIN_SAFE_INTEGER], - [roomId, Number.MAX_SAFE_INTEGER] + [roomId, Platform.minStorageKey], + [roomId, Platform.maxStorageKey] ); } diff --git a/src/ui/web/WebPlatform.js b/src/ui/web/WebPlatform.js new file mode 100644 index 00000000..cfc43fe4 --- /dev/null +++ b/src/ui/web/WebPlatform.js @@ -0,0 +1,16 @@ +export default { + get minStorageKey() { + // for indexeddb, we use unsigned 32 bit integers as keys + return 0; + }, + + get middleStorageKey() { + // for indexeddb, we use unsigned 32 bit integers as keys + return 0x7FFFFFFF; + }, + + get maxStorageKey() { + // for indexeddb, we use unsigned 32 bit integers as keys + return 0xFFFFFFFF; + }, +} From 0fd52be7101902217c30c7d883ab7451a9ff36e0 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 21:55:33 +0200 Subject: [PATCH 04/11] encode idb array keys as sortable strings that's why numeric parts of the keys have to be encoded as a fixed length, "big-endian" ordered strings, so string sorting will also sort the numeric keys correctly. this also assumes room ids don't contain the "|" character, we should probably escape the separator at some point. --- src/matrix/storage/idb/create.js | 20 ++++----- .../storage/idb/stores/RoomStateStore.js | 6 ++- .../storage/idb/stores/TimelineEventStore.js | 44 ++++++++++++++----- .../idb/stores/TimelineFragmentStore.js | 13 ++++-- 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/matrix/storage/idb/create.js b/src/matrix/storage/idb/create.js index ce8b6aca..42b41ae0 100644 --- a/src/matrix/storage/idb/create.js +++ b/src/matrix/storage/idb/create.js @@ -12,18 +12,14 @@ function createStores(db) { db.createObjectStore("roomSummary", {keyPath: "roomId"}); // need index to find live fragment? prooobably ok without for now - db.createObjectStore("timelineFragments", {keyPath: ["roomId", "id"]}); - const timelineEvents = db.createObjectStore("timelineEvents", {keyPath: ["roomId", "fragmentId", "eventIndex"]}); - timelineEvents.createIndex("byEventId", [ - "roomId", - "event.event_id" - ], {unique: true}); - - db.createObjectStore("roomState", {keyPath: [ - "roomId", - "event.type", - "event.state_key" - ]}); + //key = room_id | fragment_id + db.createObjectStore("timelineFragments", {keyPath: "key"}); + //key = room_id | fragment_id | event_index + const timelineEvents = db.createObjectStore("timelineEvents", {keyPath: "key"}); + //eventIdKey = room_id | event_id + timelineEvents.createIndex("byEventId", "eventIdKey", {unique: true}); + //key = room_id | event.type | event.state_key, + db.createObjectStore("roomState", {keyPath: "key"}); // const roomMembers = db.createObjectStore("roomMembers", {keyPath: [ // "event.room_id", diff --git a/src/matrix/storage/idb/stores/RoomStateStore.js b/src/matrix/storage/idb/stores/RoomStateStore.js index 0a6ca949..09f3cd6d 100644 --- a/src/matrix/storage/idb/stores/RoomStateStore.js +++ b/src/matrix/storage/idb/stores/RoomStateStore.js @@ -12,6 +12,8 @@ export default class RoomStateStore { } async setStateEvent(roomId, event) { - return this._roomStateStore.put({roomId, event}); + const key = `${roomId}|${event.type}|${event.state_key}`; + const entry = {roomId, event, key}; + return this._roomStateStore.put(entry); } -} \ No newline at end of file +} diff --git a/src/matrix/storage/idb/stores/TimelineEventStore.js b/src/matrix/storage/idb/stores/TimelineEventStore.js index e53f6e70..1b4e6e00 100644 --- a/src/matrix/storage/idb/stores/TimelineEventStore.js +++ b/src/matrix/storage/idb/stores/TimelineEventStore.js @@ -1,6 +1,25 @@ import EventKey from "../../../room/timeline/EventKey.js"; import Platform from "../../../../Platform.js"; +// storage keys are defined to be unsigned 32bit numbers in WebPlatform.js, which is assumed by idb +function encodeUint32(n) { + const hex = n.toString(16); + return "0".repeat(8 - hex.length) + hex; +} + +function encodeKey(roomId, fragmentId, eventIndex) { + return `${roomId}|${encodeUint32(fragmentId)}|${encodeUint32(eventIndex)}`; +} + +function encodeEventIdKey(roomId, eventId) { + return `${roomId}|${eventId}`; +} + +function decodeEventIdKey(eventIdKey) { + const [roomId, eventId] = eventIdKey.split("|"); + return {roomId, eventId}; +} + class Range { constructor(only, lower, upper, lowerOpen, upperOpen) { this._only = only; @@ -13,14 +32,14 @@ class Range { asIDBKeyRange(roomId) { // only if (this._only) { - return IDBKeyRange.only([roomId, this._only.fragmentId, this._only.eventIndex]); + return IDBKeyRange.only(encodeKey(roomId, this._only.fragmentId, this._only.eventIndex)); } // lowerBound // also bound as we don't want to move into another roomId if (this._lower && !this._upper) { return IDBKeyRange.bound( - [roomId, this._lower.fragmentId, this._lower.eventIndex], - [roomId, this._lower.fragmentId, Platform.maxStorageKey], + encodeKey(roomId, this._lower.fragmentId, this._lower.eventIndex), + encodeKey(roomId, this._lower.fragmentId, Platform.maxStorageKey), this._lowerOpen, false ); @@ -29,8 +48,8 @@ class Range { // also bound as we don't want to move into another roomId if (!this._lower && this._upper) { return IDBKeyRange.bound( - [roomId, this._upper.fragmentId, Platform.minStorageKey], - [roomId, this._upper.fragmentId, this._upper.eventIndex], + encodeKey(roomId, this._upper.fragmentId, Platform.minStorageKey), + encodeKey(roomId, this._upper.fragmentId, this._upper.eventIndex), false, this._upperOpen ); @@ -38,8 +57,8 @@ class Range { // bound if (this._lower && this._upper) { return IDBKeyRange.bound( - [roomId, this._lower.fragmentId, this._lower.eventIndex], - [roomId, this._upper.fragmentId, this._upper.eventIndex], + encodeKey(roomId, this._lower.fragmentId, this._lower.eventIndex), + encodeKey(roomId, this._upper.fragmentId, this._upper.eventIndex), this._lowerOpen, this._upperOpen ); @@ -170,7 +189,7 @@ export default class TimelineEventStore { // also passing them in chronological order makes sense as that's how we'll receive them almost always. async findFirstOccurringEventId(roomId, eventIds) { const byEventId = this._timelineStore.index("byEventId"); - const keys = eventIds.map(eventId => [roomId, eventId]); + const keys = eventIds.map(eventId => encodeEventIdKey(roomId, eventId)); const results = new Array(keys.length); let firstFoundKey; @@ -191,8 +210,7 @@ export default class TimelineEventStore { firstFoundKey = firstFoundAndPrecedingResolved(); return !!firstFoundKey; }); - // key of index is [roomId, eventId], so pick out eventId - return firstFoundKey && firstFoundKey[1]; + return firstFoundKey && decodeEventIdKey(firstFoundKey).eventId; } /** Inserts a new entry into the store. The combination of roomId and eventKey should not exist yet, or an error is thrown. @@ -201,6 +219,8 @@ export default class TimelineEventStore { * @throws {StorageError} ... */ insert(entry) { + entry.key = encodeKey(entry.roomId, entry.fragmentId, entry.eventIndex); + entry.eventIdKey = encodeEventIdKey(entry.roomId, entry.event.event_id); // TODO: map error? or in idb/store? return this._timelineStore.add(entry); } @@ -215,7 +235,7 @@ export default class TimelineEventStore { } get(roomId, eventKey) { - return this._timelineStore.get([roomId, eventKey.fragmentId, eventKey.eventIndex]); + return this._timelineStore.get(encodeKey(roomId, eventKey.fragmentId, eventKey.eventIndex)); } // returns the entries as well!! (or not always needed? I guess not always needed, so extra method) removeRange(roomId, range) { @@ -224,6 +244,6 @@ export default class TimelineEventStore { } getByEventId(roomId, eventId) { - return this._timelineStore.index("byEventId").get([roomId, eventId]); + return this._timelineStore.index("byEventId").get(encodeEventIdKey(roomId, eventId)); } } diff --git a/src/matrix/storage/idb/stores/TimelineFragmentStore.js b/src/matrix/storage/idb/stores/TimelineFragmentStore.js index 1e08bbec..2d86a100 100644 --- a/src/matrix/storage/idb/stores/TimelineFragmentStore.js +++ b/src/matrix/storage/idb/stores/TimelineFragmentStore.js @@ -1,5 +1,11 @@ import Platform from "../../../../Platform.js"; +function encodeKey(roomId, fragmentId) { + let fragmentIdHex = fragmentId.toString(16); + fragmentIdHex = "0".repeat(8 - fragmentIdHex.length) + fragmentIdHex; + return `${roomId}|${fragmentIdHex}`; +} + export default class RoomFragmentStore { constructor(store) { this._store = store; @@ -7,8 +13,8 @@ export default class RoomFragmentStore { _allRange(roomId) { return IDBKeyRange.bound( - [roomId, Platform.minStorageKey], - [roomId, Platform.maxStorageKey] + encodeKey(roomId, Platform.minStorageKey), + encodeKey(roomId, Platform.maxStorageKey) ); } @@ -35,6 +41,7 @@ export default class RoomFragmentStore { // depends if we want to do anything smart with fragment ids, // like give them meaning depending on range. not for now probably ... add(fragment) { + fragment.key = encodeKey(fragment.roomId, fragment.id); return this._store.add(fragment); } @@ -43,6 +50,6 @@ export default class RoomFragmentStore { } get(roomId, fragmentId) { - return this._store.get([roomId, fragmentId]); + return this._store.get(encodeKey(roomId, fragmentId)); } } From bbb5e35bcb049be0103f44e9962b44fdfb041e6b Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 22:00:50 +0200 Subject: [PATCH 05/11] wrap everything that can throw a idb DOMException in StorageError as lumia gives very cryptic errors without a stacktrace. --- src/matrix/error.js | 3 - src/matrix/storage/common.js | 14 ++++ src/matrix/storage/idb/storage.js | 20 ++++-- src/matrix/storage/idb/store.js | 61 +++++++++++++++- .../storage/idb/stores/TimelineEventStore.js | 69 ++++++++++--------- .../idb/stores/TimelineFragmentStore.js | 13 ++-- src/matrix/storage/idb/transaction.js | 3 +- src/matrix/storage/idb/utils.js | 14 +++- src/matrix/sync.js | 9 +-- 9 files changed, 148 insertions(+), 58 deletions(-) diff --git a/src/matrix/error.js b/src/matrix/error.js index 520698d9..847d50b2 100644 --- a/src/matrix/error.js +++ b/src/matrix/error.js @@ -5,9 +5,6 @@ export class HomeServerError extends Error { } } -export class StorageError extends Error { -} - export class RequestAbortError extends Error { } diff --git a/src/matrix/storage/common.js b/src/matrix/storage/common.js index d1050e5a..aa72fa0e 100644 --- a/src/matrix/storage/common.js +++ b/src/matrix/storage/common.js @@ -4,3 +4,17 @@ export const STORE_MAP = Object.freeze(STORE_NAMES.reduce((nameMap, name) => { nameMap[name] = name; return nameMap; }, {})); + +export class StorageError extends Error { + constructor(message, cause) { + let fullMessage = message; + if (cause) { + fullMessage += ": "; + if (cause.name) { + fullMessage += `(${cause.name}) `; + } + fullMessage += cause.message; + } + super(fullMessage); + } +} diff --git a/src/matrix/storage/idb/storage.js b/src/matrix/storage/idb/storage.js index ca7e2256..25bb0d39 100644 --- a/src/matrix/storage/idb/storage.js +++ b/src/matrix/storage/idb/storage.js @@ -1,5 +1,5 @@ import Transaction from "./transaction.js"; -import { STORE_NAMES } from "../common.js"; +import { STORE_NAMES, StorageError } from "../common.js"; export default class Storage { constructor(idbDatabase) { @@ -14,19 +14,27 @@ export default class Storage { _validateStoreNames(storeNames) { const idx = storeNames.findIndex(name => !STORE_NAMES.includes(name)); if (idx !== -1) { - throw new Error(`Tried to open a transaction for unknown store ${storeNames[idx]}`); + throw new StorageError(`Tried top, a transaction unknown store ${storeNames[idx]}`); } } async readTxn(storeNames) { this._validateStoreNames(storeNames); - const txn = this._db.transaction(storeNames, "readonly"); - return new Transaction(txn, storeNames); + try { + const txn = this._db.transaction(storeNames, "readonly"); + return new Transaction(txn, storeNames); + } catch(err) { + throw new StorageError("readTxn failed", err); + } } async readWriteTxn(storeNames) { this._validateStoreNames(storeNames); - const txn = this._db.transaction(storeNames, "readwrite"); - return new Transaction(txn, storeNames); + try { + const txn = this._db.transaction(storeNames, "readwrite"); + return new Transaction(txn, storeNames); + } catch(err) { + throw new StorageError("readWriteTxn failed", err); + } } } diff --git a/src/matrix/storage/idb/store.js b/src/matrix/storage/idb/store.js index 9b5daf46..fd2cc84d 100644 --- a/src/matrix/storage/idb/store.js +++ b/src/matrix/storage/idb/store.js @@ -1,9 +1,64 @@ import QueryTarget from "./query-target.js"; import { reqAsPromise } from "./utils.js"; +import { StorageError } from "../common.js"; + +class QueryTargetWrapper { + constructor(qt) { + this._qt = qt; + } + + openKeyCursor(...params) { + try { + return this._qt.openKeyCursor(...params); + } catch(err) { + throw new StorageError("openKeyCursor failed", err); + } + } + + openCursor(...params) { + try { + return this._qt.openCursor(...params); + } catch(err) { + throw new StorageError("openCursor failed", err); + } + } + + put(...params) { + try { + return this._qt.put(...params); + } catch(err) { + throw new StorageError("put failed", err); + } + } + + add(...params) { + try { + return this._qt.add(...params); + } catch(err) { + throw new StorageError("add failed", err); + } + } + + get(...params) { + try { + return this._qt.get(...params); + } catch(err) { + throw new StorageError("get failed", err); + } + } + + index(...params) { + try { + return this._qt.index(...params); + } catch(err) { + throw new StorageError("index failed", err); + } + } +} export default class Store extends QueryTarget { constructor(idbStore) { - super(idbStore); + super(new QueryTargetWrapper(idbStore)); } get _idbStore() { @@ -11,7 +66,7 @@ export default class Store extends QueryTarget { } index(indexName) { - return new QueryTarget(this._idbStore.index(indexName)); + return new QueryTarget(new QueryTargetWrapper(this._idbStore.index(indexName))); } put(value) { @@ -21,4 +76,4 @@ export default class Store extends QueryTarget { add(value) { return reqAsPromise(this._idbStore.add(value)); } -} \ No newline at end of file +} diff --git a/src/matrix/storage/idb/stores/TimelineEventStore.js b/src/matrix/storage/idb/stores/TimelineEventStore.js index 1b4e6e00..d88884bf 100644 --- a/src/matrix/storage/idb/stores/TimelineEventStore.js +++ b/src/matrix/storage/idb/stores/TimelineEventStore.js @@ -1,4 +1,5 @@ import EventKey from "../../../room/timeline/EventKey.js"; +import { StorageError } from "../../common.js"; import Platform from "../../../../Platform.js"; // storage keys are defined to be unsigned 32bit numbers in WebPlatform.js, which is assumed by idb @@ -30,38 +31,42 @@ class Range { } asIDBKeyRange(roomId) { - // only - if (this._only) { - return IDBKeyRange.only(encodeKey(roomId, this._only.fragmentId, this._only.eventIndex)); - } - // lowerBound - // also bound as we don't want to move into another roomId - if (this._lower && !this._upper) { - return IDBKeyRange.bound( - encodeKey(roomId, this._lower.fragmentId, this._lower.eventIndex), - encodeKey(roomId, this._lower.fragmentId, Platform.maxStorageKey), - this._lowerOpen, - false - ); - } - // upperBound - // also bound as we don't want to move into another roomId - if (!this._lower && this._upper) { - return IDBKeyRange.bound( - encodeKey(roomId, this._upper.fragmentId, Platform.minStorageKey), - encodeKey(roomId, this._upper.fragmentId, this._upper.eventIndex), - false, - this._upperOpen - ); - } - // bound - if (this._lower && this._upper) { - return IDBKeyRange.bound( - encodeKey(roomId, this._lower.fragmentId, this._lower.eventIndex), - encodeKey(roomId, this._upper.fragmentId, this._upper.eventIndex), - this._lowerOpen, - this._upperOpen - ); + try { + // only + if (this._only) { + return IDBKeyRange.only(encodeKey(roomId, this._only.fragmentId, this._only.eventIndex)); + } + // lowerBound + // also bound as we don't want to move into another roomId + if (this._lower && !this._upper) { + return IDBKeyRange.bound( + encodeKey(roomId, this._lower.fragmentId, this._lower.eventIndex), + encodeKey(roomId, this._lower.fragmentId, Platform.maxStorageKey), + this._lowerOpen, + false + ); + } + // upperBound + // also bound as we don't want to move into another roomId + if (!this._lower && this._upper) { + return IDBKeyRange.bound( + encodeKey(roomId, this._upper.fragmentId, Platform.minStorageKey), + encodeKey(roomId, this._upper.fragmentId, this._upper.eventIndex), + false, + this._upperOpen + ); + } + // bound + if (this._lower && this._upper) { + return IDBKeyRange.bound( + encodeKey(roomId, this._lower.fragmentId, this._lower.eventIndex), + encodeKey(roomId, this._upper.fragmentId, this._upper.eventIndex), + this._lowerOpen, + this._upperOpen + ); + } + } catch(err) { + throw new StorageError(`IDBKeyRange failed with data: ` + JSON.stringify(this), err); } } } diff --git a/src/matrix/storage/idb/stores/TimelineFragmentStore.js b/src/matrix/storage/idb/stores/TimelineFragmentStore.js index 2d86a100..b84759bd 100644 --- a/src/matrix/storage/idb/stores/TimelineFragmentStore.js +++ b/src/matrix/storage/idb/stores/TimelineFragmentStore.js @@ -1,3 +1,4 @@ +import { StorageError } from "../../common.js"; import Platform from "../../../../Platform.js"; function encodeKey(roomId, fragmentId) { @@ -12,10 +13,14 @@ export default class RoomFragmentStore { } _allRange(roomId) { - return IDBKeyRange.bound( - encodeKey(roomId, Platform.minStorageKey), - encodeKey(roomId, Platform.maxStorageKey) - ); + try { + return IDBKeyRange.bound( + encodeKey(roomId, Platform.minStorageKey), + encodeKey(roomId, Platform.maxStorageKey) + ); + } catch (err) { + throw new StorageError(`error from IDBKeyRange with roomId ${roomId}`, err); + } } all(roomId) { diff --git a/src/matrix/storage/idb/transaction.js b/src/matrix/storage/idb/transaction.js index 1a16d08d..a005706d 100644 --- a/src/matrix/storage/idb/transaction.js +++ b/src/matrix/storage/idb/transaction.js @@ -1,4 +1,5 @@ import {txnAsPromise} from "./utils.js"; +import {StorageError} from "../common.js"; import Store from "./store.js"; import SessionStore from "./stores/SessionStore.js"; import RoomSummaryStore from "./stores/RoomSummaryStore.js"; @@ -21,7 +22,7 @@ export default class Transaction { _idbStore(name) { if (!this._allowedStoreNames.includes(name)) { // more specific error? this is a bug, so maybe not ... - throw new Error(`Invalid store for transaction: ${name}, only ${this._allowedStoreNames.join(", ")} are allowed.`); + throw new StorageError(`Invalid store for transaction: ${name}, only ${this._allowedStoreNames.join(", ")} are allowed.`); } return new Store(this._txn.objectStore(name)); } diff --git a/src/matrix/storage/idb/utils.js b/src/matrix/storage/idb/utils.js index 83ef3411..f5b73cf3 100644 --- a/src/matrix/storage/idb/utils.js +++ b/src/matrix/storage/idb/utils.js @@ -1,3 +1,5 @@ +import { StorageError } from "../common.js"; + export function openDatabase(name, createObjectStore, version) { const req = window.indexedDB.open(name, version); req.onupgradeneeded = (ev) => { @@ -8,17 +10,21 @@ export function openDatabase(name, createObjectStore, version) { return reqAsPromise(req); } +function wrapError(err) { + return new StorageError(`wrapped DOMException`, err); +} + export function reqAsPromise(req) { return new Promise((resolve, reject) => { req.addEventListener("success", event => resolve(event.target.result)); - req.addEventListener("error", event => reject(event.target.error)); + req.addEventListener("error", event => reject(wrapError(event.target.error))); }); } export function txnAsPromise(txn) { return new Promise((resolve, reject) => { txn.addEventListener("complete", resolve); - txn.addEventListener("abort", reject); + txn.addEventListener("abort", e => reject(wrapError(e))); }); } @@ -42,6 +48,8 @@ export function iterateCursor(cursor, processValue) { cursor.continue(jumpTo); } }; + }).catch(err => { + throw new StorageError("iterateCursor failed", err); }); } @@ -97,7 +105,7 @@ export async function findStoreValue(db, storeName, toCursor, matchesValue) { } }); if (!matched) { - throw new Error("Value not found"); + throw new StorageError("Value not found"); } return match; } diff --git a/src/matrix/sync.js b/src/matrix/sync.js index ad6074cc..fd0d2bf6 100644 --- a/src/matrix/sync.js +++ b/src/matrix/sync.js @@ -1,8 +1,4 @@ -import { - RequestAbortError, - HomeServerError, - StorageError -} from "./error.js"; +import {RequestAbortError} from "./error.js"; import EventEmitter from "../EventEmitter.js"; const INCREMENTAL_TIMEOUT = 30000; @@ -111,7 +107,8 @@ export default class Sync extends EventEmitter { await syncTxn.complete(); console.info("syncTxn committed!!"); } catch (err) { - throw new StorageError("unable to commit sync tranaction", err); + console.error("unable to commit sync tranaction", err.message); + throw err; } // emit room related events after txn has been closed for(let {room, changes} of roomChanges) { From b882e0ef8a640a6cdef512401f93c67ea9321d69 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 22:02:00 +0200 Subject: [PATCH 06/11] respect argument count of idb calls lumia doesn't like undefined arguments if they are being left out, so call the idb calls with the exact amount of arguments --- src/matrix/storage/idb/query-target.js | 20 ++++++++++++++++---- src/matrix/storage/idb/utils.js | 4 +++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/matrix/storage/idb/query-target.js b/src/matrix/storage/idb/query-target.js index ec5c4530..a5c38b15 100644 --- a/src/matrix/storage/idb/query-target.js +++ b/src/matrix/storage/idb/query-target.js @@ -5,6 +5,18 @@ export default class QueryTarget { this._target = target; } + _openCursor(range, direction) { + if (range && direction) { + return this._target.openCursor(range, direction); + } else if (range) { + return this._target.openCursor(range); + } else if (direction) { + return this._target.openCursor(null, direction); + } else { + return this._target.openCursor(); + } + } + get(key) { return reqAsPromise(this._target.get(key)); } @@ -34,7 +46,7 @@ export default class QueryTarget { } async selectAll(range, direction) { - const cursor = this._target.openCursor(range, direction); + const cursor = this._openCursor(range, direction); const results = []; await iterateCursor(cursor, (value) => { results.push(value); @@ -97,7 +109,7 @@ export default class QueryTarget { _reduce(range, reducer, initialValue, direction) { let reducedValue = initialValue; - const cursor = this._target.openCursor(range, direction); + const cursor = this._openCursor(range, direction); return iterateCursor(cursor, (value) => { reducedValue = reducer(reducedValue, value); return {done: false}; @@ -111,7 +123,7 @@ export default class QueryTarget { } async _selectWhile(range, predicate, direction) { - const cursor = this._target.openCursor(range, direction); + const cursor = this._openCursor(range, direction); const results = []; await iterateCursor(cursor, (value) => { results.push(value); @@ -121,7 +133,7 @@ export default class QueryTarget { } async _find(range, predicate, direction) { - const cursor = this._target.openCursor(range, direction); + const cursor = this._openCursor(range, direction); let result; const found = await iterateCursor(cursor, (value) => { const found = predicate(value); diff --git a/src/matrix/storage/idb/utils.js b/src/matrix/storage/idb/utils.js index f5b73cf3..367d5e7d 100644 --- a/src/matrix/storage/idb/utils.js +++ b/src/matrix/storage/idb/utils.js @@ -44,8 +44,10 @@ export function iterateCursor(cursor, processValue) { const {done, jumpTo} = processValue(cursor.value, cursor.key); if (done) { resolve(true); - } else { + } else if(jumpTo) { cursor.continue(jumpTo); + } else { + cursor.continue(); } }; }).catch(err => { From 72c193cce5b1df4ea07107c462c96618ef0e9798 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 22:07:25 +0200 Subject: [PATCH 07/11] page to debug app on mobile phones without remote access to tools --- index-build-debug.html | 43 +++++++++++++++++++++++++++++ src/ui/web/session/SyncStatusBar.js | 3 +- 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 index-build-debug.html diff --git a/index-build-debug.html b/index-build-debug.html new file mode 100644 index 00000000..7e27801b --- /dev/null +++ b/index-build-debug.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + diff --git a/src/ui/web/session/SyncStatusBar.js b/src/ui/web/session/SyncStatusBar.js index 08ab9955..792aaa24 100644 --- a/src/ui/web/session/SyncStatusBar.js +++ b/src/ui/web/session/SyncStatusBar.js @@ -11,7 +11,8 @@ export default class SyncStatusBar extends TemplateView { "SyncStatusBar_shown": true, }}, [ vm => vm.status, - t.if(vm => !vm.isSyncing, t => t.button({onClick: () => vm.trySync()}, "Try syncing")) + t.if(vm => !vm.isSyncing, t => t.button({onClick: () => vm.trySync()}, "Try syncing")), + window.DEBUG ? t.button({id: "showlogs"}, "Show logs") : "" ]); } } From 59a303daa0d36374c765284f437ca5b6085f2f0d Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 22:08:40 +0200 Subject: [PATCH 08/11] make user config available from phone on local wlan --- src/main.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.js b/src/main.js index 6500420c..02289a9a 100644 --- a/src/main.js +++ b/src/main.js @@ -5,10 +5,10 @@ import Sync from "./matrix/sync.js"; import SessionView from "./ui/web/session/SessionView.js"; import SessionViewModel from "./domain/session/SessionViewModel.js"; -const HOST = "localhost"; +const HOST = "192.168.2.108"; const HOMESERVER = `http://${HOST}:8008`; const USERNAME = "bruno1"; -const USER_ID = `@${USERNAME}:${HOST}`; +const USER_ID = `@${USERNAME}:localhost`; const PASSWORD = "testtest"; function getSessionInfo(userId) { @@ -50,7 +50,6 @@ function showSession(container, session, sync) { container.appendChild(view.mount()); } -// eslint-disable-next-line no-unused-vars export default async function main(container) { try { let sessionInfo = getSessionInfo(USER_ID); From 4b178713222946477aeedeec14327494c943b5d7 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 22:09:46 +0200 Subject: [PATCH 09/11] prototypes for lumia idb changes (removing array keys, etc ...) --- prototypes/base256.html | 30 +++++++++ prototypes/idb-cmp-numbers.html | 110 +++++++++++++++++++++++++++++++ prototypes/idb-cmp.html | 76 +++++++++++++++++++++ prototypes/idb-continue-key.html | 5 ++ prototypes/idb-multi-key.html | 75 +++++++++++++++++++++ 5 files changed, 296 insertions(+) create mode 100644 prototypes/base256.html create mode 100644 prototypes/idb-cmp-numbers.html create mode 100644 prototypes/idb-cmp.html create mode 100644 prototypes/idb-multi-key.html diff --git a/prototypes/base256.html b/prototypes/base256.html new file mode 100644 index 00000000..52096f67 --- /dev/null +++ b/prototypes/base256.html @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/prototypes/idb-cmp-numbers.html b/prototypes/idb-cmp-numbers.html new file mode 100644 index 00000000..a2d63748 --- /dev/null +++ b/prototypes/idb-cmp-numbers.html @@ -0,0 +1,110 @@ + + + + + + + + + + + diff --git a/prototypes/idb-cmp.html b/prototypes/idb-cmp.html new file mode 100644 index 00000000..62ae68f0 --- /dev/null +++ b/prototypes/idb-cmp.html @@ -0,0 +1,76 @@ + + + + + + + + + + + diff --git a/prototypes/idb-continue-key.html b/prototypes/idb-continue-key.html index dc488deb..dacf1740 100644 --- a/prototypes/idb-continue-key.html +++ b/prototypes/idb-continue-key.html @@ -2,6 +2,11 @@ + + + From 90a38078e04e14479eccd250a6f393ff8be7aa6d Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 22:16:45 +0200 Subject: [PATCH 10/11] unused import --- src/matrix/room/timeline/persistence/TimelineReader.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/matrix/room/timeline/persistence/TimelineReader.js b/src/matrix/room/timeline/persistence/TimelineReader.js index 7d86115b..01c9f693 100644 --- a/src/matrix/room/timeline/persistence/TimelineReader.js +++ b/src/matrix/room/timeline/persistence/TimelineReader.js @@ -1,5 +1,4 @@ import {directionalConcat, directionalAppend} from "./common.js"; -import EventKey from "../EventKey.js"; import Direction from "../Direction.js"; import EventEntry from "../entries/EventEntry.js"; import FragmentBoundaryEntry from "../entries/FragmentBoundaryEntry.js"; From 1c89ce2ed9800ba351e46794daa8f007e76276dd Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 26 Jun 2019 22:20:01 +0200 Subject: [PATCH 11/11] ignore bundle --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 78af6c1a..3669f86f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.sublime-project *.sublime-workspace -node_modules \ No newline at end of file +node_modules +bundle.js