open static method

Future<CRDTReplica> open({
  1. required String documentId,
  2. FutureOr<CRDTStorageBackend> storage()?,
  3. CRDTSocketClient sync(
    1. CRDTDocument document
    )?,
  4. void onDocument(
    1. CRDTDocument document
    )?,
  5. void onStorageError(
    1. Object error,
    2. StackTrace stack
    )?,
  6. bool ownsStorage = true,
})

Opens documentId on this device and starts to sync it.

Completes once the local copy is ready, without waiting for the network. Follow the connection on client.

Leave storage null to keep the document in memory, and sync null to keep it on this device. onDocument runs on the new document before the restore, as on CRDTStorageBackendDocuments.openDocument.

onStorageError gets every storage error. When the storage fails to open or to restore, the document starts empty and in memory, and persistence is null. onDocument then runs a second time, on that document. Without onStorageError that error is rethrown. An error thrown by onDocument is always rethrown.

ownsStorage says whether close also closes the backend. When sync throws, what was opened is closed and the error is rethrown.

Implementation

static Future<CRDTReplica> open({
  required String documentId,
  FutureOr<CRDTStorageBackend> Function()? storage,
  CRDTSocketClient Function(CRDTDocument document)? sync,
  void Function(CRDTDocument document)? onDocument,
  void Function(Object error, StackTrace stack)? onStorageError,
  bool ownsStorage = true,
}) async {
  final local = await _openLocal(
    documentId: documentId,
    storage: storage,
    onDocument: onDocument,
    onStorageError: onStorageError,
    ownsStorage: ownsStorage,
  );

  final CRDTSocketClient? client;
  try {
    client = sync?.call(local.document);
  } catch (_) {
    await _release(
      local.document,
      local.persistence,
      local.backend,
      ownsStorage: ownsStorage,
    );
    rethrow;
  }

  final replica = CRDTReplica._(
    document: local.document,
    client: client,
    persistence: local.persistence,
    backend: local.backend,
    ownsStorage: ownsStorage,
  );
  // Not awaited: the local copy is usable now, and a handshake can take as
  // long as the network does.
  if (client != null) {
    unawaited(client.connect());
  }
  return replica;
}