Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .codacy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
exclude_paths:
- "docs/reference/**"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ vendor/*
dist/*
build/*
TySug
docs/sourcey/node_modules/
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ Currently, it's a fairly naive approach and not (yet) backed by ML.

# Using TySug

The generated [Go API reference](https://tysug.net/docs/reference/) covers the
library, web service, keyboard models, and runnable examples directly from the
current source tree.

You can use TySug as stand-alone webservice to match against a known-list. If you have Docker you'll have it up and running in a few minutes.

## TL;DR
Expand Down
Binary file added docs/reference/_og/index.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reference/_og/pkg-cmd-web.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reference/_og/pkg-finder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reference/_og/pkg-internal-rwc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reference/_og/pkg-keyboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reference/_og/pkg-server-service.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reference/_og/pkg-server.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions docs/reference/index.html

Large diffs are not rendered by default.

61 changes: 61 additions & 0 deletions docs/reference/llms-full.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# TySug

github.com/Dynom/TySug/cmd/web

## Go API

### cmd/web

Path: `/docs/reference/pkg-cmd-web.html`

github.com/Dynom/TySug/cmd/web

import "github.com/Dynom/TySug/cmd/web" Index Variables Types type Config Variables Version contains the app version, the value is changed during compile time to the appropriate Git tag Source: cmd/web/main.go:16 Copy var Version = "dev" Types type Config Source: cmd/web/config.go:4 Config holds TySug's central config parameters Copy type Config struct { References map [ string ][] string `toml:"references"` Client struct { InputLengthMax int `toml:"inputLengthMax"` } `toml:"client"` CORS struct { AllowedOrigins [] string `toml:"allowedOrigins"` } `toml:"CORS"` Server struct { ListenOn string `toml:"listenOn"` Headers [] struct { Name string `toml:"name"` Value string `toml:"value"` } `toml:"headers"` Log struct { Level string `toml:"level"` } `toml:"log"` Profiler struct { Enable bool `toml:"enable"` Prefix string `toml:"prefix"` } `toml:"profiler"` } `toml:"server"` } Fields References map[string][]string `toml:"references"` Client struct { InputLengthMax int `toml:"inputLengthMax"` } `toml:"client"` CORS struct { AllowedOrigins []string `toml:"allowedOrigins"` } `toml:"CORS"` Server struct { ListenOn string `toml:"listenOn"` Headers []struct { Name string `toml:"name"` Value string `toml:"value"` } `toml:"headers"` Log struct { Level string `toml:"level"` } `toml:"log"` Profiler struct { Enable bool `toml:"enable"` Prefix string `toml:"prefix"` } `toml:"profiler"` } `toml:"server"`

### finder

Path: `/docs/reference/pkg-finder.html`

github.com/Dynom/TySug/finder

import "github.com/Dynom/TySug/finder" Index Constants Variables Functions func MarkingTypoProcessor() Processor func New(list []string, options ...Option) (*Finder, error) func NewDamerauLevenshtein() Algorithm func NewJaro() Algorithm func NewJaroWinkler(boostThreshold float64, prefixLength int) Algorithm func NewJaroWinklerDefaults() Algorithm func NewWagnerFischer(insert, delete, substitution int) Algorithm func WithAlgorithm(alg Algorithm) Option func WithLengthTolerance(t float64) Option func WithPreProcessor(p ...Processor) Option func WithPrefixBuckets(enable bool) Option Types type Algorithm type Finder type Option type Processor Constants These constants hold the value of the lowest and highest possible scores. Compatible with JSON serialization. It's not ideal to mix presentation with business logic but in this instance it was convenient and similarly effective as math.Inf(-1) Source: finder/find.go:38 Copy const ( WorstScoreValue = - 1 * math . MaxFloat32 BestScoreValue = math . MaxFloat32 ) Variables Source: finder/find.go:25 Copy var ( ErrNoAlgorithmDefined = errors . New ( "no algorithm defined" ) ErrPrefixExceedsInputLen = errors . New ( "prefix length exceeds input length" ) ) Functions func MarkingTypoProcessor() Processor Source: finder/processor.go:11 func New(list []string, options ...Option) (*Finder, error) Source: finder/find.go:43 New creates a new instance of Finder. The order of the list is significant func NewDamerauLevenshtein() Algorithm Source: finder/algorithm.go:43 NewDamerauLevenshtein returns the DamerauLevenshtein algorithm func NewJaro() Algorithm Source: finder/algorithm.go:66 NewJaro returns the default Jaro algorithm @see Original https://rosettacode.org/wiki/Jaro_distance#Go Relevant discussions: https://github.com/xrash/smetrics/issues/7#issuecomment-664794681 Changes over original: Reduced allocations Added rounding on the unaligned matches as per: http://www.alias-i.com/lingpipe/docs/api/com/aliasi/spell/JaroWinklerDistance.html Added support for 1 character inputs, by making sure the match distances is never negative func NewJaroWinkler(boostThreshold float64, prefixLength int) Algorithm Source: finder/algorithm.go:20 NewJaroWinkler returns the JaroWinkler algorithm func NewJaroWinklerDefaults() Algorithm Source: finder/algorithm.go:15 NewJaroWinklerDefaults returns the Jaro Winkler algorithm with 0.7 boost threshold and a prefix length of 4 func NewWagnerFischer(insert, delete, substitution int) Algorithm Source: finder/algorithm.go:51 NewWagnerFischer returns the NewWagnerFischer algorithm, sensible defaults are: i:1, d:3, s:1 func WithAlgorithm(alg Algorithm) Option Source: finder/option.go:7 WithAlgorithm allows you to set any algorithm func WithLengthTolerance(t float64) Option Source: finder/option.go:16 WithLengthTolerance defines a percentage of length above we no longer consider a length difference a typo, but instead we consider it as "completely wrong". A value of 0.2 specifies a tolerance of at most ~20% difference in size, with a minimum of 1 character. A value of 0 (the default) disables this feature. func WithPreProcessor(p ...Processor) Option Source: finder/option.go:32 func WithPrefixBuckets(enable bool) Option Source: finder/option.go:24 WithPrefixBuckets splits the reference list into buckets by their first letter. At a trade-off that the first character must be correct, this will significantly improve performance as it has a much smaller list to consider Types type Algorithm Source: finder/algorithm.go:12 Algorithm the type to comply with to create your own algorithm Note that the return value must be greater than WorstScoreValue and less than BestScoreValue Copy type Algorithm func ( a , b string ) float64 type Finder Source: finder/find.go:13 Finder is the type to find the nearest reference Copy type Finder struct { // contains filtered or unexported fields } func Exact(input string) bool Source: finder/find.go:94 Exact returns true if the input is an exact match. func Finder) Find(input string) (string, float64, bool) Source: finder/find.go:104 Find returns the best alternative, score and if it was an exact match or not. Since algorithms can define their own upper-bound, there is no "best" value. func FindCtx(ctx context.Context, input string) (string, float64, bool) Source: finder/find.go:110 FindCtx is the same as Find, with context support. func FindTopRankingCtx(ctx context.Context, input string) ([]string, float64, bool) Source: finder/find.go:116 FindTopRankingCtx returns a list (of at least one element) of references with the same "best" score func FindTopRankingPrefixCtx(ctx context.Context, input string, prefixLength uint) (list []string, exact bool, err error) Source: finder/find.go:123 FindTopRankingPrefixCtx requires the references to have an exact prefix match on N characters of the input. prefixLength cannot exceed length of input func GetMatchingPrefix(ctx context.Context, prefix string, max uint) ([]string, error) Source: finder/find.go:141 GetMatchingPrefix returns up to max ref's, that start with the prefix argument func Refresh(list []string) Source: finder/find.go:62 Refresh replaces the internal reference list. type Option Source: finder/option.go:4 Option is the type accepted by finder to set specific options Copy type Option func ( sug * Finder ) type Processor Source: finder/processor.go:9 Copy type Processor func ( string ) string

### internal/rwc

Path: `/docs/reference/pkg-internal-rwc.html`

github.com/Dynom/TySug/internal/rwc

import "github.com/Dynom/TySug/internal/rwc" Index Functions func New() *RWCMutex Types type RWCMutex type RWCMutexer Functions func New() *RWCMutex Source: internal/rwc/lock.go:19 Types type RWCMutex Source: internal/rwc/lock.go:27 Copy type RWCMutex struct { // contains filtered or unexported fields } func Lock() Source: internal/rwc/lock.go:37 Lock locks write workloads func RLock() Source: internal/rwc/lock.go:68 RLock allows read workloads to wait for writers to complete. func RUnlock() Source: internal/rwc/lock.go:76 RUnlock signals that a read workload is completed, so that a writer can start func Unlock() Source: internal/rwc/lock.go:51 Unlock releases locked write workloads type RWCMutexer Source: internal/rwc/lock.go:12 RWCMutexer is mostly just a copy & paste from sync.RWMutex but with channels. It outperforms sync.RWMutex on workloads with many short-read locks scenarios versus small wlock. See benchmarks for context Copy type RWCMutexer interface { RLock () RUnlock () Lock () Unlock () } Methods RLock func() RUnlock func() Lock func() Unlock func()

### keyboard

Path: `/docs/reference/pkg-keyboard.html`

github.com/Dynom/TySug/keyboard

import "github.com/Dynom/TySug/keyboard" Index Constants Functions func New(l Layout) KeyDist Types type KeyDist type Layout Constants Predefined keyboard layouts Source: keyboard/distance.go:12 Copy const ( Default Layout = QwertyUS QwertyUS Layout = "qwerty-us" ) Functions func New(l Layout) KeyDist Source: keyboard/distance.go:56 New produces a new instance of KeyDist, based on the keyboard layout you choose Types type KeyDist Source: keyboard/distance.go:51 KeyDist is the type that allows to find the best alternative based on keyboard layouts Copy type KeyDist struct { // contains filtered or unexported fields } func CalculateDistance(input, ref string) float64 Source: keyboard/distance.go:79 CalculateDistance calculates the total distances of the reference to the input func FindNearest(input string, list []string) (string, float64) Source: keyboard/distance.go:63 FindNearest finds the item in the list that is nearest to the input, based on the keyboard layout type Layout Source: keyboard/distance.go:8 Layout is the type used to define keyboard layouts Copy type Layout string

### server

Path: `/docs/reference/pkg-server.html`

github.com/Dynom/TySug/server

import "github.com/Dynom/TySug/server" Index Constants Variables Functions func NewHTTP(sr ServiceRegistry, mux *http.ServeMux, options ...Option) TySugServer func NewServiceRegistry() ServiceRegistry func WithCORS(allowedOrigins []string) Option func WithDefaultHeaders(headers http.Header) Option func WithGzipHandler() Option func WithInputLimitValidator(inputMax int) Option func WithLogger(logger *logrus.Logger) Option func WithPProf(prefix string) Option Types type Option type Service type ServiceRegistry type TySugServer type Validator Constants Context value parameters Source: server/http.go:29 Copy const ( CtxRequestID contextKey = iota ) Header constants Source: server/http.go:34 Copy const ( HeaderRequestID = "X-Request-ID" ) Variables Errors Source: server/http.go:19 Copy var ( ErrMissingBody = errors . New ( "missing body" ) ErrInvalidRequest = errors . New ( "invalid request" ) ErrInvalidRequestBody = errors . New ( "invalid request body" ) ErrBodyTooLarge = errors . New ( "body too large" ) ) Functions func NewHTTP(sr ServiceRegistry, mux *http.ServeMux, options ...Option) TySugServer Source: server/http.go:73 NewHTTP constructs a new TySugServer func NewServiceRegistry() ServiceRegistry Source: server/service_registry.go:14 NewServiceRegistry creates a new registry func WithCORS(allowedOrigins []string) Option Source: server/option.go:51 WithCORS adds the CORS handler to the request handling func WithDefaultHeaders(headers http.Header) Option Source: server/option.go:30 WithDefaultHeaders sets the default headers to be used when writing a response. func WithGzipHandler() Option Source: server/option.go:96 WithGzipHandler adds a gzip handler to the server's handlers func WithInputLimitValidator(inputMax int) Option Source: server/option.go:75 WithInputLimitValidator specifies a max input-value limit validator func WithLogger(logger *logrus.Logger) Option Source: server/option.go:19 WithLogger sets the logger to be used when encountering http-related errors. Errors are written to the standard error output in most cases. Printing on the standard output is reserved to extreme case where writing on stderr failed. func WithPProf(prefix string) Option Source: server/option.go:103 WithPProf enables pprof Types type Option Source: server/option.go:14 Option is a handy type used for configuration purposes Copy type Option func ( * TySugServer ) type Service Source: server/service.go:6 Service is the type any service must implement Copy type Service interface { Find ( ctx context . Context , input string ) ( string , float64 , bool ) } Methods Find func(ctx context.Context, input string) (string, float64, bool) type ServiceRegistry Source: server/service_registry.go:8 ServiceRegistry holds (opinionated) service objects for handling specific requests Copy type ServiceRegistry struct { // contains filtered or unexported fields } func GetServiceForList(name string) Service Source: server/service_registry.go:31 GetServiceForList returns a service able to handle a specific list func HasServiceForList(name string) bool Source: server/service_registry.go:40 HasServiceForList returns true only if a service has been registered for a certain list func Register(listName string, svc Service) *ServiceRegistry Source: server/service_registry.go:22 Register registers a new service with a list of references type TySugServer Source: server/http.go:56 TySugServer the HTTP server Copy type TySugServer struct { Logger * logrus . Logger // contains filtered or unexported fields } Fields Logger *logrus.Logger func ListenOnAndServe(addr string) error Source: server/http.go:66 ListenOnAndServe allows to set the host:port URL late. It calls ListenAndServe() type Validator Source: server/http.go:53 Validator is a type to validate a client request, returning a nil error means all went well. Copy type Validator func ( TSRequest tySugRequest ) error

### server/service

Path: `/docs/reference/pkg-server-service.html`

github.com/Dynom/TySug/server/service

import "github.com/Dynom/TySug/server/service" Index Functions func NewDomain(references []string, logger *logrus.Logger, options ...finder.Option) (Service, error) Types type Service Functions func NewDomain(references []string, logger *logrus.Logger, options ...finder.Option) (Service, error) Source: server/service/domain.go:14 NewDomain creates a new service Types type Service Source: server/service/domain.go:33 Service is the service type Copy type Service struct { // contains filtered or unexported fields } func Find(ctx context.Context, input string) (string, float64, bool) Source: server/service/domain.go:40 Find returns the nearest reference

### Go API

Path: `/docs/reference/`

github.com/Dynom/TySug

github.com/Dynom/TySug cmd/web github.com/Dynom/TySug/cmd/web finder github.com/Dynom/TySug/finder internal/rwc github.com/Dynom/TySug/internal/rwc keyboard github.com/Dynom/TySug/keyboard server github.com/Dynom/TySug/server server/service github.com/Dynom/TySug/server/service
13 changes: 13 additions & 0 deletions docs/reference/llms.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# TySug

> github.com/Dynom/TySug/cmd/web

## Go API

- [cmd/web](/docs/reference/pkg-cmd-web.html): github.com/Dynom/TySug/cmd/web
- [finder](/docs/reference/pkg-finder.html): github.com/Dynom/TySug/finder
- [internal/rwc](/docs/reference/pkg-internal-rwc.html): github.com/Dynom/TySug/internal/rwc
- [keyboard](/docs/reference/pkg-keyboard.html): github.com/Dynom/TySug/keyboard
- [server](/docs/reference/pkg-server.html): github.com/Dynom/TySug/server
- [server/service](/docs/reference/pkg-server-service.html): github.com/Dynom/TySug/server/service
- [Go API](/docs/reference/): github.com/Dynom/TySug
83 changes: 83 additions & 0 deletions docs/reference/pkg-cmd-web.html

Large diffs are not rendered by default.

197 changes: 197 additions & 0 deletions docs/reference/pkg-finder.html

Large diffs are not rendered by default.

80 changes: 80 additions & 0 deletions docs/reference/pkg-internal-rwc.html

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions docs/reference/pkg-keyboard.html

Large diffs are not rendered by default.

49 changes: 49 additions & 0 deletions docs/reference/pkg-server-service.html

Large diffs are not rendered by default.

184 changes: 184 additions & 0 deletions docs/reference/pkg-server.html

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/reference/search-index.json

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions docs/reference/sitemap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by Sourcey https://sourcey.com -->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>https://tysug.net/docs/reference/pkg-cmd-web.html</loc></url>
<url><loc>https://tysug.net/docs/reference/pkg-finder.html</loc></url>
<url><loc>https://tysug.net/docs/reference/pkg-internal-rwc.html</loc></url>
<url><loc>https://tysug.net/docs/reference/pkg-keyboard.html</loc></url>
<url><loc>https://tysug.net/docs/reference/pkg-server.html</loc></url>
<url><loc>https://tysug.net/docs/reference/pkg-server-service.html</loc></url>
<url><loc>https://tysug.net/docs/reference/</loc></url>
</urlset>
2,474 changes: 2,474 additions & 0 deletions docs/reference/sourcey.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/reference/sourcey.js

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions docs/sourcey/fix-base-path.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { readFile, writeFile } from "node:fs/promises";

const basePath = "/docs/reference/";
const html = {
index: await readFile("../reference/index.html", "utf8"),
cmdWeb: await readFile("../reference/pkg-cmd-web.html", "utf8"),
finder: await readFile("../reference/pkg-finder.html", "utf8"),
internalRwc: await readFile("../reference/pkg-internal-rwc.html", "utf8"),
keyboard: await readFile("../reference/pkg-keyboard.html", "utf8"),
server: await readFile("../reference/pkg-server.html", "utf8"),
serverService: await readFile("../reference/pkg-server-service.html", "utf8"),
};
let replacements = 0;

const rewritten = Object.fromEntries(
Object.entries(html).map(([name, contents]) => [
name,
contents.replaceAll(
/href="\/(index\.html|pkg-[^"]+\.html)"/g,
(_match, target) => {
replacements += 1;
return `href="${basePath}${target}"`;
},
),
]),
);

if (replacements === 0) {
throw new Error("No Sourcey navigation links were rewritten");
}

await writeFile("../reference/index.html", rewritten.index);
await writeFile("../reference/pkg-cmd-web.html", rewritten.cmdWeb);
await writeFile("../reference/pkg-finder.html", rewritten.finder);
await writeFile("../reference/pkg-internal-rwc.html", rewritten.internalRwc);
await writeFile("../reference/pkg-keyboard.html", rewritten.keyboard);
await writeFile("../reference/pkg-server.html", rewritten.server);
await writeFile(
"../reference/pkg-server-service.html",
rewritten.serverService,
);

console.log(`Rewrote ${replacements} navigation links for ${basePath}`);
15 changes: 15 additions & 0 deletions docs/sourcey/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "tysug-sourcey-docs",
"private": true,
"engines": {
"node": ">=20"
},
"packageManager": "pnpm@11.7.0",
"scripts": {
"build": "node ./node_modules/sourcey/dist/cli.js build --config sourcey.config.ts --output ../reference && node fix-base-path.mjs"
},
"devDependencies": {
"consola": "3.4.2",
"sourcey": "3.6.5"
}
}
Loading