@ai-matrx/design-system 0.18.2 → 0.18.3
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 +12 -0
- package/dist/content-transfer.cjs +119 -28
- package/dist/content-transfer.cjs.map +1 -1
- package/dist/content-transfer.js +119 -28
- package/dist/content-transfer.js.map +1 -1
- package/dist/data-table/data-row-inspector.cjs +119 -28
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +119 -28
- package/dist/data-table/data-row-inspector.js.map +1 -1
- package/dist/data-table/data-row-window.cjs +119 -28
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +119 -28
- package/dist/data-table/data-row-window.js.map +1 -1
- package/dist/data-table/index.cjs +119 -28
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.js +119 -28
- package/dist/data-table/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.18.3 — 2026-09-12
|
|
4
|
+
|
|
5
|
+
Reopening an Alchemy preparation now checks the current source while retaining
|
|
6
|
+
manual drafts. Changed direct sources offer an explicit keep-or-regenerate
|
|
7
|
+
choice, all-matching sources detect identity changes without eagerly fetching
|
|
8
|
+
pages, and failed refreshes remain visible instead of silently reusing stale
|
|
9
|
+
content.
|
|
10
|
+
|
|
11
|
+
### Consumer action
|
|
12
|
+
|
|
13
|
+
Update to 0.18.3. No host configuration changes are required.
|
|
14
|
+
|
|
3
15
|
## 0.18.2 — 2026-09-12
|
|
4
16
|
|
|
5
17
|
Alchemy copy sessions now reset only when their explicit identity changes,
|
|
@@ -1250,6 +1250,10 @@ function materialIdentity(material) {
|
|
|
1250
1250
|
}
|
|
1251
1251
|
return `payload:${id}`;
|
|
1252
1252
|
}
|
|
1253
|
+
function snapshotContent(snapshot) {
|
|
1254
|
+
const { sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits } = snapshot;
|
|
1255
|
+
return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
|
|
1256
|
+
}
|
|
1253
1257
|
function useFence() {
|
|
1254
1258
|
const mounted = React8.useRef(true);
|
|
1255
1259
|
const nextId = React8.useRef(0);
|
|
@@ -1352,7 +1356,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1352
1356
|
const captured = await material.capture(signal);
|
|
1353
1357
|
sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
|
|
1354
1358
|
} else if ("kind" in material) {
|
|
1355
|
-
sourceMaterial =
|
|
1359
|
+
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => (0, import_content_transfer2.directSource)(material, { sourceId: materialIdentity(material), label: sourceLabel, ...applyMenuProjection && projection ? { projection } : {}, ...applyMenuProjection && sections ? { sections } : {} }) };
|
|
1356
1360
|
} else if (applyMenuProjection && (projection || sections)) {
|
|
1357
1361
|
sourceMaterial = {
|
|
1358
1362
|
id: material.id,
|
|
@@ -1369,7 +1373,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1369
1373
|
} else {
|
|
1370
1374
|
sourceMaterial = material;
|
|
1371
1375
|
}
|
|
1372
|
-
const raw =
|
|
1376
|
+
const raw = await sourceMaterial.capture({ scope, signal });
|
|
1373
1377
|
const constrained = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, raw.snapshot.limits);
|
|
1374
1378
|
const result = await (0, import_content_transfer2.capture)({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
|
|
1375
1379
|
if (scope !== "all-matching" || !collectPages) return result;
|
|
@@ -1429,31 +1433,117 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1429
1433
|
fence.finish(controller);
|
|
1430
1434
|
}
|
|
1431
1435
|
}, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
|
|
1432
|
-
const openWorkspace = React8.useCallback(
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
const
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1436
|
+
const openWorkspace = React8.useCallback(
|
|
1437
|
+
async (key = primaryWorkspaceKey, variant) => {
|
|
1438
|
+
const variantMaterial = variant && "kind" in variant.source ? {
|
|
1439
|
+
id: `variant:${key}`,
|
|
1440
|
+
label: variant.label,
|
|
1441
|
+
capture: async () => (0, import_content_transfer2.directSource)(variant.source, {
|
|
1442
|
+
sourceId: `variant:${key}`,
|
|
1443
|
+
label: variant.label
|
|
1444
|
+
})
|
|
1445
|
+
} : variant?.source;
|
|
1446
|
+
const captureWorkspace = (scope, signal, collectPages = true) => captureOne(variantMaterial ?? primary, scope, signal, true, collectPages);
|
|
1447
|
+
workspaceCaptures.current.set(key, captureWorkspace);
|
|
1448
|
+
const existing = workspaces[key];
|
|
1449
|
+
const { controller, id } = fence.begin();
|
|
1450
|
+
if (existing) {
|
|
1451
|
+
try {
|
|
1452
|
+
const allMatching = existing.scope === "all-matching";
|
|
1453
|
+
const fresh = await captureWorkspace(
|
|
1454
|
+
existing.scope,
|
|
1455
|
+
controller.signal,
|
|
1456
|
+
!allMatching
|
|
1457
|
+
);
|
|
1458
|
+
if (!fence.valid(id, controller) || !workspaceCaptures.current.has(key))
|
|
1459
|
+
return;
|
|
1460
|
+
if (allMatching && (!existing.allMatching || !fresh.allMatching))
|
|
1461
|
+
throw new Error(
|
|
1462
|
+
"This source can no longer provide an all-matching snapshot."
|
|
1463
|
+
);
|
|
1464
|
+
const collectionIdentity = (value) => value && {
|
|
1465
|
+
query: value.source.query,
|
|
1466
|
+
projection: value.projection,
|
|
1467
|
+
columns: value.columns,
|
|
1468
|
+
limits: value.limits
|
|
1469
|
+
};
|
|
1470
|
+
const changed = allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot);
|
|
1471
|
+
setWorkspaces((current) => {
|
|
1472
|
+
const retained = current[key];
|
|
1473
|
+
if (!retained) return current;
|
|
1474
|
+
return {
|
|
1475
|
+
...current,
|
|
1476
|
+
[key]: {
|
|
1477
|
+
...retained,
|
|
1478
|
+
error: fresh.collectionError,
|
|
1479
|
+
...allMatching ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: retained.scope } } : { pending: void 0 }
|
|
1480
|
+
}
|
|
1481
|
+
};
|
|
1482
|
+
});
|
|
1483
|
+
setWorkspaceKey(key);
|
|
1484
|
+
setWorkspaceOpen(true);
|
|
1485
|
+
} catch (error) {
|
|
1486
|
+
if (fence.valid(id, controller) && workspaceCaptures.current.has(key)) {
|
|
1487
|
+
setWorkspaces(
|
|
1488
|
+
(current) => current[key] ? {
|
|
1489
|
+
...current,
|
|
1490
|
+
[key]: {
|
|
1491
|
+
...current[key],
|
|
1492
|
+
error: errorMessage(error, "Could not refresh source")
|
|
1493
|
+
}
|
|
1494
|
+
} : current
|
|
1495
|
+
);
|
|
1496
|
+
setWorkspaceKey(key);
|
|
1497
|
+
setWorkspaceOpen(true);
|
|
1498
|
+
}
|
|
1499
|
+
} finally {
|
|
1500
|
+
fence.finish(controller);
|
|
1501
|
+
}
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1504
|
+
try {
|
|
1505
|
+
const result = await captureWorkspace(initialScope, controller.signal);
|
|
1506
|
+
if (!fence.valid(id, controller)) return;
|
|
1507
|
+
const resolved = (0, import_content_transfer2.resolveTransferPreferences)(
|
|
1508
|
+
providerPreferences,
|
|
1509
|
+
preferences,
|
|
1510
|
+
result.snapshot.limits
|
|
1511
|
+
);
|
|
1512
|
+
const original = (0, import_content_transfer2.createDraft)(result.snapshot);
|
|
1513
|
+
const base = {
|
|
1514
|
+
...result,
|
|
1515
|
+
key,
|
|
1516
|
+
original,
|
|
1517
|
+
draft: original,
|
|
1518
|
+
scope: initialScope,
|
|
1519
|
+
preferences: resolved,
|
|
1520
|
+
...result.collectionError ? { error: result.collectionError } : {}
|
|
1521
|
+
};
|
|
1522
|
+
setWorkspaces((current) => ({
|
|
1523
|
+
...current,
|
|
1524
|
+
[key]: { ...base, draft: rebuild(base, initialControls(base)) }
|
|
1525
|
+
}));
|
|
1526
|
+
setWorkspaceKey(key);
|
|
1527
|
+
setWorkspaceOpen(true);
|
|
1528
|
+
} catch (error) {
|
|
1529
|
+
if (fence.valid(id, controller))
|
|
1530
|
+
setNotice(errorMessage(error, "Could not capture content"));
|
|
1531
|
+
} finally {
|
|
1532
|
+
fence.finish(controller);
|
|
1533
|
+
}
|
|
1534
|
+
},
|
|
1535
|
+
[
|
|
1536
|
+
captureOne,
|
|
1537
|
+
capturePrimary,
|
|
1538
|
+
fence,
|
|
1539
|
+
initialScope,
|
|
1540
|
+
preferences,
|
|
1541
|
+
primaryWorkspaceKey,
|
|
1542
|
+
primary,
|
|
1543
|
+
providerPreferences,
|
|
1544
|
+
workspaces
|
|
1545
|
+
]
|
|
1546
|
+
);
|
|
1457
1547
|
React8.useImperativeHandle(controllerRef, () => ({
|
|
1458
1548
|
focusTrigger: () => triggerRef.current?.focus(),
|
|
1459
1549
|
prepare: async (requestedSource, options) => {
|
|
@@ -1676,7 +1766,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1676
1766
|
setBusy("capture");
|
|
1677
1767
|
try {
|
|
1678
1768
|
const result = await captureScope(scope, controller.signal);
|
|
1679
|
-
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, error: result.collectionError });
|
|
1769
|
+
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, sourceStale: false, error: result.collectionError });
|
|
1680
1770
|
} catch (error) {
|
|
1681
1771
|
if (fence.valid(id, controller)) onChange({ ...latest.current, error: errorMessage(error, "Refresh failed") });
|
|
1682
1772
|
} finally {
|
|
@@ -1919,6 +2009,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1919
2009
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
|
|
1920
2010
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
|
|
1921
2011
|
] }) : null,
|
|
2012
|
+
state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
|
|
1922
2013
|
state.pending ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
1923
2014
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "A fresh source snapshot is ready." }),
|
|
1924
2015
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
|