diff --git a/lib/kernel/src/ipc/in_process.dart b/lib/kernel/src/ipc/in_process.dart new file mode 100644 index 00000000..3c1d0c30 --- /dev/null +++ b/lib/kernel/src/ipc/in_process.dart @@ -0,0 +1,32 @@ +import 'package:clide/clide.dart'; +import 'package:clide/kernel/src/ipc/client.dart'; +import 'package:clide/kernel/src/events/bus.dart'; +import 'package:clide/kernel/src/log.dart'; +import 'package:clide/src/daemon/dispatcher.dart'; + +class InProcessClient extends DaemonClient { + InProcessClient({ + required Logger log, + required EventBus events, + required this.dispatcher, + }) : super(socketPath: '', log: log, events: events); + + final DaemonDispatcher dispatcher; + int _nextReqId = 0; + + @override + bool get isConnected => true; + + @override + Future start() async {} + + @override + Future stop() async {} + + @override + Future request(String cmd, {Map args = const {}}) { + final id = '${_nextReqId++}'; + final req = IpcRequest(id: id, cmd: cmd, args: args); + return dispatcher.dispatch(req); + } +} diff --git a/lib/main.dart b/lib/main.dart index 4a44f8c8..833274c0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -25,7 +25,19 @@ import 'package:clide/builtin/welcome/welcome.dart'; import 'dart:io' show Directory, Platform; import 'package:clide/kernel/kernel.dart'; +import 'package:clide/kernel/src/ipc/in_process.dart'; import 'package:clide/kernel/src/syntax/tree_sitter_ffi.dart'; +import 'package:clide/src/daemon/dispatcher.dart'; +import 'package:clide/src/daemon/editor_commands.dart'; +import 'package:clide/src/daemon/files_commands.dart'; +import 'package:clide/src/daemon/git_commands.dart'; +import 'package:clide/src/daemon/pane_commands.dart'; +import 'package:clide/src/daemon/pql_commands.dart'; +import 'package:clide/src/editor/registry.dart' show EditorRegistry; +import 'package:clide/src/panes/registry.dart'; +import 'package:clide/src/ipc/envelope.dart'; +import 'package:clide/src/panes/event_sink.dart'; +import 'package:clide/src/pql/client.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart' show rootBundle; import 'package:flutter/widgets.dart'; @@ -45,11 +57,22 @@ Future main() async { bundledThemes: themes, i18nLoader: AssetCatalogLoader(bundle: rootBundle), preloadNamespaces: _tier0Namespaces, - // The local unix-socket daemon is desktop-only. On web the - // connection indicator stays `disconnected` — that's the honest - // state: the Flutter-web build can't reach a local socket. - autoStartDaemonClient: !kIsWeb, - socketPath: kIsWeb ? '/clide-web-no-socket' : null, + autoStartDaemonClient: false, + daemonClientFactory: kIsWeb ? null : (log, events) { + final dispatcher = DaemonDispatcher(); + final eventSink = _BusEventSink(events); + final filesService = FilesService.atCwd(events: eventSink); + final workRoot = filesService.root; + final paneRegistry = PaneRegistry(events: eventSink); + registerPaneCommands(dispatcher, paneRegistry); + registerFilesCommands(dispatcher, filesService); + final editorRegistry = EditorRegistry(events: eventSink, workspaceRoot: workRoot); + registerEditorCommands(dispatcher, editorRegistry); + registerGitCommands(dispatcher, workRoot, eventSink); + final pql = PqlClient(workDir: workRoot); + registerPqlCommands(dispatcher, pql); + return InProcessClient(log: log, events: events, dispatcher: dispatcher); + }, ); // Register every built-in. Tier 0 activates only the four that do @@ -128,6 +151,21 @@ Future> _loadBundledThemes() async { /// Every Tier-0 extension that ships an i18n catalog. Extensions /// registered but not active (the 17 stubs) don't preload — their /// catalogs load lazily on activate in later tiers. +class _BusEventSink implements DaemonEventSink { + _BusEventSink(this._bus); + final EventBus _bus; + + @override + void emit(IpcEvent event) { + _bus.emit(DaemonEvent( + subsystem: event.subsystem, + kind: event.kind, + data: event.data, + ts: DateTime.now(), + )); + } +} + const List _tier0Namespaces = [ 'builtin.default-layout', 'builtin.welcome',