@calimero-network/mero-react 2.3.0 → 2.5.0
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/dist/index.cjs +268 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -3
- package/dist/index.d.ts +84 -3
- package/dist/index.js +263 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1493,6 +1493,18 @@ function useJoinContext() {
|
|
|
1493
1493
|
);
|
|
1494
1494
|
return { joinContext, loading, error };
|
|
1495
1495
|
}
|
|
1496
|
+
function useJoinSubgroupInheritance() {
|
|
1497
|
+
const { mero } = useMero();
|
|
1498
|
+
const { loading, error, run } = useAsyncMutation();
|
|
1499
|
+
const joinSubgroupInheritance = react.useCallback(
|
|
1500
|
+
async (groupId) => {
|
|
1501
|
+
if (!mero) return null;
|
|
1502
|
+
return run(() => mero.admin.joinSubgroupInheritance(groupId));
|
|
1503
|
+
},
|
|
1504
|
+
[mero, run]
|
|
1505
|
+
);
|
|
1506
|
+
return { joinSubgroupInheritance, loading, error };
|
|
1507
|
+
}
|
|
1496
1508
|
function useContextGroup(contextId) {
|
|
1497
1509
|
const { mero } = useMero();
|
|
1498
1510
|
const [groupId, setGroupId] = react.useState(null);
|
|
@@ -2282,6 +2294,256 @@ function useDetachContextFromGroup() {
|
|
|
2282
2294
|
);
|
|
2283
2295
|
return { detachContextFromGroup, loading, error };
|
|
2284
2296
|
}
|
|
2297
|
+
function useMigrationStatus(namespaceId, options) {
|
|
2298
|
+
const { mero } = useMero();
|
|
2299
|
+
const [status, setStatus] = react.useState(null);
|
|
2300
|
+
const [loading, setLoading] = react.useState(false);
|
|
2301
|
+
const [error, setError] = react.useState(null);
|
|
2302
|
+
const mountedRef = useMountedRef();
|
|
2303
|
+
const reqRef = react.useRef(0);
|
|
2304
|
+
const refetch = react.useCallback(async () => {
|
|
2305
|
+
if (!mero || !namespaceId) {
|
|
2306
|
+
if (mountedRef.current) {
|
|
2307
|
+
setStatus(null);
|
|
2308
|
+
setError(null);
|
|
2309
|
+
setLoading(false);
|
|
2310
|
+
}
|
|
2311
|
+
return;
|
|
2312
|
+
}
|
|
2313
|
+
const seq = ++reqRef.current;
|
|
2314
|
+
if (mountedRef.current) {
|
|
2315
|
+
setLoading(true);
|
|
2316
|
+
setError(null);
|
|
2317
|
+
}
|
|
2318
|
+
try {
|
|
2319
|
+
const result = await mero.admin.getMigrationStatus(namespaceId);
|
|
2320
|
+
if (mountedRef.current && seq === reqRef.current) {
|
|
2321
|
+
setStatus(result);
|
|
2322
|
+
}
|
|
2323
|
+
} catch (err) {
|
|
2324
|
+
const errorValue = toError(err);
|
|
2325
|
+
if (mountedRef.current && seq === reqRef.current) {
|
|
2326
|
+
setError(errorValue);
|
|
2327
|
+
}
|
|
2328
|
+
} finally {
|
|
2329
|
+
if (mountedRef.current && seq === reqRef.current) {
|
|
2330
|
+
setLoading(false);
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
}, [namespaceId, mero, mountedRef]);
|
|
2334
|
+
react.useEffect(() => {
|
|
2335
|
+
setStatus(null);
|
|
2336
|
+
setError(null);
|
|
2337
|
+
}, [namespaceId]);
|
|
2338
|
+
react.useEffect(() => {
|
|
2339
|
+
void refetch();
|
|
2340
|
+
}, [refetch]);
|
|
2341
|
+
const pollIntervalMs = options?.pollIntervalMs;
|
|
2342
|
+
react.useEffect(() => {
|
|
2343
|
+
if (!pollIntervalMs || !mero || !namespaceId) return;
|
|
2344
|
+
const handle = setInterval(() => void refetch(), pollIntervalMs);
|
|
2345
|
+
return () => clearInterval(handle);
|
|
2346
|
+
}, [pollIntervalMs, mero, namespaceId, refetch]);
|
|
2347
|
+
const rollup = status?.rollup ?? null;
|
|
2348
|
+
const members = status?.members ?? [];
|
|
2349
|
+
return {
|
|
2350
|
+
status,
|
|
2351
|
+
rollup,
|
|
2352
|
+
members,
|
|
2353
|
+
allMigrated: rollup?.allMigrated ?? false,
|
|
2354
|
+
membersPendingSignature: rollup?.membersPendingSignature ?? 0,
|
|
2355
|
+
loading,
|
|
2356
|
+
error,
|
|
2357
|
+
refetch
|
|
2358
|
+
};
|
|
2359
|
+
}
|
|
2360
|
+
function useAppVersion(contextId, expected) {
|
|
2361
|
+
const { mero } = useMero();
|
|
2362
|
+
const [appVersion, setAppVersion] = react.useState(void 0);
|
|
2363
|
+
const [loading, setLoading] = react.useState(false);
|
|
2364
|
+
const [error, setError] = react.useState(null);
|
|
2365
|
+
const mountedRef = useMountedRef();
|
|
2366
|
+
const reqRef = react.useRef(0);
|
|
2367
|
+
const refetch = react.useCallback(async () => {
|
|
2368
|
+
if (!mero || !contextId) {
|
|
2369
|
+
if (mountedRef.current) {
|
|
2370
|
+
setAppVersion(void 0);
|
|
2371
|
+
setError(null);
|
|
2372
|
+
setLoading(false);
|
|
2373
|
+
}
|
|
2374
|
+
return;
|
|
2375
|
+
}
|
|
2376
|
+
const seq = ++reqRef.current;
|
|
2377
|
+
if (mountedRef.current) {
|
|
2378
|
+
setLoading(true);
|
|
2379
|
+
setError(null);
|
|
2380
|
+
}
|
|
2381
|
+
try {
|
|
2382
|
+
const context = await mero.admin.getContext(contextId);
|
|
2383
|
+
if (mountedRef.current && seq === reqRef.current) {
|
|
2384
|
+
setAppVersion(context.applicationVersion);
|
|
2385
|
+
}
|
|
2386
|
+
} catch (err) {
|
|
2387
|
+
const errorValue = toError(err);
|
|
2388
|
+
if (mountedRef.current && seq === reqRef.current) {
|
|
2389
|
+
setError(errorValue);
|
|
2390
|
+
}
|
|
2391
|
+
} finally {
|
|
2392
|
+
if (mountedRef.current && seq === reqRef.current) {
|
|
2393
|
+
setLoading(false);
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
}, [contextId, mero, mountedRef]);
|
|
2397
|
+
react.useEffect(() => {
|
|
2398
|
+
setAppVersion(void 0);
|
|
2399
|
+
setError(null);
|
|
2400
|
+
}, [contextId]);
|
|
2401
|
+
react.useEffect(() => {
|
|
2402
|
+
void refetch();
|
|
2403
|
+
}, [refetch]);
|
|
2404
|
+
react.useEffect(() => {
|
|
2405
|
+
if (!mero?.events || !contextId) return;
|
|
2406
|
+
const off = mero.events.onAppVersionChanged((event) => {
|
|
2407
|
+
if (event.contextId !== contextId) return;
|
|
2408
|
+
if (mountedRef.current && event.toVersion) {
|
|
2409
|
+
reqRef.current += 1;
|
|
2410
|
+
setAppVersion(event.toVersion);
|
|
2411
|
+
}
|
|
2412
|
+
});
|
|
2413
|
+
return off;
|
|
2414
|
+
}, [mero, contextId, mountedRef]);
|
|
2415
|
+
const isStale = appVersion != null && expected != null && appVersion !== expected;
|
|
2416
|
+
return { appVersion, expected, isStale, loading, error, refetch };
|
|
2417
|
+
}
|
|
2418
|
+
function useMyAuthoredMigration(contextId) {
|
|
2419
|
+
const { mero } = useMero();
|
|
2420
|
+
const [summary, setSummary] = react.useState(null);
|
|
2421
|
+
const [pendingCount, setPendingCount] = react.useState(0);
|
|
2422
|
+
const mountedRef = useMountedRef();
|
|
2423
|
+
const { loading, error, run } = useAsyncMutation();
|
|
2424
|
+
const reqRef = react.useRef(0);
|
|
2425
|
+
const refresh = react.useCallback(async () => {
|
|
2426
|
+
if (!mero || !contextId) {
|
|
2427
|
+
if (mountedRef.current) setPendingCount(0);
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
const seq = ++reqRef.current;
|
|
2431
|
+
try {
|
|
2432
|
+
const count = await mero.rpc.countMyPending(contextId);
|
|
2433
|
+
if (mountedRef.current && seq === reqRef.current) setPendingCount(count);
|
|
2434
|
+
} catch {
|
|
2435
|
+
}
|
|
2436
|
+
}, [mero, contextId, mountedRef]);
|
|
2437
|
+
react.useEffect(() => {
|
|
2438
|
+
void refresh();
|
|
2439
|
+
}, [refresh]);
|
|
2440
|
+
const authorize = react.useCallback(async () => {
|
|
2441
|
+
if (!mero || !contextId) return null;
|
|
2442
|
+
const result = await run(() => mero.rpc.migrateMyEntries(contextId));
|
|
2443
|
+
if (result && mountedRef.current) {
|
|
2444
|
+
reqRef.current += 1;
|
|
2445
|
+
setSummary(result);
|
|
2446
|
+
setPendingCount(result.remaining);
|
|
2447
|
+
}
|
|
2448
|
+
return result;
|
|
2449
|
+
}, [mero, contextId, run, mountedRef]);
|
|
2450
|
+
return {
|
|
2451
|
+
summary,
|
|
2452
|
+
pendingCount,
|
|
2453
|
+
pending: pendingCount > 0,
|
|
2454
|
+
authorize,
|
|
2455
|
+
loading,
|
|
2456
|
+
error,
|
|
2457
|
+
refresh
|
|
2458
|
+
};
|
|
2459
|
+
}
|
|
2460
|
+
function MigrationPendingBanner({
|
|
2461
|
+
contextId,
|
|
2462
|
+
className,
|
|
2463
|
+
children,
|
|
2464
|
+
onMigrated
|
|
2465
|
+
}) {
|
|
2466
|
+
const { pending, pendingCount, authorize, loading } = useMyAuthoredMigration(contextId);
|
|
2467
|
+
if (!pending) return null;
|
|
2468
|
+
const handleClick = async () => {
|
|
2469
|
+
const result = await authorize();
|
|
2470
|
+
if (result && result.remaining === 0) {
|
|
2471
|
+
onMigrated?.();
|
|
2472
|
+
}
|
|
2473
|
+
};
|
|
2474
|
+
const message = children ?? `You have ${pendingCount} ${pendingCount === 1 ? "entry" : "entries"} to re-sign after a recent upgrade.`;
|
|
2475
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-testid": "migration-pending-banner", role: "status", children: [
|
|
2476
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: message }),
|
|
2477
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: handleClick, disabled: loading, children: loading ? "Migrating\u2026" : "Migrate my data" })
|
|
2478
|
+
] });
|
|
2479
|
+
}
|
|
2480
|
+
function MigrationAdminPanel({ namespaceId, pollIntervalMs, className }) {
|
|
2481
|
+
const { status, rollup, members, membersPendingSignature, error } = useMigrationStatus(
|
|
2482
|
+
namespaceId,
|
|
2483
|
+
{ pollIntervalMs }
|
|
2484
|
+
);
|
|
2485
|
+
if (error && !status) {
|
|
2486
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-testid": "migration-admin-panel", children: [
|
|
2487
|
+
"Failed to load migration status: ",
|
|
2488
|
+
error.message
|
|
2489
|
+
] });
|
|
2490
|
+
}
|
|
2491
|
+
if (!status || !rollup) {
|
|
2492
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, "data-testid": "migration-admin-panel", children: "Loading migration status\u2026" });
|
|
2493
|
+
}
|
|
2494
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, "data-testid": "migration-admin-panel", children: [
|
|
2495
|
+
error && // A poll failed after data was already loaded — keep showing the last
|
|
2496
|
+
// good rollup but flag that it may be stale.
|
|
2497
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-testid": "migration-status-error", role: "alert", children: [
|
|
2498
|
+
"Could not refresh migration status: ",
|
|
2499
|
+
error.message
|
|
2500
|
+
] }),
|
|
2501
|
+
/* @__PURE__ */ jsxRuntime.jsxs("dl", { children: [
|
|
2502
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2503
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Target version" }),
|
|
2504
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: status.targetVersion })
|
|
2505
|
+
] }),
|
|
2506
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2507
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Migrated" }),
|
|
2508
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: rollup.migrated })
|
|
2509
|
+
] }),
|
|
2510
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2511
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: "In progress" }),
|
|
2512
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: rollup.inProgress })
|
|
2513
|
+
] }),
|
|
2514
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2515
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Unknown" }),
|
|
2516
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: rollup.unknown })
|
|
2517
|
+
] }),
|
|
2518
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2519
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Total" }),
|
|
2520
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: rollup.total })
|
|
2521
|
+
] }),
|
|
2522
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2523
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: "All migrated" }),
|
|
2524
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: rollup.allMigrated ? "yes" : "no" })
|
|
2525
|
+
] }),
|
|
2526
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2527
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Members pending signature" }),
|
|
2528
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { "data-testid": "members-pending-signature", children: membersPendingSignature })
|
|
2529
|
+
] })
|
|
2530
|
+
] }),
|
|
2531
|
+
/* @__PURE__ */ jsxRuntime.jsxs("table", { children: [
|
|
2532
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
2533
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { children: "Peer" }),
|
|
2534
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { children: "State" }),
|
|
2535
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { children: "Schema" }),
|
|
2536
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { children: "Pending" })
|
|
2537
|
+
] }) }),
|
|
2538
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: members.map((m) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { "data-testid": "migration-member-row", children: [
|
|
2539
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { children: m.peer }),
|
|
2540
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { children: m.state }),
|
|
2541
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { children: m.report?.schemaVersion ?? "\u2014" }),
|
|
2542
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { children: m.report?.authoredRemaining ?? "\u2014" })
|
|
2543
|
+
] }, m.peer)) })
|
|
2544
|
+
] })
|
|
2545
|
+
] });
|
|
2546
|
+
}
|
|
2285
2547
|
|
|
2286
2548
|
Object.defineProperty(exports, "CAPABILITIES", {
|
|
2287
2549
|
enumerable: true,
|
|
@@ -2307,6 +2569,8 @@ exports.LoginModal = LoginModal;
|
|
|
2307
2569
|
exports.MERO_CSS_VARS = MERO_CSS_VARS;
|
|
2308
2570
|
exports.MeroContext = MeroContext;
|
|
2309
2571
|
exports.MeroProvider = MeroProvider;
|
|
2572
|
+
exports.MigrationAdminPanel = MigrationAdminPanel;
|
|
2573
|
+
exports.MigrationPendingBanner = MigrationPendingBanner;
|
|
2310
2574
|
exports.clearAllStorage = clearAllStorage;
|
|
2311
2575
|
exports.clearApplicationId = clearApplicationId;
|
|
2312
2576
|
exports.clearContextId = clearContextId;
|
|
@@ -2326,6 +2590,7 @@ exports.setContextIdentity = setContextIdentity;
|
|
|
2326
2590
|
exports.setNodeUrl = setNodeUrl;
|
|
2327
2591
|
exports.themeToCssVars = themeToCssVars;
|
|
2328
2592
|
exports.useAddGroupMembers = useAddGroupMembers;
|
|
2593
|
+
exports.useAppVersion = useAppVersion;
|
|
2329
2594
|
exports.useApplicationContexts = useApplicationContexts;
|
|
2330
2595
|
exports.useContextDiscovery = useContextDiscovery;
|
|
2331
2596
|
exports.useContextGroup = useContextGroup;
|
|
@@ -2350,8 +2615,11 @@ exports.useGroupUpgradeStatus = useGroupUpgradeStatus;
|
|
|
2350
2615
|
exports.useJoinContext = useJoinContext;
|
|
2351
2616
|
exports.useJoinGroup = useJoinGroup;
|
|
2352
2617
|
exports.useJoinNamespace = useJoinNamespace;
|
|
2618
|
+
exports.useJoinSubgroupInheritance = useJoinSubgroupInheritance;
|
|
2353
2619
|
exports.useMemberMetadata = useMemberMetadata;
|
|
2354
2620
|
exports.useMero = useMero;
|
|
2621
|
+
exports.useMigrationStatus = useMigrationStatus;
|
|
2622
|
+
exports.useMyAuthoredMigration = useMyAuthoredMigration;
|
|
2355
2623
|
exports.useNamespace = useNamespace;
|
|
2356
2624
|
exports.useNamespaceGroups = useNamespaceGroups;
|
|
2357
2625
|
exports.useNamespaceIdentity = useNamespaceIdentity;
|