@salesforce/vite-plugin-lwc-ui-bundle 9.19.0 → 9.20.1
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/docs/consumer-guide.md
CHANGED
|
@@ -23,17 +23,51 @@ The plugin compiles your LWC components into a single self-contained `dist/index
|
|
|
23
23
|
|
|
24
24
|
This section is for team leads and app developers deciding **how** to uplift LWCs into static bundles for agentic surfaces. It's not a setup guide — for that, see [Off-Platform Build](#off-platform-build) below.
|
|
25
25
|
|
|
26
|
-
The plugin ships configuration for a default, foundational set of UI API adapters — including `lightning/graphql`. Most uplifted bundles can rely on these defaults without writing any adapter config. During development, consumers can supplement the defaults by passing additional config to `builtins.lds()` (see [Configuring `builtins.lds()`](#configuring-builtinslds) below). Once a configuration is stable and useful to others, open a PR against [`packages/vite-plugin-lwc-ui-bundle/src/providers/lds/index.ts`](../src/providers/lds/index.ts) to add it to `
|
|
26
|
+
The plugin ships configuration for a default, foundational set of UI API adapters — including `lightning/graphql`. Most uplifted bundles can rely on these defaults without writing any adapter config. During development, consumers can supplement the defaults by passing additional config to `builtins.lds()` (see [Configuring `builtins.lds()`](#configuring-builtinslds) below). Once a configuration is stable and useful to others, open a PR against [`packages/vite-plugin-lwc-ui-bundle/src/providers/lds/index.ts`](../src/providers/lds/index.ts) to add it to `DEFAULT_REGISTRY` so it ships in the next plugin release.
|
|
27
27
|
|
|
28
28
|
The Data Orchestration Service team is not responsible for the implementation of MCP tooling, nor for the adapter configuration of capabilities outside DOS ownership. As far as external teams are concerned, DOS provides the mechanism that applies the uplift per configuration; what each adapter resolves to at runtime — and which MCP tools back it — is owned by the team that owns the underlying capability.
|
|
29
29
|
|
|
30
30
|
### What ships in the default registry today
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Every default entry is one of four **flavors**, keyed off its `type`. For the
|
|
33
|
+
exhaustive, always-current specifier/adapter list, read `DEFAULT_REGISTRY` in
|
|
34
|
+
[`src/providers/lds/index.ts`](../src/providers/lds/index.ts).
|
|
35
|
+
|
|
36
|
+
- **Wire** (`wire` / `graphql-wire`) — `@wire`-driven reactive reads, e.g.
|
|
37
|
+
`lightning/uiRecordApi`→`getRecord`, `lightning/graphql`→`graphql`.
|
|
38
|
+
- **Imperative** (`imperative-mutation` / `graphql-mutation` / `imperative-read` /
|
|
39
|
+
`graphql-imperative-read`) — promise-returning calls invoked directly, e.g.
|
|
40
|
+
`lightning/uiRecordApi`→`createRecord`/`updateRecord`,
|
|
41
|
+
`lightning/uiObjectInfoApi`→`getObjectInfo_imperative`.
|
|
42
|
+
- **State manager** (`state-manager`) — externalized LWC state managers composed
|
|
43
|
+
through an upstream per-state-manager factory, e.g.
|
|
44
|
+
`lightning/stateManagerRecord`→`createSmRecord`. Off-core they do not
|
|
45
|
+
auto-refire ([pitfall #15](../skills/setup-lwc-vite-plugin/references/known-pitfalls.md#15-state-managers-off-core-do-not-auto-refire-no-shared-luvio-store)).
|
|
46
|
+
- **State manager (graphql)** — the `lightning/stateManagerGraphQL`→`createSmGraphQL`
|
|
47
|
+
variant: same composition, but exposes `errors` (plural) and a `refresh()` that
|
|
48
|
+
off-core re-runs the query via a fresh MCP tool call.
|
|
49
|
+
|
|
50
|
+
State-manager entries use a different config shape from wire and
|
|
51
|
+
imperative entries — `LdsStateManagerConfig` carries
|
|
52
|
+
`factoryModule` + `factoryName` instead of being purely runtime-driven.
|
|
53
|
+
The load hook imports the named factory at build time and composes the
|
|
54
|
+
externalized state manager around an MCP-backed imperative adapter
|
|
55
|
+
synthesized from `mcp.toolName` + `configJsonSchema`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
{
|
|
59
|
+
type: 'state-manager',
|
|
60
|
+
factoryModule: '@salesforce/state-managers-uiapi/factory',
|
|
61
|
+
factoryName: 'createSmRecord', // or 'createSmObjectInfo', 'createSmGraphQL'
|
|
62
|
+
mcp: { toolName: 'getRecordMcpTool' },
|
|
63
|
+
configJsonSchema: { /* same per-resource constant the wire entry uses */ },
|
|
64
|
+
}
|
|
65
|
+
```
|
|
33
66
|
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
-
|
|
67
|
+
All per-state-manager metadata (`definedBy`, `requiredKeys`,
|
|
68
|
+
`optionalKeys`, predicate) lives in the upstream factory and reaches
|
|
69
|
+
off-core verbatim through the externalized state manager — registry
|
|
70
|
+
entries do **not** redeclare those fields.
|
|
37
71
|
|
|
38
72
|
### Configuring `builtins.lds()`
|
|
39
73
|
|
|
@@ -73,7 +107,7 @@ lwcVitePlugin({
|
|
|
73
107
|
**What developers should do today:**
|
|
74
108
|
|
|
75
109
|
- **Consolidate / minimize calls within each component.** GraphQL or batch-enabled adapters are an alternative — one `@wire(graphql)` query can request fields from multiple records / object types in one round-trip, replacing N separate `@wire(getRecord)` / `@wire(getObjectInfo)` calls.
|
|
76
|
-
- **Share data across components via an LWC state manager.** A state manager serves as a single source of truth so descendants subscribe rather than re-fetching. This recovers the cross-component sharing that on-platform LDS provides for free.
|
|
110
|
+
- **Share data across components via an LWC state manager.** A state manager serves as a single source of truth so descendants subscribe rather than re-fetching. The plugin's default registry now ships `lightning/stateManagerRecord`, `lightning/stateManagerObjectInfo`, and `lightning/stateManagerGraphQL` (see "What ships in the default registry today" above). This recovers most of the cross-component sharing that on-platform LDS provides for free, but because there's no shared Luvio store off-core, **state managers do not auto-refire** — a sibling component mutating the same record won't refresh other instances. See [Known pitfall #15](../skills/setup-lwc-vite-plugin/references/known-pitfalls.md#15-state-managers-off-core-do-not-auto-refire-no-shared-luvio-store) for the re-trigger pattern (call `setConfig` with the same args, or `refresh()`).
|
|
77
111
|
|
|
78
112
|
**See also:** [Known pitfall #14 — Inefficient data access: latency and lack of caching](../skills/setup-lwc-vite-plugin/references/known-pitfalls.md#14-inefficient-data-access-latency-and-lack-of-caching).
|
|
79
113
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/vite-plugin-lwc-ui-bundle",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.20.1",
|
|
4
4
|
"description": "Vite plugin for compiling LWC components into static bundles for off-platform and MCP use",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"author": "Salesforce",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"@lwc/rollup-plugin": "^9.0.0",
|
|
61
61
|
"@salesforce/lds-adapters-onestore-graphql": "^1.440.0",
|
|
62
|
-
"@salesforce/platform-sdk": "^9.
|
|
62
|
+
"@salesforce/platform-sdk": "^9.20.1",
|
|
63
63
|
"@salesforce/state-managers-uiapi": "^0.30.0",
|
|
64
|
-
"@salesforce/ui-bundle": "^9.
|
|
64
|
+
"@salesforce/ui-bundle": "^9.20.1",
|
|
65
65
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
|
|
66
66
|
"zod": "^3.23.8"
|
|
67
67
|
},
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"devDependencies": {
|
|
88
88
|
"@conduit-client/bindings-utils": "3.19.6",
|
|
89
89
|
"@conduit-client/command-base": "3.19.6",
|
|
90
|
-
"@salesforce/platform-sdk": "^9.
|
|
90
|
+
"@salesforce/platform-sdk": "^9.20.1",
|
|
91
91
|
"typescript": "^5.9.3",
|
|
92
92
|
"vite": "^7.0.0",
|
|
93
93
|
"vite-plugin-dts": "^4.5.4",
|
|
@@ -137,6 +137,21 @@ Starting from the root component, trace the dependency tree:
|
|
|
137
137
|
support (provider + mock branch)
|
|
138
138
|
- `lightning/uiRecordApi` imported AND `@wire(getRecord` / `@wire(get*`
|
|
139
139
|
actually used → needs LDS support (provider + mock branch)
|
|
140
|
+
- `lightning/stateManagerRecord` imported (default `smRecord` import)
|
|
141
|
+
→ needs `builtins.lds()` provider (default registry covers it) +
|
|
142
|
+
the `getRecordMcpTool` `callTool` mock branch (same tool the
|
|
143
|
+
`@wire(getRecord)` path uses — one branch covers both). See
|
|
144
|
+
`known-pitfalls.md` for the no-auto-refire (no shared Luvio store)
|
|
145
|
+
reactivity contract.
|
|
146
|
+
- `lightning/stateManagerObjectInfo` imported (default `smObjectInfo`
|
|
147
|
+
import) → needs `builtins.lds()` provider + the
|
|
148
|
+
`getObjectInfoMcpTool` `callTool` mock branch.
|
|
149
|
+
- `lightning/stateManagerGraphQL` imported (default `smGraphQL`
|
|
150
|
+
import) → needs `builtins.lds()` provider + the `graphqlQuery`
|
|
151
|
+
`callTool` mock branch (same tool the `@wire(graphql)` path uses).
|
|
152
|
+
Note `smGraphQL` exposes `errors` (plural) on its outer shape,
|
|
153
|
+
matching its analogous wire adapter — distinct from UIAPI managers
|
|
154
|
+
which expose `error` (singular).
|
|
140
155
|
- `lightning/*` base components → needs `lightning-base-components`
|
|
141
156
|
npm package, plus `gate()`, `accessCheck()`, and `primitiveUtils()`
|
|
142
157
|
providers because base components use these modules internally even
|
|
@@ -150,17 +165,23 @@ Starting from the root component, trace the dependency tree:
|
|
|
150
165
|
|
|
151
166
|
**Be precise with LDS detection.** The LDS provider/mock is only needed
|
|
152
167
|
when a component's `@wire` actually consumes `getRecord`/`getRecordUi`/
|
|
153
|
-
similar adapters from `lightning/uiRecordApi
|
|
154
|
-
|
|
168
|
+
similar adapters from `lightning/uiRecordApi`, **or** when a component
|
|
169
|
+
imports a `lightning/stateManager*` default export and calls its
|
|
170
|
+
`setConfig` / setters. **Do not trigger the LDS provider just because:**
|
|
155
171
|
|
|
156
172
|
- The app has a chat wrapper whose tool output happens to contain a
|
|
157
173
|
record shape (`records[...]`) — that goes through
|
|
158
174
|
`window.openai.toolOutput` + the mapper, not the LDS wire adapter.
|
|
159
175
|
- A component imports `lightning/uiRecordApi` but doesn't `@wire` it.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
`
|
|
176
|
+
- A component imports `lightning/stateManager*` but never instantiates
|
|
177
|
+
the state manager.
|
|
178
|
+
|
|
179
|
+
`builtins.lds()` wires up `@wire(getRecord)`, `@wire(graphql)`, **and**
|
|
180
|
+
the three `lightning/stateManager{Record,ObjectInfo,GraphQL}` virtual
|
|
181
|
+
modules — they all live in the same default registry. If no component
|
|
182
|
+
calls those wire adapters or instantiates a state manager, omit both
|
|
183
|
+
the provider and the corresponding mock branch (`getRecordMcpTool` /
|
|
184
|
+
`getObjectInfoMcpTool` / `graphqlQuery`). A chat wrapper that maps
|
|
164
185
|
`window.openai.toolOutput.records[...]` into a component's `@api`
|
|
165
186
|
props is independent of LDS.
|
|
166
187
|
|
|
@@ -201,6 +222,9 @@ Check in this order:
|
|
|
201
222
|
`builtins.lds()` must be present (graphql specifiers are in the default registry)
|
|
202
223
|
- Step 4 found `@wire(getRecord)` from `lightning/uiRecordApi` →
|
|
203
224
|
`builtins.lds()` must be present (one `builtins.lds()` covers both)
|
|
225
|
+
- Step 4 found any `lightning/stateManager{Record,ObjectInfo,GraphQL}`
|
|
226
|
+
import that's actually instantiated → `builtins.lds()` must be
|
|
227
|
+
present (the default registry covers all three specifiers)
|
|
204
228
|
- Step 4 found any `@salesforce/i18n/*` → `builtins.i18n()` must be
|
|
205
229
|
present
|
|
206
230
|
- Step 4 found any `@salesforce/client/*` → `builtins.client()` must
|
|
@@ -252,14 +276,20 @@ Ask the user whether to generate mocks. Mocks serve two independent
|
|
|
252
276
|
purposes — list each one **only if Step 4 / Step 2 produced something
|
|
253
277
|
to mock**, and skip lines that don't apply:
|
|
254
278
|
|
|
255
|
-
- **`callTool` branches for wire adapters** — one
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
- `
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
279
|
+
- **`callTool` branches for wire adapters and state managers** — one
|
|
280
|
+
branch per tool actually detected in Step 4. State managers share
|
|
281
|
+
tool names with their sibling wire adapters, so one branch covers
|
|
282
|
+
both call paths:
|
|
283
|
+
- `graphqlQuery` — only if Step 4 found `@wire(graphql)` **or**
|
|
284
|
+
`lightning/stateManagerGraphQL` (default `smGraphQL`) usage. Not
|
|
285
|
+
needed otherwise.
|
|
286
|
+
- `getRecordMcpTool` — only if Step 4 found `@wire(getRecord)` **or**
|
|
287
|
+
`lightning/stateManagerRecord` (default `smRecord`) usage. Not
|
|
288
|
+
needed just because a chat wrapper passes record-shaped data;
|
|
289
|
+
the wrapper reads `toolOutput`, not `callTool`.
|
|
290
|
+
- `getObjectInfoMcpTool` — only if Step 4 found
|
|
291
|
+
`lightning/stateManagerObjectInfo` (default `smObjectInfo`) usage,
|
|
292
|
+
or a future `getObjectInfo` imperative-read consumer.
|
|
263
293
|
- **Seed `window.openai.toolOutput`** — only if Step 2 generated a
|
|
264
294
|
chat wrapper. This is what drives the wrapper's initial render; the
|
|
265
295
|
mapper consumes it. It has nothing to do with `callTool`.
|
|
@@ -373,11 +403,15 @@ import lwcVitePlugin, { builtins } from "@salesforce/vite-plugin-lwc-ui-bundle";
|
|
|
373
403
|
// inside plugins -> lwcVitePlugin({ providers: [...] })
|
|
374
404
|
builtins.lds(), // default registry:
|
|
375
405
|
// lightning/uiRecordApi, uiObjectInfoApi,
|
|
376
|
-
//
|
|
406
|
+
// lightning/graphql (tool: "graphqlQuery"),
|
|
407
|
+
// lightning/stateManagerRecord -> getRecordMcpTool
|
|
408
|
+
// lightning/stateManagerObjectInfo -> getObjectInfoMcpTool
|
|
409
|
+
// lightning/stateManagerGraphQL -> graphqlQuery
|
|
377
410
|
|
|
378
411
|
// Add to / override the default registry. The argument is deep-merged onto
|
|
379
412
|
// the defaults per specifier, so you only declare what you are changing —
|
|
380
|
-
// unmentioned entries (e.g. `getRecord`, `createRecord
|
|
413
|
+
// unmentioned entries (e.g. `getRecord`, `createRecord`, the three
|
|
414
|
+
// `lightning/stateManager*` defaults) are preserved.
|
|
381
415
|
builtins.lds({
|
|
382
416
|
"lightning/graphql": {
|
|
383
417
|
graphql: { type: "graphql-wire", mcp: { toolName: "myGraphqlTool" } },
|
|
@@ -386,13 +420,55 @@ builtins.lds({
|
|
|
386
420
|
}),
|
|
387
421
|
```
|
|
388
422
|
|
|
423
|
+
**Registering or overriding a state manager** — the
|
|
424
|
+
`LdsStateManagerConfig` discriminator (`type: 'state-manager'`)
|
|
425
|
+
points the load hook at an upstream per-state-manager **factory**.
|
|
426
|
+
Composition (the externalized state manager and all its per-manager
|
|
427
|
+
metadata — `definedBy`, `requiredKeys`, `optionalKeys`, predicate)
|
|
428
|
+
lives in the upstream factory; the registry entry only carries the
|
|
429
|
+
factory specifier (`factoryModule` + `factoryName`), the MCP tool name,
|
|
430
|
+
and the JSON schema for `setConfig` validation:
|
|
431
|
+
|
|
432
|
+
```js
|
|
433
|
+
builtins.lds({
|
|
434
|
+
"lightning/stateManagerRecord": {
|
|
435
|
+
default: {
|
|
436
|
+
type: "state-manager",
|
|
437
|
+
factoryModule: "@salesforce/state-managers-uiapi/factory",
|
|
438
|
+
factoryName: "createSmRecord",
|
|
439
|
+
mcp: { toolName: "getRecordMcpTool" },
|
|
440
|
+
configJsonSchema: {
|
|
441
|
+
/* same RECORD_SCHEMA used by getRecord wire entry */
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
}),
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
The three default entries are:
|
|
449
|
+
|
|
450
|
+
| Specifier | `factoryModule` | `factoryName` | Default `mcp.toolName` |
|
|
451
|
+
| ---------------------------------- | --------------------------------------------------- | -------------------- | ---------------------- |
|
|
452
|
+
| `lightning/stateManagerRecord` | `@salesforce/state-managers-uiapi/factory` | `createSmRecord` | `getRecordMcpTool` |
|
|
453
|
+
| `lightning/stateManagerObjectInfo` | `@salesforce/state-managers-uiapi/factory` | `createSmObjectInfo` | `getObjectInfoMcpTool` |
|
|
454
|
+
| `lightning/stateManagerGraphQL` | `@salesforce/lds-adapters-onestore-graphql/factory` | `createSmGraphQL` | `graphqlQuery` |
|
|
455
|
+
|
|
456
|
+
State-manager entries do **not** carry `definedBy`, `requiredKeys`,
|
|
457
|
+
`optionalKeys`, or any predicate — those live in the upstream factory
|
|
458
|
+
and reach off-core verbatim through the externalized state manager.
|
|
459
|
+
Within an adapter entry, the override is a **wholesale replacement,
|
|
460
|
+
not a deep merge**, so when you redeclare the `default` adapter you
|
|
461
|
+
must repeat every field you want to keep (including `factoryModule` /
|
|
462
|
+
`factoryName`).
|
|
463
|
+
|
|
389
464
|
Adapt based on earlier findings:
|
|
390
465
|
|
|
391
466
|
- Set `dirs` for the detected project structure (SFDX vs namespaced).
|
|
392
467
|
- Populate `builtins.label({...})` with values from Step 6.
|
|
393
468
|
- Include `builtins.primitiveUtils()` if using `lightning-base-components`.
|
|
394
469
|
- Include `builtins.lds()` if any component uses `lightning/uiRecordApi`,
|
|
395
|
-
`lightning/uiObjectInfoApi`,
|
|
470
|
+
`lightning/uiObjectInfoApi`, `lightning/graphql`, or any of the
|
|
471
|
+
`lightning/stateManager{Record,ObjectInfo,GraphQL}` specifiers.
|
|
396
472
|
- Include `viteSingleFile()` — without it, `vite build` emits multi-file
|
|
397
473
|
output and the MCP host can't inline the bundle. See
|
|
398
474
|
`known-pitfalls.md#6` for the full config block.
|
|
@@ -406,9 +482,19 @@ Adapt based on earlier findings:
|
|
|
406
482
|
- `builtins.lds()` default for `lightning/graphql` (both `graphql` wire
|
|
407
483
|
and `executeMutation`): `graphqlQuery`. Override by registering the
|
|
408
484
|
specifier explicitly — see example above.
|
|
485
|
+
- `builtins.lds()` default for `lightning/stateManagerRecord`:
|
|
486
|
+
`getRecordMcpTool` (shared with the `getRecord` wire entry — one
|
|
487
|
+
mock branch covers both).
|
|
488
|
+
- `builtins.lds()` default for `lightning/stateManagerObjectInfo`:
|
|
489
|
+
`getObjectInfoMcpTool`.
|
|
490
|
+
- `builtins.lds()` default for `lightning/stateManagerGraphQL`:
|
|
491
|
+
`graphqlQuery` (shared with the `graphql` wire entry).
|
|
409
492
|
|
|
410
493
|
Whatever tool names you settle on here **must match** the branches in
|
|
411
|
-
`bootstrap.js` mocks (Step 8).
|
|
494
|
+
`bootstrap.js` mocks (Step 8). For state-manager consumers, also note
|
|
495
|
+
that `smGraphQL`'s outer shape exposes `errors` (plural), matching its
|
|
496
|
+
sibling wire adapter — UIAPI managers (`smRecord`, `smObjectInfo`)
|
|
497
|
+
expose `error` (singular).
|
|
412
498
|
|
|
413
499
|
#### `index.html`
|
|
414
500
|
|
|
@@ -466,6 +552,10 @@ Run this check **only** if Step 4 found actual usage of any of:
|
|
|
466
552
|
- `lightning/uiRecordApi` with real `@wire` usage of `getRecord` /
|
|
467
553
|
`createRecord` / `updateRecord`
|
|
468
554
|
- `lightning/uiObjectInfoApi` with real usage
|
|
555
|
+
- `lightning/stateManagerRecord`, `lightning/stateManagerObjectInfo`,
|
|
556
|
+
or `lightning/stateManagerGraphQL` with real instantiation (default
|
|
557
|
+
`smRecord` / `smObjectInfo` / `smGraphQL` import that's actually
|
|
558
|
+
invoked) — these all flow through the same LDS runtime
|
|
469
559
|
|
|
470
560
|
If none of the above are in the component tree, skip this sub-step
|
|
471
561
|
entirely — the LDS runtime is never loaded and the peers don't matter.
|
|
@@ -365,3 +365,49 @@ inherently a problem — only chains and overlapping fetches are. The
|
|
|
365
365
|
strategy section in
|
|
366
366
|
[`docs/consumer-guide.md`](../../../docs/consumer-guide.md#data-waterfall-awareness)
|
|
367
367
|
walks through the recommendation.
|
|
368
|
+
|
|
369
|
+
## 15. State managers off-core do not auto-refire (no shared Luvio store)
|
|
370
|
+
|
|
371
|
+
**Symptom:** A `lightning/stateManager*` instance fetches once and then
|
|
372
|
+
never updates on its own, even when sibling code in the same page
|
|
373
|
+
mutates the same record. The `data` / `status` atoms stay frozen at
|
|
374
|
+
their first-loaded values; no second `callTool` fires unless the
|
|
375
|
+
consumer triggers it.
|
|
376
|
+
|
|
377
|
+
**Cause:** On core, every `lightning/stateManager*` instance shares a
|
|
378
|
+
single Luvio store. When any other code path mutates a record (a
|
|
379
|
+
`@wire(getRecord)` re-fetch, an `updateRecord` call, another state
|
|
380
|
+
manager observing the same key), Luvio re-publishes to every
|
|
381
|
+
subscriber on the same key — so siblings re-fire automatically.
|
|
382
|
+
Off-core through `vite-plugin-lwc-ui-bundle` there is no shared store:
|
|
383
|
+
each state manager wraps its own MCP-backed adapter, and `subscribe` is
|
|
384
|
+
a deliberate no-op (nothing fans changes out). Mutations elsewhere in
|
|
385
|
+
the page do not propagate automatically.
|
|
386
|
+
|
|
387
|
+
**Fix:** Re-trigger off-core state managers explicitly when the
|
|
388
|
+
consumer knows the underlying data may have changed. Call the matching
|
|
389
|
+
setter (`setRecordId`, `setFields`, …) or `setConfig(currentConfig)`
|
|
390
|
+
with the same arguments to re-run the adapter; `smGraphQL` also exposes
|
|
391
|
+
`refresh()` (upstream PR `lds-lightning-platform#7916`), which off-core
|
|
392
|
+
re-issues the query as a fresh MCP tool call and resolves with the new
|
|
393
|
+
result (rejecting only if that re-execute itself fails):
|
|
394
|
+
|
|
395
|
+
```js
|
|
396
|
+
import smRecord from "lightning/stateManagerRecord";
|
|
397
|
+
|
|
398
|
+
const sm = smRecord();
|
|
399
|
+
sm.setConfig({ recordId: "001…", fields: ["Account.Name"] }); // initial load
|
|
400
|
+
// …later, after a sibling component mutates the same record:
|
|
401
|
+
sm.setConfig({ recordId: "001…", fields: ["Account.Name"] }); // re-fires the call
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
**On-core behavior is unchanged** — the same upstream factories power
|
|
405
|
+
both; on core the shared store means there's nothing to work around.
|
|
406
|
+
|
|
407
|
+
**Prevention:** treat state managers off-core as imperative-with-atoms
|
|
408
|
+
rather than reactive subscriptions. Audit every place where a data
|
|
409
|
+
mutation in one component should be visible in another, and add an
|
|
410
|
+
explicit re-trigger (`setConfig` / `refresh()`) at the mutation site,
|
|
411
|
+
or a broadcast/event the dependent state managers listen for. The
|
|
412
|
+
plugin cannot synthesize a Luvio store — that's a §11 Risk 1 contract
|
|
413
|
+
baked into the off-core uplift.
|