Skuld.Effects.Fresh (skuld v0.1.8)

View Source

Fresh effect - generate fresh/unique UUIDs.

Provides two handler modes:

  • Production (with_uuid7_handler/2): Generates v7 UUIDs which are time-ordered and suitable for database primary keys (good data locality, lexical ordering).

  • Test (with_test_handler/2): Generates deterministic v5 UUIDs based on a namespace and counter, making sequences reproducible for testing.

Production Usage

use Skuld.Syntax
alias Skuld.Comp
alias Skuld.Effects.Fresh

comp do
  id1 <- Fresh.fresh_uuid()
  id2 <- Fresh.fresh_uuid()
  return({id1, id2})
end
|> Fresh.with_uuid7_handler()
|> Comp.run!()
#=> {"01945a3b-...", "01945a3b-..."}  # time-ordered v7 UUIDs

Test Usage (Deterministic)

# Same namespace produces same UUID sequence - reproducible tests
namespace = Uniq.UUID.uuid4()

comp do
  uuid <- Fresh.fresh_uuid()
  return(uuid)
end
|> Fresh.with_test_handler(namespace: namespace)
|> Comp.run!()
#=> "550e8400-..."  # deterministic v5 UUID

# Running again with same namespace produces same result
comp do
  uuid <- Fresh.fresh_uuid()
  return(uuid)
end
|> Fresh.with_test_handler(namespace: namespace)
|> Comp.run!()
#=> "550e8400-..."  # same UUID!

Summary

Functions

Generate a fresh UUID.

Install a deterministic UUID handler for testing.

Install a v7 UUID handler for production use.

Functions

fresh_uuid()

@spec fresh_uuid() :: Skuld.Comp.Types.computation()

Generate a fresh UUID.

The UUID format depends on the installed handler:

  • with_uuid7_handler/2: Generates v7 UUIDs (time-ordered, production)
  • with_test_handler/2: Generates v5 UUIDs (deterministic, testing)

Example

comp do
  uuid1 <- Fresh.fresh_uuid()
  uuid2 <- Fresh.fresh_uuid()
  return({uuid1, uuid2})
end
|> Fresh.with_uuid7_handler()
|> Comp.run!()

with_test_handler(comp, opts \\ [])

Install a deterministic UUID handler for testing.

Generates reproducible UUIDs using UUID v5 (name-based, SHA-1) with a configured namespace and sequential counter. The same namespace always produces the same UUID sequence - ideal for testing.

Options

  • namespace - UUID namespace for generation (default: a fixed UUID). Can be a UUID string or one of the standard namespaces: :dns, :url, :oid, :x500, or nil.
  • output - optional function (result, final_counter) -> new_result to transform the result before returning.

Example

namespace = Uniq.UUID.uuid4()

# First run
uuid1 = comp do
  uuid <- Fresh.fresh_uuid()
  return(uuid)
end
|> Fresh.with_test_handler(namespace: namespace)
|> Comp.run!()

# Second run - same result!
uuid2 = comp do
  uuid <- Fresh.fresh_uuid()
  return(uuid)
end
|> Fresh.with_test_handler(namespace: namespace)
|> Comp.run!()

uuid1 == uuid2  #=> true

with_uuid7_handler(comp)

Install a v7 UUID handler for production use.

Generates time-ordered UUIDs using UUID v7 (RFC 9562). These UUIDs:

  • Are time-ordered (lexically sortable by creation time)
  • Have excellent database index locality
  • Are suitable for distributed systems

Example

comp do
  id <- Fresh.fresh_uuid()
  return(id)
end
|> Fresh.with_uuid7_handler()
|> Comp.run!()
#=> "01945a3b-7c9d-7000-8000-..."  # v7 UUID