S2 requires authentication and stream management that can’t be handled directly from the browser. You’ll need to implement an API proxy on your server that:
Handles authentication with S2 using your access token
Manages basins and streams (creates them if they don’t exist)
It is possible to modify this object, but such modifications will not be
reflected outside the Node.js process, or (unless explicitly requested)
to other Worker threads.
In other words, the following example would not work:
Assigning a property on process.env will implicitly convert the value
to a string. This behavior is deprecated. Future versions of Node.js may
throw an error when the value is not a string, number, or boolean.
import { env } from'node:process';
env.test =null;
console.log(env.test);
// => 'null'
env.test =undefined;
console.log(env.test);
// => 'undefined'
Use delete to delete a property from process.env.
import { env } from'node:process';
env.TEST=1;
delete env.TEST;
console.log(env.TEST);
// => undefined
On Windows operating systems, environment variables are case-insensitive.
import { env } from'node:process';
env.TEST=1;
console.log(env.test);
// => 1
Unless explicitly specified when creating a Worker instance,
each Worker thread has its own copy of process.env, based on its
parent thread's process.env, or whatever was specified as the env option
to the Worker constructor. Changes to process.env will not be visible
across Worker threads, and only the main thread can make changes that
are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner
unlike the main thread.
@since ― v0.1.27
env.
string |undefined
S2_BASIN??'your-basin',
S2Config.token: string
token:
var process:NodeJS.Process
process.
NodeJS.Process.env: NodeJS.ProcessEnv
The process.env property returns an object containing the user environment.
See environ(7).
It is possible to modify this object, but such modifications will not be
reflected outside the Node.js process, or (unless explicitly requested)
to other Worker threads.
In other words, the following example would not work:
Assigning a property on process.env will implicitly convert the value
to a string. This behavior is deprecated. Future versions of Node.js may
throw an error when the value is not a string, number, or boolean.
import { env } from'node:process';
env.test =null;
console.log(env.test);
// => 'null'
env.test =undefined;
console.log(env.test);
// => 'undefined'
Use delete to delete a property from process.env.
import { env } from'node:process';
env.TEST=1;
delete env.TEST;
console.log(env.TEST);
// => undefined
On Windows operating systems, environment variables are case-insensitive.
import { env } from'node:process';
env.TEST=1;
console.log(env.test);
// => 1
Unless explicitly specified when creating a Worker instance,
each Worker thread has its own copy of process.env, based on its
parent thread's process.env, or whatever was specified as the env option
to the Worker constructor. Changes to process.env will not be visible
across Worker threads, and only the main thread can make changes that
are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner
unlike the main thread.
@since ― v0.1.27
env.
string |undefined
S2_ACCESS_TOKEN!, // Your S2 access token
}
// HEAD /api/s2 - Health check/ping
exportconst
constHEAD: () =>Promise<Response>
HEAD=async () => {
returnnew
var Response:new (body?:BodyInit|null, init?:ResponseInit) =>Response
The Response interface of the Fetch API represents the response to a request.
The URL interface is used to parse, construct, normalize, and encode URLs. It works by providing properties which allow you to easily read and modify the components of a URL.
Decode args from URLSearchParams using Effect Schema, mirroring Electric's approach.
decodePullArgsFromSearchParams(
consturl:URL
url.
URL.searchParams: URLSearchParams
The searchParams read-only property of the URL interface returns a URLSearchParams object allowing access to the GET decoded query arguments contained in the URL.
The ok read-only property of the Response interface contains a Boolean stating whether the response was successful (status in the range 200-299) or not.
The ok read-only property of the Response interface contains a Boolean stating whether the response was successful (status in the range 200-299) or not.
Decodes an unknown input against a schema synchronously, returning the
decoded value or throwing a
SchemaError
for schema mismatches.
When to use
Use when you need to validate unknown data at a synchronous boundary and want
schema mismatches to throw SchemaError.
Details
For input already typed as the schema's Encoded type use decodeSync.
Only service-free schemas can be decoded synchronously. For alternatives that
do not throw on schema mismatches, see decodeUnknownOption,
decodeUnknownExit, or decodeUnknownEffect. Options may be provided either
when creating the decoder or when applying it; application options override
creation options.
Gotchas
Non-schema failures may throw a runtime failure instead of SchemaError.
Builds one or more append requests against S2. The helper applies the
documented 1 MiB / 1000-record limits via chunkEventsForS2, so callers
receive a request per compliant chunk instead of hitting 413 responses at
runtime.
The ok read-only property of the Response interface contains a Boolean stating whether the response was successful (status in the range 200-299) or not.
LiveStore leverages S2 streams for durable event storage. Understanding the mapping between LiveStore concepts and S2 primitives helps developers comprehend the persistence layer, though direct manipulation is discouraged.
Store to Stream: Each LiveStore storeId maps to exactly one S2 stream. The stream name is derived from the storeId after sanitization to meet S2 naming requirements.
Event Encoding: LiveStore events (AnyEncodedGlobal) are JSON-serialized and stored as the body field of S2 records. Each event contains:
name: Event type identifier
args: Event-specific payload data
seqNum: LiveStore’s global event sequence number
parentSeqNum: Previous event’s sequence number for ordering
clientId: Origin client identifier
sessionId: Session that created the event
Record Structure: When pushed to S2, each LiveStore event becomes one S2 record:
LiveStore and S2 maintain completely independent sequence numbering systems:
LiveStore’s seqNum: Stored inside the JSON event payload (starts at 0). Used for logical event ordering and cursor management within LiveStore.
S2’s seq_num: Assigned by S2 to each record in the stream (also starts at 0). Used solely for stream positioning when reading records.
These are two separate numbering systems that happen to both start at 0. While they often align numerically (first event is LiveStore seqNum 0, stored in S2 record with seq_num 0), this is coincidental rather than a direct mapping. The sync provider:
Preserves LiveStore’s sequence numbers unchanged in the event payload
Uses S2’s seq_num only for querying records from the stream (e.g., “read from position X”)
Never relies on S2’s seq_num for LiveStore’s logical event ordering