componentized/directory

componentized:valkey-sample-http-incrementor

component

Sample component that exposes wasi:http incrementing a counter based on the http path.

Imports

Exports

WIT

package root:component;

world root {
  import wasi:keyvalue/store@0.2.0-draft2;
  import wasi:keyvalue/atomics@0.2.0-draft2;
  import wasi:io/error@0.2.6;
  import wasi:io/streams@0.2.6;
  import wasi:http/types@0.2.6;

  export wasi:http/incoming-handler@0.2.6;
}
package wasi:keyvalue@0.2.0-draft2 {
  interface store {
    resource bucket;

    variant error {
      no-such-store,
      access-denied,
      other(string),
    }

    open: func(identifier: string) -> result<bucket, error>;
  }
  interface atomics {
    use store.{bucket, error};

    increment: func(bucket: borrow<bucket>, key: string, delta: s64) -> result<s64, error>;
  }
}


package wasi:io@0.2.6 {
  interface error {
    resource error;
  }
  interface streams {
    use error.{error};

    resource output-stream {
      blocking-write-and-flush: func(contents: list<u8>) -> result<_, stream-error>;
    }

    variant stream-error {
      last-operation-failed(error),
      closed,
    }
  }
}


package wasi:http@0.2.6 {
  interface types {
    use wasi:io/streams@0.2.6.{output-stream};

    resource fields {
      constructor();
    }

    resource incoming-request {
      path-with-query: func() -> option<string>;
    }

    resource response-outparam {
      set: static func(param: response-outparam, response: result<outgoing-response, error-code>);
    }

    resource outgoing-response {
      constructor(headers: headers);
      body: func() -> result<outgoing-body>;
    }

    record DNS-error-payload {
      rcode: option<string>,
      info-code: option<u16>,
    }

    record TLS-alert-received-payload {
      alert-id: option<u8>,
      alert-message: option<string>,
    }

    record field-size-payload {
      field-name: option<string>,
      field-size: option<u32>,
    }

    variant error-code {
      DNS-timeout,
      DNS-error(DNS-error-payload),
      destination-not-found,
      destination-unavailable,
      destination-IP-prohibited,
      destination-IP-unroutable,
      connection-refused,
      connection-terminated,
      connection-timeout,
      connection-read-timeout,
      connection-write-timeout,
      connection-limit-reached,
      TLS-protocol-error,
      TLS-certificate-error,
      TLS-alert-received(TLS-alert-received-payload),
      HTTP-request-denied,
      HTTP-request-length-required,
      HTTP-request-body-size(option<u64>),
      HTTP-request-method-invalid,
      HTTP-request-URI-invalid,
      HTTP-request-URI-too-long,
      HTTP-request-header-section-size(option<u32>),
      HTTP-request-header-size(option<field-size-payload>),
      HTTP-request-trailer-section-size(option<u32>),
      HTTP-request-trailer-size(field-size-payload),
      HTTP-response-incomplete,
      HTTP-response-header-section-size(option<u32>),
      HTTP-response-header-size(field-size-payload),
      HTTP-response-body-size(option<u64>),
      HTTP-response-trailer-section-size(option<u32>),
      HTTP-response-trailer-size(field-size-payload),
      HTTP-response-transfer-coding(option<string>),
      HTTP-response-content-coding(option<string>),
      HTTP-response-timeout,
      HTTP-upgrade-failed,
      HTTP-protocol-error,
      loop-detected,
      configuration-error,
      internal-error(option<string>),
    }

    type headers = fields;

    resource outgoing-body {
      write: func() -> result<output-stream>;
      finish: static func(this: outgoing-body, trailers: option<trailers>) -> result<_, error-code>;
    }

    type trailers = fields;
  }
  interface incoming-handler {
    use types.{incoming-request, response-outparam};

    handle: func(request: incoming-request, response-out: response-outparam);
  }
}