@condorinst/mobile-bridge 0.17.0 → 0.18.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/CHANGELOG.md +36 -0
- package/README.md +9 -5
- package/dist/index.cjs +45 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -4
- package/dist/index.d.ts +61 -4
- package/dist/index.js +43 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -82,6 +82,49 @@ interface DevPanelOptions {
|
|
|
82
82
|
autoRespondDelayMs?: number;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Detecção do host nativo + adapter pattern.
|
|
87
|
+
*
|
|
88
|
+
* **v0.1.0:** lançava erro quando `window.flutter_inappwebview` ausente.
|
|
89
|
+
* **v0.2.0:** ativa mock adapter (`createMockAdapter`) — destrava dev em
|
|
90
|
+
* browser comum sem buildar APK.
|
|
91
|
+
* **v0.18.0:** canal `window.CondorNative` (JavaScript channel do
|
|
92
|
+
* `webview_flutter`) — detectado **antes** do `flutter_inappwebview`, que
|
|
93
|
+
* segue suportado por transição. O canal só aceita string: a mensagem vai
|
|
94
|
+
* serializada em JSON. E o gancho `setOutgoingStamp` permite ao shell
|
|
95
|
+
* carimbar toda mensagem de saída (ex.: nonce da Camada 3) sem monkey-patch
|
|
96
|
+
* do host.
|
|
97
|
+
*
|
|
98
|
+
* Adapter ativo é cached na primeira chamada de `getActiveAdapter()`.
|
|
99
|
+
* Tests devem chamar `__resetAdapterForTests()` no `beforeEach` para
|
|
100
|
+
* forçar re-detecção (ex.: após instalar/remover `window.CondorNative`).
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Nome do JavaScript channel registrado pelo nativo
|
|
105
|
+
* (`WebViewController.addJavaScriptChannel`). Não pode ser `CondorBridge`: o
|
|
106
|
+
* plugin publica o canal como `window.<nome>`, o que colidiria com o emitter
|
|
107
|
+
* `window.CondorBridge` instalado por este SDK.
|
|
108
|
+
*/
|
|
109
|
+
declare const NATIVE_CHANNEL_NAME = "CondorNative";
|
|
110
|
+
interface FlutterInAppWebView {
|
|
111
|
+
callHandler(name: string, ...args: unknown[]): Promise<unknown>;
|
|
112
|
+
}
|
|
113
|
+
interface NativeChannel {
|
|
114
|
+
postMessage(message: string): void;
|
|
115
|
+
}
|
|
116
|
+
declare global {
|
|
117
|
+
interface Window {
|
|
118
|
+
flutter_inappwebview?: FlutterInAppWebView;
|
|
119
|
+
CondorNative?: NativeChannel;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Transforma toda mensagem JS → Native imediatamente antes do envio.
|
|
124
|
+
* Recebe e devolve o envelope `{type, version, payload}`.
|
|
125
|
+
*/
|
|
126
|
+
type OutgoingStamp = (message: Record<string, unknown>) => Record<string, unknown>;
|
|
127
|
+
|
|
85
128
|
/**
|
|
86
129
|
* Catálogo das chaves do bridge JS↔Native.
|
|
87
130
|
*
|
|
@@ -132,7 +175,8 @@ type BridgeKey = (typeof BRIDGE_KEYS)[keyof typeof BRIDGE_KEYS];
|
|
|
132
175
|
*/
|
|
133
176
|
/**
|
|
134
177
|
* Mensagem JS → Native, enviada via
|
|
135
|
-
* `window.
|
|
178
|
+
* `window.CondorNative.postMessage(JSON.stringify(msg))` (v0.18.0+) ou, no
|
|
179
|
+
* host legado, `window.flutter_inappwebview.callHandler('CondorBridge', msg)`.
|
|
136
180
|
*/
|
|
137
181
|
interface BridgeIncomingMessage {
|
|
138
182
|
type: string;
|
|
@@ -562,8 +606,8 @@ interface MockState {
|
|
|
562
606
|
interface CondorBridge {
|
|
563
607
|
/**
|
|
564
608
|
* `true` quando o adapter ativo é mock (browser dev, sem
|
|
565
|
-
* `window.flutter_inappwebview`). `false` quando
|
|
566
|
-
* WebView Flutter.
|
|
609
|
+
* `window.CondorNative` nem `window.flutter_inappwebview`). `false` quando
|
|
610
|
+
* rodando dentro do WebView Flutter.
|
|
567
611
|
*/
|
|
568
612
|
readonly isMock: boolean;
|
|
569
613
|
/**
|
|
@@ -598,6 +642,16 @@ interface CondorBridge {
|
|
|
598
642
|
* `Bridge.send('openSettings')`.
|
|
599
643
|
*/
|
|
600
644
|
openSettings(): void;
|
|
645
|
+
/**
|
|
646
|
+
* Registra uma transformação aplicada a **toda** mensagem JS → Native
|
|
647
|
+
* (`handshake` inclusive) imediatamente antes do envio. `null` remove.
|
|
648
|
+
*
|
|
649
|
+
* Existe para o shell carimbar o nonce da Camada 3
|
|
650
|
+
* (`payload._shellNonce`) num ponto único — antes da 0.18.0 isso exigia
|
|
651
|
+
* monkey-patch de `flutter_inappwebview.callHandler`, que não existe no
|
|
652
|
+
* canal `CondorNative`. Código de cliente não deve usar.
|
|
653
|
+
*/
|
|
654
|
+
setOutgoingStamp(stamp: OutgoingStamp | null): void;
|
|
601
655
|
/**
|
|
602
656
|
* Dispara `window.CondorBridge.emit(key, payload)` programaticamente —
|
|
603
657
|
* útil para simular eventos nativos em testes e dev em browser.
|
|
@@ -770,6 +824,7 @@ declare const ClientToShellMessage: v.VariantSchema<"type", [v.ObjectSchema<{
|
|
|
770
824
|
readonly type: v.LiteralSchema<"sandbox-verify-response", undefined>;
|
|
771
825
|
readonly flutterBridgeReachable: v.BooleanSchema<undefined>;
|
|
772
826
|
readonly condorBridgeReachable: v.BooleanSchema<undefined>;
|
|
827
|
+
readonly nativeChannelReachable: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
773
828
|
}, undefined>], undefined>;
|
|
774
829
|
type ClientToShellMessage = v.InferOutput<typeof ClientToShellMessage>;
|
|
775
830
|
declare const ShellToClientMessage: v.VariantSchema<"type", [v.ObjectSchema<{
|
|
@@ -841,6 +896,8 @@ interface ConfirmationRequest {
|
|
|
841
896
|
interface SandboxVerifyResult {
|
|
842
897
|
flutterBridgeReachable: boolean;
|
|
843
898
|
condorBridgeReachable: boolean;
|
|
899
|
+
/** `window.CondorNative` visível no iframe (v0.18.0). */
|
|
900
|
+
nativeChannelReachable: boolean;
|
|
844
901
|
ok: boolean;
|
|
845
902
|
}
|
|
846
903
|
|
|
@@ -967,4 +1024,4 @@ declare class BridgeShell {
|
|
|
967
1024
|
private postToClient;
|
|
968
1025
|
}
|
|
969
1026
|
|
|
970
|
-
export { type AutoRespondResponse, BRIDGE_KEYS, Bridge, BridgeClient, type BridgeClientHandshakeAck, type BridgeIncomingMessage, type BridgeKey, type BridgeOutgoingEvent, BridgeShell, type BridgeShellOptions, ClientToShellMessage, type CondorBridge, type CondorBridgeClient, type ConfirmationRequest, type DeleteMemoryAckPayload, type DevPanelOptions, type DeviceConnectionPayload, type DeviceLightSensorsPayload, type DeviceNotificationPayload, type HandshakeAck, type HandshakeOptions, type KeyPayloads, type LanguagePayload, type LightSensorsActlumus1Data, type LightSensorsActlumus2Data, type LightSensorsRawChannels, type MockMessage, type MockState, type PayloadOf, type PingPongPayload, type RealTimeAckPayload, type RequestPermissionPayload, type SandboxVerifyResult, type SensorLogPayload, type SensorLogQueryPayload, type ShellPolicy, ShellToClientMessage, type SyncTimeAckPayload, type SystemStatusPayload, type UserDevicePayload };
|
|
1027
|
+
export { type AutoRespondResponse, BRIDGE_KEYS, Bridge, BridgeClient, type BridgeClientHandshakeAck, type BridgeIncomingMessage, type BridgeKey, type BridgeOutgoingEvent, BridgeShell, type BridgeShellOptions, ClientToShellMessage, type CondorBridge, type CondorBridgeClient, type ConfirmationRequest, type DeleteMemoryAckPayload, type DevPanelOptions, type DeviceConnectionPayload, type DeviceLightSensorsPayload, type DeviceNotificationPayload, type HandshakeAck, type HandshakeOptions, type KeyPayloads, type LanguagePayload, type LightSensorsActlumus1Data, type LightSensorsActlumus2Data, type LightSensorsRawChannels, type MockMessage, type MockState, NATIVE_CHANNEL_NAME, type OutgoingStamp, type PayloadOf, type PingPongPayload, type RealTimeAckPayload, type RequestPermissionPayload, type SandboxVerifyResult, type SensorLogPayload, type SensorLogQueryPayload, type ShellPolicy, ShellToClientMessage, type SyncTimeAckPayload, type SystemStatusPayload, type UserDevicePayload };
|
package/dist/index.js
CHANGED
|
@@ -430,8 +430,22 @@ function createMockAdapter() {
|
|
|
430
430
|
}
|
|
431
431
|
|
|
432
432
|
// src/internal/native.ts
|
|
433
|
+
var NATIVE_CHANNEL_NAME = "CondorNative";
|
|
434
|
+
var outgoingStamp = null;
|
|
435
|
+
function setOutgoingStamp(stamp) {
|
|
436
|
+
outgoingStamp = stamp;
|
|
437
|
+
}
|
|
433
438
|
var activeAdapter = null;
|
|
434
|
-
function
|
|
439
|
+
function createChannelAdapter(channel) {
|
|
440
|
+
return {
|
|
441
|
+
isMock: false,
|
|
442
|
+
// Canal único: o `handlerName` não viaja — o nativo roteia por `type`.
|
|
443
|
+
callHandler(_handlerName, payload) {
|
|
444
|
+
channel.postMessage(JSON.stringify(payload));
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
function createLegacyAdapter(host) {
|
|
435
449
|
return {
|
|
436
450
|
isMock: false,
|
|
437
451
|
callHandler(handlerName, payload) {
|
|
@@ -443,9 +457,13 @@ function detectAdapter() {
|
|
|
443
457
|
if (typeof window === "undefined") {
|
|
444
458
|
return createMockAdapter();
|
|
445
459
|
}
|
|
460
|
+
const channel = window.CondorNative;
|
|
461
|
+
if (channel && typeof channel.postMessage === "function") {
|
|
462
|
+
return createChannelAdapter(channel);
|
|
463
|
+
}
|
|
446
464
|
const host = window.flutter_inappwebview;
|
|
447
465
|
if (host && typeof host.callHandler === "function") {
|
|
448
|
-
return
|
|
466
|
+
return createLegacyAdapter(host);
|
|
449
467
|
}
|
|
450
468
|
return createMockAdapter();
|
|
451
469
|
}
|
|
@@ -456,7 +474,8 @@ function getActiveAdapter() {
|
|
|
456
474
|
return activeAdapter;
|
|
457
475
|
}
|
|
458
476
|
function callNative(handlerName, payload) {
|
|
459
|
-
|
|
477
|
+
const stamped = outgoingStamp ? outgoingStamp(payload) : payload;
|
|
478
|
+
getActiveAdapter().callHandler(handlerName, stamped);
|
|
460
479
|
}
|
|
461
480
|
|
|
462
481
|
// src/internal/subscribers.ts
|
|
@@ -572,6 +591,9 @@ var Bridge = {
|
|
|
572
591
|
openSettings() {
|
|
573
592
|
this.send("openSettings");
|
|
574
593
|
},
|
|
594
|
+
setOutgoingStamp(stamp) {
|
|
595
|
+
setOutgoingStamp(stamp);
|
|
596
|
+
},
|
|
575
597
|
mockEmit(key, payload) {
|
|
576
598
|
requireMockAdapter().triggerEmit(key, payload ?? {});
|
|
577
599
|
},
|
|
@@ -647,7 +669,8 @@ function onMessage(event) {
|
|
|
647
669
|
postToShell({
|
|
648
670
|
type: "sandbox-verify-response",
|
|
649
671
|
flutterBridgeReachable: typeof w.flutter_inappwebview !== "undefined",
|
|
650
|
-
condorBridgeReachable: typeof w.CondorBridge !== "undefined"
|
|
672
|
+
condorBridgeReachable: typeof w.CondorBridge !== "undefined",
|
|
673
|
+
nativeChannelReachable: typeof w.CondorNative !== "undefined"
|
|
651
674
|
});
|
|
652
675
|
break;
|
|
653
676
|
}
|
|
@@ -773,7 +796,9 @@ var JsErrorMessage = v.object({
|
|
|
773
796
|
var SandboxVerifyResponseMessage = v.object({
|
|
774
797
|
type: v.literal("sandbox-verify-response"),
|
|
775
798
|
flutterBridgeReachable: v.boolean(),
|
|
776
|
-
condorBridgeReachable: v.boolean()
|
|
799
|
+
condorBridgeReachable: v.boolean(),
|
|
800
|
+
// Opcional: clientes com SDK < 0.18.0 não enviam.
|
|
801
|
+
nativeChannelReachable: v.optional(v.boolean())
|
|
777
802
|
});
|
|
778
803
|
var ClientToShellMessage = v.variant("type", [
|
|
779
804
|
SubscribeMessage,
|
|
@@ -828,6 +853,7 @@ var OVERRIDE_PREFIX = `<script>
|
|
|
828
853
|
(function(){
|
|
829
854
|
try { delete window.flutter_inappwebview; } catch (_) {}
|
|
830
855
|
try { delete window.CondorBridge; } catch (_) {}
|
|
856
|
+
try { delete window.CondorNative; } catch (_) {}
|
|
831
857
|
try {
|
|
832
858
|
Object.defineProperty(window, 'flutter_inappwebview', {
|
|
833
859
|
get: function(){ return undefined; },
|
|
@@ -835,6 +861,13 @@ var OVERRIDE_PREFIX = `<script>
|
|
|
835
861
|
configurable: false,
|
|
836
862
|
});
|
|
837
863
|
} catch (_) {}
|
|
864
|
+
try {
|
|
865
|
+
Object.defineProperty(window, 'CondorNative', {
|
|
866
|
+
get: function(){ return undefined; },
|
|
867
|
+
set: function(_){ /* no-op: bloqueia o canal do webview_flutter no iframe */ },
|
|
868
|
+
configurable: false,
|
|
869
|
+
});
|
|
870
|
+
} catch (_) {}
|
|
838
871
|
try {
|
|
839
872
|
Object.defineProperty(window, 'CondorBridge', {
|
|
840
873
|
get: function(){ return undefined; },
|
|
@@ -915,10 +948,12 @@ var BridgeShell = class {
|
|
|
915
948
|
if (pending) {
|
|
916
949
|
clearTimeout(pending.timer);
|
|
917
950
|
this.pendingVerifies.delete(first);
|
|
918
|
-
const
|
|
951
|
+
const nativeChannelReachable = msg.nativeChannelReachable ?? false;
|
|
952
|
+
const ok = !msg.flutterBridgeReachable && !msg.condorBridgeReachable && !nativeChannelReachable;
|
|
919
953
|
pending.resolve({
|
|
920
954
|
flutterBridgeReachable: msg.flutterBridgeReachable,
|
|
921
955
|
condorBridgeReachable: msg.condorBridgeReachable,
|
|
956
|
+
nativeChannelReachable,
|
|
922
957
|
ok
|
|
923
958
|
});
|
|
924
959
|
}
|
|
@@ -1106,6 +1141,7 @@ export {
|
|
|
1106
1141
|
BRIDGE_KEYS,
|
|
1107
1142
|
Bridge,
|
|
1108
1143
|
BridgeClient,
|
|
1109
|
-
BridgeShell
|
|
1144
|
+
BridgeShell,
|
|
1145
|
+
NATIVE_CHANNEL_NAME
|
|
1110
1146
|
};
|
|
1111
1147
|
//# sourceMappingURL=index.js.map
|