@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/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
|
|
@@ -595,6 +663,23 @@ function sleep(ms) {
|
|
|
595
663
|
var DefaultNativeActionExecutor = class {
|
|
596
664
|
constructor(registry) {
|
|
597
665
|
this.registry = registry;
|
|
666
|
+
this.actionListeners = /* @__PURE__ */ new Set();
|
|
667
|
+
}
|
|
668
|
+
onActionExecuted(listener) {
|
|
669
|
+
this.actionListeners.add(listener);
|
|
670
|
+
return () => {
|
|
671
|
+
this.actionListeners.delete(listener);
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
/** Notify listeners out-of-band; isolate each invocation so one bad listener can't poison the rest. */
|
|
675
|
+
emitActionEvent(event) {
|
|
676
|
+
for (const listener of this.actionListeners) {
|
|
677
|
+
try {
|
|
678
|
+
listener(event);
|
|
679
|
+
} catch (error3) {
|
|
680
|
+
console.warn(`[ui-bridge-native] Action listener error:`, error3);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
598
683
|
}
|
|
599
684
|
/**
|
|
600
685
|
* Execute an action on an element
|
|
@@ -608,11 +693,23 @@ var DefaultNativeActionExecutor = class {
|
|
|
608
693
|
registered = findElementByIdentifier(elementId) ?? void 0;
|
|
609
694
|
}
|
|
610
695
|
if (!registered) {
|
|
696
|
+
const failTime = Date.now();
|
|
697
|
+
const errorMsg = `Element not found: ${elementId}`;
|
|
698
|
+
this.emitActionEvent({
|
|
699
|
+
elementId,
|
|
700
|
+
action: request.action,
|
|
701
|
+
params: request.params,
|
|
702
|
+
success: false,
|
|
703
|
+
error: errorMsg,
|
|
704
|
+
timestamp: failTime,
|
|
705
|
+
requestId: request.requestId,
|
|
706
|
+
durationMs: failTime - startTime
|
|
707
|
+
});
|
|
611
708
|
return {
|
|
612
709
|
success: false,
|
|
613
|
-
error:
|
|
614
|
-
durationMs:
|
|
615
|
-
timestamp:
|
|
710
|
+
error: errorMsg,
|
|
711
|
+
durationMs: failTime - startTime,
|
|
712
|
+
timestamp: failTime,
|
|
616
713
|
requestId: request.requestId
|
|
617
714
|
};
|
|
618
715
|
}
|
|
@@ -620,33 +717,67 @@ var DefaultNativeActionExecutor = class {
|
|
|
620
717
|
const waitResult = await this.waitForElementInternal(registered.id, request.waitOptions);
|
|
621
718
|
waitDurationMs = waitResult.waitedMs;
|
|
622
719
|
if (!waitResult.met) {
|
|
720
|
+
const failTime = Date.now();
|
|
721
|
+
const errorMsg = waitResult.error || "Wait condition not met";
|
|
722
|
+
this.emitActionEvent({
|
|
723
|
+
elementId,
|
|
724
|
+
action: request.action,
|
|
725
|
+
params: request.params,
|
|
726
|
+
success: false,
|
|
727
|
+
error: errorMsg,
|
|
728
|
+
timestamp: failTime,
|
|
729
|
+
requestId: request.requestId,
|
|
730
|
+
durationMs: failTime - startTime
|
|
731
|
+
});
|
|
623
732
|
return {
|
|
624
733
|
success: false,
|
|
625
|
-
error:
|
|
626
|
-
durationMs:
|
|
627
|
-
timestamp:
|
|
734
|
+
error: errorMsg,
|
|
735
|
+
durationMs: failTime - startTime,
|
|
736
|
+
timestamp: failTime,
|
|
628
737
|
requestId: request.requestId,
|
|
629
738
|
waitDurationMs
|
|
630
739
|
};
|
|
631
740
|
}
|
|
632
741
|
}
|
|
633
742
|
const result = await this.performAction(registered, request.action, request.params);
|
|
743
|
+
const successTime = Date.now();
|
|
744
|
+
this.emitActionEvent({
|
|
745
|
+
elementId,
|
|
746
|
+
action: request.action,
|
|
747
|
+
params: request.params,
|
|
748
|
+
success: true,
|
|
749
|
+
timestamp: successTime,
|
|
750
|
+
requestId: request.requestId,
|
|
751
|
+
durationMs: successTime - startTime
|
|
752
|
+
});
|
|
634
753
|
return {
|
|
635
754
|
success: true,
|
|
636
755
|
elementState: registered.getState(),
|
|
637
756
|
result,
|
|
638
|
-
durationMs:
|
|
639
|
-
timestamp:
|
|
757
|
+
durationMs: successTime - startTime,
|
|
758
|
+
timestamp: successTime,
|
|
640
759
|
requestId: request.requestId,
|
|
641
760
|
waitDurationMs
|
|
642
761
|
};
|
|
643
762
|
} catch (error3) {
|
|
763
|
+
const failTime = Date.now();
|
|
764
|
+
const errorMsg = error3 instanceof Error ? error3.message : String(error3);
|
|
765
|
+
this.emitActionEvent({
|
|
766
|
+
elementId,
|
|
767
|
+
action: request.action,
|
|
768
|
+
params: request.params,
|
|
769
|
+
success: false,
|
|
770
|
+
error: errorMsg,
|
|
771
|
+
timestamp: failTime,
|
|
772
|
+
requestId: request.requestId,
|
|
773
|
+
durationMs: failTime - startTime
|
|
774
|
+
});
|
|
644
775
|
return {
|
|
645
776
|
success: false,
|
|
646
|
-
error:
|
|
777
|
+
error: errorMsg,
|
|
647
778
|
stack: error3 instanceof Error ? error3.stack : void 0,
|
|
648
|
-
durationMs:
|
|
649
|
-
timestamp:
|
|
779
|
+
durationMs: failTime - startTime,
|
|
780
|
+
timestamp: failTime,
|
|
650
781
|
requestId: request.requestId,
|
|
651
782
|
waitDurationMs
|
|
652
783
|
};
|
|
@@ -3564,6 +3695,186 @@ function parseQueryParams(path) {
|
|
|
3564
3695
|
}
|
|
3565
3696
|
return result;
|
|
3566
3697
|
}
|
|
3698
|
+
|
|
3699
|
+
// src/modal/modal-detector.ts
|
|
3700
|
+
var ModalDetector = class {
|
|
3701
|
+
constructor() {
|
|
3702
|
+
/** Map preserves O(1) idempotent replace by id; ordering comes from detectedAt. */
|
|
3703
|
+
this.modals = /* @__PURE__ */ new Map();
|
|
3704
|
+
}
|
|
3705
|
+
pushModal(modal) {
|
|
3706
|
+
const existing = this.modals.get(modal.id);
|
|
3707
|
+
const detectedAt = existing ? existing.detectedAt : Date.now();
|
|
3708
|
+
const next = {
|
|
3709
|
+
id: modal.id,
|
|
3710
|
+
title: modal.title,
|
|
3711
|
+
type: modal.type ?? "modal",
|
|
3712
|
+
blocking: modal.blocking ?? true,
|
|
3713
|
+
dismissible: modal.dismissible ?? true,
|
|
3714
|
+
detectedAt
|
|
3715
|
+
};
|
|
3716
|
+
this.modals.set(modal.id, next);
|
|
3717
|
+
}
|
|
3718
|
+
dismissModal(id) {
|
|
3719
|
+
this.modals.delete(id);
|
|
3720
|
+
}
|
|
3721
|
+
getSnapshotModalContext() {
|
|
3722
|
+
const active = this.getActive();
|
|
3723
|
+
const ctx = {
|
|
3724
|
+
modals: active,
|
|
3725
|
+
hasBlockingModal: active.some((m) => m.blocking),
|
|
3726
|
+
count: active.length
|
|
3727
|
+
};
|
|
3728
|
+
if (active.length > 0) {
|
|
3729
|
+
ctx.topModal = active[active.length - 1];
|
|
3730
|
+
}
|
|
3731
|
+
return ctx;
|
|
3732
|
+
}
|
|
3733
|
+
getActive() {
|
|
3734
|
+
return Array.from(this.modals.values()).sort((a, b) => a.detectedAt - b.detectedAt);
|
|
3735
|
+
}
|
|
3736
|
+
clear() {
|
|
3737
|
+
this.modals.clear();
|
|
3738
|
+
}
|
|
3739
|
+
};
|
|
3740
|
+
|
|
3741
|
+
// src/toast/toast-capture.ts
|
|
3742
|
+
var DEFAULT_MAX_RECENT = 50;
|
|
3743
|
+
var ToastCapture = class {
|
|
3744
|
+
constructor(config = {}) {
|
|
3745
|
+
this.active = /* @__PURE__ */ new Map();
|
|
3746
|
+
this.recent = [];
|
|
3747
|
+
this.totalCaptured = 0;
|
|
3748
|
+
this.maxRecent = config.maxRecent ?? DEFAULT_MAX_RECENT;
|
|
3749
|
+
}
|
|
3750
|
+
recordToast(toast) {
|
|
3751
|
+
if (this.active.has(toast.id)) {
|
|
3752
|
+
return;
|
|
3753
|
+
}
|
|
3754
|
+
const appearedAt = toast.appearedAt ?? Date.now();
|
|
3755
|
+
const entry = {
|
|
3756
|
+
id: toast.id,
|
|
3757
|
+
message: toast.message,
|
|
3758
|
+
level: toast.level ?? "info",
|
|
3759
|
+
appearedAt,
|
|
3760
|
+
visible: true,
|
|
3761
|
+
durationMs: 0
|
|
3762
|
+
};
|
|
3763
|
+
this.active.set(toast.id, entry);
|
|
3764
|
+
this.totalCaptured += 1;
|
|
3765
|
+
}
|
|
3766
|
+
dismissToast(id) {
|
|
3767
|
+
const entry = this.active.get(id);
|
|
3768
|
+
if (!entry) {
|
|
3769
|
+
return;
|
|
3770
|
+
}
|
|
3771
|
+
this.active.delete(id);
|
|
3772
|
+
const dismissedAt = Date.now();
|
|
3773
|
+
const dismissed = {
|
|
3774
|
+
...entry,
|
|
3775
|
+
dismissedAt,
|
|
3776
|
+
visible: false,
|
|
3777
|
+
durationMs: dismissedAt - entry.appearedAt
|
|
3778
|
+
};
|
|
3779
|
+
this.recent.push(dismissed);
|
|
3780
|
+
if (this.recent.length > this.maxRecent) {
|
|
3781
|
+
this.recent.shift();
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
getSnapshotToastContext() {
|
|
3785
|
+
const now = Date.now();
|
|
3786
|
+
const active = Array.from(this.active.values()).map((entry) => ({
|
|
3787
|
+
...entry,
|
|
3788
|
+
durationMs: now - entry.appearedAt
|
|
3789
|
+
}));
|
|
3790
|
+
return {
|
|
3791
|
+
active,
|
|
3792
|
+
recent: [...this.recent],
|
|
3793
|
+
totalCaptured: this.totalCaptured
|
|
3794
|
+
};
|
|
3795
|
+
}
|
|
3796
|
+
clear() {
|
|
3797
|
+
this.active.clear();
|
|
3798
|
+
this.recent = [];
|
|
3799
|
+
this.totalCaptured = 0;
|
|
3800
|
+
}
|
|
3801
|
+
};
|
|
3802
|
+
|
|
3803
|
+
// src/undo/undo-tracker.ts
|
|
3804
|
+
var DEFAULT_MAX_HISTORY = 50;
|
|
3805
|
+
function buildSummary(ctx) {
|
|
3806
|
+
if (!ctx.canUndo && !ctx.canRedo) {
|
|
3807
|
+
return "no undo available";
|
|
3808
|
+
}
|
|
3809
|
+
const parts = [];
|
|
3810
|
+
if (ctx.canUndo) {
|
|
3811
|
+
parts.push(`undo: '${ctx.undoDescription ?? "available"}'`);
|
|
3812
|
+
}
|
|
3813
|
+
if (ctx.canRedo) {
|
|
3814
|
+
parts.push(`redo: '${ctx.redoDescription ?? "available"}'`);
|
|
3815
|
+
}
|
|
3816
|
+
return parts.join(" / ");
|
|
3817
|
+
}
|
|
3818
|
+
var UndoTracker = class {
|
|
3819
|
+
constructor(config = {}) {
|
|
3820
|
+
this.actions = [];
|
|
3821
|
+
this.declaredState = null;
|
|
3822
|
+
this.maxHistory = config.maxHistory ?? DEFAULT_MAX_HISTORY;
|
|
3823
|
+
}
|
|
3824
|
+
recordAction(record) {
|
|
3825
|
+
this.actions.push(record);
|
|
3826
|
+
if (this.actions.length > this.maxHistory) {
|
|
3827
|
+
this.actions = this.actions.slice(-this.maxHistory);
|
|
3828
|
+
}
|
|
3829
|
+
}
|
|
3830
|
+
setDeclaredState(state) {
|
|
3831
|
+
this.declaredState = state;
|
|
3832
|
+
}
|
|
3833
|
+
getActionHistory() {
|
|
3834
|
+
return this.actions.slice();
|
|
3835
|
+
}
|
|
3836
|
+
getSnapshotUndoContext() {
|
|
3837
|
+
const declared = this.declaredState;
|
|
3838
|
+
if (declared) {
|
|
3839
|
+
const summary2 = buildSummary({
|
|
3840
|
+
canUndo: declared.canUndo,
|
|
3841
|
+
canRedo: declared.canRedo,
|
|
3842
|
+
undoDescription: declared.undoDescription,
|
|
3843
|
+
redoDescription: declared.redoDescription
|
|
3844
|
+
});
|
|
3845
|
+
return {
|
|
3846
|
+
canUndo: declared.canUndo,
|
|
3847
|
+
canRedo: declared.canRedo,
|
|
3848
|
+
undoDescription: declared.undoDescription,
|
|
3849
|
+
redoDescription: declared.redoDescription,
|
|
3850
|
+
undoDepth: declared.undoDepth,
|
|
3851
|
+
redoDepth: declared.redoDepth,
|
|
3852
|
+
summary: summary2
|
|
3853
|
+
};
|
|
3854
|
+
}
|
|
3855
|
+
const canUndo = this.actions.some((a) => a.reversible !== false);
|
|
3856
|
+
const canRedo = false;
|
|
3857
|
+
const lastReversible = [...this.actions].reverse().find((a) => a.reversible !== false);
|
|
3858
|
+
const undoDescription = lastReversible?.description;
|
|
3859
|
+
const summary = buildSummary({ canUndo, canRedo, undoDescription });
|
|
3860
|
+
return {
|
|
3861
|
+
canUndo,
|
|
3862
|
+
canRedo,
|
|
3863
|
+
undoDescription,
|
|
3864
|
+
summary
|
|
3865
|
+
};
|
|
3866
|
+
}
|
|
3867
|
+
executeUndo() {
|
|
3868
|
+
return { ok: false, reason: "Not implemented in native" };
|
|
3869
|
+
}
|
|
3870
|
+
executeRedo() {
|
|
3871
|
+
return { ok: false, reason: "Not implemented in native" };
|
|
3872
|
+
}
|
|
3873
|
+
clear() {
|
|
3874
|
+
this.actions = [];
|
|
3875
|
+
this.declaredState = null;
|
|
3876
|
+
}
|
|
3877
|
+
};
|
|
3567
3878
|
var UIBridgeNativeContext = createContext(null);
|
|
3568
3879
|
function UIBridgeNativeProvider({
|
|
3569
3880
|
children,
|
|
@@ -3580,6 +3891,9 @@ function UIBridgeNativeProvider({
|
|
|
3580
3891
|
}) {
|
|
3581
3892
|
const registryRef = useRef(null);
|
|
3582
3893
|
const executorRef = useRef(null);
|
|
3894
|
+
const modalDetectorRef = useRef(null);
|
|
3895
|
+
const toastCaptureRef = useRef(null);
|
|
3896
|
+
const undoTrackerRef = useRef(null);
|
|
3583
3897
|
const [serverRunning, setServerRunning] = useState(false);
|
|
3584
3898
|
if (!registryRef.current) {
|
|
3585
3899
|
registryRef.current = new NativeUIBridgeRegistry({
|
|
@@ -3593,6 +3907,12 @@ function UIBridgeNativeProvider({
|
|
|
3593
3907
|
executorRef.current = createNativeActionExecutor(registry);
|
|
3594
3908
|
}
|
|
3595
3909
|
const executor = executorRef.current;
|
|
3910
|
+
if (!modalDetectorRef.current) modalDetectorRef.current = new ModalDetector();
|
|
3911
|
+
if (!toastCaptureRef.current) toastCaptureRef.current = new ToastCapture();
|
|
3912
|
+
if (!undoTrackerRef.current) undoTrackerRef.current = new UndoTracker();
|
|
3913
|
+
const modalDetector = modalDetectorRef.current;
|
|
3914
|
+
const toastCapture = toastCaptureRef.current;
|
|
3915
|
+
const undoTracker = undoTrackerRef.current;
|
|
3596
3916
|
const serverRef = useRef(null);
|
|
3597
3917
|
const eventBridgeRef = useRef(null);
|
|
3598
3918
|
const announcerRef = useRef(null);
|
|
@@ -3781,6 +4101,22 @@ function UIBridgeNativeProvider({
|
|
|
3781
4101
|
lastRoute = current;
|
|
3782
4102
|
});
|
|
3783
4103
|
}, [routeProvider, registry]);
|
|
4104
|
+
useEffect(() => {
|
|
4105
|
+
registry.setEnrichers({ modalDetector, toastCapture, undoTracker });
|
|
4106
|
+
}, [registry, modalDetector, toastCapture, undoTracker]);
|
|
4107
|
+
useEffect(() => {
|
|
4108
|
+
const unsubscribe = executor.onActionExecuted((event) => {
|
|
4109
|
+
if (!event.success) return;
|
|
4110
|
+
undoTracker.recordAction({
|
|
4111
|
+
id: event.requestId ?? `action-${event.timestamp}`,
|
|
4112
|
+
type: event.action,
|
|
4113
|
+
targetId: event.elementId,
|
|
4114
|
+
timestamp: event.timestamp,
|
|
4115
|
+
reversible: true
|
|
4116
|
+
});
|
|
4117
|
+
});
|
|
4118
|
+
return unsubscribe;
|
|
4119
|
+
}, [executor, undoTracker]);
|
|
3784
4120
|
const on = useCallback(
|
|
3785
4121
|
(type, listener) => registry.on(type, listener),
|
|
3786
4122
|
[registry]
|
|
@@ -3795,6 +4131,9 @@ function UIBridgeNativeProvider({
|
|
|
3795
4131
|
config,
|
|
3796
4132
|
registry,
|
|
3797
4133
|
executor,
|
|
4134
|
+
modalDetector,
|
|
4135
|
+
toastCapture,
|
|
4136
|
+
undoTracker,
|
|
3798
4137
|
getElements,
|
|
3799
4138
|
getComponents,
|
|
3800
4139
|
createSnapshot,
|
|
@@ -3811,6 +4150,9 @@ function UIBridgeNativeProvider({
|
|
|
3811
4150
|
config,
|
|
3812
4151
|
registry,
|
|
3813
4152
|
executor,
|
|
4153
|
+
modalDetector,
|
|
4154
|
+
toastCapture,
|
|
4155
|
+
undoTracker,
|
|
3814
4156
|
getElements,
|
|
3815
4157
|
getComponents,
|
|
3816
4158
|
createSnapshot,
|
|
@@ -4291,6 +4633,37 @@ function useUIBridgeRequired() {
|
|
|
4291
4633
|
}
|
|
4292
4634
|
return result;
|
|
4293
4635
|
}
|
|
4636
|
+
function useUIBridgeModal(opts) {
|
|
4637
|
+
const { modalDetector } = useUIBridgeNative();
|
|
4638
|
+
const { id, title, type, blocking, dismissible } = opts;
|
|
4639
|
+
useEffect(() => {
|
|
4640
|
+
modalDetector.pushModal({ id, title, type, blocking, dismissible });
|
|
4641
|
+
return () => {
|
|
4642
|
+
modalDetector.dismissModal(id);
|
|
4643
|
+
};
|
|
4644
|
+
}, [modalDetector, id, title, type, blocking, dismissible]);
|
|
4645
|
+
}
|
|
4646
|
+
function useUIBridgeToast(opts) {
|
|
4647
|
+
const { toastCapture } = useUIBridgeNative();
|
|
4648
|
+
const { id, message, level } = opts;
|
|
4649
|
+
useEffect(() => {
|
|
4650
|
+
toastCapture.recordToast({ id, message, level });
|
|
4651
|
+
return () => {
|
|
4652
|
+
toastCapture.dismissToast(id);
|
|
4653
|
+
};
|
|
4654
|
+
}, [toastCapture, id, message, level]);
|
|
4655
|
+
}
|
|
4656
|
+
function useToastRecorder() {
|
|
4657
|
+
const { toastCapture } = useUIBridgeNative();
|
|
4658
|
+
const recordToast = useCallback(
|
|
4659
|
+
(toast) => {
|
|
4660
|
+
toastCapture.recordToast(toast);
|
|
4661
|
+
},
|
|
4662
|
+
[toastCapture]
|
|
4663
|
+
);
|
|
4664
|
+
const dismissToast = useCallback((id) => toastCapture.dismissToast(id), [toastCapture]);
|
|
4665
|
+
return { recordToast, dismissToast };
|
|
4666
|
+
}
|
|
4294
4667
|
|
|
4295
4668
|
// src/server/types.ts
|
|
4296
4669
|
var UI_BRIDGE_NATIVE_ROUTES = {
|
|
@@ -5192,6 +5565,6 @@ var styles = StyleSheet.create({
|
|
|
5192
5565
|
}
|
|
5193
5566
|
});
|
|
5194
5567
|
|
|
5195
|
-
export { CloudRelayClient, DefaultNativeActionExecutor, DeviceAnnouncer, NativeUIBridgeRegistry, NativeUIBridgeServer, UIBridgeInspector, UIBridgeNativeProvider, UI_BRIDGE_NATIVE_ROUTES, WebSocketConnection, WebSocketEventBridge, buildTreePath, buildUpgradeResponse, captureNativeResponsiveSnapshot, captureNativeStateVariations, computeAcceptKey, createDesignHandlers, createNativeActionExecutor, createNativeElementIdentifier, createNativeServer, createServerHandlers, extractHandlerNames, findAllByPattern, findElementByIdentifier, getGlobalRegistry, getNativeElementDesignData, mapNativeStyleToExtended, matchesIdentifier, parseTreePath, resetGlobalRegistry, setGlobalRegistry, useUIBridge, useUIBridgeNative, useUIBridgeNativeOptional, useUIBridgeNativeRequired, useUIBridgeRequired, useUIComponent, useUIComponentAction, useUIElement, useUIElementWithProps };
|
|
5568
|
+
export { CloudRelayClient, DefaultNativeActionExecutor, DeviceAnnouncer, ModalDetector, NativeUIBridgeRegistry, NativeUIBridgeServer, ToastCapture, UIBridgeInspector, UIBridgeNativeProvider, UI_BRIDGE_NATIVE_ROUTES, UndoTracker, WebSocketConnection, WebSocketEventBridge, buildTreePath, buildUpgradeResponse, captureNativeResponsiveSnapshot, captureNativeStateVariations, computeAcceptKey, createDesignHandlers, createNativeActionExecutor, createNativeElementIdentifier, createNativeServer, createServerHandlers, extractHandlerNames, findAllByPattern, findElementByIdentifier, getGlobalRegistry, getNativeElementDesignData, mapNativeStyleToExtended, matchesIdentifier, parseTreePath, resetGlobalRegistry, setGlobalRegistry, useToastRecorder, useUIBridge, useUIBridgeModal, useUIBridgeNative, useUIBridgeNativeOptional, useUIBridgeNativeRequired, useUIBridgeRequired, useUIBridgeToast, useUIComponent, useUIComponentAction, useUIElement, useUIElementWithProps };
|
|
5196
5569
|
//# sourceMappingURL=index.mjs.map
|
|
5197
5570
|
//# sourceMappingURL=index.mjs.map
|