freedome_client

Pure-Dart client of the Freedome public API v1 (VM, Flutter, web). It talks to a Freedome media server; models come from freedome_protocol, which is re-exported.

  • FreedomeClient: REST plus realtime (plain WebSocket freedome.v1 by default, GraphQL over WebSocket, socket.io opt-in);
  • connection state machine with reconnect and resync, offline cache and outbox;
  • credentials: guest, password, pairing, API key, cloud;
  • repositories: venues, engine, calibration, playback, content (resumable uploads), OSC, audio (zones, devices, presets, sessions, generator), audio-reactive scenes and live analysis, gateways;
  • codecs: .dome, FDMESH warp meshes, .zelim, .boranko, .comics;
  • discovery and pairing links.

Entry points

Import Content
package:freedome_client/freedome_client.dart client, repositories, codecs (every platform)
package:freedome_client/io.dart file helpers, mDNS discovery (not on web)
package:freedome_client/account.dart account API of the cloud (FreedomeAccountClient)
package:freedome_client/socket_io.dart socket.io realtime transport (opt-in)
package:freedome_client/testing.dart FakeDomeServer, FakeAccountServer for your tests

Example

import 'dart:io';

import 'package:freedome_client/freedome_client.dart';

Future<void> main() async {
  final client = FreedomeClient(
    endpoint: FreedomeEndpoint.parse('http://dome.local:8080'),
    credentials: const PasswordCredentials('operator', 'secret'),
  );
  await client.open();
  final sub = client.playback.states.listen((s) => stdout.writeln(s));
  await client.playback.play(const PlayTarget.show('night-sky'));
  await Future<void>.delayed(const Duration(seconds: 5));
  await client.playback.stop();
  await sub.cancel();
  await client.close();
}

Live control (play, faders, generator) fails fast with OfflineException while the server cannot be reached and is never queued. Other writes can be queued through an OutboxStore.

Testing your app

FakeDomeServer runs the whole contract in memory, with injected faults (latency, failNext, dropRealtime, seqGap, bumpApiMajor, …), so the same code runs in unit and widget tests without sockets:

final fake = FakeDomeServer();
final client = FreedomeClient(endpoint: fake.endpoint, transports: fake.transports);

Flutter apps: freedome_flutter adds secure token storage, Bonjour discovery and lifecycle hooks. Administration: freedome_admin.

Licence

NativeMindNONC (see LICENSE). Commercial use requires a licence from NativeMind sales: freedome.nativemind.us/commercial.

Libraries

account
Cloud account API of freedome_server (L7, 02f §11.6): sign-up / sign-in (e-mail + password, magic link, Apple, Google), refresh, e-mail confirmation, password reset / change, profile, devices, account deletion. Feed its access JWT into a media-server client with CloudCredentials(account.accessToken).
freedome_client
Freedome client SDK (pure Dart: VM, Flutter, web; 02f §6).
io
dart:io helpers of freedome_client (VM / Flutter mobile + desktop, not web): .dome files and directories, file upload sources, mDNS discovery, TLS-pinned HTTP client.
socket_io
socket.io realtime for freedome_client — opt-in (02f §7.1, F9): for servers / proxies that only pass socket.io.
testing
Test doubles of a Freedome media server (02f §13): FakeDomeServer implements contract API v1 in memory — in-process (fake.transports, works in widget tests and on the web) or bound to a port with FakeDomeServer.bind (dart:io: REST, plain WS, GraphQL, socket.io /v1, optional mDNS). Never use in production code.