@prettier-ai/dsh-client-ui-settings 0.1.2-alpha.1 → 0.1.2-alpha.2

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/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/client/ui-settings/README.md
5
- README.md: 3e4970bff9784a80716a073bf6d7f9f3e62889e5
6
- README.zh.md: a527dfe21a5c756183ffb4022ea0a8f3290f9dc5
5
+ README.md: 1dbefefe51086a68d1f2afd36d098a118337f0b9
6
+ README.zh.md: 7009b4a7f156a613a7a1ef4e38b14c11d40fa85a
package/README.md CHANGED
@@ -25,7 +25,7 @@ English | [中文](README.zh.md)
25
25
  <a id="use-this-package"></a>
26
26
  ## Use this package
27
27
 
28
- Feature plugins use this package to store and edit their preferences without re-implementing transport or schema handling. Mount it once per composition; it injects `connection` and `remote` and owns the single `settings.describe` reader in the browser.
28
+ Feature plugins use this package to store and edit their preferences without re-implementing transport or schema handling. Mount it once per composition; it injects the `remote` service with its `settings` namespace and owns the single `settings.describe` reader in the browser.
29
29
 
30
30
  ### Binding a namespace
31
31
 
@@ -51,7 +51,7 @@ The package realizes one ownership rule: the browser keeps one shared mirror of
51
51
 
52
52
  ### The describe mirror
53
53
 
54
- The plugin injects `connection` and `remote` and owns the one `settings.describe` reader in the browser: a shared mirror refreshed on every forwarded `settings/document-updated` event and on `connection/reset` (the first connection included, closing the window where a commit lands between the eager read and the SSE subscription). Cross-namespace surfaces read it through `ctx.settingsScope.describe()`, a read/fold face (`getSnapshot`/`subscribe`/`ensure`, plus `acceptView` folding a write answer in).
54
+ The plugin injects `remote` with its `settings` namespace, resolves Host persistence once from the fixed `remote.$host` facts, and owns the one `settings.describe` reader in the browser: a shared mirror refreshed on every forwarded `settings/document-updated` event and on `connection/reset` (the first connection included, closing the window where a commit lands between the eager read and the SSE subscription). Cross-namespace surfaces read it through `ctx.settingsScope.describe()`, a read/fold face (`getSnapshot`/`subscribe`/`ensure`, plus `acceptView` folding a write answer in).
55
55
 
56
56
  ### Scope derivation
57
57
 
package/README.zh.md CHANGED
@@ -25,7 +25,7 @@ kind: "package-reference"
25
25
  <a id="use-this-package"></a>
26
26
  ## 使用本包
27
27
 
28
- 功能插件用本包存储与编辑自己的偏好设置,而无需重新实现传输层或 schema 处理。每个组合挂载一次即可;它注入 `connection` `remote`,并持有浏览器中唯一的 `settings.describe` 读取方。
28
+ 功能插件用本包存储与编辑自己的偏好设置,而无需重新实现传输层或 schema 处理。每个组合挂载一次即可;它注入 `remote` 服务及其 `settings` 命名空间,并持有浏览器中唯一的 `settings.describe` 读取方。
29
29
 
30
30
  ### 绑定命名空间
31
31
 
@@ -51,7 +51,7 @@ kind: "package-reference"
51
51
 
52
52
  ### Describe 镜像
53
53
 
54
- 插件注入 `connection` `remote`,并持有浏览器中唯一的 `settings.describe` 读取方:一面共享镜像,在每次转发的 `settings/document-updated` 事件与 `connection/reset` 时刷新(首次连接也包含在内,关闭「提交落在急切读取与 SSE 订阅之间」的窗口)。跨命名空间表面通过 `ctx.settingsScope.describe()` 读它,这是一个读取/折叠面(`getSnapshot`/`subscribe`/`ensure`,另有把写应答折入的 `acceptView`)。
54
+ 插件注入 `remote` 及其 `settings` 命名空间,从固定的 `remote.$host` 事实一次性解析 Host 持久化模式,并持有浏览器中唯一的 `settings.describe` 读取方:一面共享镜像,在每次转发的 `settings/document-updated` 事件与 `connection/reset` 时刷新(首次连接也包含在内,关闭「提交落在急切读取与 SSE 订阅之间」的窗口)。跨命名空间表面通过 `ctx.settingsScope.describe()` 读它,这是一个读取/折叠面(`getSnapshot`/`subscribe`/`ensure`,另有把写应答折入的 `acceptView`)。
55
55
 
56
56
  ### Scope 派生
57
57
 
package/lib/client.js CHANGED
@@ -947,7 +947,7 @@ window.__ModuleLoader__.load({
947
947
  * the operation already crossing the wire.
948
948
  */
949
949
  var SettingsScopeController = class {
950
- api;
950
+ ctx;
951
951
  spec;
952
952
  mirror;
953
953
  persistence;
@@ -964,14 +964,15 @@ window.__ModuleLoader__.load({
964
964
  */
965
965
  pendingRevision;
966
966
  /**
967
- * @param api - settings wire face (writes only; reads ride the mirror).
967
+ * @param ctx - the providing plugin's context, whose `remote.settings`
968
+ * namespace carries this scope's writes (reads ride the mirror).
968
969
  * @param spec - namespace identity and optional narrowing decoder.
969
970
  * @param mirror - the shared describe mirror this scope derives from.
970
971
  * @param persistence - client-selected Host persistence; non-loopback pages may remain process-local.
971
972
  * @param schema - settings-owned schema operations.
972
973
  */
973
- constructor(api, spec, mirror, persistence, schema) {
974
- this.api = api;
974
+ constructor(ctx, spec, mirror, persistence, schema) {
975
+ this.ctx = ctx;
975
976
  this.spec = spec;
976
977
  this.mirror = mirror;
977
978
  this.persistence = persistence;
@@ -1041,13 +1042,7 @@ window.__ModuleLoader__.load({
1041
1042
  const generation = ++this.writeGeneration;
1042
1043
  return this.enqueue(async () => {
1043
1044
  const revision = expectedRevision ?? this.pendingRevision ?? this.getSnapshot().revision;
1044
- let response;
1045
- try {
1046
- response = await this.api.settings.mutate(this.spec.namespace, ownedOps, revision);
1047
- } catch (_settingsWriteFailure) {
1048
- await this.recover(generation);
1049
- return;
1050
- }
1045
+ const response = await this.ctx.remote.settings.mutate(this.spec.namespace, ownedOps, revision);
1051
1046
  if (!response.ok) {
1052
1047
  await this.recover(generation);
1053
1048
  return;
@@ -1131,21 +1126,25 @@ window.__ModuleLoader__.load({
1131
1126
  var SettingsScopeBinder = class extends _prettier_ai_cordis.Service {
1132
1127
  mirror;
1133
1128
  schema;
1134
- wire;
1129
+ persistence;
1130
+ /**
1131
+ * The PROVIDING fiber, kept because a Service reads `ctx` as its *consumer's*
1132
+ * fiber: letting a bound scope write through the caller's context would make
1133
+ * every caller declare `remote.settings` in its own `inject`.
1134
+ */
1135
+ owner;
1135
1136
  /**
1136
1137
  * @param ctx - the providing plugin's context.
1137
1138
  * @param config - the shared describe mirror every bound scope derives from,
1138
- * the settings-owned schema operations, and the settings Remote namespace the
1139
- * bound scopes write through. The namespace is captured here rather than read
1140
- * inside {@link bind}, because a Service reads `ctx` as its *consumer's*
1141
- * fiber: reading it there would make every caller declare `remote.settings`
1142
- * in its own `inject`.
1139
+ * the settings-owned schema operations, and the Host persistence the provider
1140
+ * resolved from `remote.$host`.
1143
1141
  */
1144
1142
  constructor(ctx, config) {
1145
1143
  super(ctx, "settingsScope");
1146
1144
  this.mirror = config.mirror;
1147
1145
  this.schema = config.schema;
1148
- this.wire = config.wire;
1146
+ this.persistence = config.persistence;
1147
+ this.owner = ctx;
1149
1148
  }
1150
1149
  /**
1151
1150
  * The shared mirror's read/fold face for cross-namespace surfaces (schema
@@ -1169,8 +1168,7 @@ window.__ModuleLoader__.load({
1169
1168
  */
1170
1169
  bind(spec) {
1171
1170
  const ctx = this.ctx;
1172
- const connection = ctx.get("connection");
1173
- const controller = new SettingsScopeController(this.wire, spec, this.mirror, connection.isLoopback ? "host" : "memory", this.schema);
1171
+ const controller = new SettingsScopeController(this.owner, spec, this.mirror, this.persistence, this.schema);
1174
1172
  ctx.effect(() => {
1175
1173
  this.mirror.ensure();
1176
1174
  return async () => {
@@ -1198,18 +1196,19 @@ window.__ModuleLoader__.load({
1198
1196
  * so an invalidation arriving mid-read is never lost and never duplicated.
1199
1197
  */
1200
1198
  var SettingsDescribeMirror = class {
1201
- api;
1199
+ ctx;
1202
1200
  persistence;
1203
1201
  store;
1204
1202
  inFlight;
1205
1203
  rerun = false;
1206
1204
  generation = 0;
1207
1205
  /**
1208
- * @param api - settings wire face.
1206
+ * @param ctx - the providing plugin's context, whose `remote.settings`
1207
+ * namespace answers the describe read.
1209
1208
  * @param persistence - client-selected Host persistence; non-loopback pages may remain process-local.
1210
1209
  */
1211
- constructor(api, persistence = "host") {
1212
- this.api = api;
1210
+ constructor(ctx, persistence = "host") {
1211
+ this.ctx = ctx;
1213
1212
  this.persistence = persistence;
1214
1213
  this.store = (0, _prettier_ai_dsh_client_store.createSnapshotStore)({
1215
1214
  status: persistence === "host" ? "idle" : "unavailable",
@@ -1297,7 +1296,7 @@ window.__ModuleLoader__.load({
1297
1296
  const generation = ++this.generation;
1298
1297
  let outcome;
1299
1298
  try {
1300
- const response = await this.api.settings.describe();
1299
+ const response = await this.ctx.remote.settings.describe();
1301
1300
  outcome = response.ok ? { view: response.value } : { failure: response.error.message };
1302
1301
  } catch (error) {
1303
1302
  outcome = { failure: error instanceof Error ? error.message : String(error) };
@@ -1328,14 +1327,10 @@ window.__ModuleLoader__.load({
1328
1327
  //#endregion
1329
1328
  //#region lib/types/client/index.js
1330
1329
  /**
1331
- * Required services: the wire handle for the mirror's reads and the forwarded
1332
- * settings invalidation the mirror refreshes on.
1330
+ * Required services: the Remote namespace the mirror reads through and the
1331
+ * forwarded settings invalidation it refreshes on.
1333
1332
  */
1334
- const inject = [
1335
- "connection",
1336
- "remote",
1337
- "remote.settings"
1338
- ];
1333
+ const inject = ["remote", "remote.settings"];
1339
1334
  /**
1340
1335
  * Provide the settings-namespace scope service over one shared describe
1341
1336
  * mirror, and keep that mirror fresh on the two signals that can move the
@@ -1347,9 +1342,8 @@ window.__ModuleLoader__.load({
1347
1342
  */
1348
1343
  function apply(ctx) {
1349
1344
  const schema = new SettingsSchemaService(ctx);
1350
- const connection = ctx.get("connection");
1351
- const wire = { settings: ctx.remote.settings };
1352
- const mirror = new SettingsDescribeMirror(wire, connection.isLoopback ? "host" : "memory");
1345
+ const persistence = ctx.remote.$host.isLoopback ? "host" : "memory";
1346
+ const mirror = new SettingsDescribeMirror(ctx, persistence);
1353
1347
  ctx.effect(() => {
1354
1348
  const disposers = [ctx.remote.$on("settings/document-updated", () => {
1355
1349
  mirror.load();
@@ -1364,7 +1358,7 @@ window.__ModuleLoader__.load({
1364
1358
  new SettingsScopeBinder(ctx, {
1365
1359
  mirror,
1366
1360
  schema,
1367
- wire
1361
+ persistence
1368
1362
  });
1369
1363
  }
1370
1364
  //#endregion
@@ -17,10 +17,10 @@ export type { SettingsScopeController, SettingsScopeBinder } from './settings-sc
17
17
  export type { SettingsScope, SettingsScopeSnapshot, SettingsScopeSpec } from './settings-contract.ts';
18
18
  export type { SettingsSchemaService } from './schema.ts';
19
19
  export type { SchemaNode } from './schema.ts';
20
- export type { SettingsDescribeFace, SettingsDescribeView, SettingsMirrorSnapshot, SettingsRemote, SettingsWireFace, } from './settings-mirror.ts';
20
+ export type { SettingsDescribeFace, SettingsDescribeView, SettingsMirrorSnapshot, } from './settings-mirror.ts';
21
21
  /**
22
- * Required services: the wire handle for the mirror's reads and the forwarded
23
- * settings invalidation the mirror refreshes on.
22
+ * Required services: the Remote namespace the mirror reads through and the
23
+ * forwarded settings invalidation it refreshes on.
24
24
  */
25
25
  export declare const inject: string[];
26
26
  /**
@@ -8,20 +8,8 @@
8
8
  * invalidations its owning plugin subscribes to and folds write answers in
9
9
  * through {@link SettingsDescribeMirror.acceptView}.
10
10
  */
11
- import type { ClientRemote, SettingsNamespaceView } from '@prettier-ai/dsh-api-remotes/client';
12
- /**
13
- * The settings Remote methods browser configuration surfaces may reach: the
14
- * redacted read plus merge, replacement, and path-addressed writes.
15
- * Named once here so the consumers share one face instead of each re-deriving
16
- * it from the namespace.
17
- */
18
- export type SettingsRemote = Pick<ClientRemote['settings'], 'describe' | 'update' | 'replace' | 'mutate'>;
19
- /** Wire face carrying the settings Remote namespace. */
20
- export interface SettingsWireFace {
21
- /** The settings Remote namespace. */
22
- settings: SettingsRemote;
23
- }
24
- type SettingsFace = SettingsWireFace;
11
+ import type { Context as ClientContext } from '@prettier-ai/cordis';
12
+ import type { SettingsNamespaceView } from '@prettier-ai/dsh-api-remotes/client';
25
13
  /** The full `settings.describe` answer the mirror serves. */
26
14
  export interface SettingsDescribeView {
27
15
  /** Every namespace a live Host plugin registered, as the Host reported it. */
@@ -77,17 +65,18 @@ export interface SettingsDescribeFace {
77
65
  * so an invalidation arriving mid-read is never lost and never duplicated.
78
66
  */
79
67
  export declare class SettingsDescribeMirror implements SettingsDescribeFace {
80
- private readonly api;
68
+ private readonly ctx;
81
69
  private readonly persistence;
82
70
  private readonly store;
83
71
  private inFlight;
84
72
  private rerun;
85
73
  private generation;
86
74
  /**
87
- * @param api - settings wire face.
75
+ * @param ctx - the providing plugin's context, whose `remote.settings`
76
+ * namespace answers the describe read.
88
77
  * @param persistence - client-selected Host persistence; non-loopback pages may remain process-local.
89
78
  */
90
- constructor(api: SettingsFace, persistence?: 'host' | 'memory');
79
+ constructor(ctx: ClientContext, persistence?: 'host' | 'memory');
91
80
  /** @returns the current sync snapshot (stable reference until the next change). */
92
81
  getSnapshot(): SettingsMirrorSnapshot;
93
82
  /**
@@ -126,5 +115,4 @@ export declare class SettingsDescribeMirror implements SettingsDescribeFace {
126
115
  private run;
127
116
  private shouldRerun;
128
117
  }
129
- export {};
130
118
  //# sourceMappingURL=settings-mirror.d.ts.map
@@ -10,8 +10,7 @@ import type { Context } from '@prettier-ai/cordis';
10
10
  import type { SettingsPathOpView } from '@prettier-ai/dsh-api-remotes/client';
11
11
  import type { SettingsSchemaService } from './schema.ts';
12
12
  import type { SettingsScope, SettingsScopeSnapshot, SettingsScopeSpec } from './settings-contract.ts';
13
- import { SettingsDescribeMirror, type SettingsDescribeFace, type SettingsWireFace } from './settings-mirror.ts';
14
- type SettingsFace = SettingsWireFace;
13
+ import { SettingsDescribeMirror, type SettingsDescribeFace } from './settings-mirror.ts';
15
14
  /**
16
15
  * One namespace's derived view over the shared describe mirror, plus that
17
16
  * namespace's serialized Host writes. Writes carry the latest known namespace
@@ -19,7 +18,7 @@ type SettingsFace = SettingsWireFace;
19
18
  * the operation already crossing the wire.
20
19
  */
21
20
  export declare class SettingsScopeController<T> implements SettingsScope<T> {
22
- private readonly api;
21
+ private readonly ctx;
23
22
  private readonly spec;
24
23
  private readonly mirror;
25
24
  private readonly persistence;
@@ -36,13 +35,14 @@ export declare class SettingsScopeController<T> implements SettingsScope<T> {
36
35
  */
37
36
  private pendingRevision;
38
37
  /**
39
- * @param api - settings wire face (writes only; reads ride the mirror).
38
+ * @param ctx - the providing plugin's context, whose `remote.settings`
39
+ * namespace carries this scope's writes (reads ride the mirror).
40
40
  * @param spec - namespace identity and optional narrowing decoder.
41
41
  * @param mirror - the shared describe mirror this scope derives from.
42
42
  * @param persistence - client-selected Host persistence; non-loopback pages may remain process-local.
43
43
  * @param schema - settings-owned schema operations.
44
44
  */
45
- constructor(api: SettingsFace, spec: SettingsScopeSpec<T>, mirror: SettingsDescribeMirror, persistence: 'host' | 'memory', schema: SettingsSchemaService);
45
+ constructor(ctx: Context, spec: SettingsScopeSpec<T>, mirror: SettingsDescribeMirror, persistence: 'host' | 'memory', schema: SettingsSchemaService);
46
46
  /** @returns the current sync snapshot (stable reference until the next change). */
47
47
  getSnapshot(): SettingsScopeSnapshot<T>;
48
48
  /**
@@ -100,20 +100,23 @@ declare module '@prettier-ai/cordis' {
100
100
  export declare class SettingsScopeBinder extends Service {
101
101
  private readonly mirror;
102
102
  private readonly schema;
103
- private readonly wire;
103
+ private readonly persistence;
104
+ /**
105
+ * The PROVIDING fiber, kept because a Service reads `ctx` as its *consumer's*
106
+ * fiber: letting a bound scope write through the caller's context would make
107
+ * every caller declare `remote.settings` in its own `inject`.
108
+ */
109
+ private readonly owner;
104
110
  /**
105
111
  * @param ctx - the providing plugin's context.
106
112
  * @param config - the shared describe mirror every bound scope derives from,
107
- * the settings-owned schema operations, and the settings Remote namespace the
108
- * bound scopes write through. The namespace is captured here rather than read
109
- * inside {@link bind}, because a Service reads `ctx` as its *consumer's*
110
- * fiber: reading it there would make every caller declare `remote.settings`
111
- * in its own `inject`.
113
+ * the settings-owned schema operations, and the Host persistence the provider
114
+ * resolved from `remote.$host`.
112
115
  */
113
116
  constructor(ctx: Context, config: {
114
117
  mirror: SettingsDescribeMirror;
115
118
  schema: SettingsSchemaService;
116
- wire: SettingsWireFace;
119
+ persistence: 'host' | 'memory';
117
120
  });
118
121
  /**
119
122
  * The shared mirror's read/fold face for cross-namespace surfaces (schema
@@ -135,5 +138,4 @@ export declare class SettingsScopeBinder extends Service {
135
138
  */
136
139
  bind<T>(spec: SettingsScopeSpec<T>): SettingsScope<T>;
137
140
  }
138
- export {};
139
141
  //# sourceMappingURL=settings-scope.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prettier-ai/dsh-client-ui-settings",
3
3
  "description": "Settings domain base plugin: the settings-namespace scope service and the canonical settings slot-type contract",
4
- "version": "0.1.2-alpha.1",
4
+ "version": "0.1.2-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -32,34 +32,27 @@
32
32
  "dsh": {
33
33
  "client": {
34
34
  "inject": [
35
- "@prettier-ai/dsh-client-connection",
36
35
  "@prettier-ai/dsh-api-remotes"
37
36
  ],
38
37
  "platform": "web"
39
38
  }
40
39
  },
41
40
  "license": "MIT",
42
- "dependencies": {
43
- "@prettier-ai/schemastery": "^3.18.1"
44
- },
45
41
  "peerDependencies": {
46
- "@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.1",
47
- "@prettier-ai/dsh-client-connection": "^0.1.2-alpha.1",
48
- "@prettier-ai/dsh-invariants": "^0.1.2-alpha.1",
49
- "@prettier-ai/dsh-settings": "^0.1.2-alpha.1",
50
- "@prettier-ai/cordis": "^4.0.1"
42
+ "@prettier-ai/cordis": "^4.0.2"
51
43
  },
52
44
  "devDependencies": {
53
45
  "@types/react": "~18.3.1",
54
46
  "react": "^18.2.0",
55
- "@prettier-ai/cordis": "^4.0.1",
56
- "@prettier-ai/dsh-client-test-runtime": "^0.1.2-alpha.1",
57
- "@prettier-ai/dsh-client-ui-slots": "^0.1.2-alpha.1",
58
- "@prettier-ai/dsh-client-store": "^0.1.2-alpha.1",
59
- "@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.1",
60
- "@prettier-ai/dsh-invariants": "^0.1.2-alpha.1",
61
- "@prettier-ai/dsh-client-connection": "^0.1.2-alpha.1",
62
- "@prettier-ai/dsh-settings": "^0.1.2-alpha.1"
47
+ "@prettier-ai/dsh-api-remotes": "^0.1.2-alpha.2",
48
+ "@prettier-ai/cordis": "^4.0.2",
49
+ "@prettier-ai/dsh-client-store": "^0.1.2-alpha.2",
50
+ "@prettier-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
51
+ "@prettier-ai/dsh-client-test-runtime": "^0.1.2-alpha.2",
52
+ "@prettier-ai/dsh-invariants": "^0.1.2-alpha.2",
53
+ "@prettier-ai/dsh-settings": "^0.1.2-alpha.2",
54
+ "@prettier-ai/schemastery": "^3.18.2",
55
+ "@prettier-ai/dsh-util-values": "^0.1.2-alpha.2"
63
56
  },
64
57
  "files": [
65
58
  "lib/index.js",