@lvce-editor/title-bar-worker 4.28.3 → 4.28.5

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.
@@ -1033,6 +1033,9 @@ const logError = () => {
1033
1033
  // handled by renderer worker
1034
1034
  };
1035
1035
  const handleMessage = event => {
1036
+ if (event.data === 'ready') {
1037
+ return Promise.resolve();
1038
+ }
1036
1039
  const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
1037
1040
  const actualExecute = event?.target?.execute || execute;
1038
1041
  return handleJsonRpcMessage(event.target, event.data, actualExecute, event.target._resolve, preparePrettyError, logError, actualRequiresSocket);
@@ -1056,6 +1059,34 @@ const listen$1 = async (module, options) => {
1056
1059
  return ipc;
1057
1060
  };
1058
1061
 
1062
+ const createSharedLazyRpc = factory => {
1063
+ let rpcPromise;
1064
+ const getOrCreate = () => {
1065
+ if (!rpcPromise) {
1066
+ rpcPromise = factory();
1067
+ }
1068
+ return rpcPromise;
1069
+ };
1070
+ return {
1071
+ async dispose() {
1072
+ const rpc = await getOrCreate();
1073
+ await rpc.dispose();
1074
+ },
1075
+ async invoke(method, ...params) {
1076
+ const rpc = await getOrCreate();
1077
+ return rpc.invoke(method, ...params);
1078
+ },
1079
+ async invokeAndTransfer(method, ...params) {
1080
+ const rpc = await getOrCreate();
1081
+ return rpc.invokeAndTransfer(method, ...params);
1082
+ },
1083
+ async send(method, ...params) {
1084
+ const rpc = await getOrCreate();
1085
+ rpc.send(method, ...params);
1086
+ }
1087
+ };
1088
+ };
1089
+
1059
1090
  const create$6 = async ({
1060
1091
  commandMap,
1061
1092
  isMessagePortOpen = true,
@@ -1091,34 +1122,6 @@ const create$5 = async ({
1091
1122
  });
1092
1123
  };
1093
1124
 
1094
- const createSharedLazyRpc = factory => {
1095
- let rpcPromise;
1096
- const getOrCreate = () => {
1097
- if (!rpcPromise) {
1098
- rpcPromise = factory();
1099
- }
1100
- return rpcPromise;
1101
- };
1102
- return {
1103
- async dispose() {
1104
- const rpc = await getOrCreate();
1105
- await rpc.dispose();
1106
- },
1107
- async invoke(method, ...params) {
1108
- const rpc = await getOrCreate();
1109
- return rpc.invoke(method, ...params);
1110
- },
1111
- async invokeAndTransfer(method, ...params) {
1112
- const rpc = await getOrCreate();
1113
- return rpc.invokeAndTransfer(method, ...params);
1114
- },
1115
- async send(method, ...params) {
1116
- const rpc = await getOrCreate();
1117
- rpc.send(method, ...params);
1118
- }
1119
- };
1120
- };
1121
-
1122
1125
  const create$4 = async ({
1123
1126
  commandMap,
1124
1127
  isMessagePortOpen,
@@ -1165,7 +1168,7 @@ const createMockRpc = ({
1165
1168
  };
1166
1169
 
1167
1170
  const rpcs = Object.create(null);
1168
- const set$6 = (id, rpc) => {
1171
+ const set$7 = (id, rpc) => {
1169
1172
  rpcs[id] = rpc;
1170
1173
  };
1171
1174
  const get$1 = id => {
@@ -1198,7 +1201,7 @@ const create$2 = rpcId => {
1198
1201
  const mockRpc = createMockRpc({
1199
1202
  commandMap
1200
1203
  });
1201
- set$6(rpcId, mockRpc);
1204
+ set$7(rpcId, mockRpc);
1202
1205
  // @ts-ignore
1203
1206
  mockRpc[Symbol.dispose] = () => {
1204
1207
  remove(rpcId);
@@ -1207,11 +1210,22 @@ const create$2 = rpcId => {
1207
1210
  return mockRpc;
1208
1211
  },
1209
1212
  set(rpc) {
1210
- set$6(rpcId, rpc);
1213
+ set$7(rpcId, rpc);
1211
1214
  }
1212
1215
  };
1213
1216
  };
1214
1217
 
1218
+ const {
1219
+ invoke: invoke$4,
1220
+ set: set$6
1221
+ } = create$2(19_001);
1222
+ const getCacheStorageItem = async (request, cacheName, bucketName, bucketOptions) => {
1223
+ return invoke$4('Cache.getCacheStorageItem', request, cacheName, bucketName, bucketOptions);
1224
+ };
1225
+ const setCacheStorageItem = async (request, value, cacheName, headers, bucketName, bucketOptions) => {
1226
+ return invoke$4('Cache.setCacheStorageItem', request, value, cacheName, headers, bucketName, bucketOptions);
1227
+ };
1228
+
1215
1229
  const Button$2 = 'button';
1216
1230
  const ContentInfo = 'contentinfo';
1217
1231
  const Menu$1 = 'menu';
@@ -1664,6 +1678,10 @@ const sendMessagePortToTextMeasurementWorker = async port => {
1664
1678
  const command = 'TextMeasurement.handleMessagePort';
1665
1679
  await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToTextMeasurementWorker', port, command, 0);
1666
1680
  };
1681
+ const sendMessagePortToCacheWorker = async port => {
1682
+ const command = 'CacheWorker.handleMessagePort';
1683
+ await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToCacheWorker', port, command, 0);
1684
+ };
1667
1685
  const minimizeWindow = async () => {
1668
1686
  return invoke$1('ElectronWindow.minimize');
1669
1687
  };
@@ -4244,23 +4262,6 @@ const handleMessagePort = async (port, viewletCommandMap, setAsRendererProcess =
4244
4262
  }
4245
4263
  };
4246
4264
 
4247
- const getMenuOffset = (x, clientX, iconWidth) => {
4248
- return clientX - x - iconWidth;
4249
- };
4250
-
4251
- const getTitleBarIndexFromPosition = (titleBarEntries, x, y) => {
4252
- let currentX = 0;
4253
- for (let i = 0; i < titleBarEntries.length; i++) {
4254
- const entry = titleBarEntries[i];
4255
- const entryWidth = entry.width;
4256
- if (x >= currentX && x < currentX + entryWidth) {
4257
- return i;
4258
- }
4259
- currentX += entryWidth;
4260
- }
4261
- return -1;
4262
- };
4263
-
4264
4265
  const focusIndex = async (state, index) => {
4265
4266
  object(state);
4266
4267
  number(index);
@@ -4303,17 +4304,7 @@ const ifElse = (menuOpenFunction, menuClosedFunction) => {
4303
4304
 
4304
4305
  const handleMouseOut = ifElse(handleMouseOutMenuOpen, handleMouseOutMenuClosed);
4305
4306
 
4306
- const handlePointerOut = (state, clientX, clientY) => {
4307
- const {
4308
- iconWidth,
4309
- x
4310
- } = state;
4311
- const titleBarEntries = getNavigableTitleBarEntries(state);
4312
- const menuX = getMenuOffset(x, clientX, iconWidth);
4313
- const index = getTitleBarIndexFromPosition(titleBarEntries, menuX);
4314
- if (index === -1) {
4315
- return state;
4316
- }
4307
+ const handlePointerOut = (state, _clientX, _clientY) => {
4317
4308
  return handleMouseOut(state);
4318
4309
  };
4319
4310
 
@@ -4464,15 +4455,96 @@ const launchTextMeasurementWorker = async () => {
4464
4455
  };
4465
4456
  };
4466
4457
 
4458
+ const createCacheWorkerLauncher = () => {
4459
+ let cacheWorkerPromise;
4460
+ return async () => {
4461
+ if (!cacheWorkerPromise) {
4462
+ cacheWorkerPromise = (async () => {
4463
+ const rpc = await create$5({
4464
+ commandMap: {},
4465
+ async send(port) {
4466
+ await sendMessagePortToCacheWorker(port);
4467
+ }
4468
+ });
4469
+ set$6(rpc);
4470
+ })();
4471
+ }
4472
+ try {
4473
+ await cacheWorkerPromise;
4474
+ } catch (error) {
4475
+ cacheWorkerPromise = undefined;
4476
+ throw error;
4477
+ }
4478
+ };
4479
+ };
4480
+ const launchCacheWorker = createCacheWorkerLauncher();
4481
+
4482
+ const cacheName = 'lvce-title-bar-measurements-v1';
4483
+ const cacheHeaders = {
4484
+ 'content-type': 'application/json'
4485
+ };
4486
+ const getCacheKey = async (labels, fontWeight, fontSize, fontFamily, letterSpacing) => {
4487
+ const input = JSON.stringify([labels, fontWeight, fontSize, fontFamily, letterSpacing]);
4488
+ const bytes = new TextEncoder().encode(input);
4489
+ const digest = await crypto.subtle.digest('SHA-256', bytes);
4490
+ const hash = Array.from(new Uint8Array(digest), byte => byte.toString(16).padStart(2, '0')).join('');
4491
+ return `/title-bar-measurements/v1/${hash}`;
4492
+ };
4493
+ const isValidWidths = (value, count) => {
4494
+ return Array.isArray(value) && value.length === count && value.every(width => typeof width === 'number' && Number.isFinite(width) && width >= 0);
4495
+ };
4496
+ const getWidths = async (key, count) => {
4497
+ await launchCacheWorker();
4498
+ const item = await getCacheStorageItem(key, cacheName);
4499
+ if (!item) {
4500
+ return undefined;
4501
+ }
4502
+ const value = JSON.parse(new TextDecoder().decode(item.body));
4503
+ return isValidWidths(value, count) ? value : undefined;
4504
+ };
4505
+ const setWidths = async (key, widths) => {
4506
+ await launchCacheWorker();
4507
+ await setCacheStorageItem(key, JSON.stringify(widths), cacheName, cacheHeaders);
4508
+ };
4509
+
4510
+ const cacheReadTimeoutMs = 500;
4511
+ const withCacheReadTimeout = async promise => {
4512
+ let timeoutId;
4513
+ const timeout = new Promise(resolve => {
4514
+ timeoutId = setTimeout(resolve, cacheReadTimeoutMs, undefined);
4515
+ });
4516
+ try {
4517
+ return await Promise.race([promise, timeout]);
4518
+ } finally {
4519
+ if (timeoutId) {
4520
+ clearTimeout(timeoutId);
4521
+ }
4522
+ }
4523
+ };
4467
4524
  const measureTextWidths2 = async (texts, fontWeight, fontSize, fontFamily, letterSpacing) => {
4468
4525
  if (typeof letterSpacing !== 'number') {
4469
4526
  throw new TypeError('letterSpacing must be of type number');
4470
4527
  }
4528
+ let cacheKey;
4529
+ try {
4530
+ const cachedWidths = await withCacheReadTimeout((async () => {
4531
+ cacheKey = await getCacheKey(texts, fontWeight, fontSize, fontFamily, letterSpacing);
4532
+ return getWidths(cacheKey, texts.length);
4533
+ })());
4534
+ if (cachedWidths) {
4535
+ return cachedWidths;
4536
+ }
4537
+ } catch {
4538
+ // Cache failures must not prevent title bar rendering.
4539
+ }
4471
4540
  const rpc = await launchTextMeasurementWorker();
4472
4541
  try {
4473
4542
  const isMonospaceFont = false;
4474
4543
  const charWidth = 0;
4475
4544
  const result = await rpc.invoke('TextMeasurement.measureTextWidths', texts, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, charWidth);
4545
+ if (cacheKey) {
4546
+ void setWidths(cacheKey, result).catch(() => {});
4547
+ }
4476
4548
  return result;
4477
4549
  } finally {
4478
4550
  await rpc[Symbol.asyncDispose]();
@@ -5200,6 +5272,23 @@ const focusPrevious = state => {
5200
5272
  return focusIndex(state, indexToFocus);
5201
5273
  };
5202
5274
 
5275
+ const getMenuOffset = (x, clientX, iconWidth) => {
5276
+ return clientX - x - iconWidth;
5277
+ };
5278
+
5279
+ const getTitleBarIndexFromPosition = (titleBarEntries, x, y) => {
5280
+ let currentX = 0;
5281
+ for (let i = 0; i < titleBarEntries.length; i++) {
5282
+ const entry = titleBarEntries[i];
5283
+ const entryWidth = entry.width;
5284
+ if (x >= currentX && x < currentX + entryWidth) {
5285
+ return i;
5286
+ }
5287
+ currentX += entryWidth;
5288
+ }
5289
+ return -1;
5290
+ };
5291
+
5203
5292
  const handleClickAt = async (state, button, eventX, eventY) => {
5204
5293
  const {
5205
5294
  iconWidth,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/title-bar-worker",
3
- "version": "4.28.3",
3
+ "version": "4.28.5",
4
4
  "description": "Title Bar Worker",
5
5
  "repository": {
6
6
  "type": "git",