Repository navigation
sql-storage-adapter v0.7.17
·
118 commits
to master
since this release
Added
- The mutation sync in
./sync(#65): a push, pull and rebase protocol for named text rows beside the cross-platform sync.MutationServer, over a store port, records each client's mutation ids in the push's own transaction, answers a pull from one snapshot with a monotonic version as its cookie, streams the pull's patch in batches, replays deletes from tombstones, and cancels a pull still openmaxPullMsafter its call (120 seconds by default).createSqlMutationStoreis a store on the library's own tables, andDrainGateblocks a scope's requests, cancels the running ones and waits for them to leave.MutationClientkeeps durable saves and a journal, rebases, applies a pull atomically, packs pushes and splits them on a 413, joins, leaves, restores across restore epochs and removes rows, andcreateFetchMutationTransportis its HTTP transport.SyncLooppushes then pulls at start, on a save, on becoming visible, on reconnecting, on sign-in and every 60 seconds while the page is visible, trying a failed cycle again after 2 seconds, doubling to 300;attachSyncLoopwires it to the page's events,changeChanneltells the page's other tabs of a commit, andcreateTabLock, in the package since 0.7.13, is exported. No existing export or behaviour changes.
Fixed
transaction()on the PostgreSQL adapter, on a connectionwithConnection()holds and onSupabaseAdapterrejects when PostgreSQL answers its COMMIT with ROLLBACK. A failed statement aborts a PostgreSQL transaction, and PostgreSQL ends the COMMIT of an aborted transaction as a ROLLBACK, with no error of its own, so a callback that caught a statement's error and went on resolvedtransaction()while nothing of it was written. The error says to run a statement that may fail under a savepoint of its own.SupabaseAdapter.batchWriteruns each operation under a savepoint, as the PostgreSQL adapter'sbatchdoes: a failed operation rolls back to its savepoint, the batch goes on, and the operations that succeeded commit. Without one, the failed operation aborted the transaction, every operation after it failed, and the COMMIT wrote nothing, while the result counted the operations before the failure as written. An operation whose values cannot be read, as when a getter throws, counts as failed too, and the batch goes on.SupabaseAdapterhears the connection errors of its clients. The server ending a session (pg_terminate_backend, a restart) or a broken socket emitted anerrorevent nothing listened to, which ends a Node process, whiletransaction()or a read the cache may keep held the client, and while the client sat idle in the pool. The statement now rejects with its own error and PostgreSQL's code (57P01 for a session the server ended), the client is closed, and an idle client's failure is logged through the host logger.- A
SupabaseAdaptertransaction, or a read the cache may keep, whose ROLLBACK could not run after a failure closes its client instead of returning it to the pool. pg'squery_timeoutrejects a statement the server still runs and drops the ROLLBACK queued behind it, so the client went back to the pool inside the transaction, and the next statement given it ran there and never committed.transaction()throws the transaction's own error, with the ROLLBACK's on it as a non-enumerablerollbackError. SupabaseAdapterwithenableCache()on sends aSELECTit may keep the values pg's ownprepareValuewrites for its parameters when the call is made, and keys the answer by those. It bound the caller's values only once it had a client, so values the caller changed after the call were bound and the answer kept under the key of the old ones; it keyed named parameters by the object's own enumerable fields, where the statement binds the value of each name it holds, inherited and non-enumerable ones too; and it keyed a Date by its time, where pg binds its text in the process's time zone, or in UTC underpg.defaults.parseInputDatesAsUTC. With pg before 8.15.0, whose main export has noutils.prepareValue, aSELECTwith parameters runs each time it is asked.SupabaseAdapter'srun,getandall, and its transaction handle'sgetandall, answer a string of several statements, sent with no parameters, as the PostgreSQL adapter does:getnull,allan empty list andrunno row's id. pg answers such a string with a list of results, which has no rows of its own, sogetandrunthrew aTypeErrorafter PostgreSQL had run every statement, andallansweredundefined.SupabaseAdapter's cache ends a--comment at a carriage return as well as a line feed, as PostgreSQL does, so-- note\rVALUES (nextval('ids'))is not taken for aSELECT, and runs each time it is asked.