Use the Universal API
Use github.com/MontFerret/ferret/v2/uapi, Ferret’s official adapter, when
your integration accepts github.com/MontFerret/api interfaces. For Native
embedding, use the root github.com/MontFerret/ferret/v2 package and
ferret.New. Use uapi.New to create and own a Native engine:
The runtime owns the engine created by New; closing the runtime closes that
engine. Pass Native options to configure modules, host services, codecs, and
defaults. Construction failures return a nil runtime and a projected Native
error; Native handles rollback. Nil options, including uapi.New(nil),
are skipped by Native. Call uapi.New() to use Native defaults.
Use Wrap when the caller supplies and owns the Native engine:
Wrap acquires no resources and leaves engine cleanup to its caller.
uapi.Wrap(nil) panics. Both constructors return *uapi.Runtime,
which implements api.Runtime. Both constructors live in uapi; the root
ferret package exposes the Native API.
The adapter translates portable source, options, and diagnostics while Native Ferret performs compilation, execution, debugging, and resource cleanup. Native and Universal option types remain separate.
Reuse a plan
portable.Compile(ctx, source, options...) returns an api.Plan.
Create independent sessions with plan.NewSession(ctx, options...), run them
with session.Run(ctx), and close each session before closing the plan.
Ordinary sessions also support sequential runs when their environment remains
unchanged.
plan.Params() returns a detached parameter-name snapshot and an error:
The Native adapter can read this metadata after plan closure and returns a nil
error. Native ferret.Plan.Params() still returns only the name slice.
For debugging, use portable.CompileDebug, then plan.NewDebugSession.
The returned api/debugger.Session supports entry, breakpoints, stepping,
frames, variables, evaluation, pause, and termination through Native debugging.
All debugger methods except Close take a non-nil context. For example:
Inspection checks cancellation before and after waiting for an active command; cancellation does not interrupt that wait. Canceled pause requests do not pause execution. Breakpoint listing returns a detached snapshot and remains available after close with a valid context. Canceling a breakpoint mutation before publication leaves the set unchanged and does not cancel the debuggee.
Replace breakpoints while running
The coordinated live-breakpoint API adds Session.ReplaceBreakpoints. Use it to
replace one source’s complete set before execution, while paused, or while running.
Requests use types from github.com/MontFerret/api/debugger and
github.com/MontFerret/api/source:
breakpoints, err := session.ReplaceBreakpoints(ctx, "query.fql", []debugger.BreakpointRequest{
{Position: source.Position{Line: 3}},
{Position: source.Position{Line: 8}},
})
An empty request slice clears that source. Results follow request order and include
the current resolved location and ID. A valid location that cannot bind returns
Bound: false. Invalid coordinates or binding modes fail the whole operation,
leaving the previous set intact. Other sources are unchanged.
The replacement becomes active atomically without pausing execution. Unchanged requests retain IDs; removed IDs are never reused in that session. A stop already decided before removal remains inspectable and may still report the removed ID. New breakpoints affect subsequent visits, never instructions already passed.
Cancellation observed before publication leaves the previous set intact. Once publication succeeds, later cancellation does not undo it or cancel the debuggee. Completed, terminated, and closed sessions reject replacement.
These signatures use API v1.0.0-alpha.19 and the corresponding Ferret update.
Live DAP/IDE support additionally requires a later daemon release and matching
Editorium pin.
Configure portable execution
| Option | Behavior |
|---|---|
api.WithOptimizationLevel |
Selects None, Basic, or Full for one compilation. Aggressive and unknown levels fail. |
api.WithParam, api.WithParams |
Supply host parameters using Native value conversion. Later settings override earlier keys; maps merge. |
api.WithOutputContentType |
Selects a codec registered on the Native engine. JSON is the default. |
api.WithFSRoot |
Selects a session-owned filesystem root while retaining the engine’s read-only policy. |
Omitted optimization inherits the engine default. Plan setters queue supported
levels; Native validates them for the compilation mode. Debug compilation accepts
omission or None. Basic/Full fails during Native option application, even if
followed by None. Session options apply to both ordinary and debug sessions, and
to the convenience Runtime.Run call.
Non-nil option callbacks run once, in order, independently of the operation
context. Session setters queue Native options and return nil; Native owns
parameter conversion and validation. If callbacks return errors, they are joined
and delegation stops. Cancellation is included only if a callback returns it.
Otherwise Native receives the original caller context and owns context validation
and cancellation. Native applies queued options and joins option-application
errors before acquiring session resources. Runtime.Run may compile before
session validation.
The portable contract allows runtime-specific validation at the point of use. Native checks output codec availability during result encoding, after the query has run. An unavailable codec therefore returns an operation error even though callbacks and session creation succeeded and query side effects may have occurred. The adapter preserves Native result and session cleanup on this path.
Parameter maps are converted after all portable callbacks finish. Changes to
those maps during translation are therefore visible to conversion. Native
rejects blank output content types and filesystem roots, and rejects an empty
name or nil value for a single parameter. In parameter maps, nil becomes none;
nil and empty maps are no-ops when applied. Runtime-specific extension options
must reject incompatible option targets.
Configure Native modules, host services, codecs, and other engine-specific
features through New options or before wrapping an existing engine. See configuration and
host values.
Own the lifetime
For runtimes created by New, Runtime.Close delegates to the owned Native
engine. Native releases its resources and rejects subsequent runtime operations.
For Wrap, Close returns nil and leaves the adapter, engine, and directly created
plans usable. Multiple adapters may borrow one engine independently. The engine’s
owner remains responsible for closing it; external closure is visible to all
borrowers.
Plan, session, and debug-session close calls delegate to Native. Plan close
rejects new sessions and wakes capacity waiters without waiting for outstanding
constructors. Use caller contexts to cancel work, settle it, then close sessions
before plans and their owning runtime or borrowed Native engine. Native engine
close does not wait for operations already started or close descendants. Parent
close does not implicitly cancel caller-owned work. Directly created sessions
and debug sessions retain their own lifecycle after plan closure.
The portable contract requires cleanup of owned resources and rejection of new
descendants after plan closure; it does not require waiting for constructors or
coordinating descendant cleanup. Callers coordinate cleanup when descendants use
parent-owned resources.
Runtime.Run delegates temporary session and plan cleanup to Native.
Settle ordinary Run calls before closing their session. Debug Close terminates and waits for active commands. Repeated and concurrent Close calls preserve the Native cleanup result and diagnostic information; projected error wrappers need not have identical pointers. Close hooks must not recursively close their own Native object. Context arguments must be non-nil.
Preserve output and diagnostics
Runtime.Run and Session.Run return (*api.Output, error). A nil output
means no output was produced. A non-nil output represents a produced value,
including empty output, and may accompany an error from a hook or cleanup step.
A zero-valued Output is not an absence sentinel. Inspect output independently
of the error:
Output bytes belong to the caller, survive cleanup, and need no Close call. Debugger commands can likewise return a completion event and output alongside an error.
Use errors.As to obtain github.com/MontFerret/api/diagnostics.Diagnostics.
The projection preserves source identity and byte coordinates, while
errors.Is and errors.As still reach Native errors and cancellation causes.
See executing queries for Native output and lifecycle details.