Skip to content

Type, document, and refactor Sync, port tests to Mocha #1331

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 47 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
e3f80ef
WIP docs, async
raucao Jun 4, 2025
2c97b61
Speed up specs, clear localStorage where used
raucao Jun 5, 2025
60373af
Use setItem for localStorage
raucao Jun 5, 2025
0a3cfd2
Use null value instead of relying on parse exception
raucao Jun 5, 2025
de9cce4
WIP Port Sync tests to Mocha
raucao Jun 4, 2025
e5c5f77
Use correct type for RS class in Sync, fix type errors
raucao Jun 5, 2025
3fad53a
WIP Types
raucao Jun 5, 2025
c1494b6
Remove unused argument and code path
raucao Jun 5, 2025
b22dc59
WIP docs, async
raucao Jun 5, 2025
70b352b
Rename sync setup functions for clarity
raucao Jun 5, 2025
afaa82a
Refactor, document doTasks; port tests for sync()
raucao Jun 6, 2025
8733e23
Refactor, document task collect functions; port tests
raucao Jun 6, 2025
2498392
Use Object.keys
raucao Jun 6, 2025
1c596c5
No explicitly public functions if not used outside of class
raucao Jun 6, 2025
f9e307f
Port more tests
raucao Jun 6, 2025
4724fcb
Types and docs for Sync
raucao Jun 6, 2025
823e28f
Formatting
raucao Jun 6, 2025
f50278d
Add 'sync-started' event
raucao Jun 6, 2025
c6ea79c
Finish porting sync tests
raucao Jun 6, 2025
a60d5bd
Refactor finishTask
raucao Jun 7, 2025
26cb53c
Remove "legacy nodes" entirely
raucao Jun 7, 2025
004f607
More types and docs for Sync
raucao Jun 7, 2025
39e06d6
Use async/await
raucao Jun 8, 2025
ad636f9
Refactor handleGetResponse
raucao Jun 8, 2025
119f384
More types and docs for Sync
raucao Jun 8, 2025
0bf6ef6
Refactor autoMerge
raucao Jun 8, 2025
57b6054
Improve function name
raucao Jun 8, 2025
9f38689
Add comment
raucao Jun 9, 2025
8905c26
Document function
raucao Jun 9, 2025
77aa057
Remove unused static property
raucao Jun 9, 2025
95d06aa
Clean up access and caching initialization
raucao Jun 9, 2025
e704370
Don't log full error for Sync errors
raucao Jun 9, 2025
8e3bb27
Partially revert 95d06aa3
raucao Jun 9, 2025
deb348c
Broadcast change events to other tabs
raucao Jun 9, 2025
305b19e
Refactor permissions for FakeAccess
raucao Jun 9, 2025
07407d4
Merge pull request #1334 from remotestorage/feature/1137-window_event…
raucao Jun 12, 2025
1a8d3f9
Types
raucao Jun 13, 2025
4ee3431
Add tests for merging nodes with empty bodies
raucao Jun 13, 2025
ebcb9e1
Fix handling of empty nodes
raucao Jun 13, 2025
5c1dac7
Re-enable all tests
raucao Jun 13, 2025
c561870
Fix cached documents not being fully deleted in Anonymous Mode
raucao Jun 13, 2025
0482c78
Remove unnecessary context for event handler calls
raucao Jun 16, 2025
16fbeb4
Emit conflict events asynchronously
raucao Jun 16, 2025
fb6bba8
Use async/await
raucao Jun 18, 2025
098962d
Fix local itemsMap being inconsistent after changes on both ends
raucao Jun 18, 2025
d04f334
Do not emit conflict events for mutual deletions
raucao Jun 18, 2025
6afc445
Always emit `sync-done` when done
raucao Jun 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ module.exports = {
],
"overrides": [
{
"files": ["*.test.ts"],
"files": ["*.test.mjs"],
"rules": {
"max-statements": 0,
"@typescript-eslint/no-empty-function": 0,
Expand Down
9 changes: 4 additions & 5 deletions src/access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ export class Access {
rootPaths: string[];
storageType: string;

// TODO create custom type for init function
static _rs_init(): void {
return;
}

constructor() {
this.reset();
}
Expand Down Expand Up @@ -197,6 +192,10 @@ export class Access {
setStorageType (type: string): void {
this.storageType = type;
}

static _rs_init(): void {
return;
}
}

export default Access;
2 changes: 1 addition & 1 deletion src/authorize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type RemoteStorage from './remotestorage';
import log from './log';
import RemoteStorage from './remotestorage';
import { localStorageAvailable, globalContext, toBase64 } from './util';
import UnauthorizedError from './unauthorized-error';
import { EventHandler } from './eventhandling';
Expand Down
30 changes: 12 additions & 18 deletions src/baseclient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import tv4 from 'tv4';
import type RemoteStorage from './remotestorage';
import type { JsonSchemas } from './interfaces/json_schema';
import type { ChangeObj } from './interfaces/change_obj';
import type { QueuedRequestResponse } from './interfaces/queued_request_response';
Expand All @@ -7,7 +8,6 @@ import SchemaNotFound from './schema-not-found-error';
import EventHandling from './eventhandling';
import config from './config';
import { applyMixins, cleanPath, isFolder } from './util';
import RemoteStorage from './remotestorage';

function getModuleNameFromBase(path: string): string {
const parts = path.split('/');
Expand Down Expand Up @@ -147,8 +147,8 @@ function getModuleNameFromBase(path: string): string {
* during sync.
*
* > [!NOTE]
* > Automatically receiving remote changes depends on the {@link caching!Caching} settings
* > for your module/paths.
* > Automatically receiving remote changes depends on the
* > {@link caching!Caching caching} settings for your module/paths.
*
* ### `window`
*
Expand Down Expand Up @@ -180,13 +180,13 @@ function getModuleNameFromBase(path: string): string {
* }
* ```
*
* But when this change is pushed out by asynchronous synchronization, this change
* may be rejected by the server, if the remote version has in the meantime changed
* from `white` to for instance `red`; this will then lead to a change event with
* origin `conflict` (usually a few seconds after the event with origin `window`,
* if you have those activated). Note that since you already changed it from
* `white` to `blue` in the local version a few seconds ago, `oldValue` is now
* your local value of `blue`:
* However, when this change is pushed out by the sync process, it will be
* rejected by the server, if the remote version has changed in the meantime,
* for example from `white` to `red`. This will lead to a change event with
* origin `conflict`, usually a few seconds after the event with origin
* `window`. Note that since you already changed it from `white` to `blue` in
* the local version a few seconds ago, `oldValue` is now your local value of
* `blue`:
*
* ```js
* {
Expand All @@ -212,11 +212,6 @@ function getModuleNameFromBase(path: string): string {
*
* If there is an algorithm to merge the differences between local and remote
* versions of the data, conflicts may be automatically resolved.
* {@link storeObject} or {@link storeFile} must not be called synchronously from
* the change event handler, nor by chaining Promises. {@link storeObject} or
* {@link storeFile} must not be called until the next iteration of the JavaScript
* Task Queue, using for example
* [`setTimeout()`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout).
*
* If no algorithm exists, conflict resolution typically involves displaying local
* and remote versions to the user, and having the user merge them, or choose
Expand Down Expand Up @@ -624,17 +619,16 @@ export class BaseClient {
* @example
* client.remove('path/to/object').then(() => console.log('item deleted'));
*/
// TODO add real return type
// TODO Don't return the RemoteResponse directly, handle response properly
remove (path: string): Promise<unknown> {
async remove (path: string): Promise<QueuedRequestResponse> {
if (typeof path !== 'string') {
return Promise.reject('Argument \'path\' of baseClient.remove must be a string');
}
if (!this.storage.access.checkPathPermission(this.makePath(path), 'rw')) {
console.warn('WARNING: Removing a document to which only read access (\'r\') was claimed');
}

return this.storage.delete(this.makePath(path));
return this.storage.delete(this.makePath(path), this.storage.connected);
}

/**
Expand Down
Loading