Developer experience and documentation #77
Labels
No labels
area:defold
area:docs
area:infra
area:protocol
area:testing
kind:bug
kind:chore
phase:breadth
phase:core
phase:hardening
phase:slice
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
yuris/spacetimedb-defold#77
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The checklist for making the SDK approachable and its documentation true. The narrative version,
with the reasoning and the evidence, is on the wiki:
Roadmap. Each item gets its own
issue when it starts; tick it here when that lands.
Done
BSATN codec and the v2 default, shipped as 2.0.0 (#9, #94). v2 is what
connectspeaksunless a caller opts out, which brings event tables, query-set-scoped subscriptions, reducer
results separated from transaction updates, and 46% of v1's bytes.
HTML5 conformance in CI (#16). Chromium runs the full six-phase smoke inside the job
container, both loads, on path-filtered push and PR rather than a weekly clock.
The HTML5 flake diagnosed and fixed (#81, #93, #98). Two causes under one number. Chromium
outlived its own teardown, and killing the process group ended that. What was left was not a
race:
bob resolvere-downloaded extension-websocket on every invocation, fatal when GitHubrefused even with the archive already cached. Both tiers now build offline from a warm
checkout. 21 v2 and 5 v1 runs green locally, then green on CI's own runners.
confirmed_readsdocumented and pinned per protocol version (#90). The option staystri-state, so a defaulted caller gets whichever default the server applies — false on v1, true
on v2 — and a test holds that resolution to peer-SDK parity.
Runtime schema fetch (#97).
stdb.schema.fetchreads the schema endpoint and builds the typetags in Lua, so a consumer can connect and decode with nothing installed beyond the SDK.
stdb.schema.to_luawrites the pinned module a release build wants, through the same walker,so the two paths cannot drift.
An editor-script regenerate command (#97).
stdb/spacetimedb.editor_scriptputsProject ▸ SpacetimeDB: Regenerate schema one click away, reading
[spacetimedb] base_urland
databasefrom the consumer'sgame.project. It carries its own JSON decoder because theeditor runtime has none, and it shells out to the consumer's
curlbecause a library's filesare zip entries, not files a shell can execute.
An example project a consumer can open and run (#102).
dev/example-chat/is a realgame.projectwith a GUI, plus a headless entry point that proves the wiring: it sends amessage and prints PASS only when that row comes back through
on_insert.A coroutine mode beside the callbacks (#102).
stdb.await(fn, ...)andstdb.await_event(db, type), following nakama-defold's opt-in wrapper rather thanauto-detecting a mode. A truthy
errraises inside the coroutine instead of being returnedfor the caller to forget, and the
stateguard is what stops aresumeon a coroutine thatnever yielded.
Expose connection state and latency (#102).
db:state()isconnecting/connected/reconnecting/closed, assigned only at the five points the SDK already learns of atransition.
db:latency()is an EMA at weight 1/8 — TCP's own SRTT smoothing — overrequest/response pairs the SDK already exchanges, so it costs no traffic;
db:ping(cb)forcesa fresh one.
Restructure the README and the wiki for their two audiences (#97, #99, #100, #102). The README
describes the SDK and carries a working example; the Usage Guide's spine is the v2 default,
with v1 on its own V1-Opt-Out page, wire archaeology on Protocol Notes, and harness and CI on
Development.
.script_api— answered, and needs no code. The Defold manual scopes.script_apitonative extensions ("located together with the extension files") and separately says the editor
generates completions for Lua modules a script requires. A pure-Lua library already gets
completion; there is nothing for a
.script_apito add. Recorded on the wiki roadmap.The cross-client
lightclaim is a test, not a measurement (#104). Phase 8 of the v1conformance run opens a second, ordinary socket and asserts the asymmetry on one commit: the
observer receives
TransactionUpdateLight, the caller a fullTransactionUpdate. Writing itfound a real defect -
stdb.protocolholds its JSON codec in a module local, so a secondconnection with a different implementation re-pointed the first one's decoding in silence.
Guarded in
connection.newnow, and mutation-proven.The extension-websocket subprotocol fix is upstream, as far as it can be. Reported as
defold/extension-websocket#67 and
answered by PR #68 from a Defold
maintainer, verified across
wasm-web,wasm_pthread-weband both macOS targets. Merging istheirs; #15 stays open until it lands and
patches/can go.Released as 3.0.0. The
docs had been bumped to
archive/v3.0.0.zipbefore the tag existed, so every installinstruction 404'd; the tag makes them true.
Parity with the official SDKs (#102, 3.0.0)
Shipped together, because they are one decision: the SDK should be recognisable to someone who
read the official docs.
Typed query builder.
tables.message:where(function(r) return r.sender:eq("yuris") end)compiles to
SELECT * FROM "message" WHERE "message"."sender" = 'yuris'. This was listed asimpossible in the comparison table and is not: the official builder also compiles to SQL text
in the client (
lib/query.ts'stoSql), and the subscription grammar is small and fullyspecified. Operators
eq ne lt lte gt gte, combinatorsand_ or_ not_,left_semijoin/right_semijoin. An unknown column, a value whose type cannot be the column's,a u64 above 2^53 given as a number, a non-hex value for an Identity, an unindexed join column —
each raises at the callsite, naming what was wrong.
not_works despite the grammar having noNOT, by inverting comparisons and applying De Morgan.
A context first in every callback.
on_insert(function(ctx, row) end), carryingdb,reducers,procedures,event, andis_active/disconnect/subscription_builder. This isthe 3.0.0 break, and every caller in the repo moved with it.
Connection builder.
stdb.builder():with_url(...):with_database(...):with_schema(gen) :on_connect(...):build(), sugar overstdb.connect, which stays.Reducer and procedure accessors.
db.reducers.send_message({ ... }, cb), generated fromthe schema, raising on a typo with the real names listed rather than failing later inside the
encoder.
Subscription builder and handle.
db:subscription_builder():on_applied(...):on_error(...) :subscribe(...), withis_active,is_ended,unsubscribe,unsubscribe_then.The example runs in CI (#103). The v2 leg builds it headless and greps for the PASS it
prints only once the row it sent comes back through
on_insert, so the example cannot rotinto a quickstart nobody executes.
Open
Nothing here. What is left of the upstream patch is not this repo's to do, and
#15 tracks it.
Not planned
Reasons recorded so they need not be re-derived: frame compression (a pure-Lua gzip/brotli inflate
is large and slow, and BSATN already halves the bytes); client-side prediction and rollback (a
game-architecture decision belonging above the cache, not inside the SDK); an offline write queue
(replaying writes against a database that moved on, when reconnect deliberately clears the cache and
replays subscriptions); and server-side surfaces such as HTTP handlers, PGWire, submodules and
schedule tables (module-authoring and operations, not a client's job). The wiki page carries the
longer form.
Roadmap: what comes after v1.1.0to Developer experience and documentation