// Generated by bynkc — do not edit by hand.
// context demo.registry

import { Ok, Err, Some, None, type Result, type Option, type ValidationError } from "../runtime.js";

/**
 * A service whose `on call` takes more than one Bynk-declared argument. The deps
 * object is the *last* parameter, so `makeSurface` must derive its type from a
 * named `<Ctx>Deps` interface rather than a fixed `Parameters<>[1]` index (which
 * would resolve to the second real argument, `target`).
 */

export type Code = string & { readonly __brand: "demo.registry.Code" };

export const Code = {
  of(value: string): Result<Code, ValidationError> {
    if (!new RegExp("^" + "[a-z0-9]{3,8}" + "$").test(value)) {
      return Err({ field: "Code", message: "must match /[a-z0-9]{3,8}/", value });
    }
    return Ok(value as Code);
  },
  unsafe(value: string): Code {
    return value as Code;
  },
};

export type Target = string & { readonly __brand: "demo.registry.Target" };

export const Target = {
  of(value: string): Result<Target, ValidationError> {
    if (!new RegExp("^" + "https?://.+" + "$").test(value)) {
      return Err({ field: "Target", message: "must match /https?://.+/", value });
    }
    return Ok(value as Target);
  },
  unsafe(value: string): Target {
    return value as Target;
  },
};

export type RegError =
    { readonly tag: "Rejected" };

export const RegError = {
  Rejected: { tag: "Rejected" } as RegError,
};

export interface Clock {
  now(): Promise<number>;
}

export const ClockToken: unique symbol = Symbol("Clock");

export class SystemClock implements Clock {
  async now(): Promise<number> {
    return 0;
  }
}

export const SystemClockProvider = { token: ClockToken, factory: () => new SystemClock() };

export const create = {
  async call(code: Code, target: Target, deps: { Clock: Clock }): Promise<Result<number, RegError>> {
    const t = await deps.Clock.now();
    return Ok(t);
  },
};

export interface DemoRegistryDeps {
  readonly Clock: Clock;
}

export function makeSurface(deps: DemoRegistryDeps) {
  return {
    async create(code: Code, target: Target): Promise<Result<number, RegError>> {
      return create.call(code, target, deps);
    },
  };
}

