webview.io 1.0.2 → 1.0.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/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/index.ts +126 -130
package/dist/index.js
CHANGED
|
@@ -679,7 +679,7 @@ var WIO = /** @class */ (function () {
|
|
|
679
679
|
* Sets up the EMBEDDED side of the bridge
|
|
680
680
|
*/
|
|
681
681
|
WIO.prototype.getInjectedJavaScript = function () {
|
|
682
|
-
return "\n (function() {\n try {\n console.log('[EMBEDDED] Initializing WIO bridge...');\n \n const RESERVED_EVENTS = ['ping', 'pong', '__heartbeat', '__heartbeat_response', '__embedded_ready', '__connection_ack', '__webview_ready'];\n \n window._wio = {\n type: 'EMBEDDED',\n connected: false,\n Events: {},\n messageQueue: [],\n connectionToken: null,\n setupComplete: false,\n\n listen: function(){\n console.log('[EMBEDDED] Setting up message listeners...');\n\n // Listen to messages from React Native\n window.addEventListener('message', function( event ){\n try {\n const message = typeof event.data === 'string' ? JSON.parse( event.data ) : event.data;\n window._wio.handleMessage( message );\n }\n catch( error ){ \n console.error('[EMBEDDED] Parse error:', error); \n }\n });\n \n // Android support\n if( typeof document !== 'undefined' ){\n document.addEventListener('message', function( event ){\n try {\n const message = typeof event.data === 'string' ? JSON.parse( event.data ) : event.data;\n window._wio.handleMessage( message );\n }\n catch( error ){ \n console.error('[EMBEDDED] Parse error:', error); \n }\n });\n }\n\n this.setupComplete = true;\n console.log('[EMBEDDED] Setup complete');\n },\n \n ackId: function(){\n const\n rmin = 100000,\n rmax = 999999,\n timestamp = Date.now(),\n random = Math.floor( Math.random() * ( rmax - rmin + 1 ) + rmin );\n\n return timestamp + '_' + random;\n },\n \n fire: function( _event, payload, cid ){\n if( !this.Events[_event] && !this.Events[_event + '--@once'] ){\n console.log('[EMBEDDED] No listener for:', _event);\n return;\n }\n \n const ackFn = cid\n ? ( error, ...args ) => {\n this.emit( _event + '--' + cid + '--@ack', { error: error || false, args } );\n }\n : undefined;\n \n let listeners = [];\n if( this.Events[_event + '--@once'] ){\n _event += '--@once';\n listeners = this.Events[_event];\n delete this.Events[_event];\n }\n else listeners = this.Events[_event] || [];\n \n listeners.forEach( fn => {\n try { \n payload !== undefined ? fn( payload, ackFn ) : fn( ackFn ); \n }\n catch( error ){ \n console.error('[EMBEDDED] Listener error:', error); \n }\n });\n },\n \n emit: function( _event, payload, fn ){\n if( typeof payload === 'function' ){\n fn = payload;\n payload = undefined;\n }\n \n if( !this.connected && !RESERVED_EVENTS.includes(_event) ){\n this.messageQueue.push({ _event, payload, fn, timestamp: Date.now() });\n console.log('[EMBEDDED] Queued message:', _event);\n return;\n }\n \n try {\n let cid;\n if( typeof fn === 'function' ){\n cid = this.ackId();\n this.once( _event + '--' + cid + '--@ack', ({ error, args }) => fn( error, ...args ) );\n }\n \n const messageData = {\n _event,\n payload,\n cid,\n timestamp: Date.now(),\n token: RESERVED_EVENTS.includes(_event) ? this.connectionToken : undefined\n };\n \n if( typeof window.ReactNativeWebView !== 'undefined' ){\n window.ReactNativeWebView.postMessage( JSON.stringify( messageData ) );\n }\n else {\n console.error('[EMBEDDED] ReactNativeWebView not available');\n }\n }\n catch( error ){\n console.error('[EMBEDDED] Emit error:', error);\n typeof fn === 'function' && fn( String(error) );\n }\n },\n \n on: function( _event, fn ){\n if( !this.Events[_event] ) this.Events[_event] = [];\n this.Events[_event].push( fn );\n },\n \n once: function( _event, fn ){\n _event += '--@once';\n if( !this.Events[_event] ) this.Events[_event] = [];\n this.Events[_event].push( fn );\n },\n \n off: function( _event, fn ){\n if( fn && this.Events[_event] ){\n const index = this.Events[_event].indexOf( fn );\n if( index > -1 ){\n this.Events[_event].splice( index, 1 );\n if( this.Events[_event].length === 0 ) delete this.Events[_event];\n }\n }\n else delete this.Events[_event];\n },\n \n processMessageQueue: function(){\n if( !this.connected || this.messageQueue.length === 0 ) return;\n \n console.log('[EMBEDDED] Processing', this.messageQueue.length, 'queued messages');\n const queue = [...this.messageQueue];\n this.messageQueue = [];\n \n queue.forEach( msg => {\n try { \n this.emit( msg._event, msg.payload, msg.fn ); \n }\n catch( error ){ \n console.error('[EMBEDDED] Queue process error:', error); \n }\n });\n },\n \n handleMessage: function( data ){\n if( !data || !data._event ) return;\n \n const { _event, payload, cid, token } = data;\n \n console.log('[EMBEDDED] Received:', _event);\n \n // Handle heartbeat response\n if( _event === '__heartbeat_response' ){\n return;\n }\n \n // Handle heartbeat request\n if( _event === '__heartbeat' ){\n this.emit('__heartbeat_response', { timestamp: Date.now() });\n return;\n }\n \n // Handle webview ready signal\n if( _event === '__webview_ready' ){\n console.log('[EMBEDDED] WebView ready signal received');\n return;\n }\n \n // Handle ping from WEBVIEW\n if( _event === 'ping' ){\n console.log('[EMBEDDED] Received ping, sending pong');\n this.connectionToken = token;\n this.emit('pong', { token: this.connectionToken });\n return;\n }\n \n // Handle connection acknowledgment\n if( _event === '__connection_ack' ){\n if( token && token !== this.connectionToken ){\n console.error('[EMBEDDED] Invalid connection token in ack');\n return;\n }\n \n console.log('[EMBEDDED] Connection established (received ack)');\n this.connected = true;\n this.processMessageQueue();\n this.fire('connect');\n return;\n }\n \n // Fire event listeners\n this.fire( _event, payload, cid );\n },\n \n announceReady: function(){\n let attempts = 0;\n const maxAttempts = 5;\n const interval = 2000;\n \n console.log('[EMBEDDED] Starting ready announcements');\n \n const announce = () => {\n if( this.connected ){\n console.log('[EMBEDDED] Connected, stopping announcements');\n return;\n }\n \n attempts++;\n if( attempts > maxAttempts ){\n console.log('[EMBEDDED] Max announcement attempts reached');\n return;\n }\n \n console.log('[EMBEDDED] Announcing ready (attempt', attempts + '/' + maxAttempts + ')');\n this.emit('__embedded_ready');\n \n setTimeout( announce, interval );\n };\n \n announce();\n }\n };\n\n // Initialize\n window._wio.listen();\n \n // Start announcing readiness after a short delay\n setTimeout(() => {\n window._wio.announceReady();\n }, 100);\n \n console.log('[EMBEDDED] WIO bridge initialized successfully');\n }\n catch( error ){\n console.error('[EMBEDDED] Setup failed:', error);\n \n // Create minimal fallback\n window._wio = {\n error: error.toString(),\n emit: function(){ console.error('[EMBEDDED] WIO failed to initialize'); },\n on: function(){},\n once: function(){},\n off: function(){}\n };\n }\n\n true;\n })();\n ";
|
|
682
|
+
return "\n (function() {\n try {\n console.log('[EMBEDDED] Initializing WIO bridge...')\n \n const RESERVED_EVENTS = [\n 'ping',\n 'pong',\n '__heartbeat',\n '__heartbeat_response',\n '__embedded_ready',\n '__connection_ack',\n '__webview_ready'\n ]\n \n // Use closure variable to avoid 'this' binding issues\n const wio = {\n type: 'EMBEDDED',\n connected: false,\n Events: {},\n messageQueue: [],\n connectionToken: null,\n setupComplete: false,\n\n listen: function(){\n console.log('[EMBEDDED] Setting up message listeners...')\n\n // Listen to messages from React Native\n window.addEventListener('message', function( event ){\n try {\n const message = typeof event.data === 'string' ? JSON.parse( event.data ) : event.data\n wio.handleMessage( message ) // Use wio instead of this\n }\n catch( error ){ console.error('[EMBEDDED] Parse error:', error ) }\n })\n \n // Android support\n if( typeof document !== 'undefined' ){\n document.addEventListener('message', function( event ){\n try {\n const message = typeof event.data === 'string' ? JSON.parse( event.data ) : event.data\n wio.handleMessage( message ) // Use wio instead of this\n }\n catch( error ){ console.error('[EMBEDDED] Parse error:', error ) }\n })\n }\n\n wio.setupComplete = true // Use wio instead of this\n console.log('[EMBEDDED] Setup complete')\n },\n \n ackId: function(){\n const\n rmin = 100000,\n rmax = 999999,\n timestamp = Date.now(),\n random = Math.floor( Math.random() * ( rmax - rmin + 1 ) + rmin )\n\n return timestamp + '_' + random\n },\n \n fire: function( _event, payload, cid ){\n if( !wio.Events[_event] && !wio.Events[_event + '--@once'] ){\n console.log('[EMBEDDED] No listener for:', _event)\n return\n }\n \n const ackFn = cid\n ? ( error, ...args ) => wio.emit( _event + '--' + cid + '--@ack', { error: error || false, args } )\n : undefined\n \n let listeners = []\n if( wio.Events[_event + '--@once'] ){\n _event += '--@once'\n listeners = wio.Events[_event]\n\n delete wio.Events[_event]\n }\n else listeners = wio.Events[_event] || []\n \n listeners.forEach( fn => {\n try { payload !== undefined ? fn( payload, ackFn ) : fn( ackFn ) }\n catch( error ){ console.error('[EMBEDDED] Listener error:', error ) }\n })\n },\n \n emit: function( _event, payload, fn ){\n if( typeof payload === 'function' ){\n fn = payload\n payload = undefined\n }\n \n if( !wio.connected && !RESERVED_EVENTS.includes(_event) ){\n wio.messageQueue.push({ _event, payload, fn, timestamp: Date.now() })\n console.log('[EMBEDDED] Queued message:', _event)\n return\n }\n \n try {\n let cid\n if( typeof fn === 'function' ){\n cid = wio.ackId()\n wio.once( _event + '--' + cid + '--@ack', ({ error, args }) => fn( error, ...args ) )\n }\n \n const messageData = {\n _event,\n payload,\n cid,\n timestamp: Date.now(),\n token: RESERVED_EVENTS.includes(_event) ? wio.connectionToken : undefined\n }\n \n if( typeof window.ReactNativeWebView !== 'undefined' )\n window.ReactNativeWebView.postMessage( JSON.stringify( messageData ) )\n else console.error('[EMBEDDED] ReactNativeWebView not available')\n }\n catch( error ){\n console.error('[EMBEDDED] Emit error:', error )\n typeof fn === 'function' && fn( String(error) )\n }\n },\n \n on: function( _event, fn ){\n if( !wio.Events[_event] ) wio.Events[_event] = []\n wio.Events[_event].push( fn )\n },\n \n once: function( _event, fn ){\n _event += '--@once'\n if( !wio.Events[_event] ) wio.Events[_event] = []\n\n wio.Events[_event].push( fn )\n },\n \n off: function( _event, fn ){\n if( fn && wio.Events[_event] ){\n const index = wio.Events[_event].indexOf( fn )\n if( index > -1 ){\n wio.Events[_event].splice( index, 1 )\n if( wio.Events[_event].length === 0 ) delete wio.Events[_event]\n }\n }\n else delete wio.Events[_event]\n },\n \n processMessageQueue: function(){\n if( !wio.connected || wio.messageQueue.length === 0 ) return\n \n console.log('[EMBEDDED] Processing', wio.messageQueue.length, 'queued messages')\n const queue = [ ...wio.messageQueue ]\n wio.messageQueue = []\n \n queue.forEach( msg => {\n try { wio.emit( msg._event, msg.payload, msg.fn ) }\n catch( error ){ console.error('[EMBEDDED] Queue process error:', error ) }\n })\n },\n \n handleMessage: function( data ){\n if( !data || !data._event ) return\n \n const { _event, payload, cid, token } = data\n \n console.log('[EMBEDDED] Received:', _event )\n \n // Handle heartbeat response\n if( _event === '__heartbeat_response' )\n return\n \n // Handle heartbeat request\n if( _event === '__heartbeat' ){\n wio.emit('__heartbeat_response', { timestamp: Date.now() })\n return\n }\n \n // Handle webview ready signal\n if( _event === '__webview_ready' ){\n console.log('[EMBEDDED] WebView ready signal received')\n return\n }\n \n // Handle ping from WEBVIEW\n if( _event === 'ping' ){\n console.log('[EMBEDDED] Received ping, sending pong')\n wio.connectionToken = token\n\n wio.emit('pong', { token: wio.connectionToken })\n return\n }\n \n // Handle connection acknowledgment\n if( _event === '__connection_ack' ){\n if( token && token !== wio.connectionToken ){\n console.error('[EMBEDDED] Invalid connection token in ack')\n return\n }\n \n console.log('[EMBEDDED] Connection established (received ack)')\n\n wio.connected = true\n wio.processMessageQueue()\n wio.fire('connect')\n\n return\n }\n \n // Fire event listeners\n wio.fire( _event, payload, cid )\n },\n \n announceReady: function(){\n let attempts = 0\n const maxAttempts = 5\n const interval = 2000\n \n console.log('[EMBEDDED] Starting ready announcements')\n \n const announce = () => {\n if( wio.connected ){\n console.log('[EMBEDDED] Connected, stopping announcements')\n return\n }\n \n attempts++\n if( attempts > maxAttempts ){\n console.log('[EMBEDDED] Max announcement attempts reached')\n return\n }\n \n console.log('[EMBEDDED] Announcing ready (attempt', attempts + '/' + maxAttempts + ')')\n wio.emit('__embedded_ready')\n \n setTimeout( announce, interval )\n }\n \n announce()\n }\n }\n\n // Expose to global scope\n window._wio = wio\n\n // Initialize\n wio.listen()\n // Start announcing readiness after a short delay\n setTimeout(() => wio.announceReady(), 100)\n \n console.log('[EMBEDDED] WIO bridge initialized successfully')\n }\n catch( error ){\n console.error('[EMBEDDED] Setup failed:', error )\n \n // Create minimal fallback\n window._wio = {\n error: error.toString(),\n emit: function(){ console.error('[EMBEDDED] WIO failed to initialize') },\n on: function(){},\n once: function(){},\n off: function(){}\n }\n }\n\n true\n })()\n ";
|
|
683
683
|
};
|
|
684
684
|
return WIO;
|
|
685
685
|
}());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webview.io",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Easy and friendly API to connect and interact between React Native and WebView with enhanced security, reliability, and modern async/await support.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
package/src/index.ts
CHANGED
|
@@ -827,11 +827,20 @@ export default class WIO {
|
|
|
827
827
|
return `
|
|
828
828
|
(function() {
|
|
829
829
|
try {
|
|
830
|
-
console.log('[EMBEDDED] Initializing WIO bridge...')
|
|
830
|
+
console.log('[EMBEDDED] Initializing WIO bridge...')
|
|
831
831
|
|
|
832
|
-
const RESERVED_EVENTS = [
|
|
832
|
+
const RESERVED_EVENTS = [
|
|
833
|
+
'ping',
|
|
834
|
+
'pong',
|
|
835
|
+
'__heartbeat',
|
|
836
|
+
'__heartbeat_response',
|
|
837
|
+
'__embedded_ready',
|
|
838
|
+
'__connection_ack',
|
|
839
|
+
'__webview_ready'
|
|
840
|
+
]
|
|
833
841
|
|
|
834
|
-
|
|
842
|
+
// Use closure variable to avoid 'this' binding issues
|
|
843
|
+
const wio = {
|
|
835
844
|
type: 'EMBEDDED',
|
|
836
845
|
connected: false,
|
|
837
846
|
Events: {},
|
|
@@ -840,34 +849,30 @@ export default class WIO {
|
|
|
840
849
|
setupComplete: false,
|
|
841
850
|
|
|
842
851
|
listen: function(){
|
|
843
|
-
console.log('[EMBEDDED] Setting up message listeners...')
|
|
852
|
+
console.log('[EMBEDDED] Setting up message listeners...')
|
|
844
853
|
|
|
845
854
|
// Listen to messages from React Native
|
|
846
855
|
window.addEventListener('message', function( event ){
|
|
847
856
|
try {
|
|
848
|
-
const message = typeof event.data === 'string' ? JSON.parse( event.data ) : event.data
|
|
849
|
-
|
|
850
|
-
}
|
|
851
|
-
catch( error ){
|
|
852
|
-
console.error('[EMBEDDED] Parse error:', error);
|
|
857
|
+
const message = typeof event.data === 'string' ? JSON.parse( event.data ) : event.data
|
|
858
|
+
wio.handleMessage( message ) // Use wio instead of this
|
|
853
859
|
}
|
|
854
|
-
|
|
860
|
+
catch( error ){ console.error('[EMBEDDED] Parse error:', error ) }
|
|
861
|
+
})
|
|
855
862
|
|
|
856
863
|
// Android support
|
|
857
864
|
if( typeof document !== 'undefined' ){
|
|
858
865
|
document.addEventListener('message', function( event ){
|
|
859
866
|
try {
|
|
860
|
-
const message = typeof event.data === 'string' ? JSON.parse( event.data ) : event.data
|
|
861
|
-
|
|
862
|
-
}
|
|
863
|
-
catch( error ){
|
|
864
|
-
console.error('[EMBEDDED] Parse error:', error);
|
|
867
|
+
const message = typeof event.data === 'string' ? JSON.parse( event.data ) : event.data
|
|
868
|
+
wio.handleMessage( message ) // Use wio instead of this
|
|
865
869
|
}
|
|
866
|
-
|
|
870
|
+
catch( error ){ console.error('[EMBEDDED] Parse error:', error ) }
|
|
871
|
+
})
|
|
867
872
|
}
|
|
868
873
|
|
|
869
|
-
|
|
870
|
-
console.log('[EMBEDDED] Setup complete')
|
|
874
|
+
wio.setupComplete = true // Use wio instead of this
|
|
875
|
+
console.log('[EMBEDDED] Setup complete')
|
|
871
876
|
},
|
|
872
877
|
|
|
873
878
|
ackId: function(){
|
|
@@ -875,58 +880,53 @@ export default class WIO {
|
|
|
875
880
|
rmin = 100000,
|
|
876
881
|
rmax = 999999,
|
|
877
882
|
timestamp = Date.now(),
|
|
878
|
-
random = Math.floor( Math.random() * ( rmax - rmin + 1 ) + rmin )
|
|
883
|
+
random = Math.floor( Math.random() * ( rmax - rmin + 1 ) + rmin )
|
|
879
884
|
|
|
880
|
-
return timestamp + '_' + random
|
|
885
|
+
return timestamp + '_' + random
|
|
881
886
|
},
|
|
882
887
|
|
|
883
888
|
fire: function( _event, payload, cid ){
|
|
884
|
-
if( !
|
|
885
|
-
console.log('[EMBEDDED] No listener for:', _event)
|
|
886
|
-
return
|
|
889
|
+
if( !wio.Events[_event] && !wio.Events[_event + '--@once'] ){
|
|
890
|
+
console.log('[EMBEDDED] No listener for:', _event)
|
|
891
|
+
return
|
|
887
892
|
}
|
|
888
893
|
|
|
889
894
|
const ackFn = cid
|
|
890
|
-
? ( error, ...args ) => {
|
|
891
|
-
|
|
892
|
-
}
|
|
893
|
-
: undefined;
|
|
895
|
+
? ( error, ...args ) => wio.emit( _event + '--' + cid + '--@ack', { error: error || false, args } )
|
|
896
|
+
: undefined
|
|
894
897
|
|
|
895
|
-
let listeners = []
|
|
896
|
-
if(
|
|
897
|
-
_event += '--@once'
|
|
898
|
-
listeners =
|
|
899
|
-
|
|
898
|
+
let listeners = []
|
|
899
|
+
if( wio.Events[_event + '--@once'] ){
|
|
900
|
+
_event += '--@once'
|
|
901
|
+
listeners = wio.Events[_event]
|
|
902
|
+
|
|
903
|
+
delete wio.Events[_event]
|
|
900
904
|
}
|
|
901
|
-
else listeners =
|
|
905
|
+
else listeners = wio.Events[_event] || []
|
|
902
906
|
|
|
903
907
|
listeners.forEach( fn => {
|
|
904
|
-
try {
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
catch( error ){
|
|
908
|
-
console.error('[EMBEDDED] Listener error:', error);
|
|
909
|
-
}
|
|
910
|
-
});
|
|
908
|
+
try { payload !== undefined ? fn( payload, ackFn ) : fn( ackFn ) }
|
|
909
|
+
catch( error ){ console.error('[EMBEDDED] Listener error:', error ) }
|
|
910
|
+
})
|
|
911
911
|
},
|
|
912
912
|
|
|
913
913
|
emit: function( _event, payload, fn ){
|
|
914
914
|
if( typeof payload === 'function' ){
|
|
915
|
-
fn = payload
|
|
916
|
-
payload = undefined
|
|
915
|
+
fn = payload
|
|
916
|
+
payload = undefined
|
|
917
917
|
}
|
|
918
918
|
|
|
919
|
-
if( !
|
|
920
|
-
|
|
921
|
-
console.log('[EMBEDDED] Queued message:', _event)
|
|
922
|
-
return
|
|
919
|
+
if( !wio.connected && !RESERVED_EVENTS.includes(_event) ){
|
|
920
|
+
wio.messageQueue.push({ _event, payload, fn, timestamp: Date.now() })
|
|
921
|
+
console.log('[EMBEDDED] Queued message:', _event)
|
|
922
|
+
return
|
|
923
923
|
}
|
|
924
924
|
|
|
925
925
|
try {
|
|
926
|
-
let cid
|
|
926
|
+
let cid
|
|
927
927
|
if( typeof fn === 'function' ){
|
|
928
|
-
cid =
|
|
929
|
-
|
|
928
|
+
cid = wio.ackId()
|
|
929
|
+
wio.once( _event + '--' + cid + '--@ack', ({ error, args }) => fn( error, ...args ) )
|
|
930
930
|
}
|
|
931
931
|
|
|
932
932
|
const messageData = {
|
|
@@ -934,165 +934,161 @@ export default class WIO {
|
|
|
934
934
|
payload,
|
|
935
935
|
cid,
|
|
936
936
|
timestamp: Date.now(),
|
|
937
|
-
token: RESERVED_EVENTS.includes(_event) ?
|
|
938
|
-
};
|
|
939
|
-
|
|
940
|
-
if( typeof window.ReactNativeWebView !== 'undefined' ){
|
|
941
|
-
window.ReactNativeWebView.postMessage( JSON.stringify( messageData ) );
|
|
942
|
-
}
|
|
943
|
-
else {
|
|
944
|
-
console.error('[EMBEDDED] ReactNativeWebView not available');
|
|
937
|
+
token: RESERVED_EVENTS.includes(_event) ? wio.connectionToken : undefined
|
|
945
938
|
}
|
|
939
|
+
|
|
940
|
+
if( typeof window.ReactNativeWebView !== 'undefined' )
|
|
941
|
+
window.ReactNativeWebView.postMessage( JSON.stringify( messageData ) )
|
|
942
|
+
else console.error('[EMBEDDED] ReactNativeWebView not available')
|
|
946
943
|
}
|
|
947
944
|
catch( error ){
|
|
948
|
-
console.error('[EMBEDDED] Emit error:', error)
|
|
949
|
-
typeof fn === 'function' && fn( String(error) )
|
|
945
|
+
console.error('[EMBEDDED] Emit error:', error )
|
|
946
|
+
typeof fn === 'function' && fn( String(error) )
|
|
950
947
|
}
|
|
951
948
|
},
|
|
952
949
|
|
|
953
950
|
on: function( _event, fn ){
|
|
954
|
-
if( !
|
|
955
|
-
|
|
951
|
+
if( !wio.Events[_event] ) wio.Events[_event] = []
|
|
952
|
+
wio.Events[_event].push( fn )
|
|
956
953
|
},
|
|
957
954
|
|
|
958
955
|
once: function( _event, fn ){
|
|
959
|
-
_event += '--@once'
|
|
960
|
-
if( !
|
|
961
|
-
|
|
956
|
+
_event += '--@once'
|
|
957
|
+
if( !wio.Events[_event] ) wio.Events[_event] = []
|
|
958
|
+
|
|
959
|
+
wio.Events[_event].push( fn )
|
|
962
960
|
},
|
|
963
961
|
|
|
964
962
|
off: function( _event, fn ){
|
|
965
|
-
if( fn &&
|
|
966
|
-
const index =
|
|
963
|
+
if( fn && wio.Events[_event] ){
|
|
964
|
+
const index = wio.Events[_event].indexOf( fn )
|
|
967
965
|
if( index > -1 ){
|
|
968
|
-
|
|
969
|
-
if(
|
|
966
|
+
wio.Events[_event].splice( index, 1 )
|
|
967
|
+
if( wio.Events[_event].length === 0 ) delete wio.Events[_event]
|
|
970
968
|
}
|
|
971
969
|
}
|
|
972
|
-
else delete
|
|
970
|
+
else delete wio.Events[_event]
|
|
973
971
|
},
|
|
974
972
|
|
|
975
973
|
processMessageQueue: function(){
|
|
976
|
-
if( !
|
|
974
|
+
if( !wio.connected || wio.messageQueue.length === 0 ) return
|
|
977
975
|
|
|
978
|
-
console.log('[EMBEDDED] Processing',
|
|
979
|
-
const queue = [...
|
|
980
|
-
|
|
976
|
+
console.log('[EMBEDDED] Processing', wio.messageQueue.length, 'queued messages')
|
|
977
|
+
const queue = [ ...wio.messageQueue ]
|
|
978
|
+
wio.messageQueue = []
|
|
981
979
|
|
|
982
980
|
queue.forEach( msg => {
|
|
983
|
-
try {
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
catch( error ){
|
|
987
|
-
console.error('[EMBEDDED] Queue process error:', error);
|
|
988
|
-
}
|
|
989
|
-
});
|
|
981
|
+
try { wio.emit( msg._event, msg.payload, msg.fn ) }
|
|
982
|
+
catch( error ){ console.error('[EMBEDDED] Queue process error:', error ) }
|
|
983
|
+
})
|
|
990
984
|
},
|
|
991
985
|
|
|
992
986
|
handleMessage: function( data ){
|
|
993
|
-
if( !data || !data._event ) return
|
|
987
|
+
if( !data || !data._event ) return
|
|
994
988
|
|
|
995
|
-
const { _event, payload, cid, token } = data
|
|
989
|
+
const { _event, payload, cid, token } = data
|
|
996
990
|
|
|
997
|
-
console.log('[EMBEDDED] Received:', _event)
|
|
991
|
+
console.log('[EMBEDDED] Received:', _event )
|
|
998
992
|
|
|
999
993
|
// Handle heartbeat response
|
|
1000
|
-
if( _event === '__heartbeat_response' )
|
|
1001
|
-
return
|
|
1002
|
-
}
|
|
994
|
+
if( _event === '__heartbeat_response' )
|
|
995
|
+
return
|
|
1003
996
|
|
|
1004
997
|
// Handle heartbeat request
|
|
1005
998
|
if( _event === '__heartbeat' ){
|
|
1006
|
-
|
|
1007
|
-
return
|
|
999
|
+
wio.emit('__heartbeat_response', { timestamp: Date.now() })
|
|
1000
|
+
return
|
|
1008
1001
|
}
|
|
1009
1002
|
|
|
1010
1003
|
// Handle webview ready signal
|
|
1011
1004
|
if( _event === '__webview_ready' ){
|
|
1012
|
-
console.log('[EMBEDDED] WebView ready signal received')
|
|
1013
|
-
return
|
|
1005
|
+
console.log('[EMBEDDED] WebView ready signal received')
|
|
1006
|
+
return
|
|
1014
1007
|
}
|
|
1015
1008
|
|
|
1016
1009
|
// Handle ping from WEBVIEW
|
|
1017
1010
|
if( _event === 'ping' ){
|
|
1018
|
-
console.log('[EMBEDDED] Received ping, sending pong')
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1011
|
+
console.log('[EMBEDDED] Received ping, sending pong')
|
|
1012
|
+
wio.connectionToken = token
|
|
1013
|
+
|
|
1014
|
+
wio.emit('pong', { token: wio.connectionToken })
|
|
1015
|
+
return
|
|
1022
1016
|
}
|
|
1023
1017
|
|
|
1024
1018
|
// Handle connection acknowledgment
|
|
1025
1019
|
if( _event === '__connection_ack' ){
|
|
1026
|
-
if( token && token !==
|
|
1027
|
-
console.error('[EMBEDDED] Invalid connection token in ack')
|
|
1028
|
-
return
|
|
1020
|
+
if( token && token !== wio.connectionToken ){
|
|
1021
|
+
console.error('[EMBEDDED] Invalid connection token in ack')
|
|
1022
|
+
return
|
|
1029
1023
|
}
|
|
1030
1024
|
|
|
1031
|
-
console.log('[EMBEDDED] Connection established (received ack)')
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1025
|
+
console.log('[EMBEDDED] Connection established (received ack)')
|
|
1026
|
+
|
|
1027
|
+
wio.connected = true
|
|
1028
|
+
wio.processMessageQueue()
|
|
1029
|
+
wio.fire('connect')
|
|
1030
|
+
|
|
1031
|
+
return
|
|
1036
1032
|
}
|
|
1037
1033
|
|
|
1038
1034
|
// Fire event listeners
|
|
1039
|
-
|
|
1035
|
+
wio.fire( _event, payload, cid )
|
|
1040
1036
|
},
|
|
1041
1037
|
|
|
1042
1038
|
announceReady: function(){
|
|
1043
|
-
let attempts = 0
|
|
1044
|
-
const maxAttempts = 5
|
|
1045
|
-
const interval = 2000
|
|
1039
|
+
let attempts = 0
|
|
1040
|
+
const maxAttempts = 5
|
|
1041
|
+
const interval = 2000
|
|
1046
1042
|
|
|
1047
|
-
console.log('[EMBEDDED] Starting ready announcements')
|
|
1043
|
+
console.log('[EMBEDDED] Starting ready announcements')
|
|
1048
1044
|
|
|
1049
1045
|
const announce = () => {
|
|
1050
|
-
if(
|
|
1051
|
-
console.log('[EMBEDDED] Connected, stopping announcements')
|
|
1052
|
-
return
|
|
1046
|
+
if( wio.connected ){
|
|
1047
|
+
console.log('[EMBEDDED] Connected, stopping announcements')
|
|
1048
|
+
return
|
|
1053
1049
|
}
|
|
1054
1050
|
|
|
1055
|
-
attempts
|
|
1051
|
+
attempts++
|
|
1056
1052
|
if( attempts > maxAttempts ){
|
|
1057
|
-
console.log('[EMBEDDED] Max announcement attempts reached')
|
|
1058
|
-
return
|
|
1053
|
+
console.log('[EMBEDDED] Max announcement attempts reached')
|
|
1054
|
+
return
|
|
1059
1055
|
}
|
|
1060
1056
|
|
|
1061
|
-
console.log('[EMBEDDED] Announcing ready (attempt', attempts + '/' + maxAttempts + ')')
|
|
1062
|
-
|
|
1057
|
+
console.log('[EMBEDDED] Announcing ready (attempt', attempts + '/' + maxAttempts + ')')
|
|
1058
|
+
wio.emit('__embedded_ready')
|
|
1063
1059
|
|
|
1064
|
-
setTimeout( announce, interval )
|
|
1065
|
-
}
|
|
1060
|
+
setTimeout( announce, interval )
|
|
1061
|
+
}
|
|
1066
1062
|
|
|
1067
|
-
announce()
|
|
1063
|
+
announce()
|
|
1068
1064
|
}
|
|
1069
|
-
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// Expose to global scope
|
|
1068
|
+
window._wio = wio
|
|
1070
1069
|
|
|
1071
1070
|
// Initialize
|
|
1072
|
-
|
|
1073
|
-
|
|
1071
|
+
wio.listen()
|
|
1074
1072
|
// Start announcing readiness after a short delay
|
|
1075
|
-
setTimeout(() =>
|
|
1076
|
-
window._wio.announceReady();
|
|
1077
|
-
}, 100);
|
|
1073
|
+
setTimeout(() => wio.announceReady(), 100)
|
|
1078
1074
|
|
|
1079
|
-
console.log('[EMBEDDED] WIO bridge initialized successfully')
|
|
1075
|
+
console.log('[EMBEDDED] WIO bridge initialized successfully')
|
|
1080
1076
|
}
|
|
1081
1077
|
catch( error ){
|
|
1082
|
-
console.error('[EMBEDDED] Setup failed:', error)
|
|
1078
|
+
console.error('[EMBEDDED] Setup failed:', error )
|
|
1083
1079
|
|
|
1084
1080
|
// Create minimal fallback
|
|
1085
1081
|
window._wio = {
|
|
1086
1082
|
error: error.toString(),
|
|
1087
|
-
emit: function(){ console.error('[EMBEDDED] WIO failed to initialize')
|
|
1083
|
+
emit: function(){ console.error('[EMBEDDED] WIO failed to initialize') },
|
|
1088
1084
|
on: function(){},
|
|
1089
1085
|
once: function(){},
|
|
1090
1086
|
off: function(){}
|
|
1091
|
-
}
|
|
1087
|
+
}
|
|
1092
1088
|
}
|
|
1093
1089
|
|
|
1094
|
-
true
|
|
1095
|
-
})()
|
|
1090
|
+
true
|
|
1091
|
+
})()
|
|
1096
1092
|
`
|
|
1097
1093
|
}
|
|
1098
1094
|
}
|