From 1ef708d950382d8b9287a999a83a243fbf2f08a6 Mon Sep 17 00:00:00 2001 From: Jonathan Poltak Samosir Date: Tue, 28 May 2024 15:26:57 +0700 Subject: [PATCH 1/9] Bring back dexie schema test coverage - Left this to decay for too long. Super important as this stuff is easy to mess up (and I had unforunately messed up twice in the last 2 months here - luckily nothing fatal) --- external/@worldbrain/memex-common | 2 +- .../backend/translation-layer/index.test.ts | 2 +- src/personal-cloud/background/index.tests.ts | 2 +- src/storage/index.test.ts | 617 +++++++++++++++++- src/tests/background-integration-tests.ts | 2 +- 5 files changed, 618 insertions(+), 7 deletions(-) diff --git a/external/@worldbrain/memex-common b/external/@worldbrain/memex-common index 7666cc8c56..7c76fb7c7b 160000 --- a/external/@worldbrain/memex-common +++ b/external/@worldbrain/memex-common @@ -1 +1 @@ -Subproject commit 7666cc8c56c638e6f784b3eb3091538961faeb8b +Subproject commit 7c76fb7c7b1df6395539f7070744b68aee868251 diff --git a/src/personal-cloud/background/backend/translation-layer/index.test.ts b/src/personal-cloud/background/backend/translation-layer/index.test.ts index c5c66d7ac4..345c6b81fb 100644 --- a/src/personal-cloud/background/backend/translation-layer/index.test.ts +++ b/src/personal-cloud/background/backend/translation-layer/index.test.ts @@ -472,7 +472,7 @@ async function setup(options?: { ) => { const clientSchemaVersion = downloadOptions?.clientSchemaVersion ?? - STORAGE_VERSIONS[37].version + STORAGE_VERSIONS[38].version const { batch } = await downloadClientUpdates({ getNow, startTime: 0, diff --git a/src/personal-cloud/background/index.tests.ts b/src/personal-cloud/background/index.tests.ts index 622f9c9356..3650dfe1e0 100644 --- a/src/personal-cloud/background/index.tests.ts +++ b/src/personal-cloud/background/index.tests.ts @@ -391,7 +391,7 @@ export async function setupSyncBackgroundTest( storageManager: serverStorage.manager, storageModules: serverStorage.modules, getSqlStorageMananager, - clientSchemaVersion: STORAGE_VERSIONS[37].version, + clientSchemaVersion: STORAGE_VERSIONS[38].version, services: { activityStreams: services.activityStreams, pushMessaging: pushMessagingService, diff --git a/src/storage/index.test.ts b/src/storage/index.test.ts index f4987248ed..82153f4fa8 100644 --- a/src/storage/index.test.ts +++ b/src/storage/index.test.ts @@ -25,9 +25,7 @@ function normalizeDexieHistory(dexieHistory: DexieSchema[]) { } describe('Storage initialization', () => { - // TODO: Fix this test - it.skip('should generate the correct Dexie schema', async () => { - return + it('should generate the correct Dexie schema', async () => { const setup = await setupBackgroundIntegrationTest() const dexieHistory = patchDirectLinksSchema( getDexieHistory(setup.storageManager.registry), @@ -852,6 +850,619 @@ describe('Storage initialization', () => { dexieSchemaVersion: 28, storexSchemaVersion: STORAGE_VERSIONS[27].version, }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, followedList, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 29, + storexSchemaVersion: STORAGE_VERSIONS[28].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, followedList, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 30, + storexSchemaVersion: STORAGE_VERSIONS[29].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 31, + storexSchemaVersion: STORAGE_VERSIONS[30].version, + }, + + /// + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + images: 'id, createdWhen, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 32, + storexSchemaVersion: STORAGE_VERSIONS[31].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + images: 'id, createdWhen, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 33, + storexSchemaVersion: STORAGE_VERSIONS[32].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl, color', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + images: 'id, createdWhen, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 34, + storexSchemaVersion: STORAGE_VERSIONS[33].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl, color', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + images: 'id, createdWhen, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 35, + storexSchemaVersion: STORAGE_VERSIONS[34].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl, color', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + images: 'id, createdWhen, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId, remoteId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 36, + storexSchemaVersion: STORAGE_VERSIONS[35].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl, color', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customListTrees: + '++id, listId, order, parentListId, path', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + images: 'id, createdWhen, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId, remoteId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 37, + storexSchemaVersion: STORAGE_VERSIONS[36].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl, color', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customListTrees: + '++id, listId, order, parentListId, path', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + images: 'id, createdWhen, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId, remoteId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 38, + storexSchemaVersion: STORAGE_VERSIONS[37].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: '[listId+url], listId, url', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl, color', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customListTrees: + '++id, listId, order, parentListId, path', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + images: 'id, createdWhen, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageEntities: '++id, name, normalizedPageUrl, order', + pageFetchBacklog: '++id, createdAt', + pageListEntries: '[listId+pageUrl], listId, pageUrl', + pageListEntryDescriptions: '[listId+pageUrl]', + pageMetadata: '++id, normalizedPageUrl', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId, remoteId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 39, + storexSchemaVersion: STORAGE_VERSIONS[38].version, + }, + { + schema: { + annotBookmarks: 'url, createdAt', + annotListEntries: + '[listId+url], listId, url, createdAt', + annotationPrivacyLevels: '++id, annotation', + annotations: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, lastEdited, pageUrl, color', + backupChanges: 'timestamp, collection', + bookmarks: 'url, time', + clientSyncLogEntry: + '[deviceId+createdOn], [collection+pk], [createdOn+sharedOn], createdOn, needsIntegration, sharedOn', + contentSharingAction: '++id, createdWhen', + customListDescriptions: 'listId', + customListTrees: + '++id, listId, order, parentListId, path', + customLists: + 'id, *nameTerms, createdAt, isDeletable, isNestable, name', + directLinks: + 'url, *_body_terms, *_comment_terms, *_pageTitle_terms, createdWhen, pageUrl', + eventLog: '[time+type], time, type', + favIcons: 'hostname', + followedList: 'sharedList', + followedListEntry: + '++id, &sharedListEntry, followedList, normalizedPageUrl', + images: 'id, createdWhen, normalizedPageUrl', + locators: '++id, fingerprint, normalizedUrl', + notifications: 'id', + pageEntities: '++id, name, normalizedPageUrl, order', + pageFetchBacklog: '++id, createdAt', + pageListEntries: + '[listId+pageUrl], listId, pageUrl, createdAt', + pageListEntryDescriptions: '[listId+pageUrl]', + pageMetadata: '++id, normalizedPageUrl', + pages: + 'url, *terms, *titleTerms, *urlTerms, domain, hostname', + personalCloudAction: '++id, createdWhen', + readablePageArchives: 'url, createdWhen, lastEdited', + readwiseAction: '++id, createdWhen', + settings: 'key', + sharedAnnotationMetadata: 'localId, remoteId', + sharedListMetadata: 'localId, remoteId', + socialBookmarks: '++id, createdAt, postId', + socialPostListEntries: '++id, listId, postId', + socialPosts: + '++id, *_text_terms, createdAt, serviceId, userId', + socialTags: '++id, name, postId', + socialUsers: '++id, name, serviceId, username', + syncDeviceInfo: 'deviceId', + tags: '[name+url], name, url', + templates: 'id, code, isFavourite, title', + visits: '[time+url], url', + }, + dexieSchemaVersion: 40, + storexSchemaVersion: STORAGE_VERSIONS[39].version, + }, ]), ) }) diff --git a/src/tests/background-integration-tests.ts b/src/tests/background-integration-tests.ts index 5327caf9ac..b1308f2693 100644 --- a/src/tests/background-integration-tests.ts +++ b/src/tests/background-integration-tests.ts @@ -256,7 +256,7 @@ export async function setupBackgroundIntegrationTest( }, storageManager: serverStorage.manager, storageModules: serverStorage.modules, - clientSchemaVersion: STORAGE_VERSIONS[37].version, + clientSchemaVersion: STORAGE_VERSIONS[38].version, view: personalCloudHub.getView(), useDownloadTranslationLayer: options?.useDownloadTranslationLayer ?? true, From 8ca6cabae3f46acbe01f4b5e90a3bd99408f239d Mon Sep 17 00:00:00 2001 From: Jonathan Poltak Samosir Date: Tue, 28 May 2024 15:53:37 +0700 Subject: [PATCH 2/9] Fix FF issue with too strict regexp causing stack overflow on complicated inputs - see submodule commit --- external/@worldbrain/memex-stemmer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/@worldbrain/memex-stemmer b/external/@worldbrain/memex-stemmer index 8a3d2510ed..5e0f2108cd 160000 --- a/external/@worldbrain/memex-stemmer +++ b/external/@worldbrain/memex-stemmer @@ -1 +1 @@ -Subproject commit 8a3d2510edbca81b045371ab220971a1c1f832e6 +Subproject commit 5e0f2108cde4b7060165de462110b4f5f0f2c196 From 59d84afd9ff8669fd2101ea782b864702ad74b6a Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 28 May 2024 11:10:31 +0200 Subject: [PATCH 3/9] bump version to 3.19.36 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d8a1b63505..f538772a7b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "worldbrain-extension", - "version": "3.19.35", + "version": "3.19.36", "homepage": "https://memex.garden", "repository": "https://github.com/WorldBrain/Memex", "scripts": { From 8151396b528a6d61318aa6a58627fec4df1f7527 Mon Sep 17 00:00:00 2001 From: Jonathan Poltak Samosir Date: Wed, 29 May 2024 13:00:10 +0700 Subject: [PATCH 4/9] Block page nav away during sidebar write RPC ops --- .../AnnotationsSidebarContainer.tsx | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/sidebar/annotations-sidebar/containers/AnnotationsSidebarContainer.tsx b/src/sidebar/annotations-sidebar/containers/AnnotationsSidebarContainer.tsx index f985ea456b..f9ea7079f6 100644 --- a/src/sidebar/annotations-sidebar/containers/AnnotationsSidebarContainer.tsx +++ b/src/sidebar/annotations-sidebar/containers/AnnotationsSidebarContainer.tsx @@ -120,18 +120,35 @@ export class AnnotationsSidebarContainer< ) window['_getState'] = () => ({ ...this.state }) - this.listenToWindowChanges() + + window.addEventListener('beforeunload', this.handleBeforeUnload) + window.addEventListener('resize', this.handleWindowResize) } - listenToWindowChanges() { - window.addEventListener('resize', () => { - if (this.state.isWidthLocked) { - this.processEvent('adjustSidebarWidth', { - newWidth: this.state.sidebarWidth, - isWidthLocked: true, - }) - } - }) + async componentWillUnmount(): Promise { + window.removeEventListener('beforeunload', this.handleBeforeUnload) + window.removeEventListener('resize', this.handleWindowResize) + await super.componentWillUnmount() + } + + private handleWindowResize = async () => { + if (this.state.isWidthLocked) { + await this.processEvent('adjustSidebarWidth', { + newWidth: this.state.sidebarWidth, + isWidthLocked: true, + }) + } + } + + // Block user nav away when some write RPC op is occurring + private handleBeforeUnload = (e: BeforeUnloadEvent) => { + let shouldBlockUnload = + this.state.noteEditState === 'running' || + this.state.noteCreateState === 'running' || + this.state.noteColorUpdateState === 'running' + if (shouldBlockUnload) { + e.preventDefault() + } } private getListDetailsById: ListDetailsGetter = (listId) => { From d3b187ae4b28f0e7d5af8821154abced740b3c3b Mon Sep 17 00:00:00 2001 From: Jonathan Poltak Samosir Date: Wed, 29 May 2024 13:18:46 +0700 Subject: [PATCH 5/9] Block page nav away during ribbon write RPC ops --- .../ribbon/react/containers/ribbon/index.tsx | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/in-page-ui/ribbon/react/containers/ribbon/index.tsx b/src/in-page-ui/ribbon/react/containers/ribbon/index.tsx index 4a25aeba83..adfc4bad9b 100644 --- a/src/in-page-ui/ribbon/react/containers/ribbon/index.tsx +++ b/src/in-page-ui/ribbon/react/containers/ribbon/index.tsx @@ -36,7 +36,7 @@ export default class RibbonContainer extends StatefulUIElement< > { private ribbonRef = React.createRef() - constructor(props) { + constructor(props: RibbonContainerProps) { super( props, new RibbonContainerLogic({ @@ -48,6 +48,15 @@ export default class RibbonContainer extends StatefulUIElement< this.ribbonRef?.current?.focusCreateForm(), }), ) + + props.events.on('bookmarkPage', () => + this.processEvent('toggleBookmark', null), + ) + props.events.on('openSpacePickerInRibbon', () => + this.processEvent('setShowListsPicker', { value: true }), + ) + props.inPageUI.events.on('ribbonAction', this.handleExternalAction) + window.addEventListener('beforeunload', this.handleBeforeUnload) } private get normalizedPageUrl(): string | null { @@ -56,24 +65,13 @@ export default class RibbonContainer extends StatefulUIElement< : null } - async componentDidMount() { - await super.componentDidMount() - this.props.inPageUI.events.on('ribbonAction', this.handleExternalAction) - - this.props.events.on('bookmarkPage', () => - this.processEvent('toggleBookmark', null), - ) - this.props.events.on('openSpacePickerInRibbon', () => - this.processEvent('setShowListsPicker', { value: true }), - ) - } - async componentWillUnmount() { - await super.componentWillUnmount() this.props.inPageUI.events.removeListener( 'ribbonAction', this.handleExternalAction, ) + window.removeEventListener('beforeunload', this.handleBeforeUnload) + await super.componentWillUnmount() } componentDidUpdate(prevProps: RibbonContainerProps) { @@ -90,6 +88,14 @@ export default class RibbonContainer extends StatefulUIElement< } } + // Block user nav away when some write RPC op is occurring + private handleBeforeUnload = (e: BeforeUnloadEvent) => { + let shouldBlockUnload = this.state.bookmark.loadState === 'running' + if (shouldBlockUnload) { + e.preventDefault() + } + } + private whichFeed = () => { if (process.env.NODE_ENV === 'production') { return 'https://memex.social/feed' From 2753aa82932059b2e9430c0cbc226a97a54d66e5 Mon Sep 17 00:00:00 2001 From: Jonathan Poltak Samosir Date: Thu, 30 May 2024 13:46:56 +0700 Subject: [PATCH 6/9] Block nav-away from page during highlight creation - covers tooltip and KB shortcut methods --- src/content-scripts/content_script/global.ts | 25 +++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/content-scripts/content_script/global.ts b/src/content-scripts/content_script/global.ts index 2298e6ac76..f2076b398f 100644 --- a/src/content-scripts/content_script/global.ts +++ b/src/content-scripts/content_script/global.ts @@ -97,7 +97,6 @@ import { HIGHLIGHT_COLORS_DEFAULT } from '@worldbrain/memex-common/lib/common-ui import { PKMSyncBackgroundModule } from 'src/pkm-integrations/background' import { injectTelegramCustomUI } from './injectionUtils/telegram' import { renderSpacesBar } from './injectionUtils/utils' -import { getTimestampedNoteWithAIsummaryForYoutubeNotes } from './injectionUtils/youtube' import { injectTwitterProfileUI, trackTwitterMessageList, @@ -113,7 +112,6 @@ import type { InPageUIComponent } from 'src/in-page-ui/shared-state/types' import type { RemoteCopyPasterInterface } from 'src/copy-paster/background/types' import type { HighlightColor } from '@worldbrain/memex-common/lib/common-ui/components/highlightColorPicker/types' import type { InPageUIInterface } from 'src/in-page-ui/background/types' -import type { Storage } from 'webextension-polyfill' import type { PseudoSelection } from '@worldbrain/memex-common/lib/in-page-ui/types' import { cloneSelectionAsPseudoObject, @@ -125,6 +123,7 @@ import { } from '@worldbrain/memex-common/lib/subscriptions/constants' import type { RemoteSearchInterface } from 'src/search/background/types' import * as anchoring from '@worldbrain/memex-common/lib/annotations' +import type { TaskState } from 'ui-logic-core/lib/types' // Content Scripts are separate bundles of javascript code that can be loaded // on demand by the browser, as needed. This main function manages the initialisation @@ -578,7 +577,17 @@ export async function main( quality: 100, }) + let highlightCreateState: TaskState = 'pristine' + // Block nav away from current page while highlight being created + window.addEventListener('beforeunload', (e) => { + let shouldBlockUnload = highlightCreateState === 'running' + if (shouldBlockUnload) { + e.preventDefault() + } + }) + const annotationsFunctions = { + // TODO: Simplify and move this logic away from here createHighlight: ( analyticsEvent?: AnalyticsEvent<'Highlights'>, ) => async ( @@ -589,6 +598,7 @@ export async function main( highlightColorSetting?: HighlightColor, preventHideTooltip?: boolean, ) => { + highlightCreateState = 'running' let anchor: Anchor let quote: string @@ -603,6 +613,7 @@ export async function main( anchor = { quote, descriptor } } if (quote?.length === 0 && !drawRectangle) { + highlightCreateState = 'success' return } @@ -618,7 +629,7 @@ export async function main( sidebarEvents.emit('showPowerUpModal', { limitReachedNotif: 'Bookmarks', }) - + highlightCreateState = 'error' return } @@ -647,6 +658,7 @@ export async function main( screenshotGrabResult == null || screenshotGrabResult.anchor == null ) { + highlightCreateState = 'success' return } @@ -722,8 +734,10 @@ export async function main( } } + highlightCreateState = 'success' return annotationId }, + // TODO: Simplify and move this logic away from here createAnnotation: ( analyticsEvent?: AnalyticsEvent<'Annotations'>, ) => async ( @@ -734,8 +748,10 @@ export async function main( commentText?: string, highlightColorSetting?: HighlightColor, ) => { + highlightCreateState = 'running' const selectionEmpty = !selection?.toString().length if (selectionEmpty) { + highlightCreateState = 'success' return } @@ -761,6 +777,7 @@ export async function main( sidebarEvents.emit('showPowerUpModal', { limitReachedNotif: 'Bookmarks', }) + highlightCreateState = 'error' return } @@ -787,6 +804,7 @@ export async function main( screenshotGrabResult == null || screenshotGrabResult.anchor == null ) { + highlightCreateState = 'success' return } @@ -868,6 +886,7 @@ export async function main( ) } } + highlightCreateState = 'success' }, askAI: () => ( highlightedText: string, From d4e115040eb2e87fd524ff5e3719adffc30a6a28 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 May 2024 17:56:23 +0200 Subject: [PATCH 7/9] finally remove rendering glitches from inpage dashboard --- external/@worldbrain/memex-common | 2 +- src/dashboard-refactor/index.tsx | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/external/@worldbrain/memex-common b/external/@worldbrain/memex-common index 7c76fb7c7b..c9a77f55f2 160000 --- a/external/@worldbrain/memex-common +++ b/external/@worldbrain/memex-common @@ -1 +1 @@ -Subproject commit 7c76fb7c7b1df6395539f7070744b68aee868251 +Subproject commit c9a77f55f245a0a8709454e763c5eaa79c31a816 diff --git a/src/dashboard-refactor/index.tsx b/src/dashboard-refactor/index.tsx index 5fe70fc7f9..e563a3b836 100644 --- a/src/dashboard-refactor/index.tsx +++ b/src/dashboard-refactor/index.tsx @@ -2389,11 +2389,15 @@ const ListSidebarContent = styled(Rnd)<{ `} ${(props) => props.peeking && - css` + css` position: absolute height: max-content; - background-color: ${(props) => props.theme.colors.greyScale1}98; - backdrop-filter: blur(30px); + background-color: ${(props) => + props.inPageMode + ? props.theme.colors.greyScale1 + : props.theme.colors.greyScale1 + '98'}; + backdrop-filter: ${(props) => + props.inPageMode ? 'unset' : 'blur(30px)'}; //box-shadow: rgb(16 30 115 / 3%) 4px 0px 16px; margin-top: 50px; margin-bottom: 9px; From f3bf29e4316f3016fa6b2d673f9aa1915e999dd9 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 May 2024 17:56:54 +0200 Subject: [PATCH 8/9] bump version to 3.19.37 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f538772a7b..09839afc20 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "worldbrain-extension", - "version": "3.19.36", + "version": "3.19.37", "homepage": "https://memex.garden", "repository": "https://github.com/WorldBrain/Memex", "scripts": { From 7ef338c36821d9c0a0571d573a7d80091e5c15d8 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 30 May 2024 17:57:40 +0200 Subject: [PATCH 9/9] merge hotfix into master --- external/@worldbrain/memex-common | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/@worldbrain/memex-common b/external/@worldbrain/memex-common index c9a77f55f2..af3d29d3a9 160000 --- a/external/@worldbrain/memex-common +++ b/external/@worldbrain/memex-common @@ -1 +1 @@ -Subproject commit c9a77f55f245a0a8709454e763c5eaa79c31a816 +Subproject commit af3d29d3a956e9871ac18ac65e12ab2b285121c7