rendertrace API

rendertrace

package

API reference for the rendertrace package.

F
function

TestTraceEnabledAtBootReadsBooleanAndObjectFlags

Parameters

internal/rendertrace/trace_wasm_test.go:10-33
func TestTraceEnabledAtBootReadsBooleanAndObjectFlags(t *testing.T)

{
	global := js.Global()
	previous := global.Get("RFW_RENDER_TRACE")
	defer func() {
		if previous.Type() == js.TypeUndefined {
			global.Get("Reflect").Call("deleteProperty", global, "RFW_RENDER_TRACE")
			return
		}
		global.Set("RFW_RENDER_TRACE", previous)
	}()

	global.Set("RFW_RENDER_TRACE", true)
	if !traceEnabledAtBoot() {
		t.Fatal("boolean true did not enable tracing")
	}
	global.Set("RFW_RENDER_TRACE", map[string]any{"enabled": true})
	if !traceEnabledAtBoot() {
		t.Fatal("object enabled flag did not enable tracing")
	}
	global.Set("RFW_RENDER_TRACE", false)
	if traceEnabledAtBoot() {
		t.Fatal("boolean false enabled tracing")
	}
}
S
struct

Cause

Cause identifies why a component render was requested.

internal/rendertrace/trace.go:5-11
type Cause struct

Fields

Name Type Description
Kind string
Module string
Store string
Key string
Signal string
S
struct

Record

Record is one phase of a render trace. Emit assigns the schema version,
sequence and timestamp so callers only provide render-specific facts.

internal/rendertrace/trace.go:15-33
type Record struct

Fields

Name Type Description
Event string
BatchID uint64
RenderID uint64
ComponentID string
ComponentName string
ParentComponentID string
Depth int
Cause Cause
Causes []Cause
QueueDepth int
CoalescedCount int
TemplateMS float64
DOMMS float64
TotalMS float64
Outcome string
Reason string
SupersededBy uint64
F
function

NormalizeCause

NormalizeCause gives callers that have no more specific provenance a stable
explicit cause instead of emitting an empty object.

Parameters

cause

Returns

internal/rendertrace/trace.go:37-42
func NormalizeCause(cause Cause) Cause

{
	if cause.Kind == "" {
		cause.Kind = "explicit"
	}
	return cause
}
F
function

AppendCause

AppendCause adds one cause unless an identical cause is already present.

Parameters

causes
cause

Returns

internal/rendertrace/trace.go:45-53
func AppendCause(causes []Cause, cause Cause) []Cause

{
	cause = NormalizeCause(cause)
	for _, existing := range causes {
		if existing == cause {
			return causes
		}
	}
	return append(causes, cause)
}
F
function

Enabled

Enabled reports that browser tracing is unavailable on native targets.

Returns

bool
internal/rendertrace/trace_stub.go:16-16
func Enabled() bool

{ return false }
F
function

SetEnabledForTest

SetEnabledForTest returns a no-op restore function on native targets.

Parameters

bool

Returns

func()
internal/rendertrace/trace_stub.go:19-19
func SetEnabledForTest(bool) func()

{ return func() {} }
F
function

NextBatchID

NextBatchID allocates a native stub batch identifier.

Returns

uint64
internal/rendertrace/trace_stub.go:22-22
func NextBatchID() uint64

{ return batchSeq.Add(1) }
F
function

NextRenderID

NextRenderID allocates a native stub render identifier.

Returns

uint64
internal/rendertrace/trace_stub.go:25-25
func NextRenderID() uint64

{ return renderSeq.Add(1) }
F
function

NowMS

NowMS returns a wall-clock timestamp for native callers.

Returns

float64
internal/rendertrace/trace_stub.go:28-28
func NowMS() float64

{ return float64(time.Now().UnixNano()) / 1e6 }
F
function

Emit

Emit is a no-op because native targets have no browser event transport.

Parameters

internal/rendertrace/trace_stub.go:31-31
func Emit(Record)

{}
F
function

traceEnabledAtBoot

Returns

bool
internal/rendertrace/trace_wasm.go:20-30
func traceEnabledAtBoot() bool

{
	value := js.Global().Get("RFW_RENDER_TRACE")
	if value.Type() == js.TypeBoolean {
		return value.Bool()
	}
	if value.Type() == js.TypeObject {
		enabled := value.Get("enabled")
		return enabled.Type() == js.TypeBoolean && enabled.Bool()
	}
	return false
}
F
function

Enabled

Enabled reports whether tracing was enabled before WASM startup. The test
override exists inside the module’s internal package so browser tests can
exercise both paths without exposing a production API.

Returns

bool
internal/rendertrace/trace_wasm.go:35-40
func Enabled() bool

{
	if testOverride >= 0 {
		return testOverride == 1
	}
	return bootEnabled
}
F
function

SetEnabledForTest

SetEnabledForTest overrides the boot flag and returns a restoring function.

Parameters

enabled
bool

Returns

func()
internal/rendertrace/trace_wasm.go:43-51
func SetEnabledForTest(enabled bool) func()

{
	previous := testOverride
	if enabled {
		testOverride = 1
	} else {
		testOverride = 0
	}
	return func() { testOverride = previous }
}
F
function

NextBatchID

NextBatchID allocates a monotonic render batch identifier.

Returns

uint64
internal/rendertrace/trace_wasm.go:54-54
func NextBatchID() uint64

{ return batchSeq.Add(1) }
F
function

NextRenderID

NextRenderID allocates a monotonic logical render identifier.

Returns

uint64
internal/rendertrace/trace_wasm.go:57-57
func NextRenderID() uint64

{ return renderSeq.Add(1) }
F
function

NowMS

NowMS returns the browser’s monotonic clock when it is available.

Returns

float64
internal/rendertrace/trace_wasm.go:60-66
func NowMS() float64

{
	performance := js.Global().Get("performance")
	if performance.Type() == js.TypeObject && performance.Get("now").Type() == js.TypeFunction {
		return performance.Call("now").Float()
	}
	return js.Global().Get("Date").Call("now").Float()
}
F
function

Emit

Emit dispatches one browser-readable trace record. Tracing must never affect
application rendering, so unsupported browser APIs or consumer errors are
contained here.

Parameters

record
internal/rendertrace/trace_wasm.go:71-130
func Emit(record Record)

{
	if !Enabled() {
		return
	}
	defer func() { _ = recover() }()

	detail := map[string]any{
		"schemaVersion": schemaVersion,
		"sequence":      sequence.Add(1),
		"timestampMs":   NowMS(),
		"event":         record.Event,
		"batchId":       record.BatchID,
		"renderId":      record.RenderID,
		"componentId":   record.ComponentID,
		"componentName": record.ComponentName,
		"depth":         record.Depth,
	}
	if record.ParentComponentID != "" {
		detail["parentComponentId"] = record.ParentComponentID
	}
	if record.Cause.Kind != "" {
		detail["cause"] = causeDetail(record.Cause)
	}
	if len(record.Causes) > 0 {
		causes := make([]any, 0, len(record.Causes))
		for _, cause := range record.Causes {
			causes = append(causes, causeDetail(cause))
		}
		detail["causes"] = causes
	}
	if record.QueueDepth > 0 {
		detail["queueDepth"] = record.QueueDepth
	}
	if record.CoalescedCount > 0 || record.Event == "scheduled" || record.Event == "coalesced" || record.Event == "started" || record.Event == "committed" {
		detail["coalescedCount"] = record.CoalescedCount
	}
	if record.Event == "committed" || record.Event == "failed" {
		detail["templateMs"] = record.TemplateMS
		detail["domMs"] = record.DOMMS
		detail["totalMs"] = record.TotalMS
	}
	if record.Outcome != "" {
		detail["outcome"] = record.Outcome
	}
	if record.Reason != "" {
		detail["reason"] = record.Reason
	}
	if record.SupersededBy != 0 {
		detail["supersededByRenderId"] = record.SupersededBy
	}

	constructor := js.Global().Get("CustomEvent")
	dispatch := js.Global().Get("dispatchEvent")
	if constructor.Type() != js.TypeFunction || dispatch.Type() != js.TypeFunction {
		return
	}
	options := map[string]any{"detail": detail}
	event := constructor.New("rfw:render-trace", options)
	js.Global().Call("dispatchEvent", event)
}
F
function

causeDetail

Parameters

cause

Returns

map[string]any
internal/rendertrace/trace_wasm.go:132-148
func causeDetail(cause Cause) map[string]any

{
	cause = NormalizeCause(cause)
	detail := map[string]any{"kind": cause.Kind}
	if cause.Module != "" {
		detail["module"] = cause.Module
	}
	if cause.Store != "" {
		detail["store"] = cause.Store
	}
	if cause.Key != "" {
		detail["key"] = cause.Key
	}
	if cause.Signal != "" {
		detail["signal"] = cause.Signal
	}
	return detail
}