0.10.0: Archify Sync, optional live collaboration on a model
Several people edit one model at once through a server you run yourself (archify-vscode-ext-sync); the files stay ordinary files on each disk. Sign-in through the browser, offline-first with later merge, teammates' cursors in the Source view and text editors, and a Shared section on the model page with people, versions, Compare and Restore. Without a server nothing changes: the sync code is a separate bundle that loads only when a model is shared, after a sign-in, or when a sync command or invite link is used.
This commit is contained in:
1 parent
a9021312b0
commit
c99f3e5fe8
27 files changed
+2899
-14
No files matched your search
@@ -0,0 +1,53 @@
|
||||
import * as path from 'node:path';
|
||||
import * as vscode from 'vscode';
|
||||
import type { ModelService } from '../model/service';
|
||||
import { log } from '../util/log';
|
||||
import type { SyncFeature } from './index';
|
||||
import { liveBridge } from './liveBridge';
|
||||
|
||||
// Kept in step with SYNC_COMMANDS in ./index (which lives in the other bundle).
|
||||
const COMMANDS = [
|
||||
'archify.sync.signIn',
|
||||
'archify.sync.signOut',
|
||||
'archify.sync.share',
|
||||
'archify.sync.invite',
|
||||
'archify.sync.join',
|
||||
'archify.sync.publish',
|
||||
'archify.sync.versions',
|
||||
'archify.sync.stop',
|
||||
'archify.sync.menu',
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Archify Sync is optional. This registers its commands and the URI handler,
|
||||
* and loads dist/sync.js (Yjs, the WebSocket) only when it is needed: a model
|
||||
* in the workspace is shared, someone signed in on this machine, or a sync
|
||||
* command or link runs. Without that, nothing else happens.
|
||||
*/
|
||||
export function registerSync(context: vscode.ExtensionContext, models: ModelService): vscode.Disposable[] {
|
||||
let feature: Promise<SyncFeature> | undefined;
|
||||
const load = (): Promise<SyncFeature> =>
|
||||
(feature ??= (async () => {
|
||||
// A runtime path, so esbuild leaves the sync bundle out of this one.
|
||||
const bundle = path.join(__dirname, 'sync.js');
|
||||
const mod = require(bundle) as typeof import('./index');
|
||||
const sync = new mod.SyncFeature(context, models, log(), liveBridge);
|
||||
context.subscriptions.push(sync);
|
||||
await sync.start();
|
||||
return sync;
|
||||
})());
|
||||
|
||||
void (async () => {
|
||||
const used = context.globalState.get<boolean>('archifySync.used') === true;
|
||||
const shared = used || (await vscode.workspace.findFiles('**/.archify-sync', '{**/node_modules/**,**/.git/**}', 1)).length > 0;
|
||||
if (shared) load().catch((error) => log().error(`sync: did not start: ${String(error)}`));
|
||||
})();
|
||||
|
||||
return [
|
||||
liveBridge,
|
||||
...COMMANDS.map((id) =>
|
||||
vscode.commands.registerCommand(id, async (...args: unknown[]) => (await load()).run(id, ...args)),
|
||||
),
|
||||
vscode.window.registerUriHandler({ handleUri: async (uri) => (await load()).handleUri(uri) }),
|
||||
];
|
||||
}
|
||||
Reference in new issue
Block a user