Skip to content

Commit a2160ff

Browse files
committed
deploy: 606b7d0
1 parent c99c41d commit a2160ff

File tree

73 files changed

+476
-176
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+476
-176
lines changed

LiveDevelopment/BrowserScripts/LivePreviewTransportRemote.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,37 @@
103103
}
104104
}
105105

106+
function createLRU(max = 100) {
107+
const map = new Map();
108+
109+
return {
110+
set: function (key, value = true) {
111+
if (map.has(key)) {
112+
map.delete(key); // refresh order
113+
}
114+
map.set(key, value);
115+
if (map.size > max) {
116+
const oldestKey = map.keys().next().value;
117+
map.delete(oldestKey);
118+
}
119+
},
120+
has: function (key) {
121+
if (!map.has(key)) {
122+
return false;
123+
}
124+
const val = map.get(key);
125+
map.delete(key); // refresh order
126+
map.set(key, val);
127+
return true;
128+
},
129+
size: function() {
130+
return map.size;
131+
}
132+
};
133+
}
134+
135+
const processedMessageIDs = createLRU(1000);
136+
106137
const clientID = "" + Math.round( Math.random()*1000000000);
107138

108139
const worker = new Worker(TRANSPORT_CONFIG.LIVE_DEV_REMOTE_WORKER_SCRIPTS_FILE_NAME);
@@ -218,7 +249,12 @@
218249
case 'MESSAGE_FROM_PHOENIX':
219250
if (self._callbacks && self._callbacks.message) {
220251
const clientIDs = event.data.clientIDs,
221-
message = event.data.message;
252+
message = event.data.message,
253+
messageID = event.data.messageID;
254+
if(messageID && processedMessageIDs.has(messageID)){
255+
return; // we have already processed this message.
256+
}
257+
processedMessageIDs.set(messageID, true);
222258
if(clientIDs.includes(clientID) || clientIDs.length === 0){
223259
// clientIDs.length = 0 if the message is intended for all clients
224260
self._callbacks.message(message);
@@ -264,6 +300,7 @@
264300
_postLivePreviewMessage({
265301
type: 'BROWSER_MESSAGE',
266302
clientID: clientID,
303+
messageID: crypto.randomUUID(),
267304
message: msgStr
268305
});
269306
},

LiveDevelopment/BrowserScripts/pageLoaderWorker.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*/
2626

2727

28-
let _livePreviewNavigationChannel;
28+
let _livePreviewBroadcastChannel;
2929
let _livePreviewWebSocket, _livePreviewWebSocketOpen = false;
3030
let livePreviewDebugModeEnabled = false;
3131
function _debugLog(...args) {
@@ -106,8 +106,8 @@ let messageQueue = [];
106106
function _sendMessage(message) {
107107
if(_livePreviewWebSocket && _livePreviewWebSocketOpen) {
108108
_livePreviewWebSocket.send(mergeMetadataAndArrayBuffer(message));
109-
} else if(_livePreviewNavigationChannel){
110-
_livePreviewNavigationChannel.postMessage(message);
109+
} else if(_livePreviewBroadcastChannel){
110+
_livePreviewBroadcastChannel.postMessage(message);
111111
} else {
112112
livePreviewDebugModeEnabled && console.warn("No Channels available for live preview worker messaging," +
113113
" queueing request, waiting for channel..");
@@ -138,8 +138,8 @@ function _setupHearbeatMessenger(clientID) {
138138
}
139139

140140
function _setupBroadcastChannel(broadcastChannel, clientID) {
141-
_livePreviewNavigationChannel=new BroadcastChannel(broadcastChannel);
142-
_livePreviewNavigationChannel.onmessage = (event) => {
141+
_livePreviewBroadcastChannel=new BroadcastChannel(broadcastChannel);
142+
_livePreviewBroadcastChannel.onmessage = (event) => {
143143
const type = event.data.type;
144144
switch (type) {
145145
case 'TAB_ONLINE': break; // do nothing. This is a loopback message from another live preview tab

LiveDevelopment/MultiBrowserImpl/protocol/LiveDevProtocol.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,15 @@ define(function (require, exports, module) {
194194
}
195195
}
196196

197+
const processedMessageIDs = new Phoenix.libs.LRUCache({
198+
max: 1000
199+
// we dont need to set a ttl here as message ids are unique throughout lifetime. And old ids will
200+
// start getting evited from the cache. the message ids are only an issue within a fraction of a seconds when
201+
// a series of messages are sent in quick succession. Eg. user click on a div and there are 3 tabs and due to
202+
// the reflection bug, we almost immediately get 3 messages with the same id. So that will be in this cache
203+
// for a fraction of a second. so a size of 1000 should be more than enough.
204+
});
205+
197206
/**
198207
* @private
199208
* Handles a message received from the remote protocol handler via the transport.
@@ -203,12 +212,21 @@ define(function (require, exports, module) {
203212
* TODO: we should probably have a way of returning the results from all clients, not just the first?
204213
*
205214
* @param {number} clientId ID of the client that sent the message
206-
* @param {string} msg The message that was sent, in JSON string format
215+
* @param {string} msgStr The message that was sent, in JSON string format
216+
* @param {string} messageID The messageID uniquely identifying a message. in browsers, since we use broadcast
217+
* channels, we get reflections echoes when there are multiple tabs open. Ideally those reflections need to
218+
* be fixed, but that was too complex to fix, so we just reply on the message id to guarantee that a message is
219+
* only processed once and not from any reflections.
207220
*/
208-
function _receive(clientId, msgStr) {
221+
function _receive(clientId, msgStr, messageID) {
209222
var msg = JSON.parse(msgStr),
210223
event = msg.method || "event",
211224
deferred;
225+
if(messageID && processedMessageIDs.has(messageID)){
226+
return; // this message is already processed.
227+
} else if (messageID) {
228+
processedMessageIDs.set(messageID, true);
229+
}
212230
if (msg.livePreviewEditEnabled) {
213231
LivePreviewEdit.handleLivePreviewEditOperation(msg);
214232
}
@@ -305,7 +323,7 @@ define(function (require, exports, module) {
305323
_connect(msg[0], msg[1]);
306324
})
307325
.on("message.livedev", function (event, msg) {
308-
_receive(msg[0], msg[1]);
326+
_receive(msg[0], msg[1], msg[2]);
309327
})
310328
.on("close.livedev", function (event, msg) {
311329
_close(msg[0]);

LiveDevelopment/MultiBrowserImpl/transports/LivePreviewTransport.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ define(function (require, exports, module) {
111111
_transportBridge && _transportBridge.messageToLivePreviewTabs({
112112
type: 'MESSAGE_FROM_PHOENIX',
113113
clientIDs,
114-
message
114+
message,
115+
messageID: crypto.randomUUID()
115116
});
116117
transportMessagesSendCount ++;
117118
transportMessagesSendSizeB = transportMessagesSendSizeB + message.length;
@@ -135,7 +136,7 @@ define(function (require, exports, module) {
135136
window.logger.livePreview.log(
136137
"Live Preview: Phoenix received event from Browser preview tab/iframe: ", event.data);
137138
const message = event.data.message.message || "";
138-
exports.trigger('message', [event.data.message.clientID, message]);
139+
exports.trigger('message', [event.data.message.clientID, message, event.data.message.messageID]);
139140
transportMessagesRecvSizeB = transportMessagesRecvSizeB + message.length;
140141
transportMessagesRecvCount++;
141142
}

appConfig.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ window.AppConfig = {
3333
"app_update_url": "https://updates.phcode.io/tauri/update-latest-experimental-build.json",
3434
"extensionTakedownURL": "https://updates.phcode.io/extension_takedown.json",
3535
"linting.enabled_by_default": true,
36-
"build_timestamp": "2025-10-15T04:30:46.910Z",
36+
"build_timestamp": "2025-10-22T05:43:33.360Z",
3737
"googleAnalyticsID": "G-P4HJFPDB76",
3838
"googleAnalyticsIDDesktop": "G-VE5BXWJ0HF",
3939
"mixPanelID": "49c4d164b592be2350fc7af06a259bf3",
@@ -45,7 +45,7 @@ window.AppConfig = {
4545
"bugsnagEnv": "development"
4646
},
4747
"name": "Phoenix Code",
48-
"version": "4.1.2-21594",
48+
"version": "4.1.2-21595",
4949
"apiVersion": "4.1.2",
5050
"homepage": "https://core.ai",
5151
"issues": {

assets/default-project/en.zip

0 Bytes
Binary file not shown.

assets/sample-projects/HTML5.zip

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.

assets/sample-projects/explore.zip

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)