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

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

/**
 * A fresh `Meter` key reads a nested record of zeros: every field of a zeroable
 * record zero-initialises recursively.
 */

export type MeterId = string & { readonly __brand: "demo.meter.MeterId" };

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

export interface Totals {
  readonly hits: number;
  readonly bytes: number;
}

export const Totals = {
};

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

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

export interface MeterState {
  readonly totals: Totals;
  readonly active: boolean;
}

const __MeterRegistry = new StateRegistry();
function __zeroOfMeterState(): MeterState { return { totals: { hits: 0, bytes: 0 }, active: false }; }

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

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

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

  async hits(deps: {}): Promise<Result<number, MeterError>> {
    const currentState = await this.loadState();
    return Ok(currentState.totals.hits);
  }

}

export function __makeMeter(key: MeterId, env?: { METER?: DurableObjectNamespace }): Meter {
  return makeAgent(__MeterRegistry, env?.METER, key, (state) => new Meter(state));
}

export const hits = {
  async call(id: MeterId, deps: {}): Promise<Result<number, MeterError>> {
    const meter = __makeMeter(id);
    const total = await meter.hits(deps);
    return total;
  },
};

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

export interface DemoMeterDeps {
}

export function makeSurface(deps: DemoMeterDeps) {
  return {
    async hits(id: MeterId): Promise<Result<number, MeterError>> {
      return hits.call(id, deps);
    },
  };
}

