@mars-sea/dsh-commandcode-provider 0.11.13 → 0.11.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.11.14] - 2026-09-24
8
+
9
+ ### Fixed
10
+
11
+ - The settings page now delegates remote settings persistence to the DSH Host/gateway instead of silently switching non-loopback pages to a process-local read-only scope. The client always reads `settings.describe` and submits `settings.mutate`; the Host's `writable` fact and the gateway's authenticated write policy remain the authority. This allows an authenticated reverse-proxy deployment to edit settings while keeping unauthorized or Host-locked deployments read-only.
12
+
7
13
  ## [0.11.13] - 2026-09-24
8
14
 
9
15
  ### Changed
package/lib/client.js CHANGED
@@ -37,7 +37,6 @@ window.__ModuleLoader__.load({
37
37
  }
38
38
  //#endregion
39
39
  //#region src/client/settings-scope.ts
40
- const MEMORY_STATUS = "unavailable";
41
40
  /**
42
41
  * Backoff before re-reading a directory whose FIRST read failed, in millis.
43
42
  *
@@ -89,7 +88,6 @@ window.__ModuleLoader__.load({
89
88
  resolveRemote;
90
89
  timer;
91
90
  store;
92
- persistence;
93
91
  inFlight;
94
92
  rerun = false;
95
93
  generation = 0;
@@ -99,15 +97,13 @@ window.__ModuleLoader__.load({
99
97
  disposed = false;
100
98
  /**
101
99
  * @param resolveRemote - Reads the inject-captured `remote.settings` namespace.
102
- * @param persistence - Client-selected Host persistence; non-loopback pages may stay process-local.
103
100
  * @param timer - Retry timer seam (see {@link SETTINGS_DESCRIBE_RETRY_MS}).
104
101
  */
105
- constructor(resolveRemote, persistence, timer = REAL_SETTINGS_TIMER) {
102
+ constructor(resolveRemote, timer = REAL_SETTINGS_TIMER) {
106
103
  this.resolveRemote = resolveRemote;
107
104
  this.timer = timer;
108
- this.persistence = persistence;
109
105
  this.store = createSnapshotStore({
110
- status: persistence === "host" ? "idle" : MEMORY_STATUS,
106
+ status: "idle",
111
107
  view: null,
112
108
  error: null
113
109
  });
@@ -118,7 +114,7 @@ window.__ModuleLoader__.load({
118
114
  subscribe(listener) {
119
115
  return this.store.subscribe(listener);
120
116
  }
121
- /** The cheap idempotent entry: kick a first read (a no-op on memory persistence). */
117
+ /** The cheap idempotent entry: kick a first read. */
122
118
  ensure() {
123
119
  this.load();
124
120
  }
@@ -128,7 +124,7 @@ window.__ModuleLoader__.load({
128
124
  * @returns settlement after this call's freshness is reflected.
129
125
  */
130
126
  load() {
131
- if (this.disposed || this.persistence === "memory") return Promise.resolve();
127
+ if (this.disposed) return Promise.resolve();
132
128
  this.clearRetry();
133
129
  if (this.inFlight !== void 0) {
134
130
  this.rerun = true;
@@ -242,33 +238,29 @@ window.__ModuleLoader__.load({
242
238
  store;
243
239
  mirror;
244
240
  namespace;
245
- persistence;
246
241
  tail = Promise.resolve();
247
242
  writeGeneration = 0;
248
243
  disposed = false;
249
244
  unsubscribe;
250
245
  /** Revision answered by a superseded write still ahead of the mirror. */
251
246
  pendingRevision;
252
- constructor(resolveRemote, mirror, namespace, persistence) {
247
+ constructor(resolveRemote, mirror, namespace) {
253
248
  this.resolveRemote = resolveRemote;
254
249
  this.mirror = mirror;
255
250
  this.namespace = namespace;
256
- this.persistence = persistence;
257
251
  this.store = createSnapshotStore({
258
- status: persistence === "host" ? "loading" : "unavailable",
252
+ status: "loading",
259
253
  value: void 0,
260
254
  base: void 0,
261
255
  user: void 0,
262
256
  revision: void 0,
263
257
  writable: false,
264
- mode: persistence
258
+ mode: "host"
265
259
  });
266
- if (persistence === "host") {
267
- this.unsubscribe = mirror.subscribe(() => {
268
- this.derive();
269
- });
260
+ this.unsubscribe = mirror.subscribe(() => {
270
261
  this.derive();
271
- }
262
+ });
263
+ this.derive();
272
264
  }
273
265
  getSnapshot() {
274
266
  return this.store.getSnapshot();
@@ -377,9 +369,9 @@ window.__ModuleLoader__.load({
377
369
  if (sameSnapshot(candidate, current)) return;
378
370
  this.store.set(candidate);
379
371
  }
380
- /** Queue operations one at a time; memory persistence and disposal are no-ops. */
372
+ /** Queue operations one at a time; disposal makes the queue inert. */
381
373
  enqueue(operation) {
382
- if (this.persistence === "memory" || this.disposed) return Promise.resolve();
374
+ if (this.disposed) return Promise.resolve();
383
375
  const task = this.tail.then(async () => {
384
376
  if (this.disposed) return;
385
377
  await operation();
@@ -418,26 +410,22 @@ window.__ModuleLoader__.load({
418
410
  * @returns The scope plus the refresh/dispose handles the entry wires into its fiber.
419
411
  */
420
412
  function createSettingsScope(context, namespace, resolveRemote, timer = REAL_SETTINGS_TIMER) {
421
- const loopback = context.remote.$host?.isLoopback === true;
422
- const persistence = loopback ? "host" : "memory";
423
- const mirror = new SettingsDescribeMirror(resolveRemote, persistence, timer);
424
- const scope = new RemoteSettingsScope(resolveRemote, mirror, namespace, persistence);
413
+ const mirror = new SettingsDescribeMirror(resolveRemote, timer);
414
+ const scope = new RemoteSettingsScope(resolveRemote, mirror, namespace);
425
415
  const disposers = [];
426
- if (loopback) {
427
- if (typeof context.remote.$on === "function") {
428
- const off = context.remote.$on("settings/document-updated", () => {
429
- mirror.ensure();
430
- });
431
- if (typeof off === "function") disposers.push(off);
432
- }
433
- if (typeof context.on === "function") {
434
- const off = context.on("connection/reset", () => {
435
- mirror.load();
436
- });
437
- if (typeof off === "function") disposers.push(off);
438
- }
439
- mirror.ensure();
416
+ if (typeof context.remote.$on === "function") {
417
+ const off = context.remote.$on("settings/document-updated", () => {
418
+ mirror.ensure();
419
+ });
420
+ if (typeof off === "function") disposers.push(off);
421
+ }
422
+ if (typeof context.on === "function") {
423
+ const off = context.on("connection/reset", () => {
424
+ mirror.load();
425
+ });
426
+ if (typeof off === "function") disposers.push(off);
440
427
  }
428
+ mirror.ensure();
441
429
  return {
442
430
  getSnapshot: () => scope.getSnapshot(),
443
431
  subscribe: (listener) => scope.subscribe(listener),
@@ -2325,7 +2313,7 @@ window.__ModuleLoader__.load({
2325
2313
  }
2326
2314
  //#endregion
2327
2315
  //#region package.json
2328
- var version = "0.11.13";
2316
+ var version = "0.11.14";
2329
2317
  var repository = {
2330
2318
  "type": "git",
2331
2319
  "url": "git+https://github.com/Mars-Sea/dsh-commandcode-provider.git"