@qontinui/ui-bridge-native 0.1.6 → 0.2.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/control/{action-executor.d.ts → index.d.mts} +14 -6
- package/dist/control/index.d.ts +95 -5
- package/dist/control/index.js +74 -11
- package/dist/control/index.js.map +1 -1
- package/dist/control/index.mjs +74 -11
- package/dist/control/index.mjs.map +1 -1
- package/dist/core/index.d.mts +46 -0
- package/dist/core/index.d.ts +43 -6
- package/dist/core/index.js +69 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +69 -1
- package/dist/core/index.mjs.map +1 -1
- package/dist/debug/{inspector.d.ts → index.d.mts} +6 -3
- package/dist/debug/index.d.ts +44 -4
- package/dist/debug/index.js.map +1 -1
- package/dist/debug/index.mjs.map +1 -1
- package/dist/design/{design-inspector-native.d.ts → index.d.mts} +11 -7
- package/dist/design/index.d.ts +60 -5
- package/dist/{design/design-types.d.ts → design-types-BHr6Q1FX.d.mts} +11 -10
- package/dist/design-types-BHr6Q1FX.d.ts +205 -0
- package/dist/http-server-DCdR8WlL.d.mts +622 -0
- package/dist/http-server-Dj3grQW4.d.ts +622 -0
- package/dist/index.d.mts +89 -0
- package/dist/index.d.ts +86 -28
- package/dist/index.js +391 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +386 -13
- package/dist/index.mjs.map +1 -1
- package/dist/react/{useAutoRegister.d.ts → index.d.mts} +15 -7
- package/dist/react/index.d.ts +69 -8
- package/dist/react/index.js +388 -12
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +386 -13
- package/dist/react/index.mjs.map +1 -1
- package/dist/registry-Cahd8Gn2.d.mts +230 -0
- package/dist/{core/registry.d.ts → registry-z-3WJsxp.d.ts} +28 -10
- package/dist/server/index.d.mts +119 -0
- package/dist/server/index.d.ts +117 -13
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/types-DAfCeWXc.d.mts +197 -0
- package/dist/{core/types.d.ts → types-Oz13YLZq.d.mts} +124 -30
- package/dist/types-Oz13YLZq.d.ts +477 -0
- package/dist/{control/types.d.ts → types-ajakyp-l.d.ts} +36 -15
- package/dist/useUIBridgeToast-D32KXyL1.d.ts +720 -0
- package/dist/useUIBridgeToast-GmT1TzUe.d.mts +720 -0
- package/package.json +1 -1
- package/dist/control/action-executor.d.ts.map +0 -1
- package/dist/control/index.d.ts.map +0 -1
- package/dist/control/types.d.ts.map +0 -1
- package/dist/core/element-identifier.d.ts +0 -41
- package/dist/core/element-identifier.d.ts.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/registry.d.ts.map +0 -1
- package/dist/core/types.d.ts.map +0 -1
- package/dist/debug/index.d.ts.map +0 -1
- package/dist/debug/inspector.d.ts.map +0 -1
- package/dist/design/design-inspector-native.d.ts.map +0 -1
- package/dist/design/design-types.d.ts.map +0 -1
- package/dist/design/index.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/react/UIBridgeNativeProvider.d.ts +0 -147
- package/dist/react/UIBridgeNativeProvider.d.ts.map +0 -1
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/useAutoRegister.d.ts.map +0 -1
- package/dist/react/useUIBridge.d.ts +0 -103
- package/dist/react/useUIBridge.d.ts.map +0 -1
- package/dist/react/useUIComponent.d.ts +0 -112
- package/dist/react/useUIComponent.d.ts.map +0 -1
- package/dist/react/useUIElement.d.ts +0 -162
- package/dist/react/useUIElement.d.ts.map +0 -1
- package/dist/server/design-handlers.d.ts +0 -47
- package/dist/server/design-handlers.d.ts.map +0 -1
- package/dist/server/handlers.d.ts +0 -20
- package/dist/server/handlers.d.ts.map +0 -1
- package/dist/server/http-server.d.ts +0 -247
- package/dist/server/http-server.d.ts.map +0 -1
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/types.d.ts +0 -200
- package/dist/server/types.d.ts.map +0 -1
- package/dist/server/ws-connection.d.ts +0 -48
- package/dist/server/ws-connection.d.ts.map +0 -1
- package/dist/server/ws-event-bridge.d.ts +0 -113
- package/dist/server/ws-event-bridge.d.ts.map +0 -1
- package/dist/server/ws-protocol.d.ts +0 -48
- package/dist/server/ws-protocol.d.ts.map +0 -1
- package/dist/server/ws-types.d.ts +0 -65
- package/dist/server/ws-types.d.ts.map +0 -1
- package/dist/transport/CloudRelayClient.d.ts +0 -51
- package/dist/transport/CloudRelayClient.d.ts.map +0 -1
- package/dist/transport/DeviceAnnouncer.d.ts +0 -75
- package/dist/transport/DeviceAnnouncer.d.ts.map +0 -1
- package/dist/transport/index.d.ts +0 -3
- package/dist/transport/index.d.ts.map +0 -1
package/dist/react/index.mjs
CHANGED
|
@@ -53,9 +53,34 @@ var NativeUIBridgeRegistry = class {
|
|
|
53
53
|
this.components = /* @__PURE__ */ new Map();
|
|
54
54
|
this.workflows = /* @__PURE__ */ new Map();
|
|
55
55
|
this.eventListeners = /* @__PURE__ */ new Map();
|
|
56
|
+
this.enrichers = {};
|
|
57
|
+
this.snapshotExtras = /* @__PURE__ */ new Map();
|
|
56
58
|
this.config = config;
|
|
57
59
|
}
|
|
58
60
|
// ============================================================================
|
|
61
|
+
// Snapshot Enricher Slots
|
|
62
|
+
// ============================================================================
|
|
63
|
+
/**
|
|
64
|
+
* Register/replace canonical enrichers (modal/toast/undo). HMR-safe — calling
|
|
65
|
+
* with a partial set merges into existing slots instead of clobbering them.
|
|
66
|
+
*/
|
|
67
|
+
setEnrichers(e) {
|
|
68
|
+
this.enrichers = { ...this.enrichers, ...e };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Register a custom snapshot enricher. The returned object will be
|
|
72
|
+
* `Object.assign`ed onto the snapshot, so use unique top-level keys to avoid
|
|
73
|
+
* clobbering canonical fields. Returns a disposer.
|
|
74
|
+
*/
|
|
75
|
+
registerSnapshotEnricher(name, fn) {
|
|
76
|
+
this.snapshotExtras.set(name, fn);
|
|
77
|
+
return () => this.unregisterSnapshotEnricher(name);
|
|
78
|
+
}
|
|
79
|
+
/** Remove a custom snapshot enricher by name */
|
|
80
|
+
unregisterSnapshotEnricher(name) {
|
|
81
|
+
this.snapshotExtras.delete(name);
|
|
82
|
+
}
|
|
83
|
+
// ============================================================================
|
|
59
84
|
// Element Management
|
|
60
85
|
// ============================================================================
|
|
61
86
|
/**
|
|
@@ -418,7 +443,7 @@ var NativeUIBridgeRegistry = class {
|
|
|
418
443
|
const currentRoute = routeInfo.currentRoute;
|
|
419
444
|
elements = elements.filter((e) => e.registrationRoute === currentRoute);
|
|
420
445
|
}
|
|
421
|
-
|
|
446
|
+
const snapshot = {
|
|
422
447
|
timestamp: Date.now(),
|
|
423
448
|
elements: elements.map((e) => {
|
|
424
449
|
const handlers = extractHandlerNames(e.props);
|
|
@@ -450,6 +475,49 @@ var NativeUIBridgeRegistry = class {
|
|
|
450
475
|
currentRoute: routeInfo?.currentRoute ?? null,
|
|
451
476
|
segments: routeInfo?.segments
|
|
452
477
|
};
|
|
478
|
+
if (this.enrichers.modalDetector) {
|
|
479
|
+
try {
|
|
480
|
+
snapshot.modalStack = this.enrichers.modalDetector.getSnapshotModalContext();
|
|
481
|
+
} catch (error3) {
|
|
482
|
+
if (this.config.verbose) {
|
|
483
|
+
console.warn(`[ui-bridge-native] modalDetector enricher threw:`, error3);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (this.enrichers.toastCapture) {
|
|
488
|
+
try {
|
|
489
|
+
snapshot.toasts = this.enrichers.toastCapture.getSnapshotToastContext();
|
|
490
|
+
} catch (error3) {
|
|
491
|
+
if (this.config.verbose) {
|
|
492
|
+
console.warn(`[ui-bridge-native] toastCapture enricher threw:`, error3);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (this.enrichers.undoTracker) {
|
|
497
|
+
try {
|
|
498
|
+
snapshot.undoRedo = this.enrichers.undoTracker.getSnapshotUndoContext();
|
|
499
|
+
} catch (error3) {
|
|
500
|
+
if (this.config.verbose) {
|
|
501
|
+
console.warn(`[ui-bridge-native] undoTracker enricher threw:`, error3);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if (this.snapshotExtras.size > 0) {
|
|
506
|
+
const ctx = { elements, currentRoute: routeInfo?.currentRoute ?? null };
|
|
507
|
+
for (const [name, fn] of this.snapshotExtras) {
|
|
508
|
+
try {
|
|
509
|
+
const extra = fn(ctx);
|
|
510
|
+
if (extra && typeof extra === "object") {
|
|
511
|
+
Object.assign(snapshot, extra);
|
|
512
|
+
}
|
|
513
|
+
} catch (error3) {
|
|
514
|
+
if (this.config.verbose) {
|
|
515
|
+
console.warn(`[ui-bridge-native] snapshot enricher "${name}" threw:`, error3);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return snapshot;
|
|
453
521
|
}
|
|
454
522
|
/**
|
|
455
523
|
* Get registry statistics
|
|
@@ -543,6 +611,23 @@ function sleep(ms) {
|
|
|
543
611
|
var DefaultNativeActionExecutor = class {
|
|
544
612
|
constructor(registry) {
|
|
545
613
|
this.registry = registry;
|
|
614
|
+
this.actionListeners = /* @__PURE__ */ new Set();
|
|
615
|
+
}
|
|
616
|
+
onActionExecuted(listener) {
|
|
617
|
+
this.actionListeners.add(listener);
|
|
618
|
+
return () => {
|
|
619
|
+
this.actionListeners.delete(listener);
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
/** Notify listeners out-of-band; isolate each invocation so one bad listener can't poison the rest. */
|
|
623
|
+
emitActionEvent(event) {
|
|
624
|
+
for (const listener of this.actionListeners) {
|
|
625
|
+
try {
|
|
626
|
+
listener(event);
|
|
627
|
+
} catch (error3) {
|
|
628
|
+
console.warn(`[ui-bridge-native] Action listener error:`, error3);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
546
631
|
}
|
|
547
632
|
/**
|
|
548
633
|
* Execute an action on an element
|
|
@@ -556,11 +641,23 @@ var DefaultNativeActionExecutor = class {
|
|
|
556
641
|
registered = findElementByIdentifier(elementId) ?? void 0;
|
|
557
642
|
}
|
|
558
643
|
if (!registered) {
|
|
644
|
+
const failTime = Date.now();
|
|
645
|
+
const errorMsg = `Element not found: ${elementId}`;
|
|
646
|
+
this.emitActionEvent({
|
|
647
|
+
elementId,
|
|
648
|
+
action: request.action,
|
|
649
|
+
params: request.params,
|
|
650
|
+
success: false,
|
|
651
|
+
error: errorMsg,
|
|
652
|
+
timestamp: failTime,
|
|
653
|
+
requestId: request.requestId,
|
|
654
|
+
durationMs: failTime - startTime
|
|
655
|
+
});
|
|
559
656
|
return {
|
|
560
657
|
success: false,
|
|
561
|
-
error:
|
|
562
|
-
durationMs:
|
|
563
|
-
timestamp:
|
|
658
|
+
error: errorMsg,
|
|
659
|
+
durationMs: failTime - startTime,
|
|
660
|
+
timestamp: failTime,
|
|
564
661
|
requestId: request.requestId
|
|
565
662
|
};
|
|
566
663
|
}
|
|
@@ -568,33 +665,67 @@ var DefaultNativeActionExecutor = class {
|
|
|
568
665
|
const waitResult = await this.waitForElementInternal(registered.id, request.waitOptions);
|
|
569
666
|
waitDurationMs = waitResult.waitedMs;
|
|
570
667
|
if (!waitResult.met) {
|
|
668
|
+
const failTime = Date.now();
|
|
669
|
+
const errorMsg = waitResult.error || "Wait condition not met";
|
|
670
|
+
this.emitActionEvent({
|
|
671
|
+
elementId,
|
|
672
|
+
action: request.action,
|
|
673
|
+
params: request.params,
|
|
674
|
+
success: false,
|
|
675
|
+
error: errorMsg,
|
|
676
|
+
timestamp: failTime,
|
|
677
|
+
requestId: request.requestId,
|
|
678
|
+
durationMs: failTime - startTime
|
|
679
|
+
});
|
|
571
680
|
return {
|
|
572
681
|
success: false,
|
|
573
|
-
error:
|
|
574
|
-
durationMs:
|
|
575
|
-
timestamp:
|
|
682
|
+
error: errorMsg,
|
|
683
|
+
durationMs: failTime - startTime,
|
|
684
|
+
timestamp: failTime,
|
|
576
685
|
requestId: request.requestId,
|
|
577
686
|
waitDurationMs
|
|
578
687
|
};
|
|
579
688
|
}
|
|
580
689
|
}
|
|
581
690
|
const result = await this.performAction(registered, request.action, request.params);
|
|
691
|
+
const successTime = Date.now();
|
|
692
|
+
this.emitActionEvent({
|
|
693
|
+
elementId,
|
|
694
|
+
action: request.action,
|
|
695
|
+
params: request.params,
|
|
696
|
+
success: true,
|
|
697
|
+
timestamp: successTime,
|
|
698
|
+
requestId: request.requestId,
|
|
699
|
+
durationMs: successTime - startTime
|
|
700
|
+
});
|
|
582
701
|
return {
|
|
583
702
|
success: true,
|
|
584
703
|
elementState: registered.getState(),
|
|
585
704
|
result,
|
|
586
|
-
durationMs:
|
|
587
|
-
timestamp:
|
|
705
|
+
durationMs: successTime - startTime,
|
|
706
|
+
timestamp: successTime,
|
|
588
707
|
requestId: request.requestId,
|
|
589
708
|
waitDurationMs
|
|
590
709
|
};
|
|
591
710
|
} catch (error3) {
|
|
711
|
+
const failTime = Date.now();
|
|
712
|
+
const errorMsg = error3 instanceof Error ? error3.message : String(error3);
|
|
713
|
+
this.emitActionEvent({
|
|
714
|
+
elementId,
|
|
715
|
+
action: request.action,
|
|
716
|
+
params: request.params,
|
|
717
|
+
success: false,
|
|
718
|
+
error: errorMsg,
|
|
719
|
+
timestamp: failTime,
|
|
720
|
+
requestId: request.requestId,
|
|
721
|
+
durationMs: failTime - startTime
|
|
722
|
+
});
|
|
592
723
|
return {
|
|
593
724
|
success: false,
|
|
594
|
-
error:
|
|
725
|
+
error: errorMsg,
|
|
595
726
|
stack: error3 instanceof Error ? error3.stack : void 0,
|
|
596
|
-
durationMs:
|
|
597
|
-
timestamp:
|
|
727
|
+
durationMs: failTime - startTime,
|
|
728
|
+
timestamp: failTime,
|
|
598
729
|
requestId: request.requestId,
|
|
599
730
|
waitDurationMs
|
|
600
731
|
};
|
|
@@ -3512,6 +3643,186 @@ function parseQueryParams(path) {
|
|
|
3512
3643
|
}
|
|
3513
3644
|
return result;
|
|
3514
3645
|
}
|
|
3646
|
+
|
|
3647
|
+
// src/modal/modal-detector.ts
|
|
3648
|
+
var ModalDetector = class {
|
|
3649
|
+
constructor() {
|
|
3650
|
+
/** Map preserves O(1) idempotent replace by id; ordering comes from detectedAt. */
|
|
3651
|
+
this.modals = /* @__PURE__ */ new Map();
|
|
3652
|
+
}
|
|
3653
|
+
pushModal(modal) {
|
|
3654
|
+
const existing = this.modals.get(modal.id);
|
|
3655
|
+
const detectedAt = existing ? existing.detectedAt : Date.now();
|
|
3656
|
+
const next = {
|
|
3657
|
+
id: modal.id,
|
|
3658
|
+
title: modal.title,
|
|
3659
|
+
type: modal.type ?? "modal",
|
|
3660
|
+
blocking: modal.blocking ?? true,
|
|
3661
|
+
dismissible: modal.dismissible ?? true,
|
|
3662
|
+
detectedAt
|
|
3663
|
+
};
|
|
3664
|
+
this.modals.set(modal.id, next);
|
|
3665
|
+
}
|
|
3666
|
+
dismissModal(id) {
|
|
3667
|
+
this.modals.delete(id);
|
|
3668
|
+
}
|
|
3669
|
+
getSnapshotModalContext() {
|
|
3670
|
+
const active = this.getActive();
|
|
3671
|
+
const ctx = {
|
|
3672
|
+
modals: active,
|
|
3673
|
+
hasBlockingModal: active.some((m) => m.blocking),
|
|
3674
|
+
count: active.length
|
|
3675
|
+
};
|
|
3676
|
+
if (active.length > 0) {
|
|
3677
|
+
ctx.topModal = active[active.length - 1];
|
|
3678
|
+
}
|
|
3679
|
+
return ctx;
|
|
3680
|
+
}
|
|
3681
|
+
getActive() {
|
|
3682
|
+
return Array.from(this.modals.values()).sort((a, b) => a.detectedAt - b.detectedAt);
|
|
3683
|
+
}
|
|
3684
|
+
clear() {
|
|
3685
|
+
this.modals.clear();
|
|
3686
|
+
}
|
|
3687
|
+
};
|
|
3688
|
+
|
|
3689
|
+
// src/toast/toast-capture.ts
|
|
3690
|
+
var DEFAULT_MAX_RECENT = 50;
|
|
3691
|
+
var ToastCapture = class {
|
|
3692
|
+
constructor(config = {}) {
|
|
3693
|
+
this.active = /* @__PURE__ */ new Map();
|
|
3694
|
+
this.recent = [];
|
|
3695
|
+
this.totalCaptured = 0;
|
|
3696
|
+
this.maxRecent = config.maxRecent ?? DEFAULT_MAX_RECENT;
|
|
3697
|
+
}
|
|
3698
|
+
recordToast(toast) {
|
|
3699
|
+
if (this.active.has(toast.id)) {
|
|
3700
|
+
return;
|
|
3701
|
+
}
|
|
3702
|
+
const appearedAt = toast.appearedAt ?? Date.now();
|
|
3703
|
+
const entry = {
|
|
3704
|
+
id: toast.id,
|
|
3705
|
+
message: toast.message,
|
|
3706
|
+
level: toast.level ?? "info",
|
|
3707
|
+
appearedAt,
|
|
3708
|
+
visible: true,
|
|
3709
|
+
durationMs: 0
|
|
3710
|
+
};
|
|
3711
|
+
this.active.set(toast.id, entry);
|
|
3712
|
+
this.totalCaptured += 1;
|
|
3713
|
+
}
|
|
3714
|
+
dismissToast(id) {
|
|
3715
|
+
const entry = this.active.get(id);
|
|
3716
|
+
if (!entry) {
|
|
3717
|
+
return;
|
|
3718
|
+
}
|
|
3719
|
+
this.active.delete(id);
|
|
3720
|
+
const dismissedAt = Date.now();
|
|
3721
|
+
const dismissed = {
|
|
3722
|
+
...entry,
|
|
3723
|
+
dismissedAt,
|
|
3724
|
+
visible: false,
|
|
3725
|
+
durationMs: dismissedAt - entry.appearedAt
|
|
3726
|
+
};
|
|
3727
|
+
this.recent.push(dismissed);
|
|
3728
|
+
if (this.recent.length > this.maxRecent) {
|
|
3729
|
+
this.recent.shift();
|
|
3730
|
+
}
|
|
3731
|
+
}
|
|
3732
|
+
getSnapshotToastContext() {
|
|
3733
|
+
const now = Date.now();
|
|
3734
|
+
const active = Array.from(this.active.values()).map((entry) => ({
|
|
3735
|
+
...entry,
|
|
3736
|
+
durationMs: now - entry.appearedAt
|
|
3737
|
+
}));
|
|
3738
|
+
return {
|
|
3739
|
+
active,
|
|
3740
|
+
recent: [...this.recent],
|
|
3741
|
+
totalCaptured: this.totalCaptured
|
|
3742
|
+
};
|
|
3743
|
+
}
|
|
3744
|
+
clear() {
|
|
3745
|
+
this.active.clear();
|
|
3746
|
+
this.recent = [];
|
|
3747
|
+
this.totalCaptured = 0;
|
|
3748
|
+
}
|
|
3749
|
+
};
|
|
3750
|
+
|
|
3751
|
+
// src/undo/undo-tracker.ts
|
|
3752
|
+
var DEFAULT_MAX_HISTORY = 50;
|
|
3753
|
+
function buildSummary(ctx) {
|
|
3754
|
+
if (!ctx.canUndo && !ctx.canRedo) {
|
|
3755
|
+
return "no undo available";
|
|
3756
|
+
}
|
|
3757
|
+
const parts = [];
|
|
3758
|
+
if (ctx.canUndo) {
|
|
3759
|
+
parts.push(`undo: '${ctx.undoDescription ?? "available"}'`);
|
|
3760
|
+
}
|
|
3761
|
+
if (ctx.canRedo) {
|
|
3762
|
+
parts.push(`redo: '${ctx.redoDescription ?? "available"}'`);
|
|
3763
|
+
}
|
|
3764
|
+
return parts.join(" / ");
|
|
3765
|
+
}
|
|
3766
|
+
var UndoTracker = class {
|
|
3767
|
+
constructor(config = {}) {
|
|
3768
|
+
this.actions = [];
|
|
3769
|
+
this.declaredState = null;
|
|
3770
|
+
this.maxHistory = config.maxHistory ?? DEFAULT_MAX_HISTORY;
|
|
3771
|
+
}
|
|
3772
|
+
recordAction(record) {
|
|
3773
|
+
this.actions.push(record);
|
|
3774
|
+
if (this.actions.length > this.maxHistory) {
|
|
3775
|
+
this.actions = this.actions.slice(-this.maxHistory);
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
setDeclaredState(state) {
|
|
3779
|
+
this.declaredState = state;
|
|
3780
|
+
}
|
|
3781
|
+
getActionHistory() {
|
|
3782
|
+
return this.actions.slice();
|
|
3783
|
+
}
|
|
3784
|
+
getSnapshotUndoContext() {
|
|
3785
|
+
const declared = this.declaredState;
|
|
3786
|
+
if (declared) {
|
|
3787
|
+
const summary2 = buildSummary({
|
|
3788
|
+
canUndo: declared.canUndo,
|
|
3789
|
+
canRedo: declared.canRedo,
|
|
3790
|
+
undoDescription: declared.undoDescription,
|
|
3791
|
+
redoDescription: declared.redoDescription
|
|
3792
|
+
});
|
|
3793
|
+
return {
|
|
3794
|
+
canUndo: declared.canUndo,
|
|
3795
|
+
canRedo: declared.canRedo,
|
|
3796
|
+
undoDescription: declared.undoDescription,
|
|
3797
|
+
redoDescription: declared.redoDescription,
|
|
3798
|
+
undoDepth: declared.undoDepth,
|
|
3799
|
+
redoDepth: declared.redoDepth,
|
|
3800
|
+
summary: summary2
|
|
3801
|
+
};
|
|
3802
|
+
}
|
|
3803
|
+
const canUndo = this.actions.some((a) => a.reversible !== false);
|
|
3804
|
+
const canRedo = false;
|
|
3805
|
+
const lastReversible = [...this.actions].reverse().find((a) => a.reversible !== false);
|
|
3806
|
+
const undoDescription = lastReversible?.description;
|
|
3807
|
+
const summary = buildSummary({ canUndo, canRedo, undoDescription });
|
|
3808
|
+
return {
|
|
3809
|
+
canUndo,
|
|
3810
|
+
canRedo,
|
|
3811
|
+
undoDescription,
|
|
3812
|
+
summary
|
|
3813
|
+
};
|
|
3814
|
+
}
|
|
3815
|
+
executeUndo() {
|
|
3816
|
+
return { ok: false, reason: "Not implemented in native" };
|
|
3817
|
+
}
|
|
3818
|
+
executeRedo() {
|
|
3819
|
+
return { ok: false, reason: "Not implemented in native" };
|
|
3820
|
+
}
|
|
3821
|
+
clear() {
|
|
3822
|
+
this.actions = [];
|
|
3823
|
+
this.declaredState = null;
|
|
3824
|
+
}
|
|
3825
|
+
};
|
|
3515
3826
|
var UIBridgeNativeContext = createContext(null);
|
|
3516
3827
|
function UIBridgeNativeProvider({
|
|
3517
3828
|
children,
|
|
@@ -3528,6 +3839,9 @@ function UIBridgeNativeProvider({
|
|
|
3528
3839
|
}) {
|
|
3529
3840
|
const registryRef = useRef(null);
|
|
3530
3841
|
const executorRef = useRef(null);
|
|
3842
|
+
const modalDetectorRef = useRef(null);
|
|
3843
|
+
const toastCaptureRef = useRef(null);
|
|
3844
|
+
const undoTrackerRef = useRef(null);
|
|
3531
3845
|
const [serverRunning, setServerRunning] = useState(false);
|
|
3532
3846
|
if (!registryRef.current) {
|
|
3533
3847
|
registryRef.current = new NativeUIBridgeRegistry({
|
|
@@ -3541,6 +3855,12 @@ function UIBridgeNativeProvider({
|
|
|
3541
3855
|
executorRef.current = createNativeActionExecutor(registry);
|
|
3542
3856
|
}
|
|
3543
3857
|
const executor = executorRef.current;
|
|
3858
|
+
if (!modalDetectorRef.current) modalDetectorRef.current = new ModalDetector();
|
|
3859
|
+
if (!toastCaptureRef.current) toastCaptureRef.current = new ToastCapture();
|
|
3860
|
+
if (!undoTrackerRef.current) undoTrackerRef.current = new UndoTracker();
|
|
3861
|
+
const modalDetector = modalDetectorRef.current;
|
|
3862
|
+
const toastCapture = toastCaptureRef.current;
|
|
3863
|
+
const undoTracker = undoTrackerRef.current;
|
|
3544
3864
|
const serverRef = useRef(null);
|
|
3545
3865
|
const eventBridgeRef = useRef(null);
|
|
3546
3866
|
const announcerRef = useRef(null);
|
|
@@ -3729,6 +4049,22 @@ function UIBridgeNativeProvider({
|
|
|
3729
4049
|
lastRoute = current;
|
|
3730
4050
|
});
|
|
3731
4051
|
}, [routeProvider, registry]);
|
|
4052
|
+
useEffect(() => {
|
|
4053
|
+
registry.setEnrichers({ modalDetector, toastCapture, undoTracker });
|
|
4054
|
+
}, [registry, modalDetector, toastCapture, undoTracker]);
|
|
4055
|
+
useEffect(() => {
|
|
4056
|
+
const unsubscribe = executor.onActionExecuted((event) => {
|
|
4057
|
+
if (!event.success) return;
|
|
4058
|
+
undoTracker.recordAction({
|
|
4059
|
+
id: event.requestId ?? `action-${event.timestamp}`,
|
|
4060
|
+
type: event.action,
|
|
4061
|
+
targetId: event.elementId,
|
|
4062
|
+
timestamp: event.timestamp,
|
|
4063
|
+
reversible: true
|
|
4064
|
+
});
|
|
4065
|
+
});
|
|
4066
|
+
return unsubscribe;
|
|
4067
|
+
}, [executor, undoTracker]);
|
|
3732
4068
|
const on = useCallback(
|
|
3733
4069
|
(type, listener) => registry.on(type, listener),
|
|
3734
4070
|
[registry]
|
|
@@ -3743,6 +4079,9 @@ function UIBridgeNativeProvider({
|
|
|
3743
4079
|
config,
|
|
3744
4080
|
registry,
|
|
3745
4081
|
executor,
|
|
4082
|
+
modalDetector,
|
|
4083
|
+
toastCapture,
|
|
4084
|
+
undoTracker,
|
|
3746
4085
|
getElements,
|
|
3747
4086
|
getComponents,
|
|
3748
4087
|
createSnapshot,
|
|
@@ -3759,6 +4098,9 @@ function UIBridgeNativeProvider({
|
|
|
3759
4098
|
config,
|
|
3760
4099
|
registry,
|
|
3761
4100
|
executor,
|
|
4101
|
+
modalDetector,
|
|
4102
|
+
toastCapture,
|
|
4103
|
+
undoTracker,
|
|
3762
4104
|
getElements,
|
|
3763
4105
|
getComponents,
|
|
3764
4106
|
createSnapshot,
|
|
@@ -4276,7 +4618,38 @@ function useAutoRegister(options = {}) {
|
|
|
4276
4618
|
isEnabled: enabled && !!bridge?.registry
|
|
4277
4619
|
};
|
|
4278
4620
|
}
|
|
4621
|
+
function useUIBridgeModal(opts) {
|
|
4622
|
+
const { modalDetector } = useUIBridgeNative();
|
|
4623
|
+
const { id, title, type, blocking, dismissible } = opts;
|
|
4624
|
+
useEffect(() => {
|
|
4625
|
+
modalDetector.pushModal({ id, title, type, blocking, dismissible });
|
|
4626
|
+
return () => {
|
|
4627
|
+
modalDetector.dismissModal(id);
|
|
4628
|
+
};
|
|
4629
|
+
}, [modalDetector, id, title, type, blocking, dismissible]);
|
|
4630
|
+
}
|
|
4631
|
+
function useUIBridgeToast(opts) {
|
|
4632
|
+
const { toastCapture } = useUIBridgeNative();
|
|
4633
|
+
const { id, message, level } = opts;
|
|
4634
|
+
useEffect(() => {
|
|
4635
|
+
toastCapture.recordToast({ id, message, level });
|
|
4636
|
+
return () => {
|
|
4637
|
+
toastCapture.dismissToast(id);
|
|
4638
|
+
};
|
|
4639
|
+
}, [toastCapture, id, message, level]);
|
|
4640
|
+
}
|
|
4641
|
+
function useToastRecorder() {
|
|
4642
|
+
const { toastCapture } = useUIBridgeNative();
|
|
4643
|
+
const recordToast = useCallback(
|
|
4644
|
+
(toast) => {
|
|
4645
|
+
toastCapture.recordToast(toast);
|
|
4646
|
+
},
|
|
4647
|
+
[toastCapture]
|
|
4648
|
+
);
|
|
4649
|
+
const dismissToast = useCallback((id) => toastCapture.dismissToast(id), [toastCapture]);
|
|
4650
|
+
return { recordToast, dismissToast };
|
|
4651
|
+
}
|
|
4279
4652
|
|
|
4280
|
-
export { UIBridgeNativeProvider, useAutoRegister, useUIBridge, useUIBridgeNative, useUIBridgeNativeOptional, useUIBridgeNativeRequired, useUIBridgeRequired, useUIComponent, useUIComponentAction, useUIElement, useUIElementWithProps };
|
|
4653
|
+
export { UIBridgeNativeProvider, useAutoRegister, useToastRecorder, useUIBridge, useUIBridgeModal, useUIBridgeNative, useUIBridgeNativeOptional, useUIBridgeNativeRequired, useUIBridgeRequired, useUIBridgeToast, useUIComponent, useUIComponentAction, useUIElement, useUIElementWithProps };
|
|
4281
4654
|
//# sourceMappingURL=index.mjs.map
|
|
4282
4655
|
//# sourceMappingURL=index.mjs.map
|