Live source protocol and support status
SqsMap's own gis-live-v1 carries complete Point snapshots or deltas. Phase 11.4a moves the existing desktop validator into the sqs-geo Rust module; the desktop Dataset adapter uses the same implementation. The module compiles for wasm32. Phase 11.4b exposes batch ingestion through public C, WASM, SDK and common scripts. Phases11.4c1/c2 connect HTTP and WebSocket receivers with separate transport acceptance; protocol and batch-ingestion checks alone do not establish a network receiver.
The existing desktop gis.live.connect uses HTTP polling/WebSocket and scene ownership, following scene start/pause/stop. gis.live.snapshot freezes the displayed version for analysis. Uniform source handles, cross-host pause/resume/cancellation and network channels are being connected. Ordinary GeoJSON setData/updateData retains its own format; gis-live-v1 is a separate SqsMap extension.
Complete snapshots and deltas
{"kind":"snapshot","epoch":"demo","sequence":"9007199254740993","points":[{"id":"a","coordinate":[117,27],"properties":{"name":"Sample","active":true}}]}
{"kind":"delta","epoch":"demo","baseSequence":"9007199254740993","sequence":"9007199254740994","upserts":[{"id":"b","coordinate":[118,27],"properties":{"name":"Sample two","active":null}}],"deletes":["a"]}
The schema is fixed at initialization: at most 32 fields, names of 1..64 bytes, types string/number/boolean, nullable values. Every point contains exactly the declared fields; string values are at most 1024 bytes and numbers must be finite. Point IDs are unique strings of 1..128 bytes. Coordinates are WGS84 longitude/latitude, longitude ±180 and latitude ±85.0511287798066; at most 4096 points are retained.
A complete snapshot may change epoch. Within an epoch, sequences advance; an identical verified update or equivalent complete snapshot at the same sequence does not advance revision again. Deltas require explicit enablement, the same epoch, baseSequence equal to the current sequence and a larger new sequence. A discontinuity reports Conflict and requires a full snapshot. Upserts and deletes must not duplicate or overlap.
An epoch is a 1..128-byte string. sequence/baseSequence are decimal u128 strings of 1..39 digits, up to 340282366920938463463374607431768211455. Do not convert them to JavaScript Number. Message versions and map-source dataRevision are separate concepts; their association will be specified with the source adapter.
Atomic validation and budgets
Each message and retained point state has a separate 8 MiB serialized JSON limit. Before cloning input, validation checks at most 32 levels and 200000 nodes. Counting uses a writer without allocating the full JSON text. Point state and the last batch are retained separately; pending_bytes measures serialization size rather than total process memory.
Invalid fields, coordinates, unknown members or types report InvalidArgument; exceeded budgets or u64 revision overflow report ResourceLimit. Failure preserves points, epoch, sequence, revision and the last batch. Duplicate messages consume no revision. geojson returns a stable-ID-ordered independent copy; later source changes do not modify a frozen copy. Network concurrency/rate limits, in-flight cancellation, pause/resume and complete scene ownership belong to subsequent receiver phases.
Rust module usage
use std::collections::BTreeMap;
use sqs_geo::live::Snapshot;
let mut state = Snapshot::new(BTreeMap::from([
("name".into(), "string".into()),
("active".into(), "boolean".into()),
]))?;
state.apply(&serde_json::json!({"kind":"snapshot","epoch":"demo","sequence":"0","points":[]}), false)?;
let frozen_geojson = state.geojson();
The module has no HTTP-client, application-UI, GDAL or scene-host dependency; it reuses serde/serde_json already in the project. This snippet is for Rust source integration. Native live methods and common scripts will be published when those adapters work. External OS, mobile-device and formal-release acceptance remain separate records.
Shared source ingestion, HTTP polling and WebSocket are connected. Scene/mobile integration continues separately.