Files
archify-vscode-ext/src/sync/loader.ts
root-at-skic 9ccd67b2dd 0.10.1: Archify Sync in the status bar, server address as a setting
In workspaces with Archify files, Archify Sync sits in the status bar and
opens a menu: sign in, share, join, server address, settings. The new
archify.sync.server setting (empty by default) is used without asking,
and in workspace settings gives a project one server.
archify.sync.statusBar hides the entry.
2026-11-06 23:21:56 +02:00

75 lines
3.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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',
'archify.sync.setServer',
] 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;
// Until the sync bundle loads, this entry is the way in; then the bundle's own one takes over.
const entry = vscode.window.createStatusBarItem('archify.sync', vscode.StatusBarAlignment.Left, 50);
entry.name = 'Archify Sync';
entry.text = '$(cloud) Archify Sync';
entry.tooltip = 'Archify Sync (optional): sign in, share a model with others or join one. Set the server under Settings › Archify › Sync.';
entry.command = 'archify.sync.menu';
// Only where there are Archify files: the extension also starts for JSON and HTML.
let archifyHere = false;
const showEntry = () => {
const wanted = archifyHere && !feature && vscode.workspace.getConfiguration('archify.sync').get<boolean>('statusBar', true);
if (wanted) entry.show();
else entry.hide();
};
void Promise.resolve(vscode.workspace.findFiles('**/*.{archify,archify-registry,archify-decision}', '{**/node_modules/**,**/.git/**}', 1)).then((found) => {
archifyHere = found.length > 0;
showEntry();
});
const load = (): Promise<SyncFeature> =>
(feature ??= (async () => {
showEntry();
// 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 [
entry,
vscode.workspace.onDidChangeConfiguration((e) => e.affectsConfiguration('archify.sync.statusBar') && showEntry()),
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) }),
];
}