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

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

/**
 * A fresh `Tally` key must read `count == 0`: Int state zero-initialises.
 */

export type TallyId = string & { readonly __brand: "demo.tally.TallyId" };

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

export type TallyError =
    { readonly tag: "Missing" };

export const TallyError = {
  Missing: { tag: "Missing" } as TallyError,
};

export interface TallyState {
  readonly count: number;
}

const __TallyRegistry = new StateRegistry();
function __zeroOfTallyState(): TallyState { return { count: 0 }; }

export class Tally {
  state: DurableObjectState;
  constructor(state: DurableObjectState) {
    this.state = state;
  }

  private async loadState(): Promise<TallyState> {
    const stored = await this.state.storage.get<TallyState>("state");
    return stored ?? __zeroOfTallyState();
  }

  private async commitState(s: TallyState): Promise<void> {
    await this.state.storage.put("state", s);
  }

  async current(deps: {}): Promise<Result<number, TallyError>> {
    const currentState = await this.loadState();
    return Ok(currentState.count);
  }

}

export function __makeTally(key: TallyId, env?: { TALLY?: DurableObjectNamespace }): Tally {
  return makeAgent(__TallyRegistry, env?.TALLY, key, (state) => new Tally(state));
}

export const read = {
  async call(id: TallyId, deps: {}): Promise<Result<number, TallyError>> {
    const tally = __makeTally(id);
    const total = await tally.current(deps);
    return total;
  },
};

export function __resetAgents(): void {
  __TallyRegistry.reset();
}

export interface DemoTallyDeps {
}

export function makeSurface(deps: DemoTallyDeps) {
  return {
    async read(id: TallyId): Promise<Result<number, TallyError>> {
      return read.call(id, deps);
    },
  };
}

