# AsyncNamespace

    public struct AsyncNamespace

Swift concurrency for the `DataStack` are exposed through this namespace. Extend this type if you need to add other `async` utilities for `DataStack`.

### Public

- `base`

  The `DataStack` instance

  #### Declaration

  Swift

      public let base: DataStack

- `addStorage(_:)` Asynchronous

  Swift concurrency extension for `CoreStore.DataStack`‘s `addStorage(...)` API. Asynchronously adds a `StorageInterface` to the stack.

      let storage = try await dataStack.async.addStorage(
          InMemoryStore(configuration: "Config1")
      )

  Throws

  A `CoreStoreError` value indicating the failure reason

  #### Declaration

  Swift

      public func addStorage<T: StorageInterface>(
          _ storage: T
      ) async throws -> T

  #### Parameters

  `storage` | the storage

  #### Return Value

  The `StorageInterface` instance added to the `DataStack`. Note that the `StorageInterface` event value may not always be the same instance as the parameter argument if a previous `StorageInterface` was already added at the same URL and with the same configuration.

- `addStorage(_:)`

  Swift concurrency extension for `CoreStore.DataStack`‘s `addStorage(...)` API. Asynchronously adds a `LocalStorage` to the stack. Migrations are also initiated by default. The event emits `MigrationProgress` `enum` values.

      for try await migrationProgress in dataStack.async.addStorage(
          SQLiteStore(
              fileName: "core_data.sqlite",
              configuration: "Config1"
          )
      ) {

          print("\(round(migrationProgress.fractionCompleted * 100)) %") // 0.0 ~ 1.0
      }

  Throws

  A `CoreStoreError` value indicating the failure reason

  #### Declaration

  Swift

      public func addStorage<T>(
          _ storage: T
      ) -> AsyncThrowingStream<MigrationProgress<T>, Swift.Error>

  #### Parameters

  `storage` | the local storage

  #### Return Value

  An `AsyncThrowingStream` that emits a `MigrationProgress` value with metadata for migration progress. Note that the `LocalStorage` event value may not always be the same instance as the parameter argument if a previous `LocalStorage` was already added at the same URL and with the same configuration.

- `importObject(_:source:)` Asynchronous

  Swift concurrency extension for `CoreStore.DataStack`‘s `importObject(...)` API. Creates an `ImportableObject` by importing from the specified import source. The event value will be the object instance correctly associated for the `DataStack`.

      let object = try await dataStack.async.importObject(
          Into<Person>(),
          source: ["name": "John"]
      )

  Throws

  A `CoreStoreError` value indicating the failure reason

  #### Declaration

  Swift

      public func importObject<O: DynamicObject & ImportableObject>(
          _ into: Into<O>,
          source: O.ImportSource
      ) async throws -> O?

  #### Parameters

  `into` | an `Into` clause specifying the entity type
  `source` | the object to import values from

  #### Return Value

  The object instance correctly associated for the `DataStack` if the object was imported successfully, or `nil` if the `ImportableObject` ignored the `source`.

- `importObject(_:source:)` Asynchronous

  Swift concurrency extension for `CoreStore.DataStack`‘s `importObject(...)` API. Updates an existing `ImportableObject` by importing values from the specified import source. The event value will be the object instance correctly associated for the `DataStack`.

      let importedPerson = try await dataStack.async.importObject(
          existingPerson,
          source: ["name": "John", "age": 30]
      )

  Throws

  A `CoreStoreError` value indicating the failure reason

  #### Declaration

  Swift

      public func importObject<O: DynamicObject & ImportableObject>(
          _ object: O,
          source: O.ImportSource
      ) async throws -> O?

  #### Parameters

  `object` | the object to update
  `source` | the object to import values from

  #### Return Value

  The object instance correctly associated for the `DataStack` if the object was imported successfully, or `nil` if the `ImportableObject` ignored the `source`.

- `importUniqueObject(_:source:)` Asynchronous

  Swift concurrency extension for `CoreStore.DataStack`‘s `importUniqueObject(...)` API. Updates an existing `ImportableUniqueObject` or creates a new instance by importing from the specified import source. The event value will be the object instance correctly associated for the `DataStack`.

      let person = try await dataStack.async.importUniqueObject(
          Into<Person>(),
          source: ["name": "John", "age": 30]
      )

  Throws

  A `CoreStoreError` value indicating the failure reason

  #### Declaration

  Swift

      public func importUniqueObject<O: DynamicObject & ImportableUniqueObject>(
          _ into: Into<O>,
          source: O.ImportSource
      ) async throws -> O?

  #### Parameters

  `into` | an `Into` clause specifying the entity type
  `source` | the object to import values from

  #### Return Value

  The object instance correctly associated for the `DataStack` if the object was imported successfully, or `nil` if the `ImportableUniqueObject` ignored the `source`.

- `importUniqueObjects(_:sourceArray:preProcess:)` Asynchronous

  Swift concurrency extension for `CoreStore.DataStack`‘s `importUniqueObjects(...)` API. Updates existing `ImportableUniqueObject`s or creates them by importing from the specified array of import sources. `ImportableUniqueObject` methods are called on the objects in the same order as they are in the `sourceArray`, and are returned in an array with that same order. The event values will be object instances correctly associated for the `DataStack`.

      let people = try await dataStack.async.importUniqueObjects(
          Into<Person>(),
          sourceArray: [
              ["name": "John"],
              ["name": "Bob"],
              ["name": "Joe"]
          ]
      )

  Warning

  If `sourceArray` contains multiple import sources with same ID, no merging will occur and ONLY THE LAST duplicate will be imported.

  Throws

  A `CoreStoreError` value indicating the failure reason

  #### Declaration

  Swift

      public func importUniqueObjects<O: DynamicObject & ImportableUniqueObject, S: Sequence>(
          _ into: Into<O>,
          sourceArray: S,
          preProcess: @escaping (_ mapping: [O.UniqueIDType: O.ImportSource]) throws -> [O.UniqueIDType: O.ImportSource] = { $0 }
      ) async throws -> [O]
      where S.Iterator.Element == O.ImportSource

  #### Parameters

  `into` | an `Into` clause specifying the entity type
  `sourceArray` | the array of objects to import values from
  `preProcess` | a closure that lets the caller tweak the internal `UniqueIDType`-to-`ImportSource` mapping to be used for importing. Callers can remove from/add to/update `mapping` and return the updated array from the closure.

  #### Return Value

  The imported objects correctly associated for the `DataStack`.

- `perform(_:)` Asynchronous

  Swift concurrency extension for `CoreStore.DataStack`‘s `perform(asynchronous:...)` API. Performs a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. The event value will be the value returned from the `task` closure. Any errors thrown from inside the `task` will be wrapped in a `CoreStoreError` before being thrown from the `async` method. To cancel/rollback changes, call `transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.

      let result = try await dataStack.async.perform(
          asynchronous: { (transaction) -> (inserted: Set<NSManagedObject>, deleted: Set<NSManagedObject>) in

              // ...
              return (
                  transaction.insertedObjects(),
                  transaction.deletedObjects()
              )
          }
      )
      let inserted = dataStack.fetchExisting(result.inserted)
      let deleted = dataStack.fetchExisting(result.deleted)

  Throws

  A `CoreStoreError` value indicating the failure reason

  #### Declaration

  Swift

      public func perform<Output>(
          _ asynchronous: @escaping (AsynchronousDataTransaction) throws -> Output
      ) async throws -> Output

  #### Parameters

  `task` | the asynchronous closure where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.

  #### Return Value

  The value returned from the `task` closure.