script

package
v0.0.0-...-9e054ec Latest Latest
Warning

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

Go to latest
Published: Apr 25, 2024 License: Apache-2.0 Imports: 37 Imported by: 0

Documentation

Overview

Package script contains support for loading configuration scripts built as JavaScript programs.

Index

Constants

This section is empty.

Variables

Set is used by Wire.

Functions

func AddMeta

func AddMeta(source string, tbl ident.Table, mut *types.Mutation)

AddMeta decorates the mutation with a standard set of properties.

func HelpCommand

func HelpCommand() *cobra.Command

HelpCommand returns an extended help command to print TypeScript bindings for the userscript API.

func SourceName

func SourceName(target ident.Schematic) ident.Ident

SourceName returns a standardized representation of a source name.

Types

type Config

type Config struct {
	FS       fs.FS   // A filesystem to load resources fs.
	MainPath string  // A path, relative to FS that holds the entrypoint.
	Options  Options // The target for calls to api.setOptions().

	// An external filesystem path. This will be cleared after Preflight
	// has been called. This symbol is exported for testing.
	UserScriptPath string
}

Config drives UserScript behavior.

func (*Config) Bind

func (c *Config) Bind(f *pflag.FlagSet)

Bind adds flags to the set.

func (*Config) Preflight

func (c *Config) Preflight() error

Preflight will set FS and MainPath, if UserScriptPath is set.

type DeleteKey

type DeleteKey func(ctx context.Context, mut types.Mutation) (types.Mutation, bool, error)

DeleteKey is similar to Map in that it has the opportunity to modify or filter a mutation before subsequent processing. Rather than operating on types.Mutation.Data, it should instead base its behavior on types.Mutation.Key. DeleteKey functions are internally synchronized to ensure single-threaded access to the underlying JS VM.

type Dispatch

type Dispatch func(ctx context.Context, mutation types.Mutation) (*ident.TableMap[[]types.Mutation], error)

A Dispatch function receives a source mutation and assigns mutations to some number of downstream tables. Dispatch functions are internally synchronized to ensure single-threaded access to the underlying JS VM.

type FlagOptions

type FlagOptions struct {
	Flags *pflag.FlagSet
}

FlagOptions adapts a pflag.FlagSet to the Options interface.

func (*FlagOptions) Set

func (o *FlagOptions) Set(key, value string) error

Set implements Options.

type Loader

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

Loader is responsible for the first-pass execution of the user script. It will load all required resources, parse, and execute the top-level API calls. It should be noted that a Loader is a global resource which is independent of any particular target schema. In order to resolve the various table names against a specific target schema, call Loader.Bind to return a UserScript that operates within the given target schema.

func ProvideLoader

func ProvideLoader(
	ctx context.Context, applyConfigs *applycfg.Configs, cfg *Config, diags *diag.Diagnostics,
) (*Loader, error)

ProvideLoader is called by Wire to perform the initial script loading, parsing, and top-level api handling. This provider may return nil if there is no configuration.

func (*Loader) Bind

func (l *Loader) Bind(
	ctx *stopper.Context,
	target ident.Schematic,
	targetAcceptor types.TableAcceptor,
	watchers types.Watchers,
) (*UserScript, error)

Bind resolves the various table names used in the script file to the target schema. Any asynchronous processes launched by the script (e.g. promises) will be executed within the provided stopper.Context.

At present, each returned UserScript shares a common JS runtime.

type Map

type Map func(ctx context.Context, mut types.Mutation) (types.Mutation, bool, error)

A Map function may modify the mutations that are applied to a specific table. The boolean value will be false if the input mutation should be discarded. Map functions are internally synchronized to ensure single-threaded access to the underlying JS VM.

type Options

type Options interface{ Set(key, value string) error }

Options is an injection point for a value that will receive any additional configuration from api.setOptions.

var NoOptions Options = &noOptions{}

NoOptions always returns an error when invoked.

type Source

type Source struct {
	// The table to apply incoming deletes to; this assumes that the
	// target schema is using FK's with ON DELETE CASCADE.
	DeletesTo ident.Table
	// A user-provided function that routes mutations to zero or more
	// tables.
	Dispatch Dispatch `json:"-"`
	// Enable recursion in sources which support nested sources.
	Recurse bool
}

A Source holds user-provided configuration options for a generic data-source.

type Target

type Target struct {
	applycfg.Config
	// A user-provided function to modify of filter mutations that
	// delete a row in the target table.
	DeleteKey DeleteKey `json:"-"`
	// A user-provided function to modify or filter mutations bound for
	// the target table.
	Map Map `json:"-"`
	// A user-defined TableAcceptor that may execute arbitrary SQL or
	// call [UserScript.Delegate].
	UserAcceptor types.TableAcceptor `json:"-"`
}

A Target holds user-provided configuration options for a target table.

type UserScript

type UserScript struct {
	Delegate types.TableAcceptor
	Sources  *ident.Map[*Source]
	Targets  *ident.TableMap[*Target]
	// contains filtered or unexported fields
}

UserScript encapsulates a user-provided configuration expressed as a JavaScript program.

NB: The single-threaded nature of JavaScript means that only a single goroutine may execute JS code at any given point in time. These critical sections are coordinated through the execJS method. It's also the case that the JS user code is tightly coupled to the particular goja.Runtime that loaded the script (e.g. JS global variables). Should contention on the runtime become problematic, the correct solution would be to create multiple Loaders that each evaluate a separate UserScript. The tradedoff here is that each instance of the userscript would then have distinct global variables.

func (*UserScript) Diagnostic

func (s *UserScript) Diagnostic(_ context.Context) any

Diagnostic implements diag.Diagnostic.

func (*UserScript) Exited

func (s *UserScript) Exited()

Exited implements goja.AsyncContextTracker. If [UserScript.tracker] is non-nil, it will be exited and the reference cleared.

func (*UserScript) Grab

func (s *UserScript) Grab() any

Grab implements goja.AsyncContextTracker. The object returned from this method, an [asyncTracker], will be associated with any promise chains that may be created by the user script.

func (*UserScript) Resumed

func (s *UserScript) Resumed(obj any)

Resumed implements goja.AsyncContextTracker. If the object is an [asyncTracker], its [asyncTracker.enter] method will be called with the receiver.

Jump to

Keyboard shortcuts

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