@lark-apaas/client-toolkit-lite 1.1.7-alpha.2 → 1.1.7-alpha.20

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.cjs CHANGED
@@ -33,6 +33,7 @@ var index_exports = {};
33
33
  __export(index_exports, {
34
34
  ActiveLink: () => ActiveLink,
35
35
  AppContainer: () => AppContainer_default,
36
+ ErrorRender: () => ErrorRender_default,
36
37
  NavLink: () => NavLink2,
37
38
  PagePlaceholder: () => PagePlaceholder_default,
38
39
  QueryProvider: () => QueryProvider_default,
@@ -42,6 +43,7 @@ __export(index_exports, {
42
43
  avatarImages: () => avatar_exports,
43
44
  axiosForBackend: () => axiosForBackend,
44
45
  bannerImages: () => banner_exports,
46
+ capabilityClient: () => capabilityClient,
45
47
  clsxWithTw: () => clsxWithTw,
46
48
  copyToClipboard: () => copyToClipboard,
47
49
  coverImages: () => cover_exports,
@@ -58,6 +60,7 @@ __export(index_exports, {
58
60
  isIpad: () => isIpad,
59
61
  isMobile: () => isMobile,
60
62
  isPreview: () => isPreview,
63
+ logger: () => logger,
61
64
  normalizeBasePath: () => normalizeBasePath,
62
65
  reportTeaEvent: () => reportTeaEvent,
63
66
  resolveAppUrl: () => resolveAppUrl,
@@ -71,7 +74,8 @@ __export(index_exports, {
71
74
  module.exports = __toCommonJS(index_exports);
72
75
 
73
76
  // src/components/AppContainer/index.tsx
74
- var import_react7 = __toESM(require("react"), 1);
77
+ var import_react9 = __toESM(require("react"), 1);
78
+ var import_miaoda_inspector = require("@lark-apaas/miaoda-inspector");
75
79
 
76
80
  // src/runtime/react-devtools-hook.ts
77
81
  if (typeof window !== "undefined" && process.env.NODE_ENV !== "production") {
@@ -127,29 +131,1002 @@ function initAxiosConfig(axiosInstance2) {
127
131
  if (!axiosInstance2) {
128
132
  axiosInstance2 = import_axios.default;
129
133
  }
130
- axiosInstance2.interceptors.request.use((config) => {
134
+ axiosInstance2.interceptors.request.use((config2) => {
131
135
  const csrfToken = getCsrfToken();
132
136
  if (csrfToken) {
133
- config.headers["X-Suda-Csrf-Token"] = csrfToken;
137
+ config2.headers["X-Suda-Csrf-Token"] = csrfToken;
134
138
  }
135
139
  if (typeof window !== "undefined") {
136
- config.headers["X-Page-Route"] = window.location.pathname;
140
+ config2.headers["X-Page-Route"] = window.location.pathname;
137
141
  }
138
- return config;
142
+ return config2;
139
143
  }, (error) => Promise.reject(error));
140
144
  axiosInstance2.interceptors.response.use((response) => response, (error) => {
141
145
  if (process.env.NODE_ENV !== "production") {
142
146
  console.warn("[axios]", error.config?.method?.toUpperCase(), error.config?.url, error.message);
143
147
  }
144
- return Promise.reject(error);
148
+ return Promise.reject(error);
149
+ });
150
+ }
151
+ __name(initAxiosConfig, "initAxiosConfig");
152
+
153
+ // src/logger/logger.ts
154
+ var import_observable_web = require("@lark-apaas/observable-web");
155
+
156
+ // src/logger/intercept-global-error.ts
157
+ var import_internal_slardar = require("@lark-apaas/internal-slardar");
158
+
159
+ // src/utils/hmr-api.ts
160
+ var import_meta = {};
161
+ function createWebpackHmrApi(hot) {
162
+ return {
163
+ onSuccess(callback) {
164
+ let lastStatus = null;
165
+ const handler = /* @__PURE__ */ __name((status) => {
166
+ if (status === "idle" && lastStatus === "apply") {
167
+ try {
168
+ callback();
169
+ } catch (e) {
170
+ console.error("[HMR] Success callback error:", e);
171
+ }
172
+ }
173
+ lastStatus = status;
174
+ }, "handler");
175
+ hot.addStatusHandler(handler);
176
+ return () => hot.removeStatusHandler(handler);
177
+ },
178
+ onError(callback) {
179
+ const handler = /* @__PURE__ */ __name((status) => {
180
+ if (status === "fail" || status === "abort") {
181
+ try {
182
+ callback(new Error(`HMR ${status}`));
183
+ } catch (e) {
184
+ console.error("[HMR] Error callback error:", e);
185
+ }
186
+ }
187
+ }, "handler");
188
+ hot.addStatusHandler(handler);
189
+ return () => hot.removeStatusHandler(handler);
190
+ }
191
+ };
192
+ }
193
+ __name(createWebpackHmrApi, "createWebpackHmrApi");
194
+ function getHmrApi() {
195
+ if (process.env.NODE_ENV === "production") return null;
196
+ if (import_meta.webpackHot) {
197
+ return createWebpackHmrApi(import_meta.webpackHot);
198
+ }
199
+ if (typeof module !== "undefined" && module.hot) {
200
+ return createWebpackHmrApi(module.hot);
201
+ }
202
+ if (window.__VITE_HMR__) {
203
+ return window.__VITE_HMR__;
204
+ }
205
+ return null;
206
+ }
207
+ __name(getHmrApi, "getHmrApi");
208
+
209
+ // src/utils/postMessage.ts
210
+ var PARENT_ORIGIN_KEY = "__parentOrigin";
211
+ function getParentOriginFromParams() {
212
+ try {
213
+ const params = new URLSearchParams(window.location.search);
214
+ const origin = params.get(PARENT_ORIGIN_KEY);
215
+ if (origin) {
216
+ sessionStorage.setItem(PARENT_ORIGIN_KEY, origin);
217
+ return origin;
218
+ }
219
+ } catch {
220
+ }
221
+ try {
222
+ return sessionStorage.getItem(PARENT_ORIGIN_KEY) || void 0;
223
+ } catch {
224
+ return void 0;
225
+ }
226
+ }
227
+ __name(getParentOriginFromParams, "getParentOriginFromParams");
228
+ function getLegacyParentOrigin() {
229
+ const { origin } = window.location;
230
+ if (origin.includes("force.feishuapp.net")) {
231
+ return "https://force.feishu.cn";
232
+ }
233
+ if (origin.includes("force-pre.feishuapp.net")) {
234
+ return "https://force.feishu-pre.cn";
235
+ }
236
+ if (origin.includes("force.byted.org")) {
237
+ return "https://force.feishu-boe.cn";
238
+ }
239
+ if (origin.includes("feishuapp.cn") || origin.includes("miaoda.feishuapp.net")) {
240
+ return "https://miaoda.feishu.cn";
241
+ }
242
+ if (origin.includes("fsapp.kundou.cn") || origin.includes("miaoda-pre.feishuapp.net")) {
243
+ return "https://miaoda.feishu-pre.cn";
244
+ }
245
+ return "https://miaoda.feishu-boe.cn";
246
+ }
247
+ __name(getLegacyParentOrigin, "getLegacyParentOrigin");
248
+ function resolveParentOrigin() {
249
+ try {
250
+ if (document.referrer) {
251
+ const referrerOrigin = new URL(document.referrer).origin;
252
+ if (referrerOrigin.startsWith("http://localhost") || referrerOrigin.startsWith("http://127.0.0.1")) {
253
+ return referrerOrigin;
254
+ }
255
+ }
256
+ } catch {
257
+ }
258
+ const paramOrigin = getParentOriginFromParams();
259
+ if (paramOrigin) return paramOrigin;
260
+ return process.env?.FORCE_FRAMEWORK_DOMAIN_MAIN ?? getLegacyParentOrigin();
261
+ }
262
+ __name(resolveParentOrigin, "resolveParentOrigin");
263
+ function submitPostMessage(message, targetOrigin) {
264
+ try {
265
+ const parentOrigin = resolveParentOrigin();
266
+ const origin = targetOrigin ?? parentOrigin;
267
+ if (!origin) return;
268
+ window.parent.postMessage(message, origin);
269
+ } catch (e) {
270
+ console.error("postMessage error", e);
271
+ }
272
+ }
273
+ __name(submitPostMessage, "submitPostMessage");
274
+
275
+ // src/logger/log-types.ts
276
+ var LOG_LEVELS = [
277
+ "debug",
278
+ "info",
279
+ "warn",
280
+ "error",
281
+ "success"
282
+ ];
283
+ function isLogLevel(value) {
284
+ return typeof value === "string" && LOG_LEVELS.includes(value);
285
+ }
286
+ __name(isLogLevel, "isLogLevel");
287
+
288
+ // src/logger/intercept-global-error.ts
289
+ var devServerDisconnectInfo = null;
290
+ var retryCount = 0;
291
+ function processDevServerLog(log) {
292
+ if (!log) return;
293
+ const devFlag = log.includes("[webpack-dev-server]") || log.includes("[vite]");
294
+ if (devFlag && log.includes("Disconnected")) {
295
+ const time = Date.now();
296
+ devServerDisconnectInfo = {
297
+ time
298
+ };
299
+ submitPostMessage({
300
+ type: "DevServerMessage",
301
+ data: {
302
+ type: "devServer-status",
303
+ status: "disconnected"
304
+ }
305
+ });
306
+ import_internal_slardar.slardar.sendEvent({
307
+ name: "sandbox-devServer",
308
+ metrics: {
309
+ time
310
+ },
311
+ categories: {
312
+ type: "disconnected"
313
+ }
314
+ });
315
+ return;
316
+ }
317
+ if (!devServerDisconnectInfo) {
318
+ return;
319
+ }
320
+ if (devFlag && log.includes("Trying to reconnect")) {
321
+ if (retryCount) {
322
+ import_internal_slardar.slardar.sendEvent({
323
+ name: "sandbox-devServer",
324
+ metrics: {
325
+ retryCount: retryCount + 1
326
+ },
327
+ categories: {
328
+ type: "reconnect-failed"
329
+ }
330
+ });
331
+ }
332
+ retryCount++;
333
+ return;
334
+ }
335
+ const hmrFlag = log.includes("[HMR]");
336
+ if (hmrFlag || devFlag && (log.includes("Socket connected") || log.includes("App updated") || log.includes("App hot update") || log.includes("connected"))) {
337
+ submitPostMessage({
338
+ type: "DevServerMessage",
339
+ data: {
340
+ type: "devServer-status",
341
+ status: "connected"
342
+ }
343
+ });
344
+ const startTime = devServerDisconnectInfo.time;
345
+ const duration = Date.now() - startTime;
346
+ import_internal_slardar.slardar.sendEvent({
347
+ name: "sandbox-devServer",
348
+ metrics: {
349
+ startTime,
350
+ duration
351
+ },
352
+ categories: {
353
+ type: "devServer-reconnected"
354
+ }
355
+ });
356
+ devServerDisconnectInfo = null;
357
+ retryCount = 0;
358
+ }
359
+ }
360
+ __name(processDevServerLog, "processDevServerLog");
361
+ function listenModuleHmr() {
362
+ const hmr = getHmrApi();
363
+ if (hmr) {
364
+ hmr.onSuccess(() => {
365
+ submitPostMessage({
366
+ type: "DevServerMessage",
367
+ data: {
368
+ type: "devServer-status",
369
+ status: "hmr-apply-success"
370
+ }
371
+ });
372
+ });
373
+ hmr.onError((error) => {
374
+ console.warn("hmr apply failed", error);
375
+ import_internal_slardar.slardar.sendEvent({
376
+ name: "sandbox-devServer",
377
+ categories: {
378
+ type: "hmr-apply-failed",
379
+ error: String(error)
380
+ }
381
+ });
382
+ });
383
+ }
384
+ }
385
+ __name(listenModuleHmr, "listenModuleHmr");
386
+ var PROXY_CONSOLE_METHOD = [
387
+ "log",
388
+ "info",
389
+ "warn",
390
+ "error"
391
+ ];
392
+ function interceptErrors() {
393
+ window.addEventListener("error", (event) => {
394
+ logger.error(event.error);
395
+ });
396
+ window.addEventListener("unhandledrejection", (event) => {
397
+ logger.error(event.reason);
398
+ });
399
+ listenModuleHmr();
400
+ PROXY_CONSOLE_METHOD.forEach((method) => {
401
+ const originalMethod = window.console[method];
402
+ window.console[method] = (...args) => {
403
+ originalMethod(...args);
404
+ const level = method === "log" ? "info" : method;
405
+ const first = args[0];
406
+ if (typeof first === "string") {
407
+ processDevServerLog(first);
408
+ }
409
+ if (typeof first === "string" && first.startsWith("[Dataloom]") && isLogLevel(level)) {
410
+ logger.log({
411
+ level,
412
+ args
413
+ });
414
+ submitPostMessage({
415
+ type: "Console",
416
+ method,
417
+ data: args
418
+ });
419
+ }
420
+ };
421
+ });
422
+ }
423
+ __name(interceptErrors, "interceptErrors");
424
+
425
+ // src/utils/safeStringify.ts
426
+ function safeStringify(obj) {
427
+ const seen = /* @__PURE__ */ new Set();
428
+ try {
429
+ return JSON.stringify(obj, (_key, value) => {
430
+ if (typeof value === "object" && value !== null) {
431
+ if (seen.has(value)) {
432
+ return "[Circular]";
433
+ }
434
+ seen.add(value);
435
+ }
436
+ if (typeof value === "bigint") {
437
+ return value.toString();
438
+ }
439
+ if (value instanceof Date) {
440
+ return value.toISOString();
441
+ }
442
+ if (value instanceof Map) {
443
+ return Object.fromEntries(value);
444
+ }
445
+ if (value instanceof Set) {
446
+ return Array.from(value);
447
+ }
448
+ if (value instanceof Error) {
449
+ return {
450
+ name: value.name,
451
+ message: value.message,
452
+ stack: value.stack
453
+ };
454
+ }
455
+ if (typeof value === "undefined") {
456
+ return "undefined";
457
+ }
458
+ if (typeof value === "symbol") {
459
+ return value.toString();
460
+ }
461
+ return value;
462
+ });
463
+ } catch {
464
+ return "";
465
+ } finally {
466
+ seen.clear();
467
+ }
468
+ }
469
+ __name(safeStringify, "safeStringify");
470
+ function processLogParams(args) {
471
+ return args.map((arg) => {
472
+ if (typeof arg === "string") return arg;
473
+ if (arg instanceof Error) {
474
+ return `${arg.name}: ${arg.message}
475
+ ${arg.stack ?? ""}`;
476
+ }
477
+ if (typeof arg === "object" && arg !== null) {
478
+ return safeStringify(arg);
479
+ }
480
+ return String(arg);
481
+ });
482
+ }
483
+ __name(processLogParams, "processLogParams");
484
+ function mapLogLevel(level) {
485
+ if (level === "warn") return "WARN";
486
+ if (level === "error") return "ERROR";
487
+ return "INFO";
488
+ }
489
+ __name(mapLogLevel, "mapLogLevel");
490
+
491
+ // src/logger/selected-logs.ts
492
+ var import_stacktrace_js = __toESM(require("stacktrace-js"), 1);
493
+
494
+ // src/logger/batch-logger.ts
495
+ var BatchLogger = class {
496
+ static {
497
+ __name(this, "BatchLogger");
498
+ }
499
+ config;
500
+ logQueue = [];
501
+ flushTimer = null;
502
+ isProcessing = false;
503
+ originConsole;
504
+ constructor(console1, config2) {
505
+ this.originConsole = {
506
+ ...console1
507
+ };
508
+ const { userId = "", tenantId = "", appId = "" } = window || {};
509
+ this.config = {
510
+ userId,
511
+ tenantId,
512
+ appId,
513
+ // 需要加请求路径前缀
514
+ endpoint: (process.env.CLIENT_BASE_PATH || "") + "/dev/logs/collect-batch",
515
+ sizeThreshold: 20,
516
+ flushInterval: 1e3,
517
+ maxRetries: 3,
518
+ retryDelay: 500,
519
+ headers: {
520
+ "Content-Type": "application/json"
521
+ },
522
+ ...config2 || {}
523
+ };
524
+ this.startFlushTimer();
525
+ this.setupBeforeUnloadHandler();
526
+ }
527
+ /**
528
+ * 批量记录日志(对外暴露的唯一方法)
529
+ */
530
+ batchLog(level, message, source) {
531
+ const logEntry = {
532
+ id: this.generateId(),
533
+ level,
534
+ message,
535
+ source,
536
+ timestamp: Date.now()
537
+ };
538
+ this.logQueue.push(logEntry);
539
+ if (this.logQueue.length >= this.config.sizeThreshold) {
540
+ this.flush();
541
+ }
542
+ }
543
+ /**
544
+ * 刷新日志队列,全部发送
545
+ */
546
+ async flush() {
547
+ if (this.isProcessing || this.logQueue.length === 0) {
548
+ return;
549
+ }
550
+ this.isProcessing = true;
551
+ const logsToSend = this.logQueue.splice(0, this.logQueue.length);
552
+ try {
553
+ await this.sendBatch(logsToSend);
554
+ } catch (error) {
555
+ this.logQueue.unshift(...logsToSend);
556
+ } finally {
557
+ this.isProcessing = false;
558
+ }
559
+ }
560
+ /**
561
+ * 发送日志批次到后端
562
+ */
563
+ async sendBatch(logs) {
564
+ const collectLogs = logs.map((log) => ({
565
+ level: log.level,
566
+ message: log.message,
567
+ time: new Date(log.timestamp).toISOString(),
568
+ source: log.source,
569
+ user_id: this.config.userId,
570
+ tenant_id: this.config.tenantId,
571
+ app_id: this.config.appId
572
+ }));
573
+ let retries = 0;
574
+ while (retries <= this.config.maxRetries) {
575
+ try {
576
+ await this.execFetch(this.config.endpoint, {
577
+ method: "POST",
578
+ headers: this.config.headers,
579
+ body: JSON.stringify(collectLogs)
580
+ });
581
+ return;
582
+ } catch (error) {
583
+ retries++;
584
+ if (retries > this.config.maxRetries) {
585
+ this.originConsole.error(`Failed to send logs (attempt ${retries}), retrying in ${this.config.retryDelay}ms...`);
586
+ } else {
587
+ this.originConsole.warn(`Failed to send logs (attempt ${retries}), retrying in ${this.config.retryDelay}ms...`);
588
+ }
589
+ await this.delay(this.config.retryDelay * retries);
590
+ }
591
+ }
592
+ }
593
+ /**
594
+ * 执行实际的fetch请求
595
+ */
596
+ async execFetch(url, options) {
597
+ return fetch(url, options);
598
+ }
599
+ /**
600
+ * 启动自动刷新定时器
601
+ */
602
+ startFlushTimer() {
603
+ if (this.flushTimer) {
604
+ clearInterval(this.flushTimer);
605
+ }
606
+ this.flushTimer = setInterval(() => {
607
+ if (this.logQueue.length > 0) {
608
+ this.flush();
609
+ }
610
+ }, this.config.flushInterval);
611
+ }
612
+ /**
613
+ * 设置页面卸载时的处理
614
+ */
615
+ setupBeforeUnloadHandler() {
616
+ if (typeof window !== "undefined") {
617
+ window.addEventListener("beforeunload", () => {
618
+ this.flush().finally(() => {
619
+ this.destroy();
620
+ });
621
+ });
622
+ }
623
+ }
624
+ /**
625
+ * 延迟函数
626
+ */
627
+ delay(ms) {
628
+ return new Promise((resolve) => setTimeout(resolve, ms));
629
+ }
630
+ /**
631
+ * 生成唯一ID
632
+ */
633
+ generateId() {
634
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
635
+ }
636
+ /**
637
+ * 销毁资源
638
+ */
639
+ async destroy() {
640
+ if (this.flushTimer) {
641
+ clearInterval(this.flushTimer);
642
+ this.flushTimer = null;
643
+ }
644
+ if (this.logQueue.length > 0) {
645
+ await this.flush();
646
+ }
647
+ }
648
+ /**
649
+ * 获取队列大小
650
+ */
651
+ getQueueSize() {
652
+ return this.logQueue.length;
653
+ }
654
+ /**
655
+ * 更新配置
656
+ */
657
+ updateConfig(newConfig) {
658
+ this.config = {
659
+ ...this.config,
660
+ ...newConfig
661
+ };
662
+ this.startFlushTimer();
663
+ }
664
+ };
665
+ var defaultBatchLogger = null;
666
+ function batchLogInfo(level, message, source) {
667
+ if (!defaultBatchLogger) {
668
+ return;
669
+ }
670
+ defaultBatchLogger.batchLog(level, message, source);
671
+ }
672
+ __name(batchLogInfo, "batchLogInfo");
673
+ if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
674
+ defaultBatchLogger = new BatchLogger(console);
675
+ }
676
+
677
+ // src/logger/selected-logs.ts
678
+ function mapStacktrace(stacktrace) {
679
+ return stacktrace.map((frame) => ({
680
+ functionName: frame.functionName || "",
681
+ fileName: frame.fileName || "",
682
+ lineNumber: frame.lineNumber || 0,
683
+ columnNumber: frame.columnNumber || 0
684
+ }));
685
+ }
686
+ __name(mapStacktrace, "mapStacktrace");
687
+ function reportStacktraceParseError(e, context) {
688
+ if (window.parent === window) return;
689
+ try {
690
+ submitPostMessage({
691
+ type: "STACKTRACE_PARSE_ERROR",
692
+ payload: {
693
+ error: e instanceof Error ? e.message : String(e),
694
+ context
695
+ }
696
+ });
697
+ } catch {
698
+ }
699
+ }
700
+ __name(reportStacktraceParseError, "reportStacktraceParseError");
701
+ async function getStacktrace() {
702
+ const stacktrace = await import_stacktrace_js.default.get();
703
+ return mapStacktrace(stacktrace);
704
+ }
705
+ __name(getStacktrace, "getStacktrace");
706
+ function errorReplacer(_key, value) {
707
+ if (value instanceof Error) {
708
+ return {
709
+ message: value.message,
710
+ stack: value.stack,
711
+ name: value.name
712
+ };
713
+ }
714
+ return value;
715
+ }
716
+ __name(errorReplacer, "errorReplacer");
717
+ function generateLogId() {
718
+ try {
719
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
720
+ return crypto.randomUUID();
721
+ }
722
+ } catch {
723
+ }
724
+ return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
725
+ }
726
+ __name(generateLogId, "generateLogId");
727
+ var lastLogInfo = null;
728
+ async function sendSelectedLog(logWithoutID) {
729
+ try {
730
+ const log = {
731
+ ...logWithoutID,
732
+ id: generateLogId()
733
+ };
734
+ const newParts = [];
735
+ for (let i = 0; i < log.args.length; i++) {
736
+ const item = log.args[i];
737
+ if (item instanceof Error) {
738
+ const newError = {
739
+ message: item.message,
740
+ stack: item.stack,
741
+ name: item.name
742
+ };
743
+ if (!log.meta.stacktrace) {
744
+ try {
745
+ const stacktrace = await import_stacktrace_js.default.fromError(item);
746
+ log.meta.stacktrace = mapStacktrace(stacktrace);
747
+ } catch (e) {
748
+ reportStacktraceParseError(e, "StackTrace.fromError");
749
+ }
750
+ }
751
+ newParts.push(newError.message, newError);
752
+ } else {
753
+ newParts.push(item);
754
+ }
755
+ }
756
+ log.args = newParts;
757
+ if (!log.meta.stacktrace) {
758
+ try {
759
+ const frames = await getStacktrace();
760
+ const firstFrameIndex = frames.findIndex((frame) => !frame.fileName.includes("client-toolkit-lite/dist/logger"));
761
+ log.meta.stacktrace = firstFrameIndex === -1 ? [] : frames.slice(firstFrameIndex);
762
+ } catch (e) {
763
+ reportStacktraceParseError(e, "getStacktrace");
764
+ }
765
+ }
766
+ if (log.meta.skipFrame === void 0) {
767
+ log.meta.skipFrame = 2;
768
+ }
769
+ const logJSON = JSON.stringify(log, errorReplacer);
770
+ const logForDedup = {
771
+ ...log
772
+ };
773
+ delete logForDedup.id;
774
+ const logContentForDedup = JSON.stringify(logForDedup, errorReplacer);
775
+ if (lastLogInfo && lastLogInfo.content === logContentForDedup) {
776
+ lastLogInfo.count++;
777
+ log.meta.isDuplicate = true;
778
+ log.meta.duplicateCount = lastLogInfo.count;
779
+ log.meta.duplicateOfId = lastLogInfo.id;
780
+ const updatedJSON = JSON.stringify(log, errorReplacer);
781
+ try {
782
+ batchLogInfo("info", updatedJSON);
783
+ } catch {
784
+ }
785
+ if (window.parent !== window) {
786
+ try {
787
+ submitPostMessage({
788
+ type: "SELECTED_LOG",
789
+ payload: updatedJSON
790
+ });
791
+ } catch {
792
+ }
793
+ }
794
+ return;
795
+ }
796
+ lastLogInfo = {
797
+ content: logContentForDedup,
798
+ id: log.id,
799
+ count: 1
800
+ };
801
+ try {
802
+ batchLogInfo("info", logJSON);
803
+ } catch {
804
+ }
805
+ if (window.parent !== window) {
806
+ try {
807
+ submitPostMessage({
808
+ type: "SELECTED_LOG",
809
+ payload: logJSON
810
+ });
811
+ } catch {
812
+ }
813
+ }
814
+ } catch {
815
+ }
816
+ }
817
+ __name(sendSelectedLog, "sendSelectedLog");
818
+ function sendTypedLogV2(logWithMeta) {
819
+ void sendSelectedLog({
820
+ type: "typedLogV2",
821
+ level: logWithMeta.level,
822
+ args: logWithMeta.args,
823
+ meta: logWithMeta.meta ?? {}
824
+ });
825
+ }
826
+ __name(sendTypedLogV2, "sendTypedLogV2");
827
+ var typedLogInterceptor = /* @__PURE__ */ __name((originLogger) => ({
828
+ debug: /* @__PURE__ */ __name((message, ...args) => {
829
+ try {
830
+ originLogger.debug(message, ...args);
831
+ } catch {
832
+ }
833
+ sendTypedLogV2({
834
+ level: "info",
835
+ args: [
836
+ message,
837
+ ...args
838
+ ],
839
+ meta: {}
840
+ });
841
+ }, "debug"),
842
+ info: /* @__PURE__ */ __name((message, ...args) => {
843
+ try {
844
+ originLogger.info(message, ...args);
845
+ } catch {
846
+ }
847
+ sendTypedLogV2({
848
+ level: "info",
849
+ args: [
850
+ message,
851
+ ...args
852
+ ],
853
+ meta: {}
854
+ });
855
+ }, "info"),
856
+ warn: /* @__PURE__ */ __name((message, ...args) => {
857
+ try {
858
+ originLogger.warn(message, ...args);
859
+ } catch {
860
+ }
861
+ sendTypedLogV2({
862
+ level: "warn",
863
+ args: [
864
+ message,
865
+ ...args
866
+ ],
867
+ meta: {}
868
+ });
869
+ }, "warn"),
870
+ error: /* @__PURE__ */ __name((message, ...args) => {
871
+ try {
872
+ originLogger.error(message, ...args);
873
+ } catch {
874
+ }
875
+ sendTypedLogV2({
876
+ level: "error",
877
+ args: [
878
+ message,
879
+ ...args
880
+ ],
881
+ meta: {}
882
+ });
883
+ }, "error"),
884
+ success: /* @__PURE__ */ __name((message, ...args) => {
885
+ try {
886
+ originLogger.success(message, ...args);
887
+ } catch {
888
+ }
889
+ sendTypedLogV2({
890
+ level: "success",
891
+ args: [
892
+ message,
893
+ ...args
894
+ ],
895
+ meta: {}
896
+ });
897
+ }, "success"),
898
+ log: /* @__PURE__ */ __name(({ level, args, meta }) => {
899
+ try {
900
+ originLogger.log({
901
+ level,
902
+ args,
903
+ meta
904
+ });
905
+ } catch {
906
+ }
907
+ sendTypedLogV2({
908
+ level,
909
+ args,
910
+ meta: meta ?? {}
911
+ });
912
+ }, "log")
913
+ }), "typedLogInterceptor");
914
+ var interceptors = [
915
+ typedLogInterceptor
916
+ ];
917
+
918
+ // src/logger/logger.ts
919
+ var shouldReportToObservable = process.env.NODE_ENV === "production";
920
+ var ORDERED_LEVELS = [
921
+ "debug",
922
+ "info",
923
+ "warn",
924
+ "error"
925
+ ];
926
+ var defaultConfig = {
927
+ showLevel: false,
928
+ showTimestamp: false,
929
+ level: "info",
930
+ prefix: ""
931
+ };
932
+ var config = {
933
+ ...defaultConfig
934
+ };
935
+ function configureLogger(options) {
936
+ config = {
937
+ ...defaultConfig,
938
+ ...options
939
+ };
940
+ }
941
+ __name(configureLogger, "configureLogger");
942
+ function shouldLog(level) {
943
+ return ORDERED_LEVELS.indexOf(level) >= ORDERED_LEVELS.indexOf(config.level);
944
+ }
945
+ __name(shouldLog, "shouldLog");
946
+ function getFormattedPrefix(level) {
947
+ const parts = [];
948
+ if (config.prefix) {
949
+ parts.push(`[${config.prefix}]`);
950
+ }
951
+ if (config.showLevel) {
952
+ parts.push(`[${level.toUpperCase()}]`);
953
+ }
954
+ return parts;
955
+ }
956
+ __name(getFormattedPrefix, "getFormattedPrefix");
957
+ configureLogger({
958
+ showLevel: true,
959
+ showTimestamp: false,
960
+ level: process.env.NODE_ENV === "development" ? "debug" : "error",
961
+ prefix: "MiaoDa"
962
+ });
963
+ var logger = {
964
+ debug(message, ...args) {
965
+ if (shouldLog("debug")) {
966
+ console.log(...getFormattedPrefix("debug"), message, ...args);
967
+ }
968
+ },
969
+ info(message, ...args) {
970
+ if (shouldLog("info")) {
971
+ console.log(...getFormattedPrefix("info"), message, ...args);
972
+ }
973
+ if (shouldReportToObservable) {
974
+ import_observable_web.observable.log("INFO", processLogParams([
975
+ message,
976
+ ...args
977
+ ]).join(" "));
978
+ }
979
+ },
980
+ warn(message, ...args) {
981
+ if (shouldLog("warn")) {
982
+ console.log(...getFormattedPrefix("warn"), message, ...args);
983
+ }
984
+ if (shouldReportToObservable) {
985
+ import_observable_web.observable.log("WARN", processLogParams([
986
+ message,
987
+ ...args
988
+ ]).join(" "));
989
+ }
990
+ },
991
+ error(message, ...args) {
992
+ if (shouldLog("error")) {
993
+ console.error(...getFormattedPrefix("error"), message, ...args);
994
+ }
995
+ if (shouldReportToObservable) {
996
+ import_observable_web.observable.log("ERROR", processLogParams([
997
+ message,
998
+ ...args
999
+ ]).join(" "));
1000
+ }
1001
+ },
1002
+ success(message, ...args) {
1003
+ if (shouldLog("info")) {
1004
+ console.log(...getFormattedPrefix("success"), message, ...args);
1005
+ }
1006
+ if (shouldReportToObservable) {
1007
+ import_observable_web.observable.log("INFO", processLogParams([
1008
+ message,
1009
+ ...args
1010
+ ]).join(" "));
1011
+ }
1012
+ },
1013
+ log({ level, args }) {
1014
+ if (shouldLog(level)) {
1015
+ console.log(...getFormattedPrefix(level), ...args);
1016
+ }
1017
+ if (shouldReportToObservable && level !== "debug") {
1018
+ import_observable_web.observable.log(mapLogLevel(level), processLogParams(args).join(" "));
1019
+ }
1020
+ }
1021
+ };
1022
+ if (process.env.NODE_ENV !== "production") {
1023
+ window.__RUNTIME_LOGGER__ = {
1024
+ get() {
1025
+ return logger;
1026
+ }
1027
+ };
1028
+ }
1029
+ for (const interceptor of interceptors) {
1030
+ logger = interceptor(logger);
1031
+ }
1032
+ if (process.env.NODE_ENV !== "production") {
1033
+ interceptErrors();
1034
+ }
1035
+
1036
+ // src/runtime/iframe-bridge.ts
1037
+ var import_penpal = require("penpal");
1038
+
1039
+ // src/utils/utils.ts
1040
+ var import_clsx = require("clsx");
1041
+ var import_tailwind_merge = require("tailwind-merge");
1042
+ function clsxWithTw(...inputs) {
1043
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
1044
+ }
1045
+ __name(clsxWithTw, "clsxWithTw");
1046
+ function isPreview() {
1047
+ return window.IS_MIAODA_PREVIEW;
1048
+ }
1049
+ __name(isPreview, "isPreview");
1050
+ function normalizeBasePath(basePath) {
1051
+ if (!basePath || basePath === "/") {
1052
+ return "";
1053
+ }
1054
+ return basePath.replace(/\/+$/, "");
1055
+ }
1056
+ __name(normalizeBasePath, "normalizeBasePath");
1057
+ function getWsPath() {
1058
+ const rawBasePath = process.env.CLIENT_BASE_PATH || "/";
1059
+ const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
1060
+ const basePathWithoutTrailingSlash = normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
1061
+ return `${basePathWithoutTrailingSlash}/ws`;
1062
+ }
1063
+ __name(getWsPath, "getWsPath");
1064
+ function isSparkRuntime() {
1065
+ return window._IS_Spark_RUNTIME ?? process.env.runtimeMode === "fullstack";
1066
+ }
1067
+ __name(isSparkRuntime, "isSparkRuntime");
1068
+
1069
+ // src/components/AppContainer/utils/childApi.ts
1070
+ async function getRoutes() {
1071
+ let routes = [
1072
+ {
1073
+ path: "/"
1074
+ }
1075
+ ];
1076
+ try {
1077
+ const basePath = normalizeBasePath(process.env.CLIENT_BASE_PATH);
1078
+ const res = await fetch(`${basePath}/routes.json`);
1079
+ routes = await res.json();
1080
+ } catch (error) {
1081
+ console.warn("get routes.json error", error);
1082
+ }
1083
+ return routes;
1084
+ }
1085
+ __name(getRoutes, "getRoutes");
1086
+ var childApi = {
1087
+ getRoutes,
1088
+ updateAppInfo: /* @__PURE__ */ __name((appInfo) => {
1089
+ dispatchEvent(new CustomEvent("MiaoDaMetaInfoChanged", {
1090
+ detail: appInfo
1091
+ }));
1092
+ }, "updateAppInfo")
1093
+ };
1094
+
1095
+ // src/runtime/iframe-bridge.ts
1096
+ async function connectParent() {
1097
+ submitPostMessage({
1098
+ type: "PreviewReady",
1099
+ data: {}
1100
+ });
1101
+ batchLogInfo("info", JSON.stringify({
1102
+ type: "PreviewReady",
1103
+ timestamp: Date.now(),
1104
+ url: window.location.href
1105
+ }));
1106
+ const parentOrigin = resolveParentOrigin();
1107
+ if (!parentOrigin) return;
1108
+ const connection = (0, import_penpal.connectToParent)({
1109
+ parentOrigin,
1110
+ methods: {
1111
+ ...childApi
1112
+ }
145
1113
  });
1114
+ await connection.promise;
146
1115
  }
147
- __name(initAxiosConfig, "initAxiosConfig");
1116
+ __name(connectParent, "connectParent");
1117
+ function initIframeBridge() {
1118
+ if (window.parent === window) return;
1119
+ connectParent();
1120
+ }
1121
+ __name(initIframeBridge, "initIframeBridge");
148
1122
 
149
1123
  // src/runtime/index.ts
150
1124
  if (!window.__FULLSTACK_RUNTIME_INITIALIZED__) {
151
1125
  window.__FULLSTACK_RUNTIME_INITIALIZED__ = true;
152
1126
  initAxiosConfig();
1127
+ if (process.env.NODE_ENV !== "production") {
1128
+ initIframeBridge();
1129
+ }
153
1130
  }
154
1131
 
155
1132
  // src/components/AppContainer/safety.tsx
@@ -224,36 +1201,6 @@ function getInitialInfo(refresh = false) {
224
1201
  }
225
1202
  __name(getInitialInfo, "getInitialInfo");
226
1203
 
227
- // src/utils/utils.ts
228
- var import_clsx = require("clsx");
229
- var import_tailwind_merge = require("tailwind-merge");
230
- function clsxWithTw(...inputs) {
231
- return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
232
- }
233
- __name(clsxWithTw, "clsxWithTw");
234
- function isPreview() {
235
- return window.IS_MIAODA_PREVIEW;
236
- }
237
- __name(isPreview, "isPreview");
238
- function normalizeBasePath(basePath) {
239
- if (!basePath || basePath === "/") {
240
- return "";
241
- }
242
- return basePath.replace(/\/+$/, "");
243
- }
244
- __name(normalizeBasePath, "normalizeBasePath");
245
- function getWsPath() {
246
- const rawBasePath = process.env.CLIENT_BASE_PATH || "/";
247
- const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
248
- const basePathWithoutTrailingSlash = normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
249
- return `${basePathWithoutTrailingSlash}/ws`;
250
- }
251
- __name(getWsPath, "getWsPath");
252
- function isSparkRuntime() {
253
- return window._IS_Spark_RUNTIME ?? process.env.runtimeMode === "fullstack";
254
- }
255
- __name(isSparkRuntime, "isSparkRuntime");
256
-
257
1204
  // src/integrations/getAppInfo.ts
258
1205
  async function getAppInfo(refresh = false) {
259
1206
  let appInfo = typeof window !== "undefined" ? window._appInfo : void 0;
@@ -340,7 +1287,6 @@ var useAppInfo = /* @__PURE__ */ __name(() => {
340
1287
 
341
1288
  // src/hooks/useCurrentUserProfile.tsx
342
1289
  var import_react2 = require("react");
343
- var import_auth_sdk = require("@lark-apaas/auth-sdk");
344
1290
 
345
1291
  // src/integrations/getCurrentUserProfile.ts
346
1292
  function getCurrentUserProfile() {
@@ -348,6 +1294,69 @@ function getCurrentUserProfile() {
348
1294
  }
349
1295
  __name(getCurrentUserProfile, "getCurrentUserProfile");
350
1296
 
1297
+ // src/utils/url.ts
1298
+ function splitWorkspaceUrl(fullUrl) {
1299
+ try {
1300
+ const url = new URL(fullUrl);
1301
+ const pathParts = url.pathname.split("/");
1302
+ const workspacesIndex = pathParts.findIndex((part) => part === "workspaces");
1303
+ if (workspacesIndex === -1) {
1304
+ throw new Error("Invalid workspace URL format");
1305
+ }
1306
+ const basePathParts = pathParts.slice(0, workspacesIndex);
1307
+ const workspace = pathParts[workspacesIndex + 1];
1308
+ return {
1309
+ baseUrl: `${url.origin}${basePathParts.join("/")}`,
1310
+ workspace
1311
+ };
1312
+ } catch (error) {
1313
+ console.error("Error splitting workspace URL:", error);
1314
+ }
1315
+ return {
1316
+ baseUrl: fullUrl,
1317
+ // 兜底给一个,不要给空字符串,不然 createClient 都直接挂了,页面会白屏,体感不太好
1318
+ workspace: "workspace"
1319
+ };
1320
+ }
1321
+ __name(splitWorkspaceUrl, "splitWorkspaceUrl");
1322
+
1323
+ // src/integrations/dataloom.ts
1324
+ var import_dataloom = require("@lark-apaas/dataloom");
1325
+ var createDataLoomClient = /* @__PURE__ */ __name((url, pat) => {
1326
+ const { baseUrl } = url ? splitWorkspaceUrl(url) : {
1327
+ baseUrl: ""
1328
+ };
1329
+ const appId = getAppId() ?? "";
1330
+ return (0, import_dataloom.createClient)(baseUrl, pat ?? "", {
1331
+ global: {
1332
+ enableDataloomLog: process.env.NODE_ENV !== "production",
1333
+ requestRateLimit: process.env.NODE_ENV !== "production" ? 100 : void 0,
1334
+ brandName: "miaoda",
1335
+ appId
1336
+ }
1337
+ });
1338
+ }, "createDataLoomClient");
1339
+ var dataloom = null;
1340
+ var pendingPromise2 = null;
1341
+ function getDataloom() {
1342
+ if (dataloom) {
1343
+ return Promise.resolve(dataloom);
1344
+ }
1345
+ if (pendingPromise2) {
1346
+ return pendingPromise2;
1347
+ }
1348
+ pendingPromise2 = getInitialInfo().then((info) => {
1349
+ const DATALOOM_CLIENT_URL = info?.app_runtime_extra?.url;
1350
+ const DATALOOM_PAT = info?.app_runtime_extra?.token;
1351
+ dataloom = createDataLoomClient(DATALOOM_CLIENT_URL, DATALOOM_PAT);
1352
+ return dataloom;
1353
+ }).finally(() => {
1354
+ pendingPromise2 = null;
1355
+ });
1356
+ return pendingPromise2;
1357
+ }
1358
+ __name(getDataloom, "getDataloom");
1359
+
351
1360
  // src/hooks/useCurrentUserProfile.tsx
352
1361
  function getNameFromArray(nameArray) {
353
1362
  if (!nameArray || nameArray.length === 0) {
@@ -372,7 +1381,8 @@ var useCurrentUserProfile = /* @__PURE__ */ __name(() => {
372
1381
  (0, import_react2.useEffect)(() => {
373
1382
  let cancelled = false;
374
1383
  const fetchAndSetUserInfo = /* @__PURE__ */ __name(async () => {
375
- const result = await import_auth_sdk.authClient.session.getUserInfo();
1384
+ const dataloom2 = await getDataloom();
1385
+ const result = await dataloom2?.service?.session?.getUserInfo();
376
1386
  if (cancelled) return;
377
1387
  const info = result?.data?.user_info;
378
1388
  const userName = getNameFromArray(info?.name);
@@ -436,7 +1446,6 @@ __name(useIsMobile, "useIsMobile");
436
1446
 
437
1447
  // src/hooks/useLogout.ts
438
1448
  var import_react4 = require("react");
439
- var import_auth_sdk2 = require("@lark-apaas/auth-sdk");
440
1449
  function useLogout() {
441
1450
  const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
442
1451
  async function handlerLogout() {
@@ -446,7 +1455,8 @@ function useLogout() {
446
1455
  }
447
1456
  setIsLoading(true);
448
1457
  try {
449
- await import_auth_sdk2.authClient.session.signOut();
1458
+ const dataloom2 = await getDataloom();
1459
+ await dataloom2.service.session.signOut();
450
1460
  } catch (error) {
451
1461
  console.error("\u767B\u51FA\u5931\u8D25", error);
452
1462
  } finally {
@@ -1073,6 +2083,92 @@ var QueryProvider = /* @__PURE__ */ __name(({ children, client }) => {
1073
2083
  }, "QueryProvider");
1074
2084
  var QueryProvider_default = QueryProvider;
1075
2085
 
2086
+ // src/components/AppContainer/IframeBridge.tsx
2087
+ var import_react8 = require("react");
2088
+ var import_react_router_dom = require("react-router-dom");
2089
+
2090
+ // src/hooks/useUpdatingRef.ts
2091
+ var import_react7 = require("react");
2092
+ function useUpdatingRef(value) {
2093
+ const ref = (0, import_react7.useRef)(value);
2094
+ ref.current = value;
2095
+ return ref;
2096
+ }
2097
+ __name(useUpdatingRef, "useUpdatingRef");
2098
+
2099
+ // src/components/AppContainer/IframeBridge.tsx
2100
+ var RouteMessageType = /* @__PURE__ */ (function(RouteMessageType2) {
2101
+ RouteMessageType2["RouteChange"] = "RouteChange";
2102
+ RouteMessageType2["RouteBack"] = "RouteBack";
2103
+ RouteMessageType2["RouteForward"] = "RouteForward";
2104
+ return RouteMessageType2;
2105
+ })(RouteMessageType || {});
2106
+ function isRouteMessageType(type) {
2107
+ return Object.values(RouteMessageType).includes(type);
2108
+ }
2109
+ __name(isRouteMessageType, "isRouteMessageType");
2110
+ function IframeBridge() {
2111
+ const location = (0, import_react_router_dom.useLocation)();
2112
+ const navigate = (0, import_react_router_dom.useNavigate)();
2113
+ const navigateRef = useUpdatingRef(navigate);
2114
+ const isActive = (0, import_react8.useRef)(false);
2115
+ const historyBack = (0, import_react8.useCallback)((_payload) => {
2116
+ navigateRef.current(-1);
2117
+ isActive.current = true;
2118
+ }, [
2119
+ navigateRef
2120
+ ]);
2121
+ const historyForward = (0, import_react8.useCallback)((_payload) => {
2122
+ navigateRef.current(1);
2123
+ isActive.current = true;
2124
+ }, [
2125
+ navigateRef
2126
+ ]);
2127
+ const operatorMessage = (0, import_react8.useMemo)(() => ({
2128
+ ["RouteBack"]: historyBack,
2129
+ ["RouteForward"]: historyForward,
2130
+ ["RouteChange"]: navigateRef.current
2131
+ }), [
2132
+ historyBack,
2133
+ historyForward,
2134
+ navigateRef
2135
+ ]);
2136
+ (0, import_react8.useEffect)(() => {
2137
+ if (isActive.current) {
2138
+ isActive.current = false;
2139
+ return;
2140
+ }
2141
+ submitPostMessage({
2142
+ type: "ChildLocationChange",
2143
+ data: location
2144
+ });
2145
+ }, [
2146
+ location
2147
+ ]);
2148
+ const handleMessage = (0, import_react8.useCallback)((event) => {
2149
+ const data = event.data ?? {};
2150
+ if (typeof data.type === "string" && isRouteMessageType(data.type)) {
2151
+ operatorMessage[data.type](data.data);
2152
+ }
2153
+ }, [
2154
+ operatorMessage
2155
+ ]);
2156
+ (0, import_react8.useEffect)(() => {
2157
+ window.addEventListener("message", handleMessage);
2158
+ return () => {
2159
+ window.removeEventListener("message", handleMessage);
2160
+ };
2161
+ }, [
2162
+ handleMessage
2163
+ ]);
2164
+ return /* @__PURE__ */ (0, import_react8.createElement)("div", {
2165
+ style: {
2166
+ display: "none"
2167
+ }
2168
+ });
2169
+ }
2170
+ __name(IframeBridge, "IframeBridge");
2171
+
1076
2172
  // src/components/AppContainer/utils/tea.ts
1077
2173
  var import_blueimp_md5 = __toESM(require("blueimp-md5"), 1);
1078
2174
  var import_sha1 = __toESM(require("crypto-js/sha1"), 1);
@@ -1184,6 +2280,31 @@ var reportTeaEvent = /* @__PURE__ */ __name(async ({ trackKey, trackParams = {}
1184
2280
  }
1185
2281
  }, "reportTeaEvent");
1186
2282
 
2283
+ // src/components/AppContainer/utils/observable.ts
2284
+ var import_observable_web2 = require("@lark-apaas/observable-web");
2285
+ var initObservable = /* @__PURE__ */ __name(() => {
2286
+ try {
2287
+ const appId = window.appId;
2288
+ import_observable_web2.observable.start({
2289
+ serviceName: "app",
2290
+ env: process.env.NODE_ENV === "development" ? import_observable_web2.AppEnv.Dev : import_observable_web2.AppEnv.Prod,
2291
+ collectorUrl: isNewPathEnabled() ? {
2292
+ log: `/app/${appId}/__runtime__/api/v1/observability/logs/collect`,
2293
+ trace: `/app/${appId}/__runtime__/api/v1/observability/traces/collect`,
2294
+ metric: `/app/${appId}/__runtime__/api/v1/observability/metrics/collect`,
2295
+ time: `/app/${appId}/__runtime__/api/v1/observability/current_server_timestamp`
2296
+ } : {
2297
+ log: `/spark/app/${appId}/runtime/api/v1/observability/logs/collect`,
2298
+ trace: `/spark/app/${appId}/runtime/api/v1/observability/traces/collect`,
2299
+ metric: `/spark/app/${appId}/runtime/api/v1/observability/metrics/collect`,
2300
+ time: `/spark/api/v1/observability/app/${appId}/current_server_timestamp`
2301
+ }
2302
+ });
2303
+ } catch (error) {
2304
+ console.error("Failed to start WebObservableSdk:", error);
2305
+ }
2306
+ }, "initObservable");
2307
+
1187
2308
  // src/types/tea.ts
1188
2309
  var TrackKey = /* @__PURE__ */ (function(TrackKey2) {
1189
2310
  TrackKey2["VIEW"] = "aily_agent_artifact_page_view";
@@ -1193,7 +2314,10 @@ var TrackKey = /* @__PURE__ */ (function(TrackKey2) {
1193
2314
  // src/components/AppContainer/index.tsx
1194
2315
  var AppContainer = /* @__PURE__ */ __name(({ children }) => {
1195
2316
  useAppInfo();
1196
- (0, import_react7.useEffect)(() => {
2317
+ (0, import_react9.useEffect)(() => {
2318
+ initObservable();
2319
+ }, []);
2320
+ (0, import_react9.useEffect)(() => {
1197
2321
  if (process.env.NODE_ENV === "production") {
1198
2322
  reportTeaEvent({
1199
2323
  trackKey: TrackKey.VIEW,
@@ -1205,14 +2329,14 @@ var AppContainer = /* @__PURE__ */ __name(({ children }) => {
1205
2329
  });
1206
2330
  }
1207
2331
  }, []);
1208
- return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement(safety_default, null), /* @__PURE__ */ import_react7.default.createElement(QueryProvider_default, null, children));
2332
+ return /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, /* @__PURE__ */ import_react9.default.createElement(safety_default, null), process.env.NODE_ENV !== "production" && /* @__PURE__ */ import_react9.default.createElement(import_miaoda_inspector.MiaodaInspector, null), process.env.NODE_ENV !== "production" && /* @__PURE__ */ import_react9.default.createElement(IframeBridge, null), /* @__PURE__ */ import_react9.default.createElement(QueryProvider_default, null, children));
1209
2333
  }, "AppContainer");
1210
2334
  var AppContainer_default = AppContainer;
1211
2335
 
1212
2336
  // src/components/Welcome/index.tsx
1213
- var import_react8 = __toESM(require("react"), 1);
2337
+ var import_react10 = __toESM(require("react"), 1);
1214
2338
  var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1", description = "\u9875\u9762\u6682\u672A\u5F00\u53D1\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85..." }) => {
1215
- return /* @__PURE__ */ import_react8.default.createElement("div", {
2339
+ return /* @__PURE__ */ import_react10.default.createElement("div", {
1216
2340
  style: {
1217
2341
  display: "flex",
1218
2342
  flexDirection: "column",
@@ -1223,7 +2347,7 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1223
2347
  padding: "0 24px",
1224
2348
  textAlign: "center"
1225
2349
  }
1226
- }, /* @__PURE__ */ import_react8.default.createElement("img", {
2350
+ }, /* @__PURE__ */ import_react10.default.createElement("img", {
1227
2351
  style: {
1228
2352
  borderRadius: 6,
1229
2353
  marginBottom: 24
@@ -1232,7 +2356,7 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1232
2356
  height: "200",
1233
2357
  src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/LMfspH/ljhwZthlaukjlkulzlp/miao/welcome.svg",
1234
2358
  alt: "Welcome"
1235
- }), /* @__PURE__ */ import_react8.default.createElement("div", {
2359
+ }), /* @__PURE__ */ import_react10.default.createElement("div", {
1236
2360
  style: {
1237
2361
  fontSize: 16,
1238
2362
  fontWeight: 500,
@@ -1240,7 +2364,7 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1240
2364
  marginBottom: 4,
1241
2365
  color: "#1f2329"
1242
2366
  }
1243
- }, title), /* @__PURE__ */ import_react8.default.createElement("div", {
2367
+ }, title), /* @__PURE__ */ import_react10.default.createElement("div", {
1244
2368
  style: {
1245
2369
  fontSize: 16,
1246
2370
  lineHeight: "24px",
@@ -1252,9 +2376,9 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1252
2376
  var Welcome_default = Welcome;
1253
2377
 
1254
2378
  // src/components/PagePlaceholder/index.tsx
1255
- var import_react9 = __toESM(require("react"), 1);
2379
+ var import_react11 = __toESM(require("react"), 1);
1256
2380
  var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1", description = "\u9875\u9762\u6682\u672A\u5F00\u53D1\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85..." }) => {
1257
- return /* @__PURE__ */ import_react9.default.createElement("div", {
2381
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
1258
2382
  style: {
1259
2383
  display: "flex",
1260
2384
  flexDirection: "column",
@@ -1265,7 +2389,7 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
1265
2389
  height: "calc(100vh - 64px)",
1266
2390
  textAlign: "center"
1267
2391
  }
1268
- }, /* @__PURE__ */ import_react9.default.createElement("img", {
2392
+ }, /* @__PURE__ */ import_react11.default.createElement("img", {
1269
2393
  style: {
1270
2394
  borderRadius: "6px",
1271
2395
  marginBottom: "24px"
@@ -1274,14 +2398,14 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
1274
2398
  height: "200",
1275
2399
  src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/LMfspH/ljhwZthlaukjlkulzlp/miao/welcome.svg",
1276
2400
  alt: "Welcome"
1277
- }), /* @__PURE__ */ import_react9.default.createElement("div", {
2401
+ }), /* @__PURE__ */ import_react11.default.createElement("div", {
1278
2402
  style: {
1279
2403
  fontSize: "16px",
1280
2404
  fontWeight: 500,
1281
2405
  marginBottom: "4px",
1282
2406
  lineHeight: "24px"
1283
2407
  }
1284
- }, title), /* @__PURE__ */ import_react9.default.createElement("div", {
2408
+ }, title), /* @__PURE__ */ import_react11.default.createElement("div", {
1285
2409
  style: {
1286
2410
  color: "#6b7280",
1287
2411
  fontSize: "16px",
@@ -1296,13 +2420,67 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
1296
2420
  }, "PagePlaceholder");
1297
2421
  var PagePlaceholder_default = PagePlaceholder;
1298
2422
 
2423
+ // src/components/ErrorRender/index.tsx
2424
+ var import_react12 = __toESM(require("react"), 1);
2425
+ var ErrorRender = /* @__PURE__ */ __name((props) => {
2426
+ const { error, resetErrorBoundary } = props;
2427
+ (0, import_react12.useEffect)(() => {
2428
+ if (error) {
2429
+ submitPostMessage({
2430
+ type: "RenderError",
2431
+ data: error
2432
+ });
2433
+ logger.log({
2434
+ level: "error",
2435
+ args: [
2436
+ "Render Error",
2437
+ error
2438
+ ],
2439
+ meta: {
2440
+ type: "render-error",
2441
+ repairMessage: "\u9875\u9762\u6E32\u67D3\u65F6\u62A5\u9519\uFF0C\u8BF7\u6839\u636E\u9519\u8BEF\u4FE1\u606F\u4FEE\u590D\u5BF9\u5E94\u9875\u9762\u7684\u4EE3\u7801"
2442
+ }
2443
+ });
2444
+ }
2445
+ }, [
2446
+ error
2447
+ ]);
2448
+ (0, import_react12.useEffect)(() => {
2449
+ if (!resetErrorBoundary) return;
2450
+ const hmr = getHmrApi();
2451
+ if (!hmr) return;
2452
+ return hmr.onSuccess(() => {
2453
+ const isVite = typeof window !== "undefined" && Boolean(window.__VITE_HMR__);
2454
+ if (isVite) {
2455
+ window.location.reload();
2456
+ } else {
2457
+ resetErrorBoundary();
2458
+ }
2459
+ });
2460
+ }, [
2461
+ resetErrorBoundary
2462
+ ]);
2463
+ return /* @__PURE__ */ import_react12.default.createElement("div", {
2464
+ className: "min-h-screen flex items-center justify-center bg-white"
2465
+ }, /* @__PURE__ */ import_react12.default.createElement("div", {
2466
+ className: "flex flex-col justify-center items-center text-center"
2467
+ }, /* @__PURE__ */ import_react12.default.createElement("img", {
2468
+ src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/ylcylz_fsph_ryhs/ljhwZthlaukjlkulzlp/feisuda/template/illustration_empty_negative_error.svg",
2469
+ alt: "render error",
2470
+ className: "mb-3 w-[100px]"
2471
+ }), /* @__PURE__ */ import_react12.default.createElement("p", {
2472
+ className: "text-l/[22px] text-[14px] text-[#1F2329] font-medium"
2473
+ }, "\u9875\u9762\u51FA\u9519\u4E86")));
2474
+ }, "ErrorRender");
2475
+ var ErrorRender_default = ErrorRender;
2476
+
1299
2477
  // src/route-components/ActiveLink.tsx
1300
- var import_react10 = __toESM(require("react"), 1);
1301
- var import_react_router_dom = require("react-router-dom");
1302
- var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick, className, style, children, ...rest }, ref) => {
1303
- const [currentHash, setCurrentHash] = (0, import_react10.useState)(() => typeof window !== "undefined" ? window.location.hash : "");
2478
+ var import_react13 = __toESM(require("react"), 1);
2479
+ var import_react_router_dom2 = require("react-router-dom");
2480
+ var ActiveLink = /* @__PURE__ */ (0, import_react13.forwardRef)(({ to, onClick, className, style, children, ...rest }, ref) => {
2481
+ const [currentHash, setCurrentHash] = (0, import_react13.useState)(() => typeof window !== "undefined" ? window.location.hash : "");
1304
2482
  const isHashRoute = typeof to === "string" && to.startsWith("#");
1305
- (0, import_react10.useEffect)(() => {
2483
+ (0, import_react13.useEffect)(() => {
1306
2484
  if (!isHashRoute) return;
1307
2485
  const handleHashChange = /* @__PURE__ */ __name(() => {
1308
2486
  setCurrentHash(window.location.hash);
@@ -1314,7 +2492,7 @@ var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick,
1314
2492
  ]);
1315
2493
  const isActive = isHashRoute && currentHash === to;
1316
2494
  if (!isHashRoute) {
1317
- return /* @__PURE__ */ import_react10.default.createElement(import_react_router_dom.NavLink, {
2495
+ return /* @__PURE__ */ import_react13.default.createElement(import_react_router_dom2.NavLink, {
1318
2496
  ref,
1319
2497
  to,
1320
2498
  onClick,
@@ -1355,7 +2533,7 @@ var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick,
1355
2533
  isPending: false,
1356
2534
  isTransitioning: false
1357
2535
  }) : children;
1358
- return /* @__PURE__ */ import_react10.default.createElement("a", {
2536
+ return /* @__PURE__ */ import_react13.default.createElement("a", {
1359
2537
  ref,
1360
2538
  href: to,
1361
2539
  onClick: handleHashClick,
@@ -1367,12 +2545,12 @@ var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick,
1367
2545
  ActiveLink.displayName = "ActiveLink";
1368
2546
 
1369
2547
  // src/route-components/NavLink.tsx
1370
- var React8 = __toESM(require("react"), 1);
1371
- var import_react_router_dom2 = require("react-router-dom");
1372
- var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, style, ...props }, ref) => {
2548
+ var React9 = __toESM(require("react"), 1);
2549
+ var import_react_router_dom3 = require("react-router-dom");
2550
+ var NavLink2 = /* @__PURE__ */ React9.forwardRef(({ to, children, className, style, ...props }, ref) => {
1373
2551
  const isHashLink = typeof to === "string" && to.startsWith("#");
1374
- const location = (0, import_react_router_dom2.useLocation)();
1375
- const navigate = (0, import_react_router_dom2.useNavigate)();
2552
+ const location = (0, import_react_router_dom3.useLocation)();
2553
+ const navigate = (0, import_react_router_dom3.useNavigate)();
1376
2554
  if (isHashLink) {
1377
2555
  const handleClick = /* @__PURE__ */ __name((e) => {
1378
2556
  e.preventDefault();
@@ -1393,7 +2571,7 @@ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, sty
1393
2571
  const resolvedClassName = typeof className === "function" ? className(renderProps) : className;
1394
2572
  const resolvedStyle = typeof style === "function" ? style(renderProps) : style;
1395
2573
  const { caseSensitive, end, replace, state, preventScrollReset, relative, viewTransition, ...restProps } = props;
1396
- return /* @__PURE__ */ React8.createElement("a", {
2574
+ return /* @__PURE__ */ React9.createElement("a", {
1397
2575
  href: to,
1398
2576
  onClick: handleClick,
1399
2577
  ref,
@@ -1402,7 +2580,7 @@ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, sty
1402
2580
  ...restProps
1403
2581
  }, typeof children === "function" ? children(renderProps) : children);
1404
2582
  }
1405
- return /* @__PURE__ */ React8.createElement(import_react_router_dom2.NavLink, {
2583
+ return /* @__PURE__ */ React9.createElement(import_react_router_dom3.NavLink, {
1406
2584
  to,
1407
2585
  ref,
1408
2586
  className,
@@ -1417,8 +2595,8 @@ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, sty
1417
2595
  NavLink2.displayName = "NavLink";
1418
2596
 
1419
2597
  // src/route-components/UniversalLink.tsx
1420
- var import_react11 = __toESM(require("react"), 1);
1421
- var import_react_router_dom3 = require("react-router-dom");
2598
+ var import_react14 = __toESM(require("react"), 1);
2599
+ var import_react_router_dom4 = require("react-router-dom");
1422
2600
  function isInternalRoute(to) {
1423
2601
  return !to.startsWith("#") && !to.startsWith("http://") && !to.startsWith("https://") && !to.startsWith("//");
1424
2602
  }
@@ -1427,15 +2605,15 @@ function isExternalLink(to) {
1427
2605
  return to.startsWith("http://") || to.startsWith("https://") || to.startsWith("//");
1428
2606
  }
1429
2607
  __name(isExternalLink, "isExternalLink");
1430
- var UniversalLink = /* @__PURE__ */ import_react11.default.forwardRef(/* @__PURE__ */ __name(function UniversalLink2({ to, ...props }, ref) {
2608
+ var UniversalLink = /* @__PURE__ */ import_react14.default.forwardRef(/* @__PURE__ */ __name(function UniversalLink2({ to, ...props }, ref) {
1431
2609
  if (isInternalRoute(to)) {
1432
- return /* @__PURE__ */ import_react11.default.createElement(import_react_router_dom3.Link, {
2610
+ return /* @__PURE__ */ import_react14.default.createElement(import_react_router_dom4.Link, {
1433
2611
  to,
1434
2612
  ref,
1435
2613
  ...props
1436
2614
  });
1437
2615
  }
1438
- return /* @__PURE__ */ import_react11.default.createElement("a", {
2616
+ return /* @__PURE__ */ import_react14.default.createElement("a", {
1439
2617
  href: to,
1440
2618
  ref,
1441
2619
  ...props,
@@ -1581,45 +2759,6 @@ function getEnvPath() {
1581
2759
  }
1582
2760
  __name(getEnvPath, "getEnvPath");
1583
2761
 
1584
- // src/utils/safeStringify.ts
1585
- function safeStringify(obj) {
1586
- const seen = /* @__PURE__ */ new Set();
1587
- try {
1588
- return JSON.stringify(obj, (_key, value) => {
1589
- if (typeof value === "object" && value !== null) {
1590
- if (seen.has(value)) {
1591
- return "[Circular]";
1592
- }
1593
- seen.add(value);
1594
- }
1595
- if (typeof value === "bigint") {
1596
- return value.toString();
1597
- }
1598
- if (value instanceof Date) {
1599
- return value.toISOString();
1600
- }
1601
- if (value instanceof Map) {
1602
- return Object.fromEntries(value);
1603
- }
1604
- if (value instanceof Set) {
1605
- return Array.from(value);
1606
- }
1607
- if (typeof value === "undefined") {
1608
- return "undefined";
1609
- }
1610
- if (typeof value === "symbol") {
1611
- return value.toString();
1612
- }
1613
- return value;
1614
- });
1615
- } catch {
1616
- return "";
1617
- } finally {
1618
- seen.clear();
1619
- }
1620
- }
1621
- __name(safeStringify, "safeStringify");
1622
-
1623
2762
  // src/utils/getAxiosForBackend.ts
1624
2763
  var import_axios2 = __toESM(require("axios"), 1);
1625
2764
  var axiosInstance;
@@ -1699,73 +2838,26 @@ function getAxiosForBackend() {
1699
2838
  __name(getAxiosForBackend, "getAxiosForBackend");
1700
2839
  var axiosForBackend = getAxiosForBackend();
1701
2840
 
1702
- // src/utils/url.ts
1703
- function splitWorkspaceUrl(fullUrl) {
1704
- try {
1705
- const url = new URL(fullUrl);
1706
- const pathParts = url.pathname.split("/");
1707
- const workspacesIndex = pathParts.findIndex((part) => part === "workspaces");
1708
- if (workspacesIndex === -1) {
1709
- throw new Error("Invalid workspace URL format");
1710
- }
1711
- const basePathParts = pathParts.slice(0, workspacesIndex);
1712
- const workspace = pathParts[workspacesIndex + 1];
1713
- return {
1714
- baseUrl: `${url.origin}${basePathParts.join("/")}`,
1715
- workspace
1716
- };
1717
- } catch (error) {
1718
- console.error("Error splitting workspace URL:", error);
1719
- }
1720
- return {
1721
- baseUrl: fullUrl,
1722
- // 兜底给一个,不要给空字符串,不然 createClient 都直接挂了,页面会白屏,体感不太好
1723
- workspace: "workspace"
1724
- };
1725
- }
1726
- __name(splitWorkspaceUrl, "splitWorkspaceUrl");
1727
-
1728
- // src/integrations/dataloom.ts
1729
- var import_dataloom = require("@lark-apaas/dataloom");
1730
- var import_auth_sdk3 = require("@lark-apaas/auth-sdk");
1731
- var createDataLoomClient = /* @__PURE__ */ __name((url, pat) => {
1732
- const { baseUrl } = url ? splitWorkspaceUrl(url) : {
1733
- baseUrl: ""
1734
- };
1735
- const appId = getAppId() ?? "";
1736
- return (0, import_dataloom.createClient)(baseUrl, pat ?? "", {
1737
- global: {
1738
- enableDataloomLog: process.env.NODE_ENV !== "production",
1739
- requestRateLimit: process.env.NODE_ENV !== "production" ? 100 : void 0,
1740
- brandName: "miaoda",
1741
- appId,
1742
- accountServices: {
1743
- user: import_auth_sdk3.authClient.user,
1744
- session: import_auth_sdk3.authClient.session
1745
- }
2841
+ // src/integrations/capabilityClient.ts
2842
+ var import_client_capability = require("@lark-apaas/client-capability");
2843
+ var _appId = getAppId();
2844
+ var _acquireUploadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_upload_url` : `/af/api/v1/studio/plugins/tmp_files/acquire_upload_url`;
2845
+ var _acquireDownloadUrl = isNewPathEnabled() ? `/app/${_appId}/__runtime__/api/v1/studio/plugins/tmp_files/acquire_download_url` : `/af/api/v1/studio/plugins/tmp_files/acquire_download_url`;
2846
+ var capabilityClient = (0, import_client_capability.createClient)({
2847
+ baseURL: normalizeBasePath(process.env.CLIENT_BASE_PATH ?? "/"),
2848
+ acquireUploadUrl: _acquireUploadUrl,
2849
+ acquireDownloadUrl: _acquireDownloadUrl,
2850
+ fetchOptions: {
2851
+ headers: {
2852
+ "X-Suda-Csrf-Token": window.csrfToken ?? ""
1746
2853
  }
1747
- });
1748
- }, "createDataLoomClient");
1749
- var dataloom = null;
1750
- var pendingPromise2 = null;
1751
- function getDataloom() {
1752
- if (dataloom) {
1753
- return Promise.resolve(dataloom);
1754
- }
1755
- if (pendingPromise2) {
1756
- return pendingPromise2;
2854
+ },
2855
+ central: {
2856
+ enabled: true,
2857
+ // window.appId 由妙搭沙箱 / 线上环境注入;非妙搭场景下 capability 调用本身不可用
2858
+ appId: _appId ?? ""
1757
2859
  }
1758
- pendingPromise2 = getInitialInfo().then((info) => {
1759
- const DATALOOM_CLIENT_URL = info?.app_runtime_extra?.url;
1760
- const DATALOOM_PAT = info?.app_runtime_extra?.token;
1761
- dataloom = createDataLoomClient(DATALOOM_CLIENT_URL, DATALOOM_PAT);
1762
- return dataloom;
1763
- }).finally(() => {
1764
- pendingPromise2 = null;
1765
- });
1766
- return pendingPromise2;
1767
- }
1768
- __name(getDataloom, "getDataloom");
2860
+ });
1769
2861
 
1770
2862
  // src/constants/img-resources/avatar.ts
1771
2863
  var avatar_exports = {};
@@ -1927,6 +3019,7 @@ var abstractArt3dRenderingCoverImg6 = "https://lf3-static.bytednsdoc.com/obj/ede
1927
3019
  0 && (module.exports = {
1928
3020
  ActiveLink,
1929
3021
  AppContainer,
3022
+ ErrorRender,
1930
3023
  NavLink,
1931
3024
  PagePlaceholder,
1932
3025
  QueryProvider,
@@ -1936,6 +3029,7 @@ var abstractArt3dRenderingCoverImg6 = "https://lf3-static.bytednsdoc.com/obj/ede
1936
3029
  avatarImages,
1937
3030
  axiosForBackend,
1938
3031
  bannerImages,
3032
+ capabilityClient,
1939
3033
  clsxWithTw,
1940
3034
  copyToClipboard,
1941
3035
  coverImages,
@@ -1952,6 +3046,7 @@ var abstractArt3dRenderingCoverImg6 = "https://lf3-static.bytednsdoc.com/obj/ede
1952
3046
  isIpad,
1953
3047
  isMobile,
1954
3048
  isPreview,
3049
+ logger,
1955
3050
  normalizeBasePath,
1956
3051
  reportTeaEvent,
1957
3052
  resolveAppUrl,