1/**
2 * The `DeliverAt` module defines the protocol used by cluster message payloads
3 * that carry their own scheduled delivery time. A value implements the protocol
4 * by exposing a method at the `DeliverAt` symbol that returns the target
5 * `DateTime`.
6 *
7 * @stability unstable
8 * @since 4.0.0
9 */
10import type { DateTime } from "../DateTime.ts"
11import { hasProperty } from "../Predicate.ts"
12
13/**
14 * Defines the property key used by values that provide a scheduled delivery time.
15 *
16 * **When to use**
17 *
18 * Use to implement the scheduled-delivery protocol on cluster message payloads
19 * by defining a method at this property key.
20 *
21 * @stability unstable
22 * @category symbols
23 * @since 4.0.0
24 */
25export const symbol = "~effect/cluster/DeliverAt"
26
27/**
28 * Interface for payloads that specify when a cluster message should be delivered
29 * by returning the target delivery `DateTime` through the `DeliverAt` symbol
30 * method.
31 *
32 * @stability unstable
33 * @category models
34 * @since 4.0.0
35 */
36export interface DeliverAt {
37 [symbol](): DateTime
38}
39
40/**
41 * Returns `true` if the value implements the `DeliverAt` scheduled-delivery
42 * protocol.
43 *
44 * @stability unstable
45 * @category guards
46 * @since 4.0.0
47 */
48export const isDeliverAt = (self: unknown): self is DeliverAt => hasProperty(self, symbol)
49
50/**
51 * Returns the scheduled delivery time in epoch milliseconds when the value
52 * implements `DeliverAt`, or `null` otherwise.
53 *
54 * @stability unstable
55 * @category accessors
56 * @since 4.0.0
57 */
58export const toMillis = (self: unknown): number | null => {
59 if (isDeliverAt(self)) {
60 return self[symbol]().epochMilliseconds
61 }
62 return null
63}