@midscene/visualizer 0.28.10-beta-20250919094051.0 → 0.28.10

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.
@@ -24,10 +24,17 @@ var __webpack_require__ = {};
24
24
  var __webpack_exports__ = {};
25
25
  __webpack_require__.r(__webpack_exports__);
26
26
  __webpack_require__.d(__webpack_exports__, {
27
+ IndexedDBStorageProvider: ()=>external_indexeddb_storage_provider_js_namespaceObject.IndexedDBStorageProvider,
28
+ StorageType: ()=>storage_provider_StorageType,
29
+ detectBestStorageType: ()=>detectBestStorageType,
30
+ IndexedDBMemoryStorageProvider: ()=>external_indexeddb_storage_provider_js_namespaceObject.MemoryStorageProvider,
31
+ IndexedDBNoOpStorageProvider: ()=>external_indexeddb_storage_provider_js_namespaceObject.NoOpStorageProvider,
27
32
  LocalStorageProvider: ()=>LocalStorageProvider,
28
- MemoryStorageProvider: ()=>MemoryStorageProvider,
29
- NoOpStorageProvider: ()=>NoOpStorageProvider
33
+ NoOpStorageProvider: ()=>NoOpStorageProvider,
34
+ createStorageProvider: ()=>createStorageProvider,
35
+ MemoryStorageProvider: ()=>MemoryStorageProvider
30
36
  });
37
+ const external_indexeddb_storage_provider_js_namespaceObject = require("./indexeddb-storage-provider.js");
31
38
  function _define_property(obj, key, value) {
32
39
  if (key in obj) Object.defineProperty(obj, key, {
33
40
  value: value,
@@ -198,13 +205,63 @@ class NoOpStorageProvider {
198
205
  async clearMessages() {}
199
206
  async saveResult(_id, _result) {}
200
207
  }
208
+ var storage_provider_StorageType = /*#__PURE__*/ function(StorageType) {
209
+ StorageType["INDEXEDDB"] = "indexeddb";
210
+ StorageType["LOCALSTORAGE"] = "localStorage";
211
+ StorageType["MEMORY"] = "memory";
212
+ StorageType["NONE"] = "none";
213
+ return StorageType;
214
+ }({});
215
+ function createStorageProvider() {
216
+ let type = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "indexeddb", namespace = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : 'playground';
217
+ switch(type){
218
+ case "indexeddb":
219
+ if ('undefined' != typeof indexedDB) return new external_indexeddb_storage_provider_js_namespaceObject.IndexedDBStorageProvider(namespace);
220
+ console.warn('IndexedDB not available, falling back to localStorage');
221
+ return createStorageProvider("localStorage", namespace);
222
+ case "localStorage":
223
+ if ('undefined' != typeof localStorage) return new LocalStorageProvider(namespace);
224
+ console.warn('localStorage not available, falling back to memory storage');
225
+ return createStorageProvider("memory", namespace);
226
+ case "memory":
227
+ return new MemoryStorageProvider();
228
+ case "none":
229
+ return new NoOpStorageProvider();
230
+ default:
231
+ throw new Error(`Unknown storage type: ${type}`);
232
+ }
233
+ }
234
+ function detectBestStorageType() {
235
+ if ('undefined' != typeof indexedDB) try {
236
+ indexedDB.open('test', 1).onerror = ()=>{};
237
+ return "indexeddb";
238
+ } catch (e) {}
239
+ if ('undefined' != typeof localStorage) try {
240
+ localStorage.setItem('test', 'test');
241
+ localStorage.removeItem('test');
242
+ return "localStorage";
243
+ } catch (e) {}
244
+ return "memory";
245
+ }
246
+ exports.IndexedDBMemoryStorageProvider = __webpack_exports__.IndexedDBMemoryStorageProvider;
247
+ exports.IndexedDBNoOpStorageProvider = __webpack_exports__.IndexedDBNoOpStorageProvider;
248
+ exports.IndexedDBStorageProvider = __webpack_exports__.IndexedDBStorageProvider;
201
249
  exports.LocalStorageProvider = __webpack_exports__.LocalStorageProvider;
202
250
  exports.MemoryStorageProvider = __webpack_exports__.MemoryStorageProvider;
203
251
  exports.NoOpStorageProvider = __webpack_exports__.NoOpStorageProvider;
252
+ exports.StorageType = __webpack_exports__.StorageType;
253
+ exports.createStorageProvider = __webpack_exports__.createStorageProvider;
254
+ exports.detectBestStorageType = __webpack_exports__.detectBestStorageType;
204
255
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
256
+ "IndexedDBMemoryStorageProvider",
257
+ "IndexedDBNoOpStorageProvider",
258
+ "IndexedDBStorageProvider",
205
259
  "LocalStorageProvider",
206
260
  "MemoryStorageProvider",
207
- "NoOpStorageProvider"
261
+ "NoOpStorageProvider",
262
+ "StorageType",
263
+ "createStorageProvider",
264
+ "detectBestStorageType"
208
265
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
209
266
  Object.defineProperty(exports, '__esModule', {
210
267
  value: true
@@ -27,6 +27,7 @@ __webpack_require__.d(__webpack_exports__, {
27
27
  usePlaygroundState: ()=>usePlaygroundState
28
28
  });
29
29
  const external_react_namespaceObject = require("react");
30
+ const storage_provider_js_namespaceObject = require("../component/universal-playground/providers/storage-provider.js");
30
31
  const constants_js_namespaceObject = require("../utils/constants.js");
31
32
  function usePlaygroundState(playgroundSDK, storage, contextProvider) {
32
33
  const [loading, setLoading] = (0, external_react_namespaceObject.useState)(false);
@@ -40,7 +41,25 @@ function usePlaygroundState(playgroundSDK, storage, contextProvider) {
40
41
  const infoListRef = (0, external_react_namespaceObject.useRef)(null);
41
42
  const currentRunningIdRef = (0, external_react_namespaceObject.useRef)(null);
42
43
  const interruptedFlagRef = (0, external_react_namespaceObject.useRef)({});
44
+ const initializedRef = (0, external_react_namespaceObject.useRef)(false);
43
45
  (0, external_react_namespaceObject.useEffect)(()=>{
46
+ const migrateFromOldNamespace = async ()=>{
47
+ const oldStorage = (0, storage_provider_js_namespaceObject.createStorageProvider)((0, storage_provider_js_namespaceObject.detectBestStorageType)(), 'playground-default');
48
+ try {
49
+ if (null == oldStorage ? void 0 : oldStorage.loadMessages) {
50
+ const oldMessages = await oldStorage.loadMessages();
51
+ if (oldMessages.length > 1) {
52
+ console.log('Found data in old namespace, migrating...');
53
+ if (null == storage ? void 0 : storage.saveMessages) await storage.saveMessages(oldMessages);
54
+ if (oldStorage.clearMessages) await oldStorage.clearMessages();
55
+ return oldMessages;
56
+ }
57
+ }
58
+ } catch (error) {
59
+ console.debug('No data found in old namespace:', error);
60
+ }
61
+ return [];
62
+ };
44
63
  const initializeMessages = async ()=>{
45
64
  const welcomeMessage = {
46
65
  ...constants_js_namespaceObject.WELCOME_MESSAGE_TEMPLATE,
@@ -48,7 +67,8 @@ function usePlaygroundState(playgroundSDK, storage, contextProvider) {
48
67
  timestamp: new Date()
49
68
  };
50
69
  if (null == storage ? void 0 : storage.loadMessages) try {
51
- const storedMessages = await storage.loadMessages();
70
+ let storedMessages = await storage.loadMessages();
71
+ if (0 === storedMessages.length) storedMessages = await migrateFromOldNamespace();
52
72
  const hasWelcomeMessage = storedMessages.some((msg)=>'welcome' === msg.id);
53
73
  hasWelcomeMessage ? setInfoList(storedMessages) : setInfoList([
54
74
  welcomeMessage,
@@ -64,8 +84,13 @@ function usePlaygroundState(playgroundSDK, storage, contextProvider) {
64
84
  welcomeMessage
65
85
  ]);
66
86
  };
67
- if (0 === infoList.length) initializeMessages();
68
- }, []);
87
+ if (storage && !initializedRef.current) {
88
+ initializedRef.current = true;
89
+ initializeMessages();
90
+ } else if (!storage && 0 === infoList.length) initializeMessages();
91
+ }, [
92
+ storage
93
+ ]);
69
94
  (0, external_react_namespaceObject.useEffect)(()=>{
70
95
  if ((null == storage ? void 0 : storage.saveMessages) && infoList.length > 1) storage.saveMessages(infoList).catch((error)=>{
71
96
  if (error instanceof DOMException && 'QuotaExceededError' === error.name) console.warn('Storage quota exceeded - some messages may not be saved persistently');
package/dist/lib/index.js CHANGED
@@ -34,6 +34,7 @@ var __webpack_exports__ = {};
34
34
  __webpack_require__.r(__webpack_exports__);
35
35
  __webpack_require__.d(__webpack_exports__, {
36
36
  timeCostStrElement: ()=>misc_index_js_namespaceObject.timeCostStrElement,
37
+ StorageType: ()=>storage_provider_js_namespaceObject.StorageType,
37
38
  actionNameForType: ()=>playground_utils_js_namespaceObject.actionNameForType,
38
39
  PlaygroundResultView: ()=>playground_result_index_js_namespaceObject.PlaygroundResultView,
39
40
  timeStr: ()=>external_utils_index_js_namespaceObject.timeStr,
@@ -53,7 +54,9 @@ __webpack_require__.d(__webpack_exports__, {
53
54
  safeOverrideAIConfig: ()=>useSafeOverrideAIConfig_js_namespaceObject.safeOverrideAIConfig,
54
55
  Logo: ()=>logo_index_js_namespaceObject.Logo,
55
56
  UniversalPlayground: ()=>universal_playground_index_js_namespaceObject.UniversalPlayground,
57
+ IndexedDBStorageProvider: ()=>storage_provider_js_namespaceObject.IndexedDBStorageProvider,
56
58
  NavActions: ()=>nav_actions_index_js_namespaceObject.NavActions,
59
+ detectBestStorageType: ()=>storage_provider_js_namespaceObject.detectBestStorageType,
57
60
  useEnvConfig: ()=>store_js_namespaceObject.useEnvConfig,
58
61
  NoOpStorageProvider: ()=>storage_provider_js_namespaceObject.NoOpStorageProvider,
59
62
  ContextPreview: ()=>context_preview_index_js_namespaceObject.ContextPreview,
@@ -66,9 +69,10 @@ __webpack_require__.d(__webpack_exports__, {
66
69
  filterBase64Value: ()=>external_utils_index_js_namespaceObject.filterBase64Value,
67
70
  NoOpContextProvider: ()=>context_provider_js_namespaceObject.NoOpContextProvider,
68
71
  highlightColorForType: ()=>color_js_namespaceObject.highlightColorForType,
72
+ createStorageProvider: ()=>storage_provider_js_namespaceObject.createStorageProvider,
69
73
  globalThemeConfig: ()=>color_js_namespaceObject.globalThemeConfig,
70
- iconForStatus: ()=>misc_index_js_namespaceObject.iconForStatus,
71
- MemoryStorageProvider: ()=>storage_provider_js_namespaceObject.MemoryStorageProvider
74
+ MemoryStorageProvider: ()=>storage_provider_js_namespaceObject.MemoryStorageProvider,
75
+ iconForStatus: ()=>misc_index_js_namespaceObject.iconForStatus
72
76
  });
73
77
  require("./component/playground/index.css");
74
78
  require("./component/universal-playground/index.css");
@@ -102,6 +106,7 @@ exports.Blackboard = __webpack_exports__.Blackboard;
102
106
  exports.ContextPreview = __webpack_exports__.ContextPreview;
103
107
  exports.EnvConfig = __webpack_exports__.EnvConfig;
104
108
  exports.EnvConfigReminder = __webpack_exports__.EnvConfigReminder;
109
+ exports.IndexedDBStorageProvider = __webpack_exports__.IndexedDBStorageProvider;
105
110
  exports.LocalStorageProvider = __webpack_exports__.LocalStorageProvider;
106
111
  exports.Logo = __webpack_exports__.Logo;
107
112
  exports.MemoryStorageProvider = __webpack_exports__.MemoryStorageProvider;
@@ -114,11 +119,14 @@ exports.PromptInput = __webpack_exports__.PromptInput;
114
119
  exports.ServiceModeControl = __webpack_exports__.ServiceModeControl;
115
120
  exports.ShinyText = __webpack_exports__.ShinyText;
116
121
  exports.StaticContextProvider = __webpack_exports__.StaticContextProvider;
122
+ exports.StorageType = __webpack_exports__.StorageType;
117
123
  exports.UniversalPlayground = __webpack_exports__.UniversalPlayground;
118
124
  exports.UniversalPlaygroundDefault = __webpack_exports__.UniversalPlaygroundDefault;
119
125
  exports.actionNameForType = __webpack_exports__.actionNameForType;
120
126
  exports.allScriptsFromDump = __webpack_exports__.allScriptsFromDump;
121
127
  exports.colorForName = __webpack_exports__.colorForName;
128
+ exports.createStorageProvider = __webpack_exports__.createStorageProvider;
129
+ exports.detectBestStorageType = __webpack_exports__.detectBestStorageType;
122
130
  exports.filterBase64Value = __webpack_exports__.filterBase64Value;
123
131
  exports.generateAnimationScripts = __webpack_exports__.generateAnimationScripts;
124
132
  exports.getPlaceholderForType = __webpack_exports__.getPlaceholderForType;
@@ -139,6 +147,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
139
147
  "ContextPreview",
140
148
  "EnvConfig",
141
149
  "EnvConfigReminder",
150
+ "IndexedDBStorageProvider",
142
151
  "LocalStorageProvider",
143
152
  "Logo",
144
153
  "MemoryStorageProvider",
@@ -151,11 +160,14 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
151
160
  "ServiceModeControl",
152
161
  "ShinyText",
153
162
  "StaticContextProvider",
163
+ "StorageType",
154
164
  "UniversalPlayground",
155
165
  "UniversalPlaygroundDefault",
156
166
  "actionNameForType",
157
167
  "allScriptsFromDump",
158
168
  "colorForName",
169
+ "createStorageProvider",
170
+ "detectBestStorageType",
159
171
  "filterBase64Value",
160
172
  "generateAnimationScripts",
161
173
  "getPlaceholderForType",
@@ -73,8 +73,9 @@ const capitalizeFirstLetter = (str)=>{
73
73
  return str.charAt(0).toUpperCase() + str.slice(1);
74
74
  };
75
75
  const allScriptsFromDump = (dump)=>{
76
- let width;
77
- let height;
76
+ const dimensionsSet = new Set();
77
+ let firstWidth;
78
+ let firstHeight;
78
79
  let sdkVersion;
79
80
  const modelBriefsSet = new Set();
80
81
  dump.executions.forEach((execution)=>{
@@ -82,12 +83,17 @@ const allScriptsFromDump = (dump)=>{
82
83
  execution.tasks.forEach((task)=>{
83
84
  var _task_uiContext_size, _task_uiContext;
84
85
  if (null == (_task_uiContext = task.uiContext) ? void 0 : null == (_task_uiContext_size = _task_uiContext.size) ? void 0 : _task_uiContext_size.width) {
85
- width = task.uiContext.size.width;
86
- height = task.uiContext.size.height;
86
+ const w = task.uiContext.size.width;
87
+ const h = task.uiContext.size.height;
88
+ if (!firstWidth) {
89
+ firstWidth = w;
90
+ firstHeight = h;
91
+ }
92
+ dimensionsSet.add(`${w}x${h}`);
87
93
  }
88
94
  });
89
95
  });
90
- if (!width || !height) {
96
+ if (!firstWidth || !firstHeight) {
91
97
  console.warn('width or height is missing in dump file');
92
98
  return {
93
99
  scripts: [],
@@ -97,7 +103,7 @@ const allScriptsFromDump = (dump)=>{
97
103
  }
98
104
  const allScripts = [];
99
105
  dump.executions.forEach((execution)=>{
100
- const scripts = generateAnimationScripts(execution, -1, width, height);
106
+ const scripts = generateAnimationScripts(execution, -1, firstWidth, firstHeight);
101
107
  if (scripts) allScripts.push(...scripts);
102
108
  execution.tasks.forEach((task)=>{
103
109
  if (task.usage) {
@@ -124,8 +130,8 @@ const allScriptsFromDump = (dump)=>{
124
130
  })();
125
131
  return {
126
132
  scripts: allScriptsWithoutIntermediateDoneFrame,
127
- width,
128
- height,
133
+ width: firstWidth,
134
+ height: firstHeight,
129
135
  sdkVersion,
130
136
  modelBriefs
131
137
  };
@@ -174,14 +180,16 @@ const generateAnimationScripts = (execution, task, imageWidth, imageHeight)=>{
174
180
  if ('Planning' === task.type) {
175
181
  const planningTask = task;
176
182
  if (planningTask.recorder && planningTask.recorder.length > 0) {
177
- var _planningTask_recorder_, _planningTask_recorder;
183
+ var _planningTask_recorder_, _planningTask_recorder, _task_uiContext_size, _task_uiContext, _task_uiContext_size1, _task_uiContext1;
178
184
  scripts.push({
179
185
  type: 'img',
180
186
  img: null == (_planningTask_recorder = planningTask.recorder) ? void 0 : null == (_planningTask_recorder_ = _planningTask_recorder[0]) ? void 0 : _planningTask_recorder_.screenshot,
181
187
  camera: 0 === index ? fullPageCameraState : void 0,
182
188
  duration: stillDuration,
183
189
  title: (0, agent_namespaceObject.typeStr)(task),
184
- subTitle: (0, agent_namespaceObject.paramStr)(task)
190
+ subTitle: (0, agent_namespaceObject.paramStr)(task),
191
+ imageWidth: (null == (_task_uiContext = task.uiContext) ? void 0 : null == (_task_uiContext_size = _task_uiContext.size) ? void 0 : _task_uiContext_size.width) || imageWidth,
192
+ imageHeight: (null == (_task_uiContext1 = task.uiContext) ? void 0 : null == (_task_uiContext_size1 = _task_uiContext1.size) ? void 0 : _task_uiContext_size1.height) || imageHeight
185
193
  });
186
194
  }
187
195
  } else if ('Insight' === task.type && 'Locate' === task.subType) {
@@ -197,16 +205,21 @@ const generateAnimationScripts = (execution, task, imageWidth, imageHeight)=>{
197
205
  };
198
206
  const context = insightTask.uiContext;
199
207
  if (null == context ? void 0 : context.screenshotBase64) {
200
- var _insightTask_log, _insightTask_output1, _insightDump_taskInfo;
208
+ var _insightTask_log, _insightTask_output1, _insightDump_taskInfo, _context_size, _context_size1;
201
209
  const insightDump = null == (_insightTask_log = insightTask.log) ? void 0 : _insightTask_log.dump;
202
210
  const insightContentLength = context.tree ? (0, extractor_namespaceObject.treeToList)(context.tree).length : 0;
203
- if (context.screenshotBase64) scripts.push({
204
- type: 'img',
205
- img: context.screenshotBase64,
206
- duration: stillAfterInsightDuration,
207
- title,
208
- subTitle
209
- });
211
+ if (context.screenshotBase64) {
212
+ var _context_size2, _context_size3;
213
+ scripts.push({
214
+ type: 'img',
215
+ img: context.screenshotBase64,
216
+ duration: stillAfterInsightDuration,
217
+ title,
218
+ subTitle,
219
+ imageWidth: (null == (_context_size2 = context.size) ? void 0 : _context_size2.width) || imageWidth,
220
+ imageHeight: (null == (_context_size3 = context.size) ? void 0 : _context_size3.height) || imageHeight
221
+ });
222
+ }
210
223
  let cameraState;
211
224
  cameraState = currentCameraState === fullPageCameraState ? void 0 : insightCameraState ? mergeTwoCameraState(currentCameraState, insightCameraState) : void 0;
212
225
  scripts.push({
@@ -219,7 +232,9 @@ const generateAnimationScripts = (execution, task, imageWidth, imageHeight)=>{
219
232
  duration: insightContentLength > 20 ? locateDuration : 0.5 * locateDuration,
220
233
  insightCameraDuration: locateDuration,
221
234
  title,
222
- subTitle
235
+ subTitle,
236
+ imageWidth: (null == (_context_size = context.size) ? void 0 : _context_size.width) || imageWidth,
237
+ imageHeight: (null == (_context_size1 = context.size) ? void 0 : _context_size1.height) || imageHeight
223
238
  });
224
239
  scripts.push({
225
240
  type: 'sleep',
@@ -230,7 +245,7 @@ const generateAnimationScripts = (execution, task, imageWidth, imageHeight)=>{
230
245
  insightOnTop = true;
231
246
  }
232
247
  } else if ('Action' === task.type && 'FalsyConditionStatement' !== task.subType) {
233
- var _task_recorder_, _task_recorder, _task_recorder_1, _task_recorder1;
248
+ var _task_recorder_, _task_recorder, _task_uiContext_size2, _task_uiContext2, _task_uiContext_size3, _task_uiContext3, _task_recorder_1, _task_recorder1;
234
249
  const title = (0, agent_namespaceObject.typeStr)(task);
235
250
  const subTitle = (0, agent_namespaceObject.paramStr)(task);
236
251
  scripts.push(pointerScript(external_index_js_namespaceObject.mousePointer, title, subTitle));
@@ -241,7 +256,9 @@ const generateAnimationScripts = (execution, task, imageWidth, imageHeight)=>{
241
256
  duration: actionDuration,
242
257
  camera: 'Sleep' === task.subType ? fullPageCameraState : insightCameraState,
243
258
  title,
244
- subTitle
259
+ subTitle,
260
+ imageWidth: (null == (_task_uiContext2 = task.uiContext) ? void 0 : null == (_task_uiContext_size2 = _task_uiContext2.size) ? void 0 : _task_uiContext_size2.width) || imageWidth,
261
+ imageHeight: (null == (_task_uiContext3 = task.uiContext) ? void 0 : null == (_task_uiContext_size3 = _task_uiContext3.size) ? void 0 : _task_uiContext_size3.height) || imageHeight
245
262
  });
246
263
  if (insightOnTop) {
247
264
  scripts.push({
@@ -254,7 +271,7 @@ const generateAnimationScripts = (execution, task, imageWidth, imageHeight)=>{
254
271
  }
255
272
  const imgStillDuration = index < taskCount - 1 ? stillDuration : 0;
256
273
  if (null == (_task_recorder1 = task.recorder) ? void 0 : null == (_task_recorder_1 = _task_recorder1[1]) ? void 0 : _task_recorder_1.screenshot) {
257
- var _task_recorder_2, _task_recorder2;
274
+ var _task_recorder_2, _task_recorder2, _task_uiContext_size4, _task_uiContext4, _task_uiContext_size5, _task_uiContext5;
258
275
  scripts.push({
259
276
  type: 'spinning-pointer',
260
277
  duration: actionSpinningPointerDuration,
@@ -267,7 +284,9 @@ const generateAnimationScripts = (execution, task, imageWidth, imageHeight)=>{
267
284
  img: null == (_task_recorder2 = task.recorder) ? void 0 : null == (_task_recorder_2 = _task_recorder2[1]) ? void 0 : _task_recorder_2.screenshot,
268
285
  duration: imgStillDuration,
269
286
  title,
270
- subTitle
287
+ subTitle,
288
+ imageWidth: (null == (_task_uiContext4 = task.uiContext) ? void 0 : null == (_task_uiContext_size4 = _task_uiContext4.size) ? void 0 : _task_uiContext_size4.width) || imageWidth,
289
+ imageHeight: (null == (_task_uiContext5 = task.uiContext) ? void 0 : null == (_task_uiContext_size5 = _task_uiContext5.size) ? void 0 : _task_uiContext_size5.height) || imageHeight
271
290
  });
272
291
  } else scripts.push({
273
292
  type: 'sleep',
@@ -280,16 +299,22 @@ const generateAnimationScripts = (execution, task, imageWidth, imageHeight)=>{
280
299
  const title = (0, agent_namespaceObject.typeStr)(task);
281
300
  const subTitle = (0, agent_namespaceObject.paramStr)(task);
282
301
  const screenshot = null == (_task_recorder3 = task.recorder) ? void 0 : null == (_task_recorder_3 = _task_recorder3[task.recorder.length - 1]) ? void 0 : _task_recorder_3.screenshot;
283
- if (screenshot) scripts.push({
284
- type: 'img',
285
- img: screenshot,
286
- duration: stillDuration,
287
- camera: fullPageCameraState,
288
- title,
289
- subTitle
290
- });
302
+ if (screenshot) {
303
+ var _task_uiContext_size6, _task_uiContext6, _task_uiContext_size7, _task_uiContext7;
304
+ scripts.push({
305
+ type: 'img',
306
+ img: screenshot,
307
+ duration: stillDuration,
308
+ camera: fullPageCameraState,
309
+ title,
310
+ subTitle,
311
+ imageWidth: (null == (_task_uiContext6 = task.uiContext) ? void 0 : null == (_task_uiContext_size6 = _task_uiContext6.size) ? void 0 : _task_uiContext_size6.width) || imageWidth,
312
+ imageHeight: (null == (_task_uiContext7 = task.uiContext) ? void 0 : null == (_task_uiContext_size7 = _task_uiContext7.size) ? void 0 : _task_uiContext_size7.height) || imageHeight
313
+ });
314
+ }
291
315
  }
292
316
  if ('finished' !== task.status) {
317
+ var _task_uiContext_size8, _task_uiContext8, _task_uiContext_size9, _task_uiContext9;
293
318
  errorStateFlag = true;
294
319
  const errorTitle = (0, agent_namespaceObject.typeStr)(task);
295
320
  const errorMsg = task.errorMessage || 'unknown error';
@@ -300,7 +325,9 @@ const generateAnimationScripts = (execution, task, imageWidth, imageHeight)=>{
300
325
  camera: fullPageCameraState,
301
326
  duration: stillDuration,
302
327
  title: errorTitle,
303
- subTitle: errorSubTitle
328
+ subTitle: errorSubTitle,
329
+ imageWidth: (null == (_task_uiContext8 = task.uiContext) ? void 0 : null == (_task_uiContext_size8 = _task_uiContext8.size) ? void 0 : _task_uiContext_size8.width) || imageWidth,
330
+ imageHeight: (null == (_task_uiContext9 = task.uiContext) ? void 0 : null == (_task_uiContext_size9 = _task_uiContext9.size) ? void 0 : _task_uiContext_size9.height) || imageHeight
304
331
  });
305
332
  return;
306
333
  }
@@ -0,0 +1,71 @@
1
+ import type { InfoListItem, StorageProvider } from '../../../types';
2
+ /**
3
+ * IndexedDB Storage implementation for playground message persistence
4
+ * Provides much larger storage capacity compared to localStorage
5
+ */
6
+ export declare class IndexedDBStorageProvider implements StorageProvider {
7
+ private dbManager;
8
+ private namespace;
9
+ private messagesCleanup;
10
+ private resultsCleanup;
11
+ constructor(namespace?: string);
12
+ /**
13
+ * Save messages to IndexedDB
14
+ */
15
+ saveMessages(messages: InfoListItem[]): Promise<void>;
16
+ /**
17
+ * Load messages from IndexedDB
18
+ */
19
+ loadMessages(): Promise<InfoListItem[]>;
20
+ /**
21
+ * Clear all messages from IndexedDB
22
+ */
23
+ clearMessages(): Promise<void>;
24
+ /**
25
+ * Save a single result to IndexedDB with compression
26
+ */
27
+ saveResult(id: string, result: InfoListItem): Promise<void>;
28
+ /**
29
+ * Load a single result from IndexedDB
30
+ */
31
+ loadResult(id: string): Promise<InfoListItem | null>;
32
+ /**
33
+ * Compress result data for storage while preserving playback functionality
34
+ */
35
+ private compressResultForStorage;
36
+ /**
37
+ * Compress screenshot if it exceeds size threshold
38
+ */
39
+ private compressScreenshotIfNeeded;
40
+ /**
41
+ * Get storage statistics
42
+ */
43
+ getStorageStats(): Promise<{
44
+ messageCount: number;
45
+ resultCount: number;
46
+ }>;
47
+ /**
48
+ * Manually trigger cleanup
49
+ */
50
+ cleanup(): Promise<void>;
51
+ }
52
+ /**
53
+ * Memory-based storage provider for IndexedDB fallback
54
+ */
55
+ export declare class MemoryStorageProvider implements StorageProvider {
56
+ private messages;
57
+ private results;
58
+ saveMessages(messages: InfoListItem[]): Promise<void>;
59
+ loadMessages(): Promise<InfoListItem[]>;
60
+ clearMessages(): Promise<void>;
61
+ saveResult(id: string, result: InfoListItem): Promise<void>;
62
+ }
63
+ /**
64
+ * No-op storage provider for disabled storage
65
+ */
66
+ export declare class NoOpStorageProvider implements StorageProvider {
67
+ saveMessages(_messages: InfoListItem[]): Promise<void>;
68
+ loadMessages(): Promise<InfoListItem[]>;
69
+ clearMessages(): Promise<void>;
70
+ saveResult(_id: string, _result: InfoListItem): Promise<void>;
71
+ }
@@ -1,4 +1,5 @@
1
1
  import type { InfoListItem, StorageProvider } from '../../../types';
2
+ import { MemoryStorageProvider as IndexedDBMemoryStorageProvider, NoOpStorageProvider as IndexedDBNoOpStorageProvider, IndexedDBStorageProvider } from './indexeddb-storage-provider';
2
3
  /**
3
4
  * Local Storage implementation for playground message persistence
4
5
  */
@@ -40,3 +41,18 @@ export declare class NoOpStorageProvider implements StorageProvider {
40
41
  clearMessages(): Promise<void>;
41
42
  saveResult(_id: string, _result: InfoListItem): Promise<void>;
42
43
  }
44
+ /**
45
+ * Storage type enumeration
46
+ */
47
+ export declare enum StorageType {
48
+ INDEXEDDB = "indexeddb",
49
+ LOCALSTORAGE = "localStorage",
50
+ MEMORY = "memory",
51
+ NONE = "none"
52
+ }
53
+ /**
54
+ * Factory function to create the appropriate storage provider
55
+ */
56
+ export declare function createStorageProvider(type?: StorageType, namespace?: string): StorageProvider;
57
+ export declare function detectBestStorageType(): StorageType;
58
+ export { IndexedDBStorageProvider, IndexedDBMemoryStorageProvider, IndexedDBNoOpStorageProvider, };
@@ -3,7 +3,7 @@ import type { FormValue, InfoListItem, PlaygroundSDKLike, StorageProvider } from
3
3
  /**
4
4
  * Hook for handling playground execution logic
5
5
  */
6
- export declare function usePlaygroundExecution(playgroundSDK: PlaygroundSDKLike | null, storage: StorageProvider | undefined, actionSpace: DeviceAction<unknown>[], loading: boolean, setLoading: (loading: boolean) => void, infoList: InfoListItem[], setInfoList: React.Dispatch<React.SetStateAction<InfoListItem[]>>, replayCounter: number, setReplayCounter: React.Dispatch<React.SetStateAction<number>>, verticalMode: boolean, currentRunningIdRef: React.MutableRefObject<number | null>, interruptedFlagRef: React.MutableRefObject<Record<number, boolean>>): {
6
+ export declare function usePlaygroundExecution(playgroundSDK: PlaygroundSDKLike | null, storage: StorageProvider | undefined | null, actionSpace: DeviceAction<unknown>[], loading: boolean, setLoading: (loading: boolean) => void, infoList: InfoListItem[], setInfoList: React.Dispatch<React.SetStateAction<InfoListItem[]>>, replayCounter: number, setReplayCounter: React.Dispatch<React.SetStateAction<number>>, verticalMode: boolean, currentRunningIdRef: React.MutableRefObject<number | null>, interruptedFlagRef: React.MutableRefObject<Record<number, boolean>>): {
7
7
  handleRun: (value: FormValue) => Promise<void>;
8
8
  handleStop: () => Promise<void>;
9
9
  canStop: boolean;
@@ -3,7 +3,7 @@ import type { ContextProvider, InfoListItem, PlaygroundSDKLike, StorageProvider
3
3
  /**
4
4
  * Hook for managing playground state
5
5
  */
6
- export declare function usePlaygroundState(playgroundSDK: PlaygroundSDKLike | null, storage?: StorageProvider, contextProvider?: ContextProvider): {
6
+ export declare function usePlaygroundState(playgroundSDK: PlaygroundSDKLike | null, storage?: StorageProvider | null, contextProvider?: ContextProvider): {
7
7
  loading: boolean;
8
8
  setLoading: import("react").Dispatch<import("react").SetStateAction<boolean>>;
9
9
  infoList: InfoListItem[];
@@ -23,5 +23,5 @@ export { timeStr, filterBase64Value } from './utils';
23
23
  export { default as ShinyText } from './component/shiny-text';
24
24
  export { UniversalPlayground, default as UniversalPlaygroundDefault, } from './component/universal-playground';
25
25
  export type { UniversalPlaygroundProps, PlaygroundSDKLike, StorageProvider, ContextProvider, UniversalPlaygroundConfig, PlaygroundBranding, InfoListItem, FormValue, ExecutionOptions, ProgressCallback, } from './types';
26
- export { LocalStorageProvider, MemoryStorageProvider, NoOpStorageProvider, } from './component/universal-playground/providers/storage-provider';
26
+ export { LocalStorageProvider, MemoryStorageProvider, NoOpStorageProvider, IndexedDBStorageProvider, createStorageProvider, detectBestStorageType, StorageType, } from './component/universal-playground/providers/storage-provider';
27
27
  export { BaseContextProvider, AgentContextProvider, StaticContextProvider, NoOpContextProvider, } from './component/universal-playground/providers/context-provider';
@@ -18,6 +18,8 @@ export interface AnimationScript {
18
18
  insightCameraDuration?: number;
19
19
  title?: string;
20
20
  subTitle?: string;
21
+ imageWidth?: number;
22
+ imageHeight?: number;
21
23
  }
22
24
  export declare const cameraStateForRect: (rect: Rect, imageWidth: number, imageHeight: number) => TargetCameraState;
23
25
  export declare const mergeTwoCameraState: (cameraState1: TargetCameraState, cameraState2: TargetCameraState) => TargetCameraState;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/visualizer",
3
- "version": "0.28.10-beta-20250919094051.0",
3
+ "version": "0.28.10",
4
4
  "repository": "https://github.com/web-infra-dev/midscene",
5
5
  "homepage": "https://midscenejs.com/",
6
6
  "types": "./dist/types/index.d.ts",
@@ -70,10 +70,10 @@
70
70
  "antd": "^5.21.6",
71
71
  "buffer": "6.0.3",
72
72
  "dayjs": "^1.11.11",
73
- "@midscene/core": "0.28.10-beta-20250919094051.0",
74
- "@midscene/shared": "0.28.10-beta-20250919094051.0",
75
- "@midscene/web": "0.28.10-beta-20250919094051.0",
76
- "@midscene/playground": "0.28.10-beta-20250919094051.0"
73
+ "@midscene/core": "0.28.10",
74
+ "@midscene/playground": "0.28.10",
75
+ "@midscene/shared": "0.28.10",
76
+ "@midscene/web": "0.28.10"
77
77
  },
78
78
  "license": "MIT",
79
79
  "scripts": {