OpenTelemetry
LiveStore has built-in support for OpenTelemetry.
Usage with React
Section titled “Usage with React”import { class ZoneContextManager
ZoneContextManager
This module provides an easy functionality for tracing action between asynchronous operations in web.
It was not possible with standard [StackContextManager]
.
It heavily depends on [zone.js]
https://www.npmjs.com/package/zone.js
.
It stores the information about context in zone. Each Context will have always new Zone;
It also supports binding a certain Span to a target that has "addEventListener" and "removeEventListener".
When this happens a new zone is being created and the provided Span is being assigned to this zone.
ZoneContextManager } from '@opentelemetry/context-zone'import { class W3CTraceContextPropagator
Propagates
SpanContext
through Trace Context format propagation.
Based on the Trace Context specification:
https://www.w3.org/TR/trace-context/
W3CTraceContextPropagator } from '@opentelemetry/core'import { class OTLPTraceExporter
Collector Trace Exporter for Node
OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'import { function resourceFromAttributes(attributes: DetectedResourceAttributes, options?: ResourceOptions): Resource
resourceFromAttributes } from '@opentelemetry/resources'import { class SimpleSpanProcessor
An implementation of the
SpanProcessor
that converts the
Span
to
ReadableSpan
and passes it to the configured exporter.
Only spans that are sampled are converted.
NOTE: This
SpanProcessor
exports every ended span individually instead of batching spans together, which causes significant performance overhead with most exporters. For production use, please consider using the
BatchSpanProcessor
instead.
SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'import { class WebTracerProvider
This class represents a web tracer with
StackContextManager
WebTracerProvider } from '@opentelemetry/sdk-trace-web'
/** * Configure a browser tracer that preserves parent/child spans across async work. * Requires a zone.js runtime (e.g. provided by many frameworks) so the ZoneContextManager * can keep context during timers, promises, and event callbacks. */export const const makeTracer: (serviceName: string) => Tracer
Configure a browser tracer that preserves parent/child spans across async work.
Requires a zone.js runtime (e.g. provided by many frameworks) so the ZoneContextManager
can keep context during timers, promises, and event callbacks.
makeTracer = (serviceName: string
serviceName: string) => { const const url: any
url = import.
The type of import.meta.
If you need to declare that a given property exists on import.meta,
this type may be augmented via interface merging.
meta.ImportMeta.env: ImportMetaEnv
env.any
VITE_OTEL_EXPORTER_OTLP_ENDPOINT const const provider: WebTracerProvider
provider = new new WebTracerProvider(config?: WebTracerConfig): WebTracerProvider
Constructs a new Tracer instance.
WebTracerProvider({ TracerConfig.spanProcessors?: SpanProcessor[]
List of SpanProcessor for the tracer
spanProcessors: const url: any
url !== var undefined
undefined ? [new new SimpleSpanProcessor(_exporter: SpanExporter): SimpleSpanProcessor
An implementation of the
SpanProcessor
that converts the
Span
to
ReadableSpan
and passes it to the configured exporter.
Only spans that are sampled are converted.
NOTE: This
SpanProcessor
exports every ended span individually instead of batching spans together, which causes significant performance overhead with most exporters. For production use, please consider using the
BatchSpanProcessor
instead.
SimpleSpanProcessor(new new OTLPTraceExporter(config?: OTLPExporterNodeConfigBase): OTLPTraceExporter
Collector Trace Exporter for Node
OTLPTraceExporter({ OTLPExporterConfigBase.url?: string
url: `${const url: any
url}/v1/traces` }))] : [], TracerConfig.resource?: Resource
Resource associated with trace telemetry
resource: function resourceFromAttributes(attributes: DetectedResourceAttributes, options?: ResourceOptions): Resource
resourceFromAttributes({ 'service.name': serviceName: string
serviceName }), })
const provider: WebTracerProvider
provider.WebTracerProvider.register(config?: SDKRegistrationConfig): void
Register this TracerProvider for use with the OpenTelemetry API.
Undefined values may be replaced with defaults, and
null values will be skipped.
register({ SDKRegistrationConfig.contextManager?: ContextManager | null
Context manager to register as the global context manager
contextManager: new new ZoneContextManager(): ZoneContextManager
ZoneContextManager
This module provides an easy functionality for tracing action between asynchronous operations in web.
It was not possible with standard [StackContextManager]
.
It heavily depends on [zone.js]
https://www.npmjs.com/package/zone.js
.
It stores the information about context in zone. Each Context will have always new Zone;
It also supports binding a certain Span to a target that has "addEventListener" and "removeEventListener".
When this happens a new zone is being created and the provided Span is being assigned to this zone.
ZoneContextManager(), SDKRegistrationConfig.propagator?: TextMapPropagator<any> | null
Propagator to register as the global propagator
propagator: new new W3CTraceContextPropagator(): W3CTraceContextPropagator
Propagates
SpanContext
through Trace Context format propagation.
Based on the Trace Context specification:
https://www.w3.org/TR/trace-context/
W3CTraceContextPropagator(), })
return const provider: WebTracerProvider
provider.BasicTracerProvider.getTracer(name: string, version?: string, options?: { schemaUrl?: string;}): Tracer
Returns a Tracer, creating one if one with the given name and version is
not already created.
This function may return different Tracer types (e.g.
NoopTracerProvider
vs. a functional tracer).
getTracer('livestore')}
export const const tracer: Tracer
tracer = const makeTracer: (serviceName: string) => Tracer
Configure a browser tracer that preserves parent/child spans across async work.
Requires a zone.js runtime (e.g. provided by many frameworks) so the ZoneContextManager
can keep context during timers, promises, and event callbacks.
makeTracer('my-app')const const useAppStore: () => Store<any, {}> & ReactApi
useAppStore = () => useStore<any, {}, Codec<Json, Json, never, never>>(options: RegistryStoreOptions<any, {}, Codec<Json, Json, never, never>>): Store<any, {}> & ReactApi
Returns a store instance augmented with hooks (store.useQuery() and store.useClientDocument()) for reactive queries.
useStore({ CreateStoreOptions<TSchema extends LiveStoreSchema, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<Json, Json, never, never>>.storeId: string
Unique identifier for the Store instance, stable for its lifetime.
- Valid characters: Only alphanumeric characters, underscores (
_), and hyphens (-)
are allowed. Must match /^[a-zA-Z0-9_-]+$/.
- Globally unique: Use globally unique IDs (e.g., nanoid) to prevent collisions across stores.
- Use namespaces: Prefix to avoid collisions and for easier identification when debugging
(e.g.,
app-root, workspace-abc123, issue-456)
storeId: 'otel-demo', CreateStoreOptions<any, {}, Codec<Json, Json, never, never>>.schema: any
The LiveStore schema defining tables, events, and materializers.
schema, CreateStoreOptions<TSchema extends LiveStoreSchema, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<Json, Json, never, never>>.adapter: Adapter
Adapter used for data storage and synchronization.
adapter, CreateStoreOptions<any, {}, Codec<Json, Json, never, never>>.batchUpdates?: (run: () => void) => void
Needed in React so LiveStore can apply multiple events in a single render.
batchUpdates, RegistryStoreOptions<TSchema extends LiveStoreSchema = LiveStoreSchema.Any, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<...>>.otelOptions?: Partial<OtelOptions>
OpenTelemetry configuration for tracing store operations.
When provided, store operations (boot, queries, commits) will be traced
under the given root span context using the specified tracer.
otelOptions: { tracer?: Tracer
tracer }, })
export const const App: FC
App: type FC<P = {}> = FunctionComponent<P>
Represents the type of a function component. Can optionally
receive a type argument that represents the props the component
receives.
FC = () => { const [const storeRegistry: StoreRegistry
storeRegistry] = useState<StoreRegistry>(initialState: StoreRegistry | (() => StoreRegistry)): [StoreRegistry, Dispatch<SetStateAction<StoreRegistry>>] (+1 overload)
Returns a stateful value, and a function to update it.
useState(() => new new StoreRegistry(config?: StoreRegistryConfig): StoreRegistry
Creates a new StoreRegistry instance.
StoreRegistry()) return ( <const Suspense: ExoticComponent<SuspenseProps>
Lets you display a fallback until its children have finished loading.
Suspense SuspenseProps.fallback?: ReactNode
A fallback react tree to show when a Suspense child (like React.lazy) suspends
fallback={const suspenseFallback: JSX.Element
suspenseFallback}> <const StoreRegistryProvider: ({ storeRegistry, children }: StoreRegistryProviderProps) => JSX.Element
React context provider that makes a
StoreRegistry
available to descendant components.
Wrap your application (or a subtree) with this provider to enable
useStore
and
useStoreRegistry
hooks within that tree.
StoreRegistryProvider storeRegistry: StoreRegistry
storeRegistry={const storeRegistry: StoreRegistry
storeRegistry}> <const AppContent: FC
AppContent /> </const Suspense: ExoticComponent<SuspenseProps>
Lets you display a fallback until its children have finished loading.
Suspense> )}
const const AppContent: FC
AppContent: type FC<P = {}> = FunctionComponent<P>
Represents the type of a function component. Can optionally
receive a type argument that represents the props the component
receives.
FC = () => { const const _store: Store<any, {}> & ReactApi
_store = const useAppStore: () => Store<any, {}> & ReactApi
useAppStore() // Use the store in your components return <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{/* Your app content */}</JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>}
import { const defineMaterializer: <TEventDef extends State.SQLite.EventDef.AnyWithoutFn>(_eventDef: TEventDef, materializer: State.SQLite.Materializer<TEventDef>) => State.SQLite.Materializer<TEventDef>
Type-safe wrapper for defining a single materializer.
Useful when defining materializers separately from the materializers() builder.
The first argument provides type inference for the second.
defineMaterializer, import Events
Events, const makeSchema: <TInputSchema extends InputSchema>(inputSchema: TInputSchema) => FromInputSchema.DeriveSchema<TInputSchema>
makeSchema, import Schema
Schema, type SessionIdSymbol = typeof SessionIdSymbolconst SessionIdSymbol: typeof SessionIdSymbol
Can be used in queries to refer to the current session id.
Will be replaced with the actual session id at runtime.
In client document table:
const uiState = State.SQLite.clientDocument({ name: 'ui_state', schema: Schema.Struct({ theme: Schema.Literals(['dark', 'light', 'system']), user: Schema.String, showToolbar: Schema.Boolean, }), default: { value: defaultFrontendState, id: SessionIdSymbol },})
Or in a client document query:
const query$ = queryDb(tables.uiState.get(SessionIdSymbol))
SessionIdSymbol, import State
State } from '@livestore/livestore'
export const const tables: { readonly todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; }; }>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>; readonly uiState: State.SQLite.ClientDocumentTableDef<...>;}
tables = { todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; };}>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>
todos: import State
State.import SQLite
SQLite.function table<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; };}, Partial<...>>(args: { ...;} & Partial<...>): State.SQLite.TableDef<...> (+2 overloads)
Creates a SQLite table definition from columns or an Effect Schema.
This function supports two main ways to define a table:
- Using explicit column definitions
- Using an Effect Schema (either the
name property needs to be provided or the schema needs to have a title/identifier)
// Using explicit columnsconst usersTable = State.SQLite.table({ name: 'users', columns: { id: State.SQLite.text({ primaryKey: true }), name: State.SQLite.text({ nullable: false }), email: State.SQLite.text({ nullable: false }), age: State.SQLite.integer({ nullable: true }), },})
// Using Effect Schema with annotationsimport { Schema } from '@livestore/utils/effect'
const UserSchema = Schema.Struct({ id: Schema.Int.pipe(State.SQLite.withPrimaryKey).pipe(State.SQLite.withAutoIncrement), email: Schema.String.pipe(State.SQLite.withUnique), name: Schema.String, active: Schema.Boolean.pipe(State.SQLite.withDefault(true)), createdAt: Schema.optional(Schema.Date),})
// Option 1: With explicit nameconst usersTable = State.SQLite.table({ name: 'users', schema: UserSchema,})
// Option 2: With name from schema annotation (title or identifier)const AnnotatedUserSchema = UserSchema.annotate({ title: 'users' })const usersTable2 = State.SQLite.table({ schema: AnnotatedUserSchema,})
// Adding indexesconst PostSchema = Schema.Struct({ id: Schema.String.pipe(State.SQLite.withPrimaryKey), title: Schema.String, authorId: Schema.String, createdAt: Schema.Date,}).annotate({ identifier: 'posts' })
const postsTable = State.SQLite.table({ schema: PostSchema, indexes: [ { name: 'idx_posts_author', columns: ['authorId'] }, { name: 'idx_posts_created', columns: ['createdAt'], isUnique: false }, ],})
table({ name: "todos"
name: 'todos', columns: { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; };}
columns: { id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false;}
id: import State
State.import SQLite
SQLite.const text: <string, string, false, typeof NoDefault, true, false>(args: { schema?: Schema.Codec<string, string, never, never>; default?: typeof NoDefault; nullable?: false; primaryKey?: true; autoIncrement?: false;}) => { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false;} (+1 overload)
text({ primaryKey?: true
primaryKey: true }), text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false;}
text: import State
State.import SQLite
SQLite.const text: () => { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false;} (+1 overload)
text(), completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false;}
completed: import State
State.import SQLite
SQLite.const boolean: <boolean, false, false, false, false>(args: { default?: false; nullable?: false; primaryKey?: false; autoIncrement?: false;}) => { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false;} (+1 overload)
boolean({ default?: false
default: false }), createdAt: { columnType: "text"; schema: Schema.Codec<Date, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false;}
createdAt: import State
State.import SQLite
SQLite.const datetime: () => { columnType: "text"; schema: Schema.Codec<Date, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false;} (+1 overload)
datetime(), }, }),const const useAppStore: () => Store<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>, {}> & ReactApi
useAppStore = () => useStore<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct<Fields extends Struct.Fields>.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>, {}, Codec<Json, Json, never, never>>(options: RegistryStoreOptions<...>): Store<...> & ReactApi
Returns a store instance augmented with hooks (store.useQuery() and store.useClientDocument()) for reactive queries.
useStore({ CreateStoreOptions<TSchema extends LiveStoreSchema, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<Json, Json, never, never>>.storeId: string
Unique identifier for the Store instance, stable for its lifetime.
- Valid characters: Only alphanumeric characters, underscores (
_), and hyphens (-)
are allowed. Must match /^[a-zA-Z0-9_-]+$/.
- Globally unique: Use globally unique IDs (e.g., nanoid) to prevent collisions across stores.
- Use namespaces: Prefix to avoid collisions and for easier identification when debugging
(e.g.,
app-root, workspace-abc123, issue-456)
storeId: 'otel-demo', CreateStoreOptions<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct<Fields extends Struct.Fields>.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<...>>; }; state: InternalState; }>, {}, Codec<...>>.schema: FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>
The LiveStore schema defining tables, events, and materializers.
schema, CreateStoreOptions<TSchema extends LiveStoreSchema, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<Json, Json, never, never>>.adapter: Adapter
Adapter used for data storage and synchronization.
adapter, CreateStoreOptions<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct<Fields extends Struct.Fields>.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<...>>; }; state: InternalState; }>, {}, Codec<...>>.batchUpdates?: (run: () => void) => void
Needed in React so LiveStore can apply multiple events in a single render.
batchUpdates, RegistryStoreOptions<TSchema extends LiveStoreSchema = LiveStoreSchema.Any, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<...>>.otelOptions?: Partial<OtelOptions>
OpenTelemetry configuration for tracing store operations.
When provided, store operations (boot, queries, commits) will be traced
under the given root span context using the specified tracer.
otelOptions: { tracer?: Tracer
tracer }, })
export const const App: FC
App: type FC<P = {}> = FunctionComponent<P>
Represents the type of a function component. Can optionally
receive a type argument that represents the props the component
receives.
FC = () => { const [const storeRegistry: StoreRegistry
storeRegistry] = useState<StoreRegistry>(initialState: StoreRegistry | (() => StoreRegistry)): [StoreRegistry, Dispatch<SetStateAction<StoreRegistry>>] (+1 overload)
Returns a stateful value, and a function to update it.
useState(() => new new StoreRegistry(config?: StoreRegistryConfig): StoreRegistry
Creates a new StoreRegistry instance.
StoreRegistry()) return ( <const Suspense: ExoticComponent<SuspenseProps>
Lets you display a fallback until its children have finished loading.
Suspense SuspenseProps.fallback?: ReactNode
A fallback react tree to show when a Suspense child (like React.lazy) suspends
fallback={const suspenseFallback: JSX.Element
suspenseFallback}> <const StoreRegistryProvider: ({ storeRegistry, children }: StoreRegistryProviderProps) => JSX.Element
React context provider that makes a
StoreRegistry
available to descendant components.
Wrap your application (or a subtree) with this provider to enable
useStore
and
useStoreRegistry
hooks within that tree.
StoreRegistryProvider storeRegistry: StoreRegistry
storeRegistry={const storeRegistry: StoreRegistry
storeRegistry}> <const AppContent: FC
AppContent /> </const StoreRegistryProvider: ({ storeRegistry, children }: StoreRegistryProviderProps) => JSX.Element
React context provider that makes a
StoreRegistry
available to descendant components.
Wrap your application (or a subtree) with this provider to enable
useStore
and
useStoreRegistry
hooks within that tree.
StoreRegistryProvider> </const Suspense: ExoticComponent<SuspenseProps>
Lets you display a fallback until its children have finished loading.
Suspense> )}
const const AppContent: FC
AppContent: type FC<P = {}> = FunctionComponent<P>
Represents the type of a function component. Can optionally
receive a type argument that represents the props the component
receives.
FC = () => { const const _store: Store<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>, {}> & ReactApi
_store = const useAppStore: () => Store<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct<Fields extends Struct.Fields>.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>, {}> & ReactApi
useAppStore() // Use the store in your components return <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{/* Your app content */}</JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>}
import { class ZoneContextManager
ZoneContextManager
This module provides an easy functionality for tracing action between asynchronous operations in web.
It was not possible with standard [StackContextManager]
.
It heavily depends on [zone.js]
https://www.npmjs.com/package/zone.js
.
It stores the information about context in zone. Each Context will have always new Zone;
It also supports binding a certain Span to a target that has "addEventListener" and "removeEventListener".
When this happens a new zone is being created and the provided Span is being assigned to this zone.
ZoneContextManager } from '@opentelemetry/context-zone'import { class W3CTraceContextPropagator
Propagates
SpanContext
through Trace Context format propagation.
Based on the Trace Context specification:
https://www.w3.org/TR/trace-context/
W3CTraceContextPropagator } from '@opentelemetry/core'import { class OTLPTraceExporter
Collector Trace Exporter for Node
OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'import { function resourceFromAttributes(attributes: DetectedResourceAttributes, options?: ResourceOptions): Resource
resourceFromAttributes } from '@opentelemetry/resources'import { class SimpleSpanProcessor
An implementation of the
SpanProcessor
that converts the
Span
to
ReadableSpan
and passes it to the configured exporter.
Only spans that are sampled are converted.
NOTE: This
SpanProcessor
exports every ended span individually instead of batching spans together, which causes significant performance overhead with most exporters. For production use, please consider using the
BatchSpanProcessor
instead.
SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'import { class WebTracerProvider
This class represents a web tracer with
StackContextManager
WebTracerProvider } from '@opentelemetry/sdk-trace-web'
/** * Configure a browser tracer that preserves parent/child spans across async work. * Requires a zone.js runtime (e.g. provided by many frameworks) so the ZoneContextManager * can keep context during timers, promises, and event callbacks. */export const const makeTracer: (serviceName: string) => Tracer
Configure a browser tracer that preserves parent/child spans across async work.
Requires a zone.js runtime (e.g. provided by many frameworks) so the ZoneContextManager
can keep context during timers, promises, and event callbacks.
makeTracer = (serviceName: string
serviceName: string) => {const const useAppStore: () => Store<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>, {}> & ReactApi
useAppStore = () => useStore<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct<Fields extends Struct.Fields>.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>, {}, Codec<Json, Json, never, never>>(options: RegistryStoreOptions<...>): Store<...> & ReactApi
Returns a store instance augmented with hooks (store.useQuery() and store.useClientDocument()) for reactive queries.
useStore({ CreateStoreOptions<TSchema extends LiveStoreSchema, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<Json, Json, never, never>>.storeId: string
Unique identifier for the Store instance, stable for its lifetime.
- Valid characters: Only alphanumeric characters, underscores (
_), and hyphens (-)
are allowed. Must match /^[a-zA-Z0-9_-]+$/.
- Globally unique: Use globally unique IDs (e.g., nanoid) to prevent collisions across stores.
- Use namespaces: Prefix to avoid collisions and for easier identification when debugging
(e.g.,
app-root, workspace-abc123, issue-456)
storeId: 'otel-demo', CreateStoreOptions<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct<Fields extends Struct.Fields>.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<...>>; }; state: InternalState; }>, {}, Codec<...>>.schema: FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>
The LiveStore schema defining tables, events, and materializers.
schema, CreateStoreOptions<TSchema extends LiveStoreSchema, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<Json, Json, never, never>>.adapter: Adapter
Adapter used for data storage and synchronization.
adapter, CreateStoreOptions<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct<Fields extends Struct.Fields>.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<...>>; }; state: InternalState; }>, {}, Codec<...>>.batchUpdates?: (run: () => void) => void
Needed in React so LiveStore can apply multiple events in a single render.
batchUpdates, RegistryStoreOptions<TSchema extends LiveStoreSchema = LiveStoreSchema.Any, TContext = {}, TSyncPayloadSchema extends Codec<Json, Json> = Codec<...>>.otelOptions?: Partial<OtelOptions>
OpenTelemetry configuration for tracing store operations.
When provided, store operations (boot, queries, commits) will be traced
under the given root span context using the specified tracer.
otelOptions: { tracer?: Tracer
tracer }, })
export const const App: FC
App: type FC<P = {}> = FunctionComponent<P>
Represents the type of a function component. Can optionally
receive a type argument that represents the props the component
receives.
FC = () => { const [const storeRegistry: StoreRegistry
storeRegistry] = useState<StoreRegistry>(initialState: StoreRegistry | (() => StoreRegistry)): [StoreRegistry, Dispatch<SetStateAction<StoreRegistry>>] (+1 overload)
Returns a stateful value, and a function to update it.
useState(() => new new StoreRegistry(config?: StoreRegistryConfig): StoreRegistry
Creates a new StoreRegistry instance.
StoreRegistry()) return ( <const Suspense: ExoticComponent<SuspenseProps>
Lets you display a fallback until its children have finished loading.
Suspense SuspenseProps.fallback?: ReactNode
A fallback react tree to show when a Suspense child (like React.lazy) suspends
fallback={const suspenseFallback: JSX.Element
suspenseFallback}> <const StoreRegistryProvider: ({ storeRegistry, children }: StoreRegistryProviderProps) => JSX.Element
React context provider that makes a
StoreRegistry
available to descendant components.
Wrap your application (or a subtree) with this provider to enable
useStore
and
useStoreRegistry
hooks within that tree.
StoreRegistryProvider storeRegistry: StoreRegistry
storeRegistry={const storeRegistry: StoreRegistry
storeRegistry}> <const AppContent: FC
AppContent /> </const StoreRegistryProvider: ({ storeRegistry, children }: StoreRegistryProviderProps) => JSX.Element
React context provider that makes a
StoreRegistry
available to descendant components.
Wrap your application (or a subtree) with this provider to enable
useStore
and
useStoreRegistry
hooks within that tree.
StoreRegistryProvider> </const Suspense: ExoticComponent<SuspenseProps>
Lets you display a fallback until its children have finished loading.
Suspense> )}
const const AppContent: FC
AppContent: type FC<P = {}> = FunctionComponent<P>
Represents the type of a function component. Can optionally
receive a type argument that represents the props the component
receives.
FC = () => { const const _store: Store<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>, {}> & ReactApi
_store = const useAppStore: () => Store<FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: EventDef<"v1.TodoCreated", Struct<Fields extends Struct.Fields>.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Type">, Struct.ReadonlySide<{ readonly id: String; readonly text: String; readonly createdAt: DateFromString; }, "Encoded">>; }; state: InternalState;}>, {}> & ReactApi
useAppStore() // Use the store in your components return <JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>{/* Your app content */}</JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div>}
const const useAppStore: () => Store<any, {}> & ReactApi
useAppStore = () => useStore<any, {}, Codec<Json, Json, never, never>>(options: RegistryStoreOptions<any, {}, Codec<Json, Json, never, never>>): Store<any, {}> & ReactApi
Returns a store instance augmented with hooks (store.useQuery() and store.useClientDocument()) for reactive queries.
useStore({import { const makeWorker: (options: WorkerOptions) => void
makeWorker } from '@livestore/adapter-web/worker'
import { import tracer
tracer } from './otel.ts'import { import schema
schema } from './schema.ts'
function makeWorker(options: WorkerOptions): void
makeWorker({ schema: LiveStoreSchema<DbSchema, EventDefRecord>
schema, otelOptions?: { tracer?: Tracer;}
otelOptions: { tracer?: Tracer
tracer } })import { const defineMaterializer: <TEventDef extends State.SQLite.EventDef.AnyWithoutFn>(_eventDef: TEventDef, materializer: State.SQLite.Materializer<TEventDef>) => State.SQLite.Materializer<TEventDef>
Type-safe wrapper for defining a single materializer.
Useful when defining materializers separately from the materializers() builder.
The first argument provides type inference for the second.
defineMaterializer, import Events
Events, const makeSchema: <TInputSchema extends InputSchema>(inputSchema: TInputSchema) => FromInputSchema.DeriveSchema<TInputSchema>
makeSchema, import Schema
Schema, type SessionIdSymbol = typeof SessionIdSymbolconst SessionIdSymbol: typeof SessionIdSymbol
Can be used in queries to refer to the current session id.
Will be replaced with the actual session id at runtime.
In client document table:
const uiState = State.SQLite.clientDocument({ name: 'ui_state', schema: Schema.Struct({ theme: Schema.Literals(['dark', 'light', 'system']), user: Schema.String, showToolbar: Schema.Boolean, }), default: { value: defaultFrontendState, id: SessionIdSymbol },})
Or in a client document query:
const query$ = queryDb(tables.uiState.get(SessionIdSymbol))
SessionIdSymbol, import State
State } from '@livestore/livestore'
export const const tables: { readonly todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; }; }>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>; readonly uiState: State.SQLite.ClientDocumentTableDef<...>;}
tables = { todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; };}>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>
todos: import State
State.import SQLite
SQLite.function table<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; };}, Partial<...>>(args: { ...;} & Partial<...>): State.SQLite.TableDef<...> (+2 overloads)
Creates a SQLite table definition from columns or an Effect Schema.
This function supports two main ways to define a table:
- Using explicit column definitions
- Using an Effect Schema (either the
name property needs to be provided or the schema needs to have a title/identifier)
// Using explicit columnsconst usersTable = State.SQLite.table({ name: 'users', columns: { id: State.SQLite.text({ primaryKey: true }), name: State.SQLite.text({ nullable: false }), email: State.SQLite.text({ nullable: false }), age: State.SQLite.integer({ nullable: true }), },})
// Using Effect Schema with annotationsimport { Schema } from '@livestore/utils/effect'
const UserSchema = Schema.Struct({ id: Schema.Int.pipe(State.SQLite.withPrimaryKey).pipe(State.SQLite.withAutoIncrement), email: Schema.String.pipe(State.SQLite.withUnique), name: Schema.String, active: Schema.Boolean.pipe(State.SQLite.withDefault(true)), createdAt: Schema.optional(Schema.Date),})
// Option 1: With explicit nameconst usersTable = State.SQLite.table({ name: 'users', schema: UserSchema,})
// Option 2: With name from schema annotation (title or identifier)const AnnotatedUserSchema = UserSchema.annotate({ title: 'users' })const usersTable2 = State.SQLite.table({ schema: AnnotatedUserSchema,})
// Adding indexesconst PostSchema = Schema.Struct({ id: Schema.String.pipe(State.SQLite.withPrimaryKey), title: Schema.String, authorId: Schema.String, createdAt: Schema.Date,}).annotate({ identifier: 'posts' })
const postsTable = State.SQLite.table({ schema: PostSchema, indexes: [ { name: 'idx_posts_author', columns: ['authorId'] }, { name: 'idx_posts_created', columns: ['createdAt'], isUnique: false }, ],})
table({ name: "todos"
name: 'todos', columns: { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; };}
columns: { id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false;}
id: import State
State.import SQLite
SQLite.const text: <string, string, false, typeof NoDefault, true, false>(args: { schema?: Schema.Codec<string, string, never, never>; default?: typeof NoDefault; nullable?: false; primaryKey?: true; autoIncrement?: false;}) => { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false;} (+1 overload)
text({ primaryKey?: true
primaryKey: true }), text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false;}
text: import State
State.import SQLite
SQLite.const text: () => { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false;} (+1 overload)
text(), completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false;}
completed: import State
State.import SQLite
SQLite.const boolean: <boolean, false, false, false, false>(args: { default?: false; nullable?: false; primaryKey?: false; autoIncrement?: false;}) => { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false;} (+1 overload)
boolean({ default?: false
default: false }), createdAt: { columnType: "text"; schema: Schema.Codec<Date, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false;}
createdAt: import State
State.import SQLite
SQLite.const datetime: () => { columnType: "text"; schema: Schema.Codec<Date, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false;} (+1 overload)
datetime(), }, }), uiState: State.SQLite.ClientDocumentTableDef<"UiState", Schema.Struct.ReadonlySide<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}, "Type">, Schema.Struct.ReadonlySide<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}, "Encoded">, { partialSet: true; default: { id: typeof SessionIdSymbol; value: { readonly newTodoText: ""; readonly filter: "all"; }; };}>
uiState: import State
State.import SQLite
SQLite.clientDocument<"UiState", Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlySide<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}, "Type">, Schema.Struct.ReadonlySide<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}, "Encoded">, { readonly name: "UiState"; readonly schema: Schema.Struct<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>; }>; readonly default: { ...; };}>({ name, schema: valueSchema, ...inputOptions }: { ...;} & { readonly name: "UiState"; readonly schema: Schema.Struct<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>; }>; readonly default: { ...; };}): State.SQLite.ClientDocumentTableDef<...>export clientDocument
Special:
- Synced across client sessions (e.g. tabs) but not across different clients
- Derived setters
- Emits client-only events
- Has implicit setter-materializers
- Similar to
React.useState (except it's persisted)
Careful:
- When changing the table definitions in a non-backwards compatible way, the state might be lost without
explicit materializers to handle the old auto-generated events
Usage:
// Querying data// `'some-id'` can be ommited for SessionIdSymbolstore.queryDb(clientDocumentTable.get('some-id'))
// Setting data// Again, `'some-id'` can be ommited for SessionIdSymbolstore.commit(clientDocumentTable.set({ someField: 'some-value' }, 'some-id'))
clientDocument({ name: "UiState"
name: 'UiState', schema: Schema.Codec<Schema.Struct.ReadonlySide<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}, "Type">, Schema.Struct.ReadonlySide<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}, "Encoded">, never, never> & Schema.Struct<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}>
schema: import Schema
Schema.function Struct<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}>(fields: { readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}): Schema.Struct<{ readonly newTodoText: Schema.String; readonly filter: Schema.Literals<readonly ["all", "active", "completed"]>;}>
Defines a struct schema from a map of field schemas.
Details
Each field value is a schema. Use
optionalKey
or
optional
to
mark fields as optional, and
mutableKey
to mark them as mutable.
The resulting schema's Type is a readonly object type with the fields'
decoded types. The Encoded form mirrors the field schemas' encoded types.
Example (Defining a basic struct)
import { Schema } from "effect"
const Person = Schema.Struct({ name: Schema.String, age: Schema.Number, email: Schema.optionalKey(Schema.String)})
// { readonly name: string; readonly age: number; readonly email?: string }type Person = typeof Person.Type
const alice = Schema.decodeUnknownSync(Person)({ name: "Alice", age: 30 })console.log(alice)// { name: 'Alice', age: 30 }
Struct({ newTodoText: Schema.String
newTodoText: import Schema
Schema.const String: Schema.String
Type-level representation of
String
.
Schema for string values. Validates that the input is typeof "string".
String, filter: Schema.Literals<readonly ["all", "active", "completed"]>
filter: import Schema
Schema.function Literals<readonly ["all", "active", "completed"]>(literals: readonly ["all", "active", "completed"]): Schema.Literals<readonly ["all", "active", "completed"]>
Creates a union schema from an array of literal values.
Example (Defining status codes)
import { Schema } from "effect"
const schema = Schema.Literals(["active", "inactive", "pending"])// accepts "active", "inactive", or "pending"
Literals(['all', 'active', 'completed']), }), default: { readonly id: typeof SessionIdSymbol; readonly value: { readonly newTodoText: ""; readonly filter: "all"; };}
default: { id: typeof SessionIdSymbol
id: const SessionIdSymbol: typeof SessionIdSymbol
Can be used in queries to refer to the current session id.
Will be replaced with the actual session id at runtime.
In client document table:
const uiState = State.SQLite.clientDocument({ name: 'ui_state', schema: Schema.Struct({ theme: Schema.Literals(['dark', 'light', 'system']), user: Schema.String, showToolbar: Schema.Boolean, }), default: { value: defaultFrontendState, id: SessionIdSymbol },})
Or in a client document query:
const query$ = queryDb(tables.uiState.get(SessionIdSymbol))
SessionIdSymbol, value: { readonly newTodoText: ""; readonly filter: "all";}
value: { newTodoText: ""
newTodoText: '', filter: "all"
filter: 'all' } }, }),} as type const = { readonly todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; }; }>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>; readonly uiState: State.SQLite.ClientDocumentTableDef<...>;}
const
export const const events: { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>;}
events = { todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Encoded">>
todoCreated: import Events
Events.synced<"v1.TodoCreated", Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Encoded">>(args: { name: "v1.TodoCreated"; schema: Schema.Codec<Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<...>, never, never>;} & Omit<...>): State.SQLite.EventDef<...>export synced
Creates a synced event definition.
Synced events are sent to the sync backend and distributed to all connected
clients. Use this for collaborative data that should be shared across users
and devices.
Event names should be versioned (e.g., v1.TodoCreated) to support
schema evolution over time.
synced({ name: "v1.TodoCreated"
name: 'v1.TodoCreated', schema: Schema.Codec<Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Encoded">, never, never>
schema: import Schema
Schema.function Struct<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}>(fields: { readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}): Schema.Struct<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}>
Defines a struct schema from a map of field schemas.
Details
Each field value is a schema. Use
optionalKey
or
optional
to
mark fields as optional, and
mutableKey
to mark them as mutable.
The resulting schema's Type is a readonly object type with the fields'
decoded types. The Encoded form mirrors the field schemas' encoded types.
Example (Defining a basic struct)
import { Schema } from "effect"
const Person = Schema.Struct({ name: Schema.String, age: Schema.Number, email: Schema.optionalKey(Schema.String)})
// { readonly name: string; readonly age: number; readonly email?: string }type Person = typeof Person.Type
const alice = Schema.decodeUnknownSync(Person)({ name: "Alice", age: 30 })console.log(alice)// { name: 'Alice', age: 30 }
Struct({ id: Schema.String
id: import Schema
Schema.const String: Schema.String
Type-level representation of
String
.
Schema for string values. Validates that the input is typeof "string".
String, text: Schema.String
text: import Schema
Schema.const String: Schema.String
Type-level representation of
String
.
Schema for string values. Validates that the input is typeof "string".
String, createdAt: Schema.DateFromString
createdAt: import Schema
Schema.const DateFromString: Schema.DateFromString
Type-level representation of
DateFromString
.
Schema that decodes a string into a JavaScript Date.
When to use
Use to model string-encoded dates that decode to JavaScript Date objects
and encode back to strings.
Details
Decoding:
The string is passed to JavaScript Date construction.
Encoding:
A valid Date is encoded as an ISO string; an invalid Date is encoded as
"Invalid Date".
Gotchas
Invalid date strings can decode to invalid Date instances.
DateFromString.Bottom<unknown, unknown, unknown, unknown, Declaration, decodeTo<Date, String, never, never>, unknown, unknown, readonly [], unknown, "readonly", "required", "no-default", "readonly", "required">.check(checks_0: Check<Date>, ...checks: Check<Date>[]): Schema.DateFromString
check(import Schema
Schema.function isDateValid(annotations?: Schema.Annotations.Filter): Filter<globalThis.Date>
Validates that a Date object represents a valid date (not an invalid date
like new Date("invalid")).
Details
JSON Schema:
This check does not have a direct JSON Schema equivalent, as JSON Schema
validates date strings, not Date objects.
Arbitrary:
When generating test data with fast-check, this applies a valid: true
constraint to ensure generated Date objects are valid.
isDateValid()), }), }),} as type const = { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>;}
const
const const materializers: { "v1.TodoCreated": State.SQLite.Materializer<State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>>;}
materializers = import State
State.import SQLite
SQLite.const materializers: <{ readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>;}>(_eventDefRecord: { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>;}, handlers: { ...;}) => { ...;}
Builder function for creating a type-safe materializer map.
This is the primary way to define materializers in LiveStore. It ensures:
- Every non-derived event has a corresponding materializer
- Materializer argument types match their event schemas
- Derived events are excluded from the required handlers
materializers(const events: { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>;}
events, { [const events: { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>;}
events.todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Encoded">>
todoCreated.name: "v1.TodoCreated"
Unique identifier for this event type. Conventionally versioned (e.g., v1.TodoCreated).
name]: defineMaterializer<State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Encoded">>>(_eventDef: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Type">, Schema.Struct.ReadonlySide<...>>, materializer: State.SQLite.Materializer<...>): State.SQLite.Materializer<...>
Type-safe wrapper for defining a single materializer.
Useful when defining materializers separately from the materializers() builder.
The first argument provides type inference for the second.
defineMaterializer(const events: { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>;}
events.todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString;}, "Encoded">>
todoCreated, ({ id: string
id, text: string
text, createdAt: Date
createdAt }) => const tables: { readonly todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; }; }>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>; readonly uiState: State.SQLite.ClientDocumentTableDef<...>;}
tables.todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; };}>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>
todos.insert: (values: { readonly text: string; readonly id: string; readonly createdAt: Date; readonly completed?: boolean;}) => QueryBuilder<readonly Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlySide<{ readonly id: Schema.Codec<string, string, never, never>; readonly text: Schema.Codec<string, string, never, never>; readonly completed: Schema.Codec<boolean, number, never, never>; readonly createdAt: Schema.Codec<Date, string, never, never>;}, "Type">[], State.SQLite.TableDefBase<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; ... 4 more ...; autoIncrement: false; }; readonly text: { ...; }; readonly completed: { ...; }; readonly createdAt: { ...; };}>, State.SQLite.WithDefaults<...>>, "select" | ... 6 more ... | "row">
Insert a new row into the table.
insert({ id: string
id, text: string
text, completed?: boolean
completed: false, createdAt: Date
createdAt }), ),})
const const state: InternalState
state = import State
State.import SQLite
SQLite.const makeState: <{ tables: { readonly todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; }; }>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>; readonly uiState: State.SQLite.ClientDocumentTableDef<...>; }; materializers: { ...; };}>(inputSchema: { tables: { readonly todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; }; }>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>; readonly uiState: State.SQLite.ClientDocumentTableDef<...>; }; materializers: { ...; };}) => InternalState
makeState({ tables: { readonly todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", { readonly id: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: true; autoIncrement: false; }; readonly text: { columnType: "text"; schema: Schema.Codec<string, string, never, never>; default: None<never>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly completed: { columnType: "integer"; schema: Schema.Codec<boolean, number, never, never>; default: Some<false>; nullable: false; primaryKey: false; autoIncrement: false; }; readonly createdAt: { ...; }; }>, State.SQLite.WithDefaults<...>, Schema.Struct<...>>; readonly uiState: State.SQLite.ClientDocumentTableDef<...>;}
tables, materializers: { "v1.TodoCreated": State.SQLite.Materializer<State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>>;}
materializers })
export const const schema: FromInputSchema.DeriveSchema<{ events: { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>; }; state: InternalState;}>
schema = makeSchema<{ events: { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>; }; state: InternalState;}>(inputSchema: { events: { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>; }; state: InternalState;}): FromInputSchema.DeriveSchema<...>
makeSchema({ events: { readonly todoCreated: State.SQLite.EventDef<"v1.TodoCreated", Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Type">, Schema.Struct.ReadonlySide<{ readonly id: Schema.String; readonly text: Schema.String; readonly createdAt: Schema.DateFromString; }, "Encoded">>;}
events, state: InternalState
state })import { class ZoneContextManager
ZoneContextManager
This module provides an easy functionality for tracing action between asynchronous operations in web.
It was not possible with standard [StackContextManager]
.
It heavily depends on [zone.js]
https://www.npmjs.com/package/zone.js
.
It stores the information about context in zone. Each Context will have always new Zone;
It also supports binding a certain Span to a target that has "addEventListener" and "removeEventListener".
When this happens a new zone is being created and the provided Span is being assigned to this zone.
ZoneContextManager } from '@opentelemetry/context-zone'import { class W3CTraceContextPropagator
Propagates
SpanContext
through Trace Context format propagation.
Based on the Trace Context specification:
https://www.w3.org/TR/trace-context/
W3CTraceContextPropagator } from '@opentelemetry/core'import { class OTLPTraceExporter
Collector Trace Exporter for Node
OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'import { function resourceFromAttributes(attributes: DetectedResourceAttributes, options?: ResourceOptions): Resource
resourceFromAttributes } from '@opentelemetry/resources'import { class SimpleSpanProcessor
An implementation of the
SpanProcessor
that converts the
Span
to
ReadableSpan
and passes it to the configured exporter.
Only spans that are sampled are converted.
NOTE: This
SpanProcessor
exports every ended span individually instead of batching spans together, which causes significant performance overhead with most exporters. For production use, please consider using the
BatchSpanProcessor
instead.
SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'import { class WebTracerProvider
This class represents a web tracer with
StackContextManager
WebTracerProvider } from '@opentelemetry/sdk-trace-web'
/** * Configure a browser tracer that preserves parent/child spans across async work. * Requires a zone.js runtime (e.g. provided by many frameworks) so the ZoneContextManager * can keep context during timers, promises, and event callbacks. */export const const makeTracer: (serviceName: string) => Tracer
Configure a browser tracer that preserves parent/child spans across async work.
Requires a zone.js runtime (e.g. provided by many frameworks) so the ZoneContextManager
can keep context during timers, promises, and event callbacks.
makeTracer = (serviceName: string
serviceName: string) => { const const url: string | undefined
url = import.
The type of import.meta.
If you need to declare that a given property exists on import.meta,
this type may be augmented via interface merging.
meta.ImportMeta.env: Bun.Env & NodeJS.ProcessEnv & ImportMetaEnv
The environment variables of the process
import.meta.env === process.env
env.string | undefined
VITE_OTEL_EXPORTER_OTLP_ENDPOINT const const provider: WebTracerProvider
provider = new new WebTracerProvider(config?: WebTracerConfig): WebTracerProvider
Constructs a new Tracer instance.
WebTracerProvider({ TracerConfig.spanProcessors?: SpanProcessor[]
List of SpanProcessor for the tracer
spanProcessors: const url: string | undefined
url !== var undefined
undefined ? [new new SimpleSpanProcessor(_exporter: SpanExporter): SimpleSpanProcessor
An implementation of the
SpanProcessor
that converts the
Span
to
ReadableSpan
and passes it to the configured exporter.
Only spans that are sampled are converted.
NOTE: This
SpanProcessor
exports every ended span individually instead of batching spans together, which causes significant performance overhead with most exporters. For production use, please consider using the
BatchSpanProcessor
instead.
SimpleSpanProcessor(new new OTLPTraceExporter(config?: OTLPExporterNodeConfigBase): OTLPTraceExporter
Collector Trace Exporter for Node
OTLPTraceExporter({ OTLPExporterConfigBase.url?: string
url: `${const url: string
url}/v1/traces` }))] : [], TracerConfig.resource?: Resource
Resource associated with trace telemetry
resource: function resourceFromAttributes(attributes: DetectedResourceAttributes, options?: ResourceOptions): Resource
resourceFromAttributes({ 'service.name': serviceName: string
serviceName }), })
const provider: WebTracerProvider
provider.WebTracerProvider.register(config?: SDKRegistrationConfig): void
Register this TracerProvider for use with the OpenTelemetry API.
Undefined values may be replaced with defaults, and
null values will be skipped.
register({ SDKRegistrationConfig.contextManager?: ContextManager | null
Context manager to register as the global context manager
contextManager: new new ZoneContextManager(): ZoneContextManager
ZoneContextManager
This module provides an easy functionality for tracing action between asynchronous operations in web.
It was not possible with standard [StackContextManager]
.
It heavily depends on [zone.js]
https://www.npmjs.com/package/zone.js
.
It stores the information about context in zone. Each Context will have always new Zone;
It also supports binding a certain Span to a target that has "addEventListener" and "removeEventListener".
When this happens a new zone is being created and the provided Span is being assigned to this zone.
ZoneContextManager(), SDKRegistrationConfig.propagator?: TextMapPropagator<any> | null
Propagator to register as the global propagator
propagator: new new W3CTraceContextPropagator(): W3CTraceContextPropagator
Propagates
SpanContext
through Trace Context format propagation.
Based on the Trace Context specification:
https://www.w3.org/TR/trace-context/
W3CTraceContextPropagator(), })
return const provider: WebTracerProvider
provider.BasicTracerProvider.getTracer(name: string, version?: string, options?: { schemaUrl?: string;}): Tracer
Returns a Tracer, creating one if one with the given name and version is
not already created.
This function may return different Tracer types (e.g.
NoopTracerProvider
vs. a functional tracer).
getTracer('livestore')}
export const const tracer: Tracer
tracer = const makeTracer: (serviceName: string) => Tracer
Configure a browser tracer that preserves parent/child spans across async work.
Requires a zone.js runtime (e.g. provided by many frameworks) so the ZoneContextManager
can keep context during timers, promises, and event callbacks.
makeTracer('my-app')export { export schema
schema } from '../framework-integrations/react/schema.ts'