fix(ios): ios local access limit for self-hosted workspace (#15338)
## Summary - Route iOS nbstore worker token reads through the main-thread MessagePort and skip Capacitor Auth on `/socket.io` polling so self-host WebSocket/XHR sync no longer hangs on Connect timeout. - Harden workspace `flavour:id` routing, DocSyncPeer abort/status handling, and `resetSync` so local selfhost edits push and Mac browsers can receive them. - Soften root-doc readiness waits and session-exchange throttling to keep mobile selfhost sign-in/sync stable under retries. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **New Features** * Improved workspace switching across local and remote environments, preserving workspace type and server context. * Added support for page navigation with query parameters. * Added iOS local-network permission messaging for self-hosted workspaces. * **Bug Fixes** * Improved document synchronization, reset handling, prioritized document refreshes, and retry behavior. * Prevented authentication headers and refresh attempts for socket connection requests. * Improved workspace reopening and routing when multiple workspace types share an ID. * Fixed handling of unlimited data query limits. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: DarkSky <darksky2048@gmail.com>
This commit is contained in:
1 parent
b530198a3b
commit
cd6593c659
15 files changed
+448
-78
No files matched your search
@@ -113,6 +113,12 @@ class TestDocStorage implements DocStorage {
|
||||
}
|
||||
}
|
||||
|
||||
class TimestampBlindDocStorage extends IndexedDBDocStorage {
|
||||
override async getDocTimestamps(): Promise<DocClocks> {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
class PermissionDeniedRemoteDocStorage implements DocStorage {
|
||||
readonly storageType = 'doc' as const;
|
||||
readonly connection = new DummyConnection();
|
||||
@@ -306,7 +312,7 @@ test('doc', async () => {
|
||||
type: 'workspace',
|
||||
});
|
||||
|
||||
const peerBDoc = new IndexedDBDocStorage({
|
||||
const peerBDoc = new TimestampBlindDocStorage({
|
||||
id: 'ws1',
|
||||
flavour: 'b',
|
||||
type: 'workspace',
|
||||
@@ -340,6 +346,26 @@ test('doc', async () => {
|
||||
docId: 'doc1',
|
||||
bin: update,
|
||||
});
|
||||
const prioritizedDocId = 'prioritized-doc';
|
||||
const localPrioritizedDoc = new YDoc();
|
||||
localPrioritizedDoc.getMap('test').set('local', true);
|
||||
const localPrioritizedClock = await peerA.get('doc').pushDocUpdate({
|
||||
docId: prioritizedDocId,
|
||||
bin: encodeStateAsUpdate(localPrioritizedDoc),
|
||||
});
|
||||
await peerASync.setPeerPushedClock('b', localPrioritizedClock);
|
||||
const remotePrioritizedDoc = new YDoc();
|
||||
remotePrioritizedDoc.getMap('test').set('remote', true);
|
||||
await peerB.get('doc').pushDocUpdate({
|
||||
docId: prioritizedDocId,
|
||||
bin: encodeStateAsUpdate(remotePrioritizedDoc),
|
||||
});
|
||||
const rootDoc = new YDoc();
|
||||
rootDoc.getMap('meta').set('name', 'Self-host workspace');
|
||||
await peerB.get('doc').pushDocUpdate({
|
||||
docId: 'ws1',
|
||||
bin: encodeStateAsUpdate(rootDoc),
|
||||
});
|
||||
|
||||
const sync = new Sync({
|
||||
local: peerA,
|
||||
@@ -348,6 +374,7 @@ test('doc', async () => {
|
||||
c: peerC,
|
||||
},
|
||||
});
|
||||
const removeRootPriority = sync.doc.addPriority('ws1', 100);
|
||||
sync.start();
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
@@ -366,8 +393,33 @@ test('doc', async () => {
|
||||
hello: 'world',
|
||||
},
|
||||
});
|
||||
|
||||
const root = await peerA.get('doc').getDoc('ws1');
|
||||
expectYjsEqual(root!.bin, {
|
||||
meta: {
|
||||
name: 'Self-host workspace',
|
||||
},
|
||||
});
|
||||
|
||||
const prioritized = await peerA.get('doc').getDoc(prioritizedDocId);
|
||||
expectYjsEqual(prioritized!.bin, {
|
||||
test: {
|
||||
local: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const removeDocPriority = sync.doc.addPriority(prioritizedDocId, 100);
|
||||
await vi.waitFor(async () => {
|
||||
const prioritized = await peerA.get('doc').getDoc(prioritizedDocId);
|
||||
expectYjsEqual(prioritized!.bin, {
|
||||
test: {
|
||||
local: true,
|
||||
remote: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
doc.getMap('test').set('foo', 'bar');
|
||||
const update2 = encodeStateAsUpdate(doc);
|
||||
await peerC.get('doc').pushDocUpdate({
|
||||
@@ -394,6 +446,13 @@ test('doc', async () => {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
removeDocPriority();
|
||||
removeRootPriority();
|
||||
sync.stop();
|
||||
peerA.disconnect();
|
||||
peerB.disconnect();
|
||||
peerC.disconnect();
|
||||
});
|
||||
|
||||
test('blob', async () => {
|
||||
|
||||
Reference in new issue
Block a user