loop

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 9, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package loop provides a zero-dependency cron parser and an injectable-clock job registry backing nib's /loop feature.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Job

type Job struct {
	ID        string    `json:"id"`
	Expr      string    `json:"expr"`
	Prompt    string    `json:"prompt"`
	Recurring bool      `json:"recurring"`
	Durable   bool      `json:"durable"`
	Created   time.Time `json:"created"`
	// contains filtered or unexported fields
}

Job is a registered recurring (or one-shot) task. Prompt is the payload to run when the job fires — a slash command or plain prompt, resolved by the host through slash.Resolve at fire time.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry is a thread-safe store of cron jobs with an injectable clock.

func NewRegistry

func NewRegistry() *Registry

NewRegistry returns an empty registry using time.Now as its clock.

func (*Registry) Add

func (r *Registry) Add(expr, prompt string, recurring, durable bool) (Job, error)

Add parses expr, registers a job, and returns it. Returns an error if the expression is invalid.

func (*Registry) Delete

func (r *Registry) Delete(id string) bool

Delete removes the job with the given id; returns whether it existed.

func (*Registry) Due

func (r *Registry) Due() []Job

Due returns the jobs whose next-fire time has arrived (<= now), advancing recurring jobs to their next slot and removing fired one-shots.

func (*Registry) List

func (r *Registry) List() []Job

List returns a copy of the current jobs, sorted by next-fire time.

func (*Registry) Load

func (r *Registry) Load(path string) (int, error)

Load reads durable jobs from path and registers them (re-parsing exprs and recomputing next-fire from the current clock). A missing file is not an error. Returns the number of jobs loaded. Jobs are re-registered with next-fire recomputed from the current clock; jobs whose expression no longer parses (or can never fire) are skipped. Job IDs are reassigned on load (use List to see current IDs); the original Created timestamp is preserved.

func (*Registry) Save

func (r *Registry) Save(path string) error

Save writes the durable jobs to path as JSON, creating parent dirs. Jobs with Durable == false are skipped. Re-parses are deferred to Load.

func (*Registry) SetClock

func (r *Registry) SetClock(now func() time.Time)

SetClock overrides the clock (tests). Must be called before Add.

type Schedule

type Schedule struct {
	// contains filtered or unexported fields
}

Schedule is a parsed cron expression: [second] minute hour day-of-month month day-of-week, all evaluated in the timezone of the time passed to Next. The leading seconds field is optional; when absent it defaults to second 0.

func Parse

func Parse(expr string) (Schedule, error)

Parse parses a 5- or 6-field cron expression. With 6 fields the leading field is seconds (0-59); with 5 fields seconds defaults to 0 (backward compatible). Supports '*', '*/n', 'a-b', 'a,b,c', and single values per field. Day-of-week 0 = Sunday.

All fields are ANDed together — including day-of-month and day-of-week. This differs from POSIX/Vixie cron, which ORs day-of-month and day-of-week when both are restricted. The deviation is acceptable here because nib's /loop never restricts both fields at once.

func (Schedule) Next

func (s Schedule) Next(after time.Time) (time.Time, bool)

Next returns the first instant strictly after `after` that matches the schedule, at second granularity. ok is false if none is found within ~4 years (guards bad exprs).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL