chore(release): version packages#281
Open
github-actions[bot] wants to merge 1 commit into
Open
Conversation
74286b7 to
05d53d8
Compare
05d53d8 to
a8f8391
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@xnetjs/core@0.1.0
Minor Changes
#284
d6d0470Thanks @crs48! - Add shared dependency-free helpers to@xnetjs/coreand unify the SSRF guard.@xnetjs/corenow exportsclamp,clamp01,formatBytes, and theliteral-host SSRF guard (
assertPublicUrl,validateExternalUrl,SsrfError),replacing several behaviour-identical copies that had drifted across packages —
including byte formatters that silently capped at megabytes and a regex-based
URL guard that missed private ranges (CGNAT, IPv4-mapped IPv6, NAT64, the
fe81::–fe8f::link-local block, and the trailing-dot bypass).@xnetjs/pluginsnow delegates its outbound-action SSRF check to the canonicalguard while keeping its
ActionSsrfErrorcontract;@xnetjs/reactbytedisplays no longer cap at megabytes.
@xnetjs/data@0.1.0
Minor Changes
#328
f626e50Thanks @crs48! - Add the account/device ledger schemas (explorations 0149 + 0243, Phase 2 foundation):AccountRecord,DeviceRecord,RecoveryRecord, andRevocationRecord. A stableaccount subject owns a set of records describing which devices may act as the account,
which recovery methods exist, and which keys are revoked (with
status+epochforrevocation), so the cloud billing binding can later pin to the account root instead of
a single device DID.
Ships with deterministic ids (
accountRecordId/deviceRecordId/ …) and the pureauthorization resolution the hub will enforce —
resolveActiveDevicesandisDeviceAuthorized("is this device currently authorized for this account?"). Therecords are authorization-exempt at the schema level because access is controller-
signed and epoch-gated (hub-enforced), not a per-node role cascade; signing enforcement
and the binding migration are follow-ups.
#329
df76befThanks @crs48! - Add account/device ledger operations (explorations 0149 + 0243, Phase 2): purebuilders that turn a ledger intent into the deterministic node to upsert —
createAccountRecord,admitDeviceRecord,revokeDeviceRecord/revokeSubjectRecord(which bumps the account epoch), plusaccountStateto resolvethe current epoch and the set of devices that may currently act as an account. These
are the rules the store/hub wiring and the content-key re-wrap will call; keeping them
pure makes device admit/revoke unit-testable on its own.
#277
4658b8fThanks @crs48! - Materialized views can now coexist with read authorization. Eachmaterialization is stamped with a reload-stable authorization fingerprint
(subject + grant-state version), so a view is authorized once at refresh and
served from the persisted cache without per-row re-checks — while any grant
change forces an
authz-changedre-materialization. The cached id list cannever serve a row a revoked viewer may no longer read. Adds a nullable
auth_fingerprintcolumn tonode_query_materializations(schema v7, appliedto existing databases via a defensive column guard) plus optional
setNodeReadAuthorizer/getAuthorizationStateVersionstorage-adapter seams.#278
4aec093Thanks @crs48! - Fix the cold-start boot stall and silent registry persistence failure (exploration 0227).Workspace presence Y.Docs (
presence-*) are now in-memory only — nevercold-loaded from
yjs_statenor persisted back — so presence-doc warming nolonger head-of-line blocks the landing read queries on the single SQLite worker
at boot.
NodePoolConfiggainsisEphemeralandlargeDocWarnBytesoptions.The sync registry now persists its tracked-node set through a new FK-free
app-state key/value (
getAppState/setAppStateon the storage adapter, backedby
sync_state) instead ofyjs_state, fixing aSQLITE_CONSTRAINT_FOREIGNKEY(787) that silently prevented the registry from ever persisting.
#331
37d4462Thanks @crs48! - Add account/device content-key re-wrap tocomputeRecipients(exploration 0243, P2.3).A new optional
expandDeviceRecipientsdependency lets each DID recipient expand toevery currently active device of the account it belongs to, so a user's content is
decryptable on all their devices: admitting a device (a
DeviceRecord) makes it arecipient on the next recompute, and revoking it removes it from future re-wraps.
Build the function from ledger records with the new
deviceRecipientExpander. When thedependency is omitted, recipients are exactly the resolved DIDs (no behavior change),
and an identity that belongs to no account expands to only itself — so an unrelated DID
never gains access to another account's data.
#283
e531d0dThanks @crs48! - Extend the map layer-source model for richer GIS layers (exploration 0230).MapLayerSourcegains two new kinds —raster(an XYZ imagery/topo tileoverlay) and
pmtiles(a self-hosted vector tileset referenced by BlobStorecontent id) — and the reserved
querykind now carries an optionalwherefilter and
tooltipproperty keys.MapBasemapIdadds a key-lesssatellitebasemap. All additive; existing inline-GeoJSON maps are unaffected.
Patch Changes
4658b8f,985ac8f,d4bfe27,4fb460a,7e6f5b7,d7a87da,fc3aa1d,5da8d92,3261a75,d6d0470,b327f99,b0cd77c,142b1c0,0e0802d,839b2b7,d9008d2,ddf47b9]:@xnetjs/identity@0.1.0
Minor Changes
#339
4fb460aThanks @crs48! - Wire social recovery ("trusted guardians") into the UI (exploration 0243) — xNet'sApple-recovery-contacts analogue. Settings → Account can split a recoverable identity
into 3 guardian share codes (any 2 recover it), and onboarding gains a "Recover with
guardian shares" path that reconstructs the identity from enough codes on a new device.
@xnetjs/identityaddsserializeShare/parseSharefor the copy-pasteablexnet-share:…codes. Recovery is entirely user-to-user; the cloud is never involved.#320
d7a87daThanks @crs48! - Add recoverable-identity primitives so a lost passkey no longer means lost data(exploration 0243, Phase 1). A recovery phrase now deterministically reproduces the
same DID and the same X25519 encryption key on any device — which is what gates
access to end-to-end-encrypted data — so typing the phrase restores your workspace
without any custodial escrow.
New exports from
@xnetjs/identity:generateRecoveryPhrase()/validateRecoveryPhrase()— mint and check phrasesagainst the recovery wordlist (now exported as
RECOVERY_WORDLIST); defaults to a24-word (~144-bit) phrase.
recoveryPhraseToBundle()/didForRecoveryPhrase()/createRecoverableIdentity()— derive a full key bundle (or just the DID) from a phrase; identical on every
device.
sealRecoveryPhrase()/openRecoveryPhrase()— encrypt a phrase at rest so it canbe re-shown later behind a passkey gate.
These are pure (no WebAuthn/storage); the IdentityManager and onboarding wiring land
in a follow-up.
#322
fc3aa1dThanks @crs48! - Add opt-in recoverable identities to theIdentityManager(exploration 0243, Phase 1).A recoverable identity is born from a recovery phrase and gated by a passkey, so it can
be rebuilt on any device by typing the phrase — without weakening the default, which
stays the stronger PRF-derived identity that stores nothing at rest.
New
IdentityManagermethods:createRecoverable()— mint a new identity from a fresh phrase, enroll a gatingpasskey, and return the phrase to show once.
importRecoveryPhrase(phrase)— adopt an identity from a phrase on a new device(lost passkey), reproducing the same DID and X25519 key.
exportRecoveryPhrase()— reveal the phrase behind a passkey gate (Settings "viewphrase"); returns null for non-recoverable identities.
isRecoverable()— whether the stored identity has a saved phrase.The sealed phrase is persisted alongside the encrypted bundle (
storeIdentitygains anoptional
recoveryarg). Also exportsenrollRecoverableIdentity.#335
5da8d92Thanks @crs48! - Add the privacy-preserving recovery-escrow primitive (exploration 0243, P3.1). Escrowlets a user recover without keeping a long recovery phrase, but without letting the
cloud read their data alone:
sealEscrow/openEscrowencrypt the recoverybackupKeyunder a user-held PIN (plus
serializeEscrow/deserializeEscrowfor the opaque blob thecloud KMS-wraps). Recovery then needs both a verified WorkOS session (the cloud's KMS
factor) and the PIN (the user's factor). A new
@xnetjs/cloud/escrowmodule holds thecloud half (
EscrowStore, injectedKmsWrapper, andenable/disable/recoverwithsession-gating — escrow is absent unless enabled and unreachable without a verified
session). The fully-custodial "cloud can recover from the login alone" variant is
deliberately not built; it needs an explicit product decision (see the design note).
#337
b327f99Thanks @crs48! - Add social-recovery ("guardians") methods to theIdentityManager(exploration 0243) —the Apple-ADP "recovery contacts" analogue, built on the Shamir secret-sharing already
in
seed-recovery.ts.createGuardianShares(config)splits a recoverable identity'sphrase into
totalSharesshares of which anythresholdreconstruct it (prompting forthe passkey to read the phrase);
recoverFromGuardianShares(shares)reconstructs thephrase from enough shares on a new device, reproduces the same DID, and enrolls a local
passkey. Recovery is entirely user-to-user — the cloud is never involved, so it stays
zero-knowledge and non-coercible by construction.
#333
ddf47b9Thanks @crs48! - Surface synced-passkey recovery in onboarding (exploration 0243, P1.4). TheIdentityManagergainsrecoverViaSyncedPasskey(), which discovers an xNet passkeysynced from another device (iCloud Keychain / Google Password Manager), unlocks it
(same PRF → same DID), and stores it locally — returning null when none is available so
the caller can fall back to the recovery phrase. The import screen now leads with a
"Use a synced passkey" option (new
USE_SYNCED_PASSKEYonboarding event), givingsame-ecosystem users a phrase-free return path.
Patch Changes
d6d0470]:@xnetjs/plugins@0.1.0
Minor Changes
#291
acbf801Thanks @crs48! - AI assist now defaults to a "scaffold" mode that keeps you the author — the modelproposes and cites, you write and own — as a guard against LLM deskilling
(Humane Internet Charter §Agency). Every assistant turn is tagged with
ai-generatedprovenance and the mode it was produced under, and a newcomposeAssistSystemPrompthelper appends the cognitive-debt guard in scaffoldmode.
draftmode (the model writes finished prose) must be opted intoexplicitly via
assistMode: 'draft'.#349
1a44c5dThanks @crs48! - Connector detection now reports the in-tab AI tiers as available only when theycan actually run, fixing a chat composer that stayed disabled with no
explanation.
webllmis gated on a newConnectorEnv.hasWebLLMEngineprobe (inaddition to WebGPU) so it's never advertised without a host-supplied engine, and
the default
prompt-apiprobe now readsLanguageModel.availability()andtreats only
'available'as ready (mere API presence with a'downloadable'model no longer counts). Adds
promptApiAvailability()(raw state, for offeringa download gesture) and
downloadPromptApiModel()(gesture-driven, monitoreddownload), plus the
PromptApiAvailabilityandLanguageModelMonitortypes.#316
2a638ecThanks @crs48! - The managed XNet Cloud AI provider (ManagedProvider) now supports streaming.It implements
stream()over the new/ai/chat/streamSSE endpoint — yieldingtext deltas as they arrive and reporting the live budget from the terminal event —
and its capabilities now advertise
streaming: true. A pre-stream402or anai_budget_exceededevent surfaces as a typedAiBudgetError, same as the unarypath. Non-streaming callers are unaffected.
#293
3c8a6a6Thanks @crs48! - Add the Right to Leave service (Humane Internet Charter §Exit):leaveWithEverythingbundles your whole workspace, your portable did:key identity, and a re-import
README into one archive, and
deleteDaytombstones remote copies and (optionally)wipes the local master — emitting only an anonymous
account.leftsignal. Leavingtakes everything and loses nothing, with no confirmshaming.
Patch Changes
#284
d6d0470Thanks @crs48! - Add shared dependency-free helpers to@xnetjs/coreand unify the SSRF guard.@xnetjs/corenow exportsclamp,clamp01,formatBytes, and theliteral-host SSRF guard (
assertPublicUrl,validateExternalUrl,SsrfError),replacing several behaviour-identical copies that had drifted across packages —
including byte formatters that silently capped at megabytes and a regex-based
URL guard that missed private ranges (CGNAT, IPv4-mapped IPv6, NAT64, the
fe81::–fe8f::link-local block, and the trailing-dot bypass).@xnetjs/pluginsnow delegates its outbound-action SSRF check to the canonicalguard while keeping its
ActionSsrfErrorcontract;@xnetjs/reactbytedisplays no longer cap at megabytes.
Updated dependencies [
f626e50,df76bef,4658b8f,4aec093,37d4462,e531d0d,d6d0470]:@xnetjs/react@0.1.0
Minor Changes
#341
1306265Thanks @crs48! - Make guardian (social) recovery configurable and threshold-aware (exploration 0243).Settings lets you choose how many guardians (2–7) and how many are needed; the onboarding
recovery screen now reads the required threshold from the pasted share codes and only
enables recovery once you have enough (rather than assuming 2-of-3), flagging unrecognized
codes as you paste.
#339
4fb460aThanks @crs48! - Wire social recovery ("trusted guardians") into the UI (exploration 0243) — xNet'sApple-recovery-contacts analogue. Settings → Account can split a recoverable identity
into 3 guardian share codes (any 2 recover it), and onboarding gains a "Recover with
guardian shares" path that reconstructs the identity from enough codes on a new device.
@xnetjs/identityaddsserializeShare/parseSharefor the copy-pasteablexnet-share:…codes. Recovery is entirely user-to-user; the cloud is never involved.#324
a155c43Thanks @crs48! - Wire opt-in recovery phrases into onboarding (exploration 0243, Phase 1). The welcomescreen gains a "Set up a recovery phrase too" option that mints a recoverable identity
and shows the phrase once to save; the "Enter recovery phrase" path now validates the
phrase against the wordlist and recovers the same identity on a new device (enrolling a
local passkey to gate it). New machine states
creating-recoverable/show-recovery-phraseand eventsCREATE_RECOVERABLE/SUBMIT_PHRASE/RECOVERABLE_CREATED/PHRASE_SAVED/IMPORT_FAILED.#333
ddf47b9Thanks @crs48! - Surface synced-passkey recovery in onboarding (exploration 0243, P1.4). TheIdentityManagergainsrecoverViaSyncedPasskey(), which discovers an xNet passkeysynced from another device (iCloud Keychain / Google Password Manager), unlocks it
(same PRF → same DID), and stores it locally — returning null when none is available so
the caller can fall back to the recovery phrase. The import screen now leads with a
"Use a synced passkey" option (new
USE_SYNCED_PASSKEYonboarding event), givingsame-ecosystem users a phrase-free return path.
Patch Changes
#284
d6d0470Thanks @crs48! - Add shared dependency-free helpers to@xnetjs/coreand unify the SSRF guard.@xnetjs/corenow exportsclamp,clamp01,formatBytes, and theliteral-host SSRF guard (
assertPublicUrl,validateExternalUrl,SsrfError),replacing several behaviour-identical copies that had drifted across packages —
including byte formatters that silently capped at megabytes and a regex-based
URL guard that missed private ranges (CGNAT, IPv4-mapped IPv6, NAT64, the
fe81::–fe8f::link-local block, and the trailing-dot bypass).@xnetjs/pluginsnow delegates its outbound-action SSRF check to the canonicalguard while keeping its
ActionSsrfErrorcontract;@xnetjs/reactbytedisplays no longer cap at megabytes.
Updated dependencies [
f626e50,df76bef,acbf801,4658b8f,985ac8f,4aec093,37d4462,0f7e114,e531d0d,4fb460a,1a44c5d,2a638ec,cae9734,d7a87da,fc3aa1d,5da8d92,3c8a6a6,d6d0470,b327f99,ddf47b9]:@xnetjs/runtime@0.1.0
Minor Changes
#278
4aec093Thanks @crs48! - Fix the cold-start boot stall and silent registry persistence failure (exploration 0227).Workspace presence Y.Docs (
presence-*) are now in-memory only — nevercold-loaded from
yjs_statenor persisted back — so presence-doc warming nolonger head-of-line blocks the landing read queries on the single SQLite worker
at boot.
NodePoolConfiggainsisEphemeralandlargeDocWarnBytesoptions.The sync registry now persists its tracked-node set through a new FK-free
app-state key/value (
getAppState/setAppStateon the storage adapter, backedby
sync_state) instead ofyjs_state, fixing aSQLITE_CONSTRAINT_FOREIGNKEY(787) that silently prevented the registry from ever persisting.
#302
0f7e114Thanks @crs48! - AddrunAdapterConformance(makeClient)— the executable "use xNet from anyframework" contract. It validates the reactive data binding (immediate live-query
snapshot then updates on mutate, no delivery after unsubscribe, one-shot fetch
round-trip, authorization denial surfaces, idempotent
destroy()) once,framework-agnostically, so a Vue/Svelte/Solid adapter only needs a thin
render-harness test on top. Exported alongside
AdapterConformanceErrorand theConformanceClientFactory/AdapterConformanceCheck/AdapterConformanceResulttypes.
Patch Changes
#280
985ac8fThanks @crs48! - Boot-stall diagnosis and two fixes (exploration 0229).@xnetjs/sqlite: the worker now emits boot-debug-gated diagnostics — aper-operation queue-wait-vs-execution timing trace and a one-shot DB-stats line
at open (file size, page/freelist counts, storage mode). This is threaded via a
new
bootDebugflag onSQLiteConfig(the worker can't readlocalStorage). Itseparates head-of-line queueing from real SQL/OPFS cost, which finally localizes
the recurring cold-start stall to a single operation.
@xnetjs/runtime:SyncManagernow dials the hub before loading the offlinequeue instead of after, so the WebSocket handshake is no longer serialized
behind local storage (which, when the single SQLite worker stalls, delayed sync
by ~18s even though the hub answers in ~200ms). The queue loads in the
background and the connect-time drain re-runs once entries are available.
#356
cae9734Thanks @crs48! - Outbound resync no longer blocks the main thread for seconds on cold open (exploration 0253).When the persisted sync cursor lags far behind the local change log (e.g. the hub never
confirmed the tail — INVALID_HASH skew),
syncLocalChanges()fetched every change since thecursor and processed the whole slice synchronously right after the sync-response resolved — the
single ~5s uninterrupted main-thread long task seen in cold-open captures. Two fixes:
String.localeCompare,which is orders of magnitude faster over a large tie-heavy slice and matches the code-unit
collation the inbound apply path already uses (the query already returns lamport-ASC order, so
this only orders ties).
can no longer monopolise a frame regardless of size.
A one-line self-gating
[NodeStoreSync] heavy outbound resyncdiagnostic names the residualsynchronous cost (the per-row deserialize inside
getChangesSince) when a resync is large, tosize the durable fix (compacting the change log). No public API or wire-contract change.
Updated dependencies [
f626e50,df76bef,acbf801,4658b8f,4aec093,37d4462,e531d0d,4fb460a,1a44c5d,2a638ec,d7a87da,fc3aa1d,5da8d92,3c8a6a6,d6d0470,b327f99,ddf47b9]:@xnetjs/sqlite@0.1.0
Minor Changes
#277
4658b8fThanks @crs48! - Materialized views can now coexist with read authorization. Eachmaterialization is stamped with a reload-stable authorization fingerprint
(subject + grant-state version), so a view is authorized once at refresh and
served from the persisted cache without per-row re-checks — while any grant
change forces an
authz-changedre-materialization. The cached id list cannever serve a row a revoked viewer may no longer read. Adds a nullable
auth_fingerprintcolumn tonode_query_materializations(schema v7, appliedto existing databases via a defensive column guard) plus optional
setNodeReadAuthorizer/getAuthorizationStateVersionstorage-adapter seams.#280
985ac8fThanks @crs48! - Boot-stall diagnosis and two fixes (exploration 0229).@xnetjs/sqlite: the worker now emits boot-debug-gated diagnostics — aper-operation queue-wait-vs-execution timing trace and a one-shot DB-stats line
at open (file size, page/freelist counts, storage mode). This is threaded via a
new
bootDebugflag onSQLiteConfig(the worker can't readlocalStorage). Itseparates head-of-line queueing from real SQL/OPFS cost, which finally localizes
the recurring cold-start stall to a single operation.
@xnetjs/runtime:SyncManagernow dials the hub before loading the offlinequeue instead of after, so the WebSocket handshake is no longer serialized
behind local storage (which, when the single SQLite worker stalls, delayed sync
by ~18s even though the hub answers in ~200ms). The queue loads in the
background and the connect-time drain re-runs once entries are available.
#282
d4bfe27Thanks @crs48! - Add parallel SQLite reads to the Electronbetter-sqlite3adapter (exploration0230). Unlike the browser — where
opfs-sahpoolholds an exclusive handle so asecond connection is impossible — native SQLite + WAL allows one writer
concurrent with many readers, each on its own connection. The adapter now:
schedulerconfig,default on) so a write/import burst can't head-of-line block an interactive
read;
readonlyReadConnection)so plain reads don't contend with write locks;
worker_threadsreaders(
readerPoolSize,'auto'sizes to the host) that serve heavy reads(FTS, aggregates, large scans) in parallel on other cores, with least-busy
dispatch and graceful fallback to the inline connection;
applyNodeBatchso a long import nolonger monopolizes the data-process thread;
getDiagnostics()/getWalStats()/checkpointWal()plus aread-your-writes window (
readYourWritesWindowMs).All additive — existing callers are unaffected, and the new behaviour is
opt-in via config (the scheduler is on by default but only reorders
non-transactional work).
#307
7e6f5b7Thanks @crs48! - Add OPFS capability detection so the storage layer can pick and explain itsdurable backend before opening —
detectOpfsCapability(), plus thesupportsOpfs,supportsSyncAccessHandle, andisCrossOriginIsolatedpredicates and the
OpfsCapability/OpfsPersistenceModetypes. The webadapter uses it to emit an accurate diagnostic when synchronous access handles
are unavailable (iOS 15.2–16.3 / older WebViews) — it falls back to the async
OPFS backend, which is still durable, rather than logging a misleading error.
This makes the mobile-webview hosting path (exploration 0238) legible: hosts can
branch on capability and target the right minimum OS.
#355
3261a75Thanks @crs48! - Web SQLiteopen()now retries on timeout instead of hard-failing the boot (exploration 0253).A cold
installOpfsSAHPoolVfs()on a large database file intermittently exceeds the 15sopen timeout — most often because a prior boot's open timed out and leaked a worker still
holding the file's exclusive OPFS sync access handle, so the next boot's
createSyncAccessHandle()blocks on the contended handle. Previously the first timeout threw("Initialization failed: Worker initialization timeout after 15s") and showed an error screen.
WebSQLiteProxy.open()now terminates the stuck worker (releasing the handle) and retries witha fresh worker up to 3 attempts via the new
openWithTimeoutRetryhelper, so the leaked-handlecascade recovers instead of failing. A genuinely broken/unavailable OPFS still fails cleanly
after the bounded attempts. Adds
SQLiteConfig.openTimeoutMs(default 15000) to tune theper-attempt timeout.
#351
839b2b7Thanks @crs48! - Cold-open boot diagnostics: bracket the SQLite worker's open/init window (exploration 0253).The 7th cold-open capture showed the ~17 s stall with
execMs: 0ANDqueueMs: 0onevery op — so it is neither slow SQL nor scheduler head-of-line blocking. The cost moved
into the one window no timer brackets: the worker's
open()/init and the dispatch gapbefore the first scheduled op. This adds the two missing log lines (gated behind
bootDebug, never throws):WebSQLiteAdapternow records per-phase open timings (OpenPhaseTimings:wasm import/init, OPFS VFS install incl. lock retries, capacity reserve, db open,
pragmas, total) exposed via
getOpenPhaseTimings(), plus publicschemaApplyMsandopenRetryAttempts. The worker host emits them as[xNet] sqlite open phases.SchedulerOpReportgainsenqueuedAt+startedAtso the worker host can tag theFIRST op after open with
idleBeforeFirstOpMs(open → first enqueue, the upstream/transport wait) and
sinceOpenMs(open → first exec) — the disambiguator between"stalled in open" and "stalled upstream".
Diagnostic only; no behaviour change on the production path.
#279
d9008d2Thanks @crs48! - Add a priority scheduler with read coalescing to the web SQLite worker(exploration 0228). All storage operations now drain through one scheduler
inside the single worker both the main thread and data worker share:
interactive reads are served ahead of queued writes, so a write or sync-apply
burst can no longer starve a read (generalizing the 0227 head-of-line fix).
Identical concurrent reads collapse into a single execution. A new
getSchedulerSnapshot()exposes queue depth for diagnostics. This is orderingonly — no parallelism is added, since
opfs-sahpoolis single-connection byconstruction.
Patch Changes
#288
b0cd77cThanks @crs48! - Forward the SQLite Web Worker's boot-debug diagnostics to the main thread so thein-app Logs panel captures them (exploration 0229). The per-op queue/exec timing
(
[xNet] sqlite op) and one-shot DB stats ([xNet] db stats @ open) wereemitted only in the dedicated worker's console, which the main-thread console tap
never sees — so every boot-stall capture/export came back missing exactly those
lines. The worker now
postMessages each boot-debug line (under a dedicateddiscriminator key that can't collide with Comlink RPC) and
WebSQLiteProxyre-emits it on the main console. Gated by
xnet:boot:debug; no effect on normaloperation.
#290
142b1c0Thanks @crs48! - Memory-map OPFS reads (PRAGMA mmap_size) on the web adapter so the first coldquery after a reload faults its working-set pages via the OS instead of
thousands of synchronous 8 KiB reads on the single worker thread (exploration
0233). The boot trace caught one cold landing query taking 15.8 s of pure
execution while every later warm query was 0 ms — the page cache only helps
re-reads, so mmap is the lever for the first read. Guarded: a no-op where the
opfs-sahpoolVFS doesn't support it.#345
0e0802dThanks @crs48! - Boot diagnostics: name every scheduled SQLite op in the boot log (exploration0249). The
WorkerSchedulerop report gains an optionaldetailfield andschedule()an optionaldetailargument; the web worker now forwards eachread/write op's whitespace-collapsed, param-free SQL text so a long
execMsline names the exact statement instead of the generic
querylabel. This is themissing field that kept the ~15 s cold-open stall unidentified across
explorations 0227–0233. Additive and backward compatible —
detailis optionaland only emitted when boot debug (
xnet:boot:debug) is on.@xnetjs/abuse@0.1.0
Patch Changes
4fb460a,d7a87da,fc3aa1d,5da8d92,b327f99,ddf47b9]:@xnetjs/cli@0.0.4
Patch Changes
f626e50,df76bef,acbf801,4658b8f,985ac8f,4aec093,37d4462,d4bfe27,0f7e114,e531d0d,4fb460a,1a44c5d,2a638ec,7e6f5b7,cae9734,d7a87da,fc3aa1d,5da8d92,3261a75,3c8a6a6,d6d0470,b327f99,b0cd77c,142b1c0,0e0802d,839b2b7,d9008d2,ddf47b9]:@xnetjs/crypto@0.1.0
Patch Changes
d6d0470]:@xnetjs/data-bridge@0.1.0
Patch Changes
f626e50,df76bef,4658b8f,985ac8f,4aec093,37d4462,d4bfe27,e531d0d,7e6f5b7,3261a75,d6d0470,b0cd77c,142b1c0,0e0802d,839b2b7,d9008d2]:@xnetjs/history@0.1.0
Patch Changes
f626e50,df76bef,4658b8f,4aec093,37d4462,e531d0d,d6d0470]:@xnetjs/storage@0.1.0
Patch Changes
4658b8f,985ac8f,d4bfe27,7e6f5b7,3261a75,d6d0470,b0cd77c,142b1c0,0e0802d,839b2b7,d9008d2]:@xnetjs/sync@0.1.0
Patch Changes
4fb460a,d7a87da,fc3aa1d,5da8d92,d6d0470,b327f99,ddf47b9]:xnet-cloud@0.0.2
Patch Changes
2e7e4c7]:@xnetjs/brain@0.0.3
Patch Changes
f626e50,df76bef,4658b8f,4aec093,37d4462,e531d0d]:@xnetjs/comms@0.0.3
Patch Changes
f626e50,df76bef,4658b8f,4aec093,37d4462,e531d0d]:@xnetjs/dashboard@0.0.3
Patch Changes
f626e50,df76bef,acbf801,4658b8f,4aec093,1306265,37d4462,e531d0d,4fb460a,1a44c5d,2a638ec,a155c43,3c8a6a6,d6d0470,ddf47b9]:@xnetjs/entitlements@0.0.2
Patch Changes
2e7e4c7Thanks @crs48! - Fix the managed-AI plan model IDs to match OpenRouter's catalog: the Anthropicmodels use a dotted version (
anthropic/claude-haiku-4.5,anthropic/claude-sonnet-4.6,anthropic/claude-opus-4.8), not a dashed one.The previous dashed IDs (
…-4-5/…-4-6/…-4-8) don't exist upstream, so atenant on a default Anthropic model got a model-not-found error. The OpenAI and
Google IDs were already correct.
@xnetjs/labs@0.0.3
Patch Changes
f626e50,df76bef,acbf801,4658b8f,4aec093,37d4462,e531d0d,1a44c5d,2a638ec,3c8a6a6,d6d0470]:@xnetjs/licenses@0.0.3
Patch Changes
@xnetjs/maps@0.0.3
Patch Changes
f626e50,df76bef,4658b8f,4aec093,37d4462,e531d0d]:@xnetjs/server@0.0.2
Patch Changes
f626e50,df76bef,4658b8f,4aec093,37d4462,e531d0d,4fb460a,d7a87da,fc3aa1d,5da8d92,b327f99,ddf47b9]:@xnetjs/social@0.0.3
Patch Changes
f626e50,df76bef,4658b8f,4aec093,37d4462,e531d0d]:@xnetjs/unreal@0.0.3
Patch Changes
f626e50,df76bef,4658b8f,4aec093,37d4462,e531d0d]: