@visactor/vseed 0.5.0 → 0.5.1

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.
Files changed (60) hide show
  1. package/dist/cjs/index.cjs +2 -2
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/esm/builder/builder/advanced/colorItems.d.ts +1 -0
  4. package/dist/esm/builder/builder/advanced/colorItems.js +21 -1
  5. package/dist/esm/builder/builder/advanced/colorItems.js.map +1 -1
  6. package/dist/esm/builder/builder/buildSpec.js.map +1 -1
  7. package/dist/esm/builder/builder/builder.d.ts +4 -0
  8. package/dist/esm/builder/builder/builder.js +2 -1
  9. package/dist/esm/builder/builder/builder.js.map +1 -1
  10. package/dist/esm/dataSelector/selector.js.map +1 -1
  11. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationArea.js +2 -2
  12. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationArea.js.map +1 -1
  13. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationAreaBand.js +2 -2
  14. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationAreaBand.js.map +1 -1
  15. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationDifferenceLine.js +63 -18
  16. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationDifferenceLine.js.map +1 -1
  17. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationHorizontalLine.js +7 -13
  18. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationHorizontalLine.js.map +1 -1
  19. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationPointCommon.js +2 -2
  20. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationPointCommon.js.map +1 -1
  21. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationVerticalLine.js +9 -15
  22. package/dist/esm/pipeline/spec/chart/pipes/annotation/annotationVerticalLine.js.map +1 -1
  23. package/dist/esm/pipeline/spec/chart/pipes/annotation/utils.d.ts +2 -0
  24. package/dist/esm/pipeline/spec/chart/pipes/annotation/utils.js +15 -1
  25. package/dist/esm/pipeline/spec/chart/pipes/annotation/utils.js.map +1 -1
  26. package/dist/esm/pipeline/utils/sandbox/execute.js.map +1 -1
  27. package/dist/esm/theme/tokenTheme.d.ts +6 -0
  28. package/dist/esm/theme/tokenTheme.js +36 -7
  29. package/dist/esm/theme/tokenTheme.js.map +1 -1
  30. package/dist/esm/types/builder/builder.d.ts +1 -0
  31. package/dist/esm/types/builder/builder.js.map +1 -1
  32. package/dist/esm/types/chartType/area/zArea.d.ts +10 -0
  33. package/dist/esm/types/chartType/bar/zBar.d.ts +10 -0
  34. package/dist/esm/types/chartType/barParallel/zBarParallel.d.ts +10 -0
  35. package/dist/esm/types/chartType/column/zColumn.d.ts +10 -0
  36. package/dist/esm/types/chartType/columnParallel/zColumnParallel.d.ts +10 -0
  37. package/dist/esm/types/chartType/line/zLine.d.ts +10 -0
  38. package/dist/esm/types/properties/annotation/annotation.d.ts +10 -0
  39. package/dist/esm/types/properties/annotation/annotationDifferenceLine.d.ts +4 -0
  40. package/dist/esm/types/properties/annotation/zAnnotationDifferenceLine.d.ts +5 -0
  41. package/dist/esm/types/properties/annotation/zAnnotationDifferenceLine.js +6 -1
  42. package/dist/esm/types/properties/annotation/zAnnotationDifferenceLine.js.map +1 -1
  43. package/dist/esm/types/properties/config/annotation/annotation.d.ts +32 -5
  44. package/dist/esm/types/properties/config/annotation/zAnnotation.d.ts +30 -4
  45. package/dist/esm/types/properties/config/annotation/zAnnotation.js +11 -1
  46. package/dist/esm/types/properties/config/annotation/zAnnotation.js.map +1 -1
  47. package/dist/esm/types/properties/config/area.d.ts +30 -4
  48. package/dist/esm/types/properties/config/bar.d.ts +45 -6
  49. package/dist/esm/types/properties/config/boxplot.d.ts +15 -2
  50. package/dist/esm/types/properties/config/column.d.ts +45 -6
  51. package/dist/esm/types/properties/config/config.d.ts +285 -38
  52. package/dist/esm/types/properties/config/dualAxis.d.ts +15 -2
  53. package/dist/esm/types/properties/config/histogram.d.ts +15 -2
  54. package/dist/esm/types/properties/config/line.d.ts +15 -2
  55. package/dist/esm/types/properties/config/race.d.ts +90 -12
  56. package/dist/esm/types/properties/config/scatter.d.ts +15 -2
  57. package/dist/esm/types/properties/theme/customTheme.d.ts +570 -76
  58. package/dist/umd/index.js +248 -134
  59. package/dist/umd/index.js.map +1 -1
  60. package/package.json +3 -8
@@ -1,4 +1,6 @@
1
1
  import type { Datum, ValueDynamicFilter } from '../../../../../types';
2
+ export type AnnotationLineStyle = 'solid' | 'dashed' | 'dotted';
3
+ export declare const getAnnotationLineDash: (lineStyle?: AnnotationLineStyle | null, lineDash?: number[] | null) => number[];
2
4
  export declare const isSubset: (sub: Datum, obj: Datum, excludeMeasuresIds?: string[]) => boolean;
3
5
  export declare const ANNOTATION_AREA_TEXT_STYLE_BY_POSITION: {
4
6
  top: {
@@ -1,3 +1,17 @@
1
+ const getAnnotationLineDash = (lineStyle, lineDash)=>{
2
+ if (Array.isArray(lineDash)) return lineDash;
3
+ if ('dashed' === lineStyle) return [
4
+ 2,
5
+ 2
6
+ ];
7
+ if ('dotted' === lineStyle) return [
8
+ 2,
9
+ 5
10
+ ];
11
+ return [
12
+ 0
13
+ ];
14
+ };
1
15
  const isSubset = (sub, obj, excludeMeasuresIds)=>Object.entries(sub).every(([key, value])=>{
2
16
  if (excludeMeasuresIds && excludeMeasuresIds.includes(key)) return false;
3
17
  if ('string' == typeof value) return obj[key] === value;
@@ -44,6 +58,6 @@ const resolveAnnotationValue = (options)=>{
44
58
  if (void 0 !== fallback) return fallback;
45
59
  return defaultValue;
46
60
  };
47
- export { ANNOTATION_AREA_TEXT_STYLE_BY_POSITION, isSubset, resolveAnnotationValue };
61
+ export { ANNOTATION_AREA_TEXT_STYLE_BY_POSITION, getAnnotationLineDash, isSubset, resolveAnnotationValue };
48
62
 
49
63
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline/spec/chart/pipes/annotation/utils.js","sources":["../../../../../../../src/pipeline/spec/chart/pipes/annotation/utils.ts"],"sourcesContent":["import type { Datum, ValueDynamicFilter } from 'src/types'\n\nexport const isSubset = (sub: Datum, obj: Datum, excludeMeasuresIds?: string[]) => {\n return Object.entries(sub).every(([key, value]) => {\n if (excludeMeasuresIds && excludeMeasuresIds.includes(key)) {\n return false\n }\n\n if (typeof value === 'string') {\n return obj[key] === value\n }\n if (typeof value === 'number') {\n return obj[key] === value\n }\n return true\n })\n}\n\nexport const ANNOTATION_AREA_TEXT_STYLE_BY_POSITION = {\n top: {\n textAlign: 'center',\n textBaseline: 'top',\n },\n topRight: {\n textAlign: 'right',\n textBaseline: 'top',\n },\n topLeft: {\n textAlign: 'left',\n textBaseline: 'top',\n },\n bottom: {\n textAlign: 'center',\n textBaseline: 'bottom',\n },\n bottomLeft: {\n textAlign: 'left',\n textBaseline: 'bottom',\n },\n bottomRight: {\n textAlign: 'right',\n textBaseline: 'bottom',\n },\n left: {\n textAlign: 'left',\n textBaseline: 'middle',\n },\n right: {\n textAlign: 'right',\n textBaseline: 'middle',\n },\n}\n\n/**\n * 解析标注线的值,优先级:dynamicFilter (success=true) > fallback > defaultValue\n */\nexport const resolveAnnotationValue = (options: {\n dynamicFilter?: ValueDynamicFilter\n fallback?: string | number\n defaultValue?: any\n}): (string | number) | (string | number)[] | undefined => {\n const { dynamicFilter, fallback, defaultValue } = options\n\n // 优先使用 dynamicFilter\n if (dynamicFilter?.result?.success && dynamicFilter.result.data !== undefined) {\n return dynamicFilter.result.data\n }\n\n // 其次使用 fallback\n if (fallback !== undefined) {\n return fallback\n }\n\n // 最后使用原始的 defaultValue\n return defaultValue\n}\n"],"names":["isSubset","sub","obj","excludeMeasuresIds","Object","key","value","ANNOTATION_AREA_TEXT_STYLE_BY_POSITION","resolveAnnotationValue","options","dynamicFilter","fallback","defaultValue","undefined"],"mappings":"AAEO,MAAMA,WAAW,CAACC,KAAYC,KAAYC,qBACxCC,OAAO,OAAO,CAACH,KAAK,KAAK,CAAC,CAAC,CAACI,KAAKC,MAAM;QAC5C,IAAIH,sBAAsBA,mBAAmB,QAAQ,CAACE,MACpD,OAAO;QAGT,IAAI,AAAiB,YAAjB,OAAOC,OACT,OAAOJ,GAAG,CAACG,IAAI,KAAKC;QAEtB,IAAI,AAAiB,YAAjB,OAAOA,OACT,OAAOJ,GAAG,CAACG,IAAI,KAAKC;QAEtB,OAAO;IACT;AAGK,MAAMC,yCAAyC;IACpD,KAAK;QACH,WAAW;QACX,cAAc;IAChB;IACA,UAAU;QACR,WAAW;QACX,cAAc;IAChB;IACA,SAAS;QACP,WAAW;QACX,cAAc;IAChB;IACA,QAAQ;QACN,WAAW;QACX,cAAc;IAChB;IACA,YAAY;QACV,WAAW;QACX,cAAc;IAChB;IACA,aAAa;QACX,WAAW;QACX,cAAc;IAChB;IACA,MAAM;QACJ,WAAW;QACX,cAAc;IAChB;IACA,OAAO;QACL,WAAW;QACX,cAAc;IAChB;AACF;AAKO,MAAMC,yBAAyB,CAACC;IAKrC,MAAM,EAAEC,aAAa,EAAEC,QAAQ,EAAEC,YAAY,EAAE,GAAGH;IAGlD,IAAIC,eAAe,QAAQ,WAAWA,AAA8BG,WAA9BH,cAAc,MAAM,CAAC,IAAI,EAC7D,OAAOA,cAAc,MAAM,CAAC,IAAI;IAIlC,IAAIC,AAAaE,WAAbF,UACF,OAAOA;IAIT,OAAOC;AACT"}
1
+ {"version":3,"file":"pipeline/spec/chart/pipes/annotation/utils.js","sources":["../../../../../../../src/pipeline/spec/chart/pipes/annotation/utils.ts"],"sourcesContent":["import type { Datum, ValueDynamicFilter } from 'src/types'\n\nexport type AnnotationLineStyle = 'solid' | 'dashed' | 'dotted'\n\nexport const getAnnotationLineDash = (lineStyle?: AnnotationLineStyle | null, lineDash?: number[] | null) => {\n if (Array.isArray(lineDash)) {\n return lineDash\n }\n\n if (lineStyle === 'dashed') {\n return [2, 2]\n }\n\n if (lineStyle === 'dotted') {\n return [2, 5]\n }\n\n return [0]\n}\n\nexport const isSubset = (sub: Datum, obj: Datum, excludeMeasuresIds?: string[]) => {\n return Object.entries(sub).every(([key, value]) => {\n if (excludeMeasuresIds && excludeMeasuresIds.includes(key)) {\n return false\n }\n\n if (typeof value === 'string') {\n return obj[key] === value\n }\n if (typeof value === 'number') {\n return obj[key] === value\n }\n return true\n })\n}\n\nexport const ANNOTATION_AREA_TEXT_STYLE_BY_POSITION = {\n top: {\n textAlign: 'center',\n textBaseline: 'top',\n },\n topRight: {\n textAlign: 'right',\n textBaseline: 'top',\n },\n topLeft: {\n textAlign: 'left',\n textBaseline: 'top',\n },\n bottom: {\n textAlign: 'center',\n textBaseline: 'bottom',\n },\n bottomLeft: {\n textAlign: 'left',\n textBaseline: 'bottom',\n },\n bottomRight: {\n textAlign: 'right',\n textBaseline: 'bottom',\n },\n left: {\n textAlign: 'left',\n textBaseline: 'middle',\n },\n right: {\n textAlign: 'right',\n textBaseline: 'middle',\n },\n}\n\n/**\n * 解析标注线的值,优先级:dynamicFilter (success=true) > fallback > defaultValue\n */\nexport const resolveAnnotationValue = (options: {\n dynamicFilter?: ValueDynamicFilter\n fallback?: string | number\n defaultValue?: any\n}): (string | number) | (string | number)[] | undefined => {\n const { dynamicFilter, fallback, defaultValue } = options\n\n // 优先使用 dynamicFilter\n if (dynamicFilter?.result?.success && dynamicFilter.result.data !== undefined) {\n return dynamicFilter.result.data\n }\n\n // 其次使用 fallback\n if (fallback !== undefined) {\n return fallback\n }\n\n // 最后使用原始的 defaultValue\n return defaultValue\n}\n"],"names":["getAnnotationLineDash","lineStyle","lineDash","Array","isSubset","sub","obj","excludeMeasuresIds","Object","key","value","ANNOTATION_AREA_TEXT_STYLE_BY_POSITION","resolveAnnotationValue","options","dynamicFilter","fallback","defaultValue","undefined"],"mappings":"AAIO,MAAMA,wBAAwB,CAACC,WAAwCC;IAC5E,IAAIC,MAAM,OAAO,CAACD,WAChB,OAAOA;IAGT,IAAID,AAAc,aAAdA,WACF,OAAO;QAAC;QAAG;KAAE;IAGf,IAAIA,AAAc,aAAdA,WACF,OAAO;QAAC;QAAG;KAAE;IAGf,OAAO;QAAC;KAAE;AACZ;AAEO,MAAMG,WAAW,CAACC,KAAYC,KAAYC,qBACxCC,OAAO,OAAO,CAACH,KAAK,KAAK,CAAC,CAAC,CAACI,KAAKC,MAAM;QAC5C,IAAIH,sBAAsBA,mBAAmB,QAAQ,CAACE,MACpD,OAAO;QAGT,IAAI,AAAiB,YAAjB,OAAOC,OACT,OAAOJ,GAAG,CAACG,IAAI,KAAKC;QAEtB,IAAI,AAAiB,YAAjB,OAAOA,OACT,OAAOJ,GAAG,CAACG,IAAI,KAAKC;QAEtB,OAAO;IACT;AAGK,MAAMC,yCAAyC;IACpD,KAAK;QACH,WAAW;QACX,cAAc;IAChB;IACA,UAAU;QACR,WAAW;QACX,cAAc;IAChB;IACA,SAAS;QACP,WAAW;QACX,cAAc;IAChB;IACA,QAAQ;QACN,WAAW;QACX,cAAc;IAChB;IACA,YAAY;QACV,WAAW;QACX,cAAc;IAChB;IACA,aAAa;QACX,WAAW;QACX,cAAc;IAChB;IACA,MAAM;QACJ,WAAW;QACX,cAAc;IAChB;IACA,OAAO;QACL,WAAW;QACX,cAAc;IAChB;AACF;AAKO,MAAMC,yBAAyB,CAACC;IAKrC,MAAM,EAAEC,aAAa,EAAEC,QAAQ,EAAEC,YAAY,EAAE,GAAGH;IAGlD,IAAIC,eAAe,QAAQ,WAAWA,AAA8BG,WAA9BH,cAAc,MAAM,CAAC,IAAI,EAC7D,OAAOA,cAAc,MAAM,CAAC,IAAI;IAIlC,IAAIC,AAAaE,WAAbF,UACF,OAAOA;IAIT,OAAOC;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline/utils/sandbox/execute.js","sources":["../../../../../src/pipeline/utils/sandbox/execute.ts"],"sourcesContent":["/* eslint-disable no-console */\n/**\n * 增强的安全代码执行器\n * @description 专为 AI 生成代码设计的安全沙箱\n * @module enhancedSecureCodeExecutor\n */\n\nimport type { CodeExecutionOptions, CodeExecutionResult } from 'src/types/sandbox'\nimport { BUILTIN_UTILS_SOURCE } from './builtin-utils'\n\n/**\n * Worker 池管理器\n * @description 复用 Worker 实例,避免重复创建开销\n */\nclass WorkerPool {\n private workers: Worker[] = []\n private availableWorkers: Worker[] = []\n private readonly maxSize: number\n private isInitialized = false\n\n constructor(maxSize = 2) {\n this.maxSize = maxSize\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) return\n\n for (let i = 0; i < this.maxSize; i++) {\n try {\n const worker = await this.createSecureWorker()\n this.workers.push(worker)\n this.availableWorkers.push(worker)\n } catch (error) {\n // 某个 Worker 初始化失败时,清理已创建的 Worker\n this.workers.forEach((w) => w.terminate())\n this.workers = []\n this.availableWorkers = []\n throw new Error(`Failed to initialize Worker pool: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n this.isInitialized = true\n }\n\n private createSecureWorker(): Promise<Worker> {\n // 直接使用内置工具库\n const libraryLoadCode = `// 内置工具库(lodash/Ramda 兼容 API)\\n${BUILTIN_UTILS_SOURCE}`\n\n const workerCode = `\n // ============================================\n // 阶段 1: 立即执行安全加固 (IIFE)\n // ============================================\n (function initSecureSandbox() {\n 'use strict';\n \n // 1.1 保存必要的原生引用(在被删除前)\n const nativeImportScripts = self.importScripts;\n const nativePostMessage = self.postMessage.bind(self);\n \n // 1.2 立即删除危险 API\n delete self.importScripts;\n delete self.fetch;\n delete self.XMLHttpRequest;\n delete self.WebSocket;\n \n // 1.3 冻结关键原型链(防止污染和篡改)\n Object.freeze(Object.prototype);\n Object.freeze(Array.prototype);\n Object.freeze(Function.prototype);\n Object.freeze(String.prototype);\n Object.freeze(Number.prototype);\n Object.freeze(Boolean.prototype);\n \n // ============================================\n // 阶段 2: 加载工具库\n // ============================================\n try {\n ${libraryLoadCode}\n } catch (error) {\n nativePostMessage({ \n initError: 'Failed to load utility library: ' + error.message \n });\n return;\n }\n \n // 验证库是否加载成功\n const utilityLib = self._;\n if (!utilityLib) {\n nativePostMessage({ \n initError: 'Builtin utility library (_ or R) not found after loading' \n });\n return;\n }\n \n // ============================================\n // 阶段 3: 创建安全上下文\n // ============================================\n const createSafeContext = (lib) => {\n const allowedGlobals = {\n // 工具库\n _: lib,\n R: lib,\n \n // 基础类型构造函数(只读)\n Array: Array,\n Object: Object,\n String: String,\n Number: Number,\n Boolean: Boolean,\n Date: Date,\n \n // 数学和工具\n Math: Math,\n JSON: JSON,\n \n // 类型检查\n parseInt: parseInt,\n parseFloat: parseFloat,\n isNaN: isNaN,\n isFinite: isFinite,\n \n // 错误类型(用于调试)\n Error: Error,\n TypeError: TypeError,\n RangeError: RangeError,\n \n // 只读的数据引用\n data: null,\n };\n \n // 使用 Proxy 严格控制访问\n return new Proxy(allowedGlobals, {\n get(target, prop) {\n if (prop === Symbol.unscopables) {\n return undefined;\n }\n \n if (prop in target) {\n return target[prop];\n }\n \n // 拒绝访问任何未定义的属性\n throw new ReferenceError(\n \\`'\\${String(prop)}' is not defined. \\\\n\\` +\n \\`Only these globals are available: \\${Object.keys(allowedGlobals).join(', ')}\\`\n );\n },\n \n set(target, prop, value) {\n // 只允许设置 data 属性(用于传递执行数据)\n if (prop === 'data') {\n target[prop] = value;\n return true;\n }\n \n // 拒绝设置其他属性\n throw new TypeError(\n \\`Cannot set property '\\${String(prop)}' on global context\\`\n );\n },\n \n has(target, prop) {\n return prop in target;\n },\n \n // 防止 getOwnPropertyDescriptor 等元编程操作\n getOwnPropertyDescriptor(target, prop) {\n if (prop in target) {\n return Object.getOwnPropertyDescriptor(target, prop);\n }\n return undefined;\n }\n });\n };\n \n const safeContext = createSafeContext(utilityLib);\n \n // ============================================\n // 阶段 4: 代码执行引擎\n // ============================================\n const executeUserCodeSafely = (code, data, timeout) => {\n // 设置超时保护(内层防御)\n let timeoutId = null;\n let isTimedOut = false;\n \n if (timeout > 0) {\n timeoutId = setTimeout(() => {\n isTimedOut = true;\n }, timeout);\n }\n \n try {\n // 超时检查函数\n // ⚠️ 注意:这只能防御\"合作式\"的代码(包含 I/O、迭代、递归)\n // 对于纯计算死循环(while(true){}),只有外层 worker.terminate() 能终止\n const checkTimeout = () => {\n if (isTimedOut) {\n throw new Error(\\`Execution timeout (exceeded \\${timeout}ms)\\`);\n }\n };\n \n // 更新安全上下文中的数据\n safeContext.data = data;\n \n // 提取安全上下文的所有变量名和值\n const contextKeys = Object.keys(safeContext);\n const contextValues = contextKeys.map(key => safeContext[key]);\n \n // 显式遮蔽 Worker 全局对象中的危险变量(设为 undefined)\n const shadowedGlobals = [\n 'self', // Worker 全局对象本身\n 'postMessage', // 通信通道(防止滥用)\n 'close', // Worker 终止方法\n 'importScripts', // 动态加载脚本(已删除,但显式遮蔽更安全)\n 'addEventListener', // 事件监听器\n 'removeEventListener',\n 'dispatchEvent',\n 'onmessage', // 消息处理器\n 'onerror', // 错误处理器\n 'onmessageerror',\n 'setTimeout', // ⚠️ 遮蔽定时器,防止资源泄漏\n 'clearTimeout',\n 'setInterval', // ⚠️ 防止用户创建大量定时器\n 'clearInterval',\n ];\n \n // 包装用户代码:在严格模式下执行,通过参数注入变量\n const wrappedCode = \\`\n \"use strict\";\n // 用户代码在这里执行,可以直接访问注入的变量(_, R, data, Math, etc.)\n \\${code}\n \\`;\n \n // 创建函数:参数是上下文变量名 + checkTimeout + 遮蔽的全局变量名\n const userFunction = new Function(\n ...contextKeys, // 安全上下文变量\n 'checkTimeout', // 超时检查函数(用户可选调用)\n ...shadowedGlobals, // 显式遮蔽的危险全局变量\n wrappedCode\n );\n \n // 执行并获取结果\n const result = userFunction(\n ...contextValues, // 安全上下文的值\n checkTimeout, // 超时检查函数\n ...shadowedGlobals.map(() => undefined) // 所有危险全局变量设为 undefined\n );\n \n // 清除超时\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n \n // 验证返回值(只检查危险类型,不限制结构)\n const validateResultType = (result) => {\n const type = typeof result\n \n // 禁止返回函数、Symbol\n if (type === 'function' || type === 'symbol') {\n throw new TypeError(\n \\`Code must not return \\${type}. Returned types must be serializable.\\`\n );\n }\n \n // 禁止返回 Promise\n if (result && typeof result.then === 'function') {\n throw new TypeError(\n \\`Code must not return a Promise. Async operations are not allowed.\\`\n );\n }\n \n // 如果是数组,检查元素的危险类型\n if (Array.isArray(result)) {\n for (let i = 0; i < result.length; i++) {\n const item = result[i];\n const itemType = typeof item;\n \n if (itemType === 'function' || itemType === 'symbol') {\n throw new TypeError(\n \\`Array element at index \\${i} has forbidden type: \\${itemType}\\`\n );\n }\n \n if (item && typeof item.then === 'function') {\n throw new TypeError(\n \\`Array element at index \\${i} is a Promise. Async operations are not allowed.\\`\n );\n }\n }\n }\n };\n \n validateResultType(result);\n \n return result;\n \n } catch (error) {\n throw error;\n } finally {\n // 清理数据引用(防止内存泄漏)\n safeContext.data = null;\n }\n };\n \n // ============================================\n // 阶段 5: 消息处理\n // ============================================\n self.onmessage = function(event) {\n // ⚠️ 防御性检查:确保消息格式正确\n if (!event || !event.data) {\n nativePostMessage({ \n taskId: 'unknown',\n success: false,\n error: 'Invalid message format: event.data is null or undefined'\n });\n return;\n }\n \n const { code, data, timeout, taskId } = event.data;\n \n // 验证必需字段\n if (!taskId) {\n nativePostMessage({ \n taskId: 'unknown',\n success: false,\n error: 'Invalid message: taskId is required'\n });\n return;\n }\n \n try {\n const result = executeUserCodeSafely(code, data, timeout);\n \n nativePostMessage({ \n taskId,\n success: true,\n result: result \n });\n \n } catch (error) {\n nativePostMessage({ \n taskId,\n success: false,\n error: error.message || String(error),\n errorType: error.constructor.name\n });\n }\n };\n \n // 错误捕获\n self.onerror = function(event) {\n nativePostMessage({ \n globalError: event.message || 'Unknown worker error'\n });\n };\n \n // 发送初始化成功消息\n nativePostMessage({ initialized: true });\n \n })(); // 立即执行\n `\n\n const blob = new Blob([workerCode], { type: 'application/javascript' })\n const blobURL = URL.createObjectURL(blob)\n\n const worker = new Worker(blobURL)\n\n // Worker 构造函数同步加载脚本,立即回收 Blob URL 防止内存泄漏\n URL.revokeObjectURL(blobURL)\n\n // 等待初始化消息\n return new Promise<Worker>((resolve, reject) => {\n let isSettled = false\n\n const cleanup = () => {\n if (!isSettled) {\n isSettled = true\n worker.onmessage = null // ⚠️ 清理监听器防止内存泄漏\n worker.onerror = null\n }\n }\n\n const timeout = setTimeout(() => {\n cleanup()\n worker.terminate()\n reject(new Error('Worker initialization timeout'))\n }, 10000)\n\n worker.onmessage = (e) => {\n if (e.data.initialized) {\n clearTimeout(timeout)\n cleanup()\n resolve(worker)\n } else if (e.data.initError) {\n clearTimeout(timeout)\n cleanup()\n worker.terminate()\n reject(new Error(e.data.initError))\n }\n }\n\n worker.onerror = (errorEvent: ErrorEvent) => {\n clearTimeout(timeout)\n cleanup()\n worker.terminate()\n const errorMessage = errorEvent.message || errorEvent.error?.message || 'Unknown worker initialization error'\n reject(new Error(`Worker initialization failed: ${errorMessage}`))\n }\n })\n }\n\n async acquire(): Promise<Worker> {\n if (!this.isInitialized) {\n await this.initialize()\n }\n\n if (this.availableWorkers.length === 0) {\n // 创建临时 Worker 时需要等待初始化完成\n try {\n const tempWorker = await this.createSecureWorker()\n return tempWorker\n } catch (error) {\n throw new Error(`Failed to create temporary Worker: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n return this.availableWorkers.pop()!\n }\n\n release(worker: Worker): void {\n if (this.workers.includes(worker)) {\n this.availableWorkers.push(worker)\n } else {\n // 临时创建的 Worker,直接终止\n worker.terminate()\n }\n }\n\n terminate(): void {\n this.workers.forEach((worker) => worker.terminate())\n this.workers = []\n this.availableWorkers = []\n this.isInitialized = false\n }\n}\n\n// 全局 Worker 池实例\nlet globalWorkerPool: WorkerPool | null = null\n// 添加初始化锁,防止并发创建多个 pool\nlet poolInitPromise: Promise<WorkerPool> | null = null\n// Worker 池配置\nlet poolConfig = { poolSize: 2 }\n\n/**\n * 获取或创建全局 Worker 池(线程安全)\n */\nfunction getOrCreateWorkerPool(): Promise<WorkerPool> {\n if (globalWorkerPool) {\n return Promise.resolve(globalWorkerPool)\n }\n\n // 如果已经在初始化中,等待现有的初始化完成\n if (poolInitPromise) {\n return poolInitPromise\n }\n\n // 创建新的 pool 并初始化\n poolInitPromise = (async () => {\n try {\n const pool = new WorkerPool(poolConfig.poolSize)\n await pool.initialize()\n globalWorkerPool = pool\n return pool\n } catch (error) {\n // 重置 promise,允许下次重试\n poolInitPromise = null\n throw error\n }\n })()\n\n return poolInitPromise\n}\n\n/**\n * 初始化 Worker 池\n * @description 预热 Worker 实例,提升首次执行性能\n *\n * **⚠️ 注意:这是一个可选的性能优化方法**\n *\n * - **懒加载模式**:如果不调用此方法,Worker 池会在首次使用时自动初始化\n * - **推荐场景**:应用启动时预热,避免首次筛选时的冷启动延迟\n * - **配置选项**:\n * - `poolSize`: Worker 池大小(默认 2)\n *\n * @param options - 初始化选项\n * @param options.poolSize - Worker 池大小,默认为 2\n *\n * @example\n * ```typescript\n * // ✅ 推荐:应用启动时预热(可选)\n * import { initializeWorkerPool } from '@visactor/vseed'\n *\n * // 在 main.ts 或入口文件中\n * await initializeWorkerPool({ poolSize: 2 })\n *\n * // ✅ 也可以:不做任何事,让 Worker 池自动初始化\n * // 首次调用 dynamicFilter 时会自动创建\n * ```\n */\nexport async function initializeWorkerPool(\n options: {\n utilityLibUrl?: string\n utilityLibSource?: string\n poolSize?: number\n } = {},\n): Promise<void> {\n // 设置配置(必须在创建 pool 之前)\n poolConfig = {\n poolSize: options.poolSize ?? 2,\n }\n\n // 使用统一的 getOrCreateWorkerPool 确保状态一致\n await getOrCreateWorkerPool()\n}\n\n/**\n * 销毁 Worker 池\n * @description 终止所有 Worker 实例并清理全局状态\n *\n * **⚠️ 注意:大多数情况下不需要手动调用此方法**\n *\n * - **一般使用**:浏览器会在页面卸载时自动清理 Worker 资源\n * - **建议场景**:\n * - 单元测试的清理阶段(`afterAll` 钩子)\n * - 开发环境热重载时清理旧实例\n * - 动态卸载整个图表库模块(极少见)\n *\n * @example\n * ```typescript\n * // ✅ 推荐:测试环境\n * afterAll(() => {\n * terminateWorkerPool()\n * })\n *\n * // ❌ 不推荐:组件卸载时(Worker 池是全局的,其他组件可能还在使用)\n * onUnmounted(() => {\n * terminateWorkerPool() // 不要这样做!\n * })\n * ```\n */\nexport function terminateWorkerPool(): void {\n if (globalWorkerPool) {\n globalWorkerPool.terminate()\n globalWorkerPool = null\n }\n // 重置初始化 Promise,避免状态不一致\n poolInitPromise = null\n}\n\n/**\n * 增强的安全验证\n * @description 针对 AI 生成代码的特定模式检查\n */\nexport function validateCodeSafety(code: string): void {\n // 1. 基础检查\n if (!code || code.trim().length === 0) {\n throw new Error('Code cannot be empty')\n }\n\n if (code.length > 50000) {\n throw new Error('Code is too long (max 50KB)')\n }\n\n // 2. 必须包含 return\n if (!/\\breturn\\b/.test(code)) {\n throw new Error('Code must contain a return statement')\n }\n\n // 3. 增强的黑名单检查\n const forbiddenPatterns = [\n // 原有的基础黑名单\n { pattern: /\\beval\\b/gi, description: 'eval()' },\n { pattern: /\\bFunction\\s*\\(/gi, description: 'Function constructor' },\n { pattern: /\\bnew\\s+Function\\b/gi, description: 'new Function()' },\n { pattern: /\\bimportScripts\\b/gi, description: 'importScripts()' },\n { pattern: /\\bfetch\\b/gi, description: 'fetch()' },\n { pattern: /\\bXMLHttpRequest\\b/gi, description: 'XMLHttpRequest' },\n { pattern: /\\bWebSocket\\b/gi, description: 'WebSocket' },\n { pattern: /\\blocalStorage\\b/gi, description: 'localStorage' },\n { pattern: /\\bsessionStorage\\b/gi, description: 'sessionStorage' },\n { pattern: /\\bindexedDB\\b/gi, description: 'indexedDB' },\n { pattern: /\\bwindow\\b/gi, description: 'window' },\n { pattern: /\\bdocument\\b/gi, description: 'document' },\n { pattern: /\\bnavigator\\b/gi, description: 'navigator' },\n { pattern: /\\blocation\\b/gi, description: 'location' },\n { pattern: /\\brequire\\b/gi, description: 'require()' },\n { pattern: /\\bimport\\s+/gi, description: 'import statement' },\n { pattern: /\\bexport\\s+/gi, description: 'export statement' },\n\n // 增强:Constructor 访问(绕过检测的常见方式)\n { pattern: /\\bconstructor\\b/gi, description: 'constructor access' },\n { pattern: /\\[['\"]constructor['\"]\\]/gi, description: 'constructor via bracket notation' },\n { pattern: /\\['constructor'\\]/gi, description: 'constructor string access' },\n\n // 增强:原型链操作\n { pattern: /\\b__proto__\\b/gi, description: '__proto__' },\n { pattern: /\\bprototype\\b/gi, description: 'prototype manipulation' },\n { pattern: /Object\\.setPrototypeOf/gi, description: 'Object.setPrototypeOf()' },\n { pattern: /Object\\.getPrototypeOf/gi, description: 'Object.getPrototypeOf()' },\n { pattern: /Object\\.create\\s*\\(\\s*null\\s*\\)/gi, description: 'Object.create(null)' },\n\n // 增强:反射和元编程\n { pattern: /\\bReflect\\./gi, description: 'Reflect API' },\n { pattern: /\\bProxy\\b/gi, description: 'Proxy constructor' },\n\n // 增强:全局对象访问\n { pattern: /\\bglobal\\b/gi, description: 'global object' },\n { pattern: /\\bglobalThis\\b/gi, description: 'globalThis' },\n { pattern: /\\bself\\s*\\[/gi, description: 'self[] access' },\n { pattern: /\\bthis\\s*\\.\\s*constructor/gi, description: 'this.constructor' },\n\n // 增强:异步操作(容易被滥用)\n { pattern: /\\basync\\s+function/gi, description: 'async function' },\n { pattern: /\\bawait\\b/gi, description: 'await keyword' },\n { pattern: /\\bnew\\s+Promise\\b/gi, description: 'new Promise()' },\n { pattern: /\\.then\\s*\\(/gi, description: 'Promise.then()' },\n\n // 增强:生成器(可能导致难以控制的执行)\n { pattern: /\\bfunction\\s*\\*/gi, description: 'generator function' },\n { pattern: /\\byield\\b/gi, description: 'yield keyword' },\n\n // 增强:动态代码生成\n { pattern: /\\.apply\\s*\\(/gi, description: 'Function.apply()' },\n { pattern: /\\.call\\s*\\(/gi, description: 'Function.call()' },\n { pattern: /\\.bind\\s*\\(/gi, description: 'Function.bind()' },\n\n // 增强:Worker 相关\n { pattern: /\\bWorker\\b/gi, description: 'Worker constructor' },\n { pattern: /\\bSharedWorker\\b/gi, description: 'SharedWorker' },\n { pattern: /\\bServiceWorker\\b/gi, description: 'ServiceWorker' },\n ]\n\n for (const { pattern, description } of forbiddenPatterns) {\n if (pattern.test(code)) {\n throw new Error(\n `Security violation: Code contains forbidden pattern \"${description}\". ` +\n `For AI-generated code, please regenerate without this pattern.`,\n )\n }\n }\n\n // 4. 检查可疑的字符串拼接(用于绕过检测)\n const suspiciousPatterns = [\n /['\"]con['\"] *\\+ *['\"]structor['\"]/gi, // \"con\" + \"structor\"\n /['\"]ev['\"] *\\+ *['\"]al['\"]/gi, // \"ev\" + \"al\"\n /['\"]__pro['\"] *\\+ *['\"]to__['\"]/gi, // \"__pro\" + \"to__\"\n /\\b(self|window|global)\\s*\\[\\s*['\"][a-z]+['\"]\\s*\\+\\s*['\"][a-z]+['\"]\\s*\\]/gi, // self[\"x\" + \"y\"]\n ]\n\n for (const pattern of suspiciousPatterns) {\n if (pattern.test(code)) {\n throw new Error(\n 'Security violation: Code contains suspicious string concatenation that may bypass security checks.',\n )\n }\n }\n\n // 5. AI 代码特定检查\n // AI 生成的代码通常比较规范,不应该包含过于 tricky 的写法\n const aiCodeWarnings = [\n { pattern: /\\[['\"][a-z_$]+['\"]\\]/gi, count: 0, threshold: 10, description: 'excessive bracket notation' },\n { pattern: /\\s*\\+\\s*['\"]/gi, count: 0, threshold: 5, description: 'excessive string concatenation' },\n ]\n\n for (const warning of aiCodeWarnings) {\n const matches = code.match(warning.pattern)\n if (matches && matches.length > warning.threshold) {\n throw new Error(\n `Security warning: Code contains ${matches.length} instances of ${warning.description}, ` +\n `which is unusual for AI-generated code. Please regenerate.`,\n )\n }\n }\n}\n\n/**\n * 代码执行函数\n * @description 使用 Worker 池和增强安全检查\n */\nexport async function executeFilterCode(options: CodeExecutionOptions): Promise<CodeExecutionResult> {\n const { code, data, timeout = 2000 } = options\n\n // 1. 环境检查(返回失败结果而不是抛出异常)\n if (typeof Worker === 'undefined') {\n return {\n success: false,\n data: [],\n error: 'Web Worker is not supported in this environment',\n }\n }\n\n try {\n // 2. 增强的安全验证\n validateCodeSafety(code)\n\n // 3. 验证输入数据\n if (!Array.isArray(data)) {\n throw new Error('Input data must be an array')\n }\n\n // 数据大小限制(防止 OOM)\n if (data.length > 100000) {\n console.warn(`[vseed] Large dataset detected: ${data.length} items. Consider pagination for better performance.`)\n }\n\n // ⚠️ 数据内存大小估算(粗略)\n const dataSize = JSON.stringify(data).length\n if (dataSize > 10 * 1024 * 1024) {\n // 10MB\n throw new Error(`Input data is too large (${(dataSize / 1024 / 1024).toFixed(1)}MB). Maximum allowed is 10MB.`)\n }\n\n // 4. 初始化或获取 Worker 池(线程安全)\n const pool = await getOrCreateWorkerPool()\n const worker = await pool.acquire()\n const taskId = `task_${Date.now()}_${Math.random().toString(36).substring(7)}`\n\n // 标记 Worker 是否应该被归还到池中(超时/错误时应该终止而不是归还)\n let shouldReleaseWorker = true\n\n try {\n const result = await new Promise<any[]>((resolve, reject) => {\n // 使用 AbortController 和 cleanup 确保监听器总是被清理\n let isSettled = false\n const cleanup = () => {\n if (!isSettled) {\n isSettled = true\n worker.removeEventListener('message', messageHandler)\n worker.removeEventListener('error', errorHandler)\n }\n }\n\n // 外层超时保护(比内层多 1 秒)\n const outerTimeoutId = setTimeout(() => {\n cleanup()\n shouldReleaseWorker = false // ⚠️ 超时时不归还 Worker\n worker.terminate() // ⚠️ 立即终止 Worker,防止继续消耗 CPU\n reject(new Error(`Execution timeout (exceeded ${timeout}ms) - outer guard`))\n }, timeout + 1000)\n\n // 消息处理\n const messageHandler = (e: MessageEvent) => {\n if (e.data.taskId !== taskId) return\n\n clearTimeout(outerTimeoutId)\n cleanup()\n\n if (e.data.success) {\n resolve(e.data.result)\n } else {\n reject(new Error(`Execution failed: ${e.data.error}${e.data.errorType ? ` (${e.data.errorType})` : ''}`))\n }\n }\n\n // 错误处理\n const errorHandler = (errorEvent: ErrorEvent) => {\n clearTimeout(outerTimeoutId)\n cleanup()\n shouldReleaseWorker = false // ⚠️ Worker 内部错误,不归还\n worker.terminate() // ⚠️ 终止异常的 Worker\n // ✅ 正确提取 ErrorEvent 中的错误信息\n const errorMessage = errorEvent.message || errorEvent.error?.message || 'Unknown worker error'\n reject(new Error(`Worker error: ${errorMessage}`))\n }\n\n worker.addEventListener('message', messageHandler)\n worker.addEventListener('error', errorHandler)\n\n worker.postMessage({\n taskId,\n code,\n data,\n timeout,\n })\n })\n\n return {\n success: true,\n data: result,\n }\n } finally {\n // 只有在正常完成时才归还 Worker\n // 超时或错误时 Worker 已被 terminate(),不应该归还到池中\n if (shouldReleaseWorker && globalWorkerPool) {\n globalWorkerPool.release(worker)\n }\n }\n } catch (error) {\n return {\n success: false,\n data: [],\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n"],"names":["WorkerPool","maxSize","i","worker","error","w","Error","String","libraryLoadCode","BUILTIN_UTILS_SOURCE","workerCode","blob","Blob","blobURL","URL","Worker","Promise","resolve","reject","isSettled","cleanup","timeout","setTimeout","e","clearTimeout","errorEvent","errorMessage","tempWorker","globalWorkerPool","poolInitPromise","poolConfig","getOrCreateWorkerPool","pool","initializeWorkerPool","options","terminateWorkerPool","validateCodeSafety","code","forbiddenPatterns","pattern","description","suspiciousPatterns","aiCodeWarnings","warning","matches","executeFilterCode","data","Array","console","dataSize","JSON","taskId","Date","Math","shouldReleaseWorker","result","messageHandler","errorHandler","outerTimeoutId"],"mappings":"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"}
1
+ {"version":3,"file":"pipeline/utils/sandbox/execute.js","sources":["../../../../../src/pipeline/utils/sandbox/execute.ts"],"sourcesContent":["/* oxlint-disable no-console */\n/**\n * 增强的安全代码执行器\n * @description 专为 AI 生成代码设计的安全沙箱\n * @module enhancedSecureCodeExecutor\n */\n\nimport type { CodeExecutionOptions, CodeExecutionResult } from 'src/types/sandbox'\nimport { BUILTIN_UTILS_SOURCE } from './builtin-utils'\n\n/**\n * Worker 池管理器\n * @description 复用 Worker 实例,避免重复创建开销\n */\nclass WorkerPool {\n private workers: Worker[] = []\n private availableWorkers: Worker[] = []\n private readonly maxSize: number\n private isInitialized = false\n\n constructor(maxSize = 2) {\n this.maxSize = maxSize\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) return\n\n for (let i = 0; i < this.maxSize; i++) {\n try {\n const worker = await this.createSecureWorker()\n this.workers.push(worker)\n this.availableWorkers.push(worker)\n } catch (error) {\n // 某个 Worker 初始化失败时,清理已创建的 Worker\n this.workers.forEach((w) => w.terminate())\n this.workers = []\n this.availableWorkers = []\n throw new Error(`Failed to initialize Worker pool: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n this.isInitialized = true\n }\n\n private createSecureWorker(): Promise<Worker> {\n // 直接使用内置工具库\n const libraryLoadCode = `// 内置工具库(lodash/Ramda 兼容 API)\\n${BUILTIN_UTILS_SOURCE}`\n\n const workerCode = `\n // ============================================\n // 阶段 1: 立即执行安全加固 (IIFE)\n // ============================================\n (function initSecureSandbox() {\n 'use strict';\n \n // 1.1 保存必要的原生引用(在被删除前)\n const nativeImportScripts = self.importScripts;\n const nativePostMessage = self.postMessage.bind(self);\n \n // 1.2 立即删除危险 API\n delete self.importScripts;\n delete self.fetch;\n delete self.XMLHttpRequest;\n delete self.WebSocket;\n \n // 1.3 冻结关键原型链(防止污染和篡改)\n Object.freeze(Object.prototype);\n Object.freeze(Array.prototype);\n Object.freeze(Function.prototype);\n Object.freeze(String.prototype);\n Object.freeze(Number.prototype);\n Object.freeze(Boolean.prototype);\n \n // ============================================\n // 阶段 2: 加载工具库\n // ============================================\n try {\n ${libraryLoadCode}\n } catch (error) {\n nativePostMessage({ \n initError: 'Failed to load utility library: ' + error.message \n });\n return;\n }\n \n // 验证库是否加载成功\n const utilityLib = self._;\n if (!utilityLib) {\n nativePostMessage({ \n initError: 'Builtin utility library (_ or R) not found after loading' \n });\n return;\n }\n \n // ============================================\n // 阶段 3: 创建安全上下文\n // ============================================\n const createSafeContext = (lib) => {\n const allowedGlobals = {\n // 工具库\n _: lib,\n R: lib,\n \n // 基础类型构造函数(只读)\n Array: Array,\n Object: Object,\n String: String,\n Number: Number,\n Boolean: Boolean,\n Date: Date,\n \n // 数学和工具\n Math: Math,\n JSON: JSON,\n \n // 类型检查\n parseInt: parseInt,\n parseFloat: parseFloat,\n isNaN: isNaN,\n isFinite: isFinite,\n \n // 错误类型(用于调试)\n Error: Error,\n TypeError: TypeError,\n RangeError: RangeError,\n \n // 只读的数据引用\n data: null,\n };\n \n // 使用 Proxy 严格控制访问\n return new Proxy(allowedGlobals, {\n get(target, prop) {\n if (prop === Symbol.unscopables) {\n return undefined;\n }\n \n if (prop in target) {\n return target[prop];\n }\n \n // 拒绝访问任何未定义的属性\n throw new ReferenceError(\n \\`'\\${String(prop)}' is not defined. \\\\n\\` +\n \\`Only these globals are available: \\${Object.keys(allowedGlobals).join(', ')}\\`\n );\n },\n \n set(target, prop, value) {\n // 只允许设置 data 属性(用于传递执行数据)\n if (prop === 'data') {\n target[prop] = value;\n return true;\n }\n \n // 拒绝设置其他属性\n throw new TypeError(\n \\`Cannot set property '\\${String(prop)}' on global context\\`\n );\n },\n \n has(target, prop) {\n return prop in target;\n },\n \n // 防止 getOwnPropertyDescriptor 等元编程操作\n getOwnPropertyDescriptor(target, prop) {\n if (prop in target) {\n return Object.getOwnPropertyDescriptor(target, prop);\n }\n return undefined;\n }\n });\n };\n \n const safeContext = createSafeContext(utilityLib);\n \n // ============================================\n // 阶段 4: 代码执行引擎\n // ============================================\n const executeUserCodeSafely = (code, data, timeout) => {\n // 设置超时保护(内层防御)\n let timeoutId = null;\n let isTimedOut = false;\n \n if (timeout > 0) {\n timeoutId = setTimeout(() => {\n isTimedOut = true;\n }, timeout);\n }\n \n try {\n // 超时检查函数\n // ⚠️ 注意:这只能防御\"合作式\"的代码(包含 I/O、迭代、递归)\n // 对于纯计算死循环(while(true){}),只有外层 worker.terminate() 能终止\n const checkTimeout = () => {\n if (isTimedOut) {\n throw new Error(\\`Execution timeout (exceeded \\${timeout}ms)\\`);\n }\n };\n \n // 更新安全上下文中的数据\n safeContext.data = data;\n \n // 提取安全上下文的所有变量名和值\n const contextKeys = Object.keys(safeContext);\n const contextValues = contextKeys.map(key => safeContext[key]);\n \n // 显式遮蔽 Worker 全局对象中的危险变量(设为 undefined)\n const shadowedGlobals = [\n 'self', // Worker 全局对象本身\n 'postMessage', // 通信通道(防止滥用)\n 'close', // Worker 终止方法\n 'importScripts', // 动态加载脚本(已删除,但显式遮蔽更安全)\n 'addEventListener', // 事件监听器\n 'removeEventListener',\n 'dispatchEvent',\n 'onmessage', // 消息处理器\n 'onerror', // 错误处理器\n 'onmessageerror',\n 'setTimeout', // ⚠️ 遮蔽定时器,防止资源泄漏\n 'clearTimeout',\n 'setInterval', // ⚠️ 防止用户创建大量定时器\n 'clearInterval',\n ];\n \n // 包装用户代码:在严格模式下执行,通过参数注入变量\n const wrappedCode = \\`\n \"use strict\";\n // 用户代码在这里执行,可以直接访问注入的变量(_, R, data, Math, etc.)\n \\${code}\n \\`;\n \n // 创建函数:参数是上下文变量名 + checkTimeout + 遮蔽的全局变量名\n const userFunction = new Function(\n ...contextKeys, // 安全上下文变量\n 'checkTimeout', // 超时检查函数(用户可选调用)\n ...shadowedGlobals, // 显式遮蔽的危险全局变量\n wrappedCode\n );\n \n // 执行并获取结果\n const result = userFunction(\n ...contextValues, // 安全上下文的值\n checkTimeout, // 超时检查函数\n ...shadowedGlobals.map(() => undefined) // 所有危险全局变量设为 undefined\n );\n \n // 清除超时\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n \n // 验证返回值(只检查危险类型,不限制结构)\n const validateResultType = (result) => {\n const type = typeof result\n \n // 禁止返回函数、Symbol\n if (type === 'function' || type === 'symbol') {\n throw new TypeError(\n \\`Code must not return \\${type}. Returned types must be serializable.\\`\n );\n }\n \n // 禁止返回 Promise\n if (result && typeof result.then === 'function') {\n throw new TypeError(\n \\`Code must not return a Promise. Async operations are not allowed.\\`\n );\n }\n \n // 如果是数组,检查元素的危险类型\n if (Array.isArray(result)) {\n for (let i = 0; i < result.length; i++) {\n const item = result[i];\n const itemType = typeof item;\n \n if (itemType === 'function' || itemType === 'symbol') {\n throw new TypeError(\n \\`Array element at index \\${i} has forbidden type: \\${itemType}\\`\n );\n }\n \n if (item && typeof item.then === 'function') {\n throw new TypeError(\n \\`Array element at index \\${i} is a Promise. Async operations are not allowed.\\`\n );\n }\n }\n }\n };\n \n validateResultType(result);\n \n return result;\n \n } catch (error) {\n throw error;\n } finally {\n // 清理数据引用(防止内存泄漏)\n safeContext.data = null;\n }\n };\n \n // ============================================\n // 阶段 5: 消息处理\n // ============================================\n self.onmessage = function(event) {\n // ⚠️ 防御性检查:确保消息格式正确\n if (!event || !event.data) {\n nativePostMessage({ \n taskId: 'unknown',\n success: false,\n error: 'Invalid message format: event.data is null or undefined'\n });\n return;\n }\n \n const { code, data, timeout, taskId } = event.data;\n \n // 验证必需字段\n if (!taskId) {\n nativePostMessage({ \n taskId: 'unknown',\n success: false,\n error: 'Invalid message: taskId is required'\n });\n return;\n }\n \n try {\n const result = executeUserCodeSafely(code, data, timeout);\n \n nativePostMessage({ \n taskId,\n success: true,\n result: result \n });\n \n } catch (error) {\n nativePostMessage({ \n taskId,\n success: false,\n error: error.message || String(error),\n errorType: error.constructor.name\n });\n }\n };\n \n // 错误捕获\n self.onerror = function(event) {\n nativePostMessage({ \n globalError: event.message || 'Unknown worker error'\n });\n };\n \n // 发送初始化成功消息\n nativePostMessage({ initialized: true });\n \n })(); // 立即执行\n `\n\n const blob = new Blob([workerCode], { type: 'application/javascript' })\n const blobURL = URL.createObjectURL(blob)\n\n const worker = new Worker(blobURL)\n\n // Worker 构造函数同步加载脚本,立即回收 Blob URL 防止内存泄漏\n URL.revokeObjectURL(blobURL)\n\n // 等待初始化消息\n return new Promise<Worker>((resolve, reject) => {\n let isSettled = false\n\n const cleanup = () => {\n if (!isSettled) {\n isSettled = true\n worker.onmessage = null // ⚠️ 清理监听器防止内存泄漏\n worker.onerror = null\n }\n }\n\n const timeout = setTimeout(() => {\n cleanup()\n worker.terminate()\n reject(new Error('Worker initialization timeout'))\n }, 10000)\n\n worker.onmessage = (e) => {\n if (e.data.initialized) {\n clearTimeout(timeout)\n cleanup()\n resolve(worker)\n } else if (e.data.initError) {\n clearTimeout(timeout)\n cleanup()\n worker.terminate()\n reject(new Error(e.data.initError))\n }\n }\n\n worker.onerror = (errorEvent: ErrorEvent) => {\n clearTimeout(timeout)\n cleanup()\n worker.terminate()\n const errorMessage = errorEvent.message || errorEvent.error?.message || 'Unknown worker initialization error'\n reject(new Error(`Worker initialization failed: ${errorMessage}`))\n }\n })\n }\n\n async acquire(): Promise<Worker> {\n if (!this.isInitialized) {\n await this.initialize()\n }\n\n if (this.availableWorkers.length === 0) {\n // 创建临时 Worker 时需要等待初始化完成\n try {\n const tempWorker = await this.createSecureWorker()\n return tempWorker\n } catch (error) {\n throw new Error(`Failed to create temporary Worker: ${error instanceof Error ? error.message : String(error)}`)\n }\n }\n\n return this.availableWorkers.pop()!\n }\n\n release(worker: Worker): void {\n if (this.workers.includes(worker)) {\n this.availableWorkers.push(worker)\n } else {\n // 临时创建的 Worker,直接终止\n worker.terminate()\n }\n }\n\n terminate(): void {\n this.workers.forEach((worker) => worker.terminate())\n this.workers = []\n this.availableWorkers = []\n this.isInitialized = false\n }\n}\n\n// 全局 Worker 池实例\nlet globalWorkerPool: WorkerPool | null = null\n// 添加初始化锁,防止并发创建多个 pool\nlet poolInitPromise: Promise<WorkerPool> | null = null\n// Worker 池配置\nlet poolConfig = { poolSize: 2 }\n\n/**\n * 获取或创建全局 Worker 池(线程安全)\n */\nfunction getOrCreateWorkerPool(): Promise<WorkerPool> {\n if (globalWorkerPool) {\n return Promise.resolve(globalWorkerPool)\n }\n\n // 如果已经在初始化中,等待现有的初始化完成\n if (poolInitPromise) {\n return poolInitPromise\n }\n\n // 创建新的 pool 并初始化\n poolInitPromise = (async () => {\n try {\n const pool = new WorkerPool(poolConfig.poolSize)\n await pool.initialize()\n globalWorkerPool = pool\n return pool\n } catch (error) {\n // 重置 promise,允许下次重试\n poolInitPromise = null\n throw error\n }\n })()\n\n return poolInitPromise\n}\n\n/**\n * 初始化 Worker 池\n * @description 预热 Worker 实例,提升首次执行性能\n *\n * **⚠️ 注意:这是一个可选的性能优化方法**\n *\n * - **懒加载模式**:如果不调用此方法,Worker 池会在首次使用时自动初始化\n * - **推荐场景**:应用启动时预热,避免首次筛选时的冷启动延迟\n * - **配置选项**:\n * - `poolSize`: Worker 池大小(默认 2)\n *\n * @param options - 初始化选项\n * @param options.poolSize - Worker 池大小,默认为 2\n *\n * @example\n * ```typescript\n * // ✅ 推荐:应用启动时预热(可选)\n * import { initializeWorkerPool } from '@visactor/vseed'\n *\n * // 在 main.ts 或入口文件中\n * await initializeWorkerPool({ poolSize: 2 })\n *\n * // ✅ 也可以:不做任何事,让 Worker 池自动初始化\n * // 首次调用 dynamicFilter 时会自动创建\n * ```\n */\nexport async function initializeWorkerPool(\n options: {\n utilityLibUrl?: string\n utilityLibSource?: string\n poolSize?: number\n } = {},\n): Promise<void> {\n // 设置配置(必须在创建 pool 之前)\n poolConfig = {\n poolSize: options.poolSize ?? 2,\n }\n\n // 使用统一的 getOrCreateWorkerPool 确保状态一致\n await getOrCreateWorkerPool()\n}\n\n/**\n * 销毁 Worker 池\n * @description 终止所有 Worker 实例并清理全局状态\n *\n * **⚠️ 注意:大多数情况下不需要手动调用此方法**\n *\n * - **一般使用**:浏览器会在页面卸载时自动清理 Worker 资源\n * - **建议场景**:\n * - 单元测试的清理阶段(`afterAll` 钩子)\n * - 开发环境热重载时清理旧实例\n * - 动态卸载整个图表库模块(极少见)\n *\n * @example\n * ```typescript\n * // ✅ 推荐:测试环境\n * afterAll(() => {\n * terminateWorkerPool()\n * })\n *\n * // ❌ 不推荐:组件卸载时(Worker 池是全局的,其他组件可能还在使用)\n * onUnmounted(() => {\n * terminateWorkerPool() // 不要这样做!\n * })\n * ```\n */\nexport function terminateWorkerPool(): void {\n if (globalWorkerPool) {\n globalWorkerPool.terminate()\n globalWorkerPool = null\n }\n // 重置初始化 Promise,避免状态不一致\n poolInitPromise = null\n}\n\n/**\n * 增强的安全验证\n * @description 针对 AI 生成代码的特定模式检查\n */\nexport function validateCodeSafety(code: string): void {\n // 1. 基础检查\n if (!code || code.trim().length === 0) {\n throw new Error('Code cannot be empty')\n }\n\n if (code.length > 50000) {\n throw new Error('Code is too long (max 50KB)')\n }\n\n // 2. 必须包含 return\n if (!/\\breturn\\b/.test(code)) {\n throw new Error('Code must contain a return statement')\n }\n\n // 3. 增强的黑名单检查\n const forbiddenPatterns = [\n // 原有的基础黑名单\n { pattern: /\\beval\\b/gi, description: 'eval()' },\n { pattern: /\\bFunction\\s*\\(/gi, description: 'Function constructor' },\n { pattern: /\\bnew\\s+Function\\b/gi, description: 'new Function()' },\n { pattern: /\\bimportScripts\\b/gi, description: 'importScripts()' },\n { pattern: /\\bfetch\\b/gi, description: 'fetch()' },\n { pattern: /\\bXMLHttpRequest\\b/gi, description: 'XMLHttpRequest' },\n { pattern: /\\bWebSocket\\b/gi, description: 'WebSocket' },\n { pattern: /\\blocalStorage\\b/gi, description: 'localStorage' },\n { pattern: /\\bsessionStorage\\b/gi, description: 'sessionStorage' },\n { pattern: /\\bindexedDB\\b/gi, description: 'indexedDB' },\n { pattern: /\\bwindow\\b/gi, description: 'window' },\n { pattern: /\\bdocument\\b/gi, description: 'document' },\n { pattern: /\\bnavigator\\b/gi, description: 'navigator' },\n { pattern: /\\blocation\\b/gi, description: 'location' },\n { pattern: /\\brequire\\b/gi, description: 'require()' },\n { pattern: /\\bimport\\s+/gi, description: 'import statement' },\n { pattern: /\\bexport\\s+/gi, description: 'export statement' },\n\n // 增强:Constructor 访问(绕过检测的常见方式)\n { pattern: /\\bconstructor\\b/gi, description: 'constructor access' },\n { pattern: /\\[['\"]constructor['\"]\\]/gi, description: 'constructor via bracket notation' },\n { pattern: /\\['constructor'\\]/gi, description: 'constructor string access' },\n\n // 增强:原型链操作\n { pattern: /\\b__proto__\\b/gi, description: '__proto__' },\n { pattern: /\\bprototype\\b/gi, description: 'prototype manipulation' },\n { pattern: /Object\\.setPrototypeOf/gi, description: 'Object.setPrototypeOf()' },\n { pattern: /Object\\.getPrototypeOf/gi, description: 'Object.getPrototypeOf()' },\n { pattern: /Object\\.create\\s*\\(\\s*null\\s*\\)/gi, description: 'Object.create(null)' },\n\n // 增强:反射和元编程\n { pattern: /\\bReflect\\./gi, description: 'Reflect API' },\n { pattern: /\\bProxy\\b/gi, description: 'Proxy constructor' },\n\n // 增强:全局对象访问\n { pattern: /\\bglobal\\b/gi, description: 'global object' },\n { pattern: /\\bglobalThis\\b/gi, description: 'globalThis' },\n { pattern: /\\bself\\s*\\[/gi, description: 'self[] access' },\n { pattern: /\\bthis\\s*\\.\\s*constructor/gi, description: 'this.constructor' },\n\n // 增强:异步操作(容易被滥用)\n { pattern: /\\basync\\s+function/gi, description: 'async function' },\n { pattern: /\\bawait\\b/gi, description: 'await keyword' },\n { pattern: /\\bnew\\s+Promise\\b/gi, description: 'new Promise()' },\n { pattern: /\\.then\\s*\\(/gi, description: 'Promise.then()' },\n\n // 增强:生成器(可能导致难以控制的执行)\n { pattern: /\\bfunction\\s*\\*/gi, description: 'generator function' },\n { pattern: /\\byield\\b/gi, description: 'yield keyword' },\n\n // 增强:动态代码生成\n { pattern: /\\.apply\\s*\\(/gi, description: 'Function.apply()' },\n { pattern: /\\.call\\s*\\(/gi, description: 'Function.call()' },\n { pattern: /\\.bind\\s*\\(/gi, description: 'Function.bind()' },\n\n // 增强:Worker 相关\n { pattern: /\\bWorker\\b/gi, description: 'Worker constructor' },\n { pattern: /\\bSharedWorker\\b/gi, description: 'SharedWorker' },\n { pattern: /\\bServiceWorker\\b/gi, description: 'ServiceWorker' },\n ]\n\n for (const { pattern, description } of forbiddenPatterns) {\n if (pattern.test(code)) {\n throw new Error(\n `Security violation: Code contains forbidden pattern \"${description}\". ` +\n `For AI-generated code, please regenerate without this pattern.`,\n )\n }\n }\n\n // 4. 检查可疑的字符串拼接(用于绕过检测)\n const suspiciousPatterns = [\n /['\"]con['\"] *\\+ *['\"]structor['\"]/gi, // \"con\" + \"structor\"\n /['\"]ev['\"] *\\+ *['\"]al['\"]/gi, // \"ev\" + \"al\"\n /['\"]__pro['\"] *\\+ *['\"]to__['\"]/gi, // \"__pro\" + \"to__\"\n /\\b(self|window|global)\\s*\\[\\s*['\"][a-z]+['\"]\\s*\\+\\s*['\"][a-z]+['\"]\\s*\\]/gi, // self[\"x\" + \"y\"]\n ]\n\n for (const pattern of suspiciousPatterns) {\n if (pattern.test(code)) {\n throw new Error(\n 'Security violation: Code contains suspicious string concatenation that may bypass security checks.',\n )\n }\n }\n\n // 5. AI 代码特定检查\n // AI 生成的代码通常比较规范,不应该包含过于 tricky 的写法\n const aiCodeWarnings = [\n { pattern: /\\[['\"][a-z_$]+['\"]\\]/gi, count: 0, threshold: 10, description: 'excessive bracket notation' },\n { pattern: /\\s*\\+\\s*['\"]/gi, count: 0, threshold: 5, description: 'excessive string concatenation' },\n ]\n\n for (const warning of aiCodeWarnings) {\n const matches = code.match(warning.pattern)\n if (matches && matches.length > warning.threshold) {\n throw new Error(\n `Security warning: Code contains ${matches.length} instances of ${warning.description}, ` +\n `which is unusual for AI-generated code. Please regenerate.`,\n )\n }\n }\n}\n\n/**\n * 代码执行函数\n * @description 使用 Worker 池和增强安全检查\n */\nexport async function executeFilterCode(options: CodeExecutionOptions): Promise<CodeExecutionResult> {\n const { code, data, timeout = 2000 } = options\n\n // 1. 环境检查(返回失败结果而不是抛出异常)\n if (typeof Worker === 'undefined') {\n return {\n success: false,\n data: [],\n error: 'Web Worker is not supported in this environment',\n }\n }\n\n try {\n // 2. 增强的安全验证\n validateCodeSafety(code)\n\n // 3. 验证输入数据\n if (!Array.isArray(data)) {\n throw new Error('Input data must be an array')\n }\n\n // 数据大小限制(防止 OOM)\n if (data.length > 100000) {\n console.warn(`[vseed] Large dataset detected: ${data.length} items. Consider pagination for better performance.`)\n }\n\n // ⚠️ 数据内存大小估算(粗略)\n const dataSize = JSON.stringify(data).length\n if (dataSize > 10 * 1024 * 1024) {\n // 10MB\n throw new Error(`Input data is too large (${(dataSize / 1024 / 1024).toFixed(1)}MB). Maximum allowed is 10MB.`)\n }\n\n // 4. 初始化或获取 Worker 池(线程安全)\n const pool = await getOrCreateWorkerPool()\n const worker = await pool.acquire()\n const taskId = `task_${Date.now()}_${Math.random().toString(36).substring(7)}`\n\n // 标记 Worker 是否应该被归还到池中(超时/错误时应该终止而不是归还)\n let shouldReleaseWorker = true\n\n try {\n const result = await new Promise<any[]>((resolve, reject) => {\n // 使用 AbortController 和 cleanup 确保监听器总是被清理\n let isSettled = false\n const cleanup = () => {\n if (!isSettled) {\n isSettled = true\n worker.removeEventListener('message', messageHandler)\n worker.removeEventListener('error', errorHandler)\n }\n }\n\n // 外层超时保护(比内层多 1 秒)\n const outerTimeoutId = setTimeout(() => {\n cleanup()\n shouldReleaseWorker = false // ⚠️ 超时时不归还 Worker\n worker.terminate() // ⚠️ 立即终止 Worker,防止继续消耗 CPU\n reject(new Error(`Execution timeout (exceeded ${timeout}ms) - outer guard`))\n }, timeout + 1000)\n\n // 消息处理\n const messageHandler = (e: MessageEvent) => {\n if (e.data.taskId !== taskId) return\n\n clearTimeout(outerTimeoutId)\n cleanup()\n\n if (e.data.success) {\n resolve(e.data.result)\n } else {\n reject(new Error(`Execution failed: ${e.data.error}${e.data.errorType ? ` (${e.data.errorType})` : ''}`))\n }\n }\n\n // 错误处理\n const errorHandler = (errorEvent: ErrorEvent) => {\n clearTimeout(outerTimeoutId)\n cleanup()\n shouldReleaseWorker = false // ⚠️ Worker 内部错误,不归还\n worker.terminate() // ⚠️ 终止异常的 Worker\n // ✅ 正确提取 ErrorEvent 中的错误信息\n const errorMessage = errorEvent.message || errorEvent.error?.message || 'Unknown worker error'\n reject(new Error(`Worker error: ${errorMessage}`))\n }\n\n worker.addEventListener('message', messageHandler)\n worker.addEventListener('error', errorHandler)\n\n worker.postMessage({\n taskId,\n code,\n data,\n timeout,\n })\n })\n\n return {\n success: true,\n data: result,\n }\n } finally {\n // 只有在正常完成时才归还 Worker\n // 超时或错误时 Worker 已被 terminate(),不应该归还到池中\n if (shouldReleaseWorker && globalWorkerPool) {\n globalWorkerPool.release(worker)\n }\n }\n } catch (error) {\n return {\n success: false,\n data: [],\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n"],"names":["WorkerPool","maxSize","i","worker","error","w","Error","String","libraryLoadCode","BUILTIN_UTILS_SOURCE","workerCode","blob","Blob","blobURL","URL","Worker","Promise","resolve","reject","isSettled","cleanup","timeout","setTimeout","e","clearTimeout","errorEvent","errorMessage","tempWorker","globalWorkerPool","poolInitPromise","poolConfig","getOrCreateWorkerPool","pool","initializeWorkerPool","options","terminateWorkerPool","validateCodeSafety","code","forbiddenPatterns","pattern","description","suspiciousPatterns","aiCodeWarnings","warning","matches","executeFilterCode","data","Array","console","dataSize","JSON","taskId","Date","Math","shouldReleaseWorker","result","messageHandler","errorHandler","outerTimeoutId"],"mappings":"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"}
@@ -44,6 +44,12 @@ export type TokenThemeDefinition = {
44
44
  tableHoverHeaderInlineBackgroundColor?: string;
45
45
  tableSelectedBorderColor?: string;
46
46
  tableSelectedBackgroundColor?: string;
47
+ annotationLineColor?: string;
48
+ annotationLineStyle?: 'solid' | 'dashed' | 'dotted';
49
+ annotationLineDash?: number[];
50
+ annotationTextColor?: string;
51
+ annotationTextBackgroundColor?: string;
52
+ annotationTextBackgroundOpacity?: number;
47
53
  };
48
54
  export type TokenThemeRegistry = Record<string, TokenThemeDefinition>;
49
55
  export type RegisterTokenThemeOptions = {
@@ -149,23 +149,52 @@ const getChartPatch = (tokens)=>({
149
149
  titleColor: tokens.textPrimary
150
150
  }
151
151
  });
152
- const getAnnotationPatch = (tokens)=>({
152
+ const getAnnotationLinePatch = (tokens)=>({
153
+ lineColor: tokens.annotationLineColor,
154
+ lineStyle: tokens.annotationLineStyle,
155
+ lineDash: tokens.annotationLineDash,
156
+ textColor: tokens.annotationTextColor,
157
+ textBackgroundColor: tokens.annotationTextBackgroundColor,
158
+ textBackgroundBorderColor: tokens.annotationTextBackgroundColor,
159
+ textBackgroundOpacity: tokens.annotationTextBackgroundOpacity
160
+ });
161
+ const getAnnotationTextPatch = (tokens)=>({
162
+ textColor: tokens.annotationTextColor,
163
+ textBackgroundColor: tokens.annotationTextBackgroundColor,
164
+ textBackgroundBorderColor: tokens.annotationTextBackgroundColor,
165
+ textBackgroundOpacity: tokens.annotationTextBackgroundOpacity
166
+ });
167
+ const getAnnotationPatch = (tokens)=>{
168
+ const annotationLinePatch = getAnnotationLinePatch(tokens);
169
+ const annotationTextPatch = getAnnotationTextPatch(tokens);
170
+ return {
153
171
  annotationPoint: {
154
- textFontSize: tokens.labelFontSize
172
+ textFontSize: tokens.labelFontSize,
173
+ ...annotationTextPatch
155
174
  },
156
175
  annotationHorizontalLine: {
157
- textFontSize: tokens.labelFontSize
176
+ textFontSize: tokens.labelFontSize,
177
+ ...annotationLinePatch
158
178
  },
159
179
  annotationVerticalLine: {
160
- textFontSize: tokens.labelFontSize
180
+ textFontSize: tokens.labelFontSize,
181
+ ...annotationLinePatch
161
182
  },
162
183
  annotationDifferenceLine: {
163
- textFontSize: tokens.labelFontSize
184
+ textFontSize: tokens.labelFontSize,
185
+ lineColor: tokens.annotationLineColor,
186
+ lineStyle: tokens.annotationLineStyle,
187
+ lineDash: tokens.annotationLineDash,
188
+ textColor: tokens.annotationTextColor,
189
+ textBackgroundColor: tokens.annotationTextBackgroundColor,
190
+ textBackgroundOpacity: tokens.annotationTextBackgroundOpacity
164
191
  },
165
192
  annotationArea: {
166
- textFontSize: tokens.labelFontSize
193
+ textFontSize: tokens.labelFontSize,
194
+ ...annotationTextPatch
167
195
  }
168
- });
196
+ };
197
+ };
169
198
  const getRegressionLinePatch = (tokens)=>({
170
199
  kdeRegressionLine: {
171
200
  textFontSize: tokens.labelFontSize
@@ -1 +1 @@
1
- {"version":3,"file":"theme/tokenTheme.js","sources":["../../../src/theme/tokenTheme.ts"],"sourcesContent":["import tinycolor from 'tinycolor2'\nimport type { Config, CustomThemeConfig } from 'src/types'\nimport { registerAll } from '../builder/register/all'\nimport { registerCustomTheme } from '../builder/register/theme'\nimport { darkTheme } from './dark'\nimport { lightTheme } from './light'\n\nexport type TokenThemeBase = 'light' | 'dark'\n\nexport type TokenThemeDefinition = {\n baseTheme: TokenThemeBase\n fontFamily?: string\n tableHeaderFontSize?: number\n tableBodyFontSize?: number\n labelFontSize?: number\n tooltipFontSize?: number\n axisFontSize?: number\n legendFontSize?: number\n playerFontSize?: number\n colorScheme: [string, string, ...string[]]\n linearColorScheme: [string, string]\n textPrimary: string\n textSecondary: string\n borderColor: string\n surfaceColor?: string\n surfaceBackgroundColor?: string\n accentColor?: string\n positiveColor?: string\n negativeColor?: string\n tooltipBackgroundColor: string\n tooltipBorderColor?: string\n axisLabelColor?: string\n axisTitleColor?: string\n axisGridColor?: string\n axisLineColor?: string\n labelColor?: string\n labelStroke?: string\n legendLabelColor?: string\n legendPagerIconColor?: string\n legendPagerIconDisableColor?: string\n playerRailColor?: string\n playerSliderHandleColor?: string\n playerSliderHandleBorderColor?: string\n tableBorderColor?: string\n tableBodyFontColor?: string\n tableHeaderFontColor?: string\n tableHeaderBackgroundColor?: string\n tableHoverBodyBackgroundColor?: string\n tableHoverBodyInlineBackgroundColor?: string\n tableHoverHeaderBackgroundColor?: string\n tableHoverHeaderInlineBackgroundColor?: string\n tableSelectedBorderColor?: string\n tableSelectedBackgroundColor?: string\n}\n\nexport type TokenThemeRegistry = Record<string, TokenThemeDefinition>\n\nexport type RegisterTokenThemeOptions = {\n ensureRegisterAll?: boolean\n}\n\ntype ThemeConfigMap = NonNullable<CustomThemeConfig['config']>\ntype ThemeConfigKey = keyof ThemeConfigMap\n\nconst raceChartTypes: ThemeConfigKey[] = ['raceBar', 'raceColumn', 'raceScatter', 'raceLine', 'racePie', 'raceDonut']\n\nlet hasEnsuredRegisterAll = false\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nconst mergeThemeNode = <T>(base: T, patch: Partial<T>): T => {\n if (!isRecord(base) || !isRecord(patch)) {\n return patch as T\n }\n\n const result: Record<string, unknown> = { ...base }\n for (const [key, patchValue] of Object.entries(patch)) {\n if (patchValue === undefined) {\n continue\n }\n\n const currentValue = result[key]\n if (Array.isArray(patchValue)) {\n result[key] = [...patchValue]\n continue\n }\n\n if (isRecord(currentValue) && isRecord(patchValue)) {\n result[key] = mergeThemeNode(currentValue, patchValue)\n continue\n }\n\n result[key] = patchValue\n }\n\n return result as T\n}\n\nconst withAlpha = (color: string, alpha: number) => tinycolor(color).setAlpha(alpha).toRgbString()\n\nconst ensureRegisterAll = (options?: RegisterTokenThemeOptions) => {\n if (options?.ensureRegisterAll === false || hasEnsuredRegisterAll) {\n return\n }\n\n registerAll()\n hasEnsuredRegisterAll = true\n}\n\nconst getAccentColor = (tokens: TokenThemeDefinition) => tokens.accentColor || tokens.colorScheme[0]\n\nconst getAxisPatch = (tokens: TokenThemeDefinition) => ({\n label: {\n labelColor: tokens.axisLabelColor || tokens.textSecondary,\n labelFontSize: tokens.axisFontSize,\n },\n title: {\n titleColor: tokens.axisTitleColor || tokens.textSecondary,\n titleFontSize: tokens.axisFontSize,\n },\n grid: {\n gridColor: tokens.axisGridColor || tokens.borderColor,\n },\n tick: {\n tickColor: tokens.axisLineColor || tokens.borderColor,\n },\n line: {\n lineColor: tokens.axisLineColor || tokens.borderColor,\n },\n})\n\nconst getPivotGridPatch = (tokens: TokenThemeDefinition) => ({\n borderColor: tokens.tableBorderColor || tokens.borderColor,\n bodyFontSize: tokens.tableBodyFontSize,\n bodyFontColor: tokens.tableBodyFontColor || tokens.textPrimary,\n headerFontSize: tokens.tableHeaderFontSize,\n headerFontColor: tokens.tableHeaderFontColor || tokens.textPrimary,\n headerBackgroundColor: tokens.tableHeaderBackgroundColor || tokens.surfaceColor || 'transparent',\n hoverHeaderBackgroundColor: tokens.tableHoverHeaderBackgroundColor || withAlpha(getAccentColor(tokens), 0.18),\n hoverHeaderInlineBackgroundColor:\n tokens.tableHoverHeaderInlineBackgroundColor || withAlpha(getAccentColor(tokens), 0.08),\n titleFontColor: tokens.textPrimary,\n titleFontSize: tokens.tableHeaderFontSize,\n chartGridColor: tokens.axisGridColor || tokens.borderColor,\n axisLabelColor: tokens.axisLabelColor || tokens.textSecondary,\n axisLabelFontSize: tokens.axisFontSize,\n})\n\nconst getPlayerPatch = (tokens: TokenThemeDefinition) => {\n const accentColor = getAccentColor(tokens)\n\n return {\n fontFamily: tokens.fontFamily,\n fontSize: tokens.playerFontSize,\n railColor: tokens.playerRailColor || tokens.borderColor,\n trackColor: accentColor,\n sliderHandleColor: tokens.playerSliderHandleColor || tokens.surfaceColor || '#ffffff',\n sliderHandleBorderColor: tokens.playerSliderHandleBorderColor || accentColor,\n startButtonColor: accentColor,\n pauseButtonColor: accentColor,\n backwardButtonColor: accentColor,\n forwardButtonColor: accentColor,\n }\n}\n\nconst getTablePatch = (tokens: TokenThemeDefinition) => {\n const accentColor = getAccentColor(tokens)\n\n return {\n borderColor: tokens.tableBorderColor || tokens.borderColor,\n bodyFontSize: tokens.tableBodyFontSize,\n bodyFontFamily: tokens.fontFamily,\n bodyFontColor: tokens.tableBodyFontColor || tokens.textPrimary,\n headerFontSize: tokens.tableHeaderFontSize,\n headerFontFamily: tokens.fontFamily,\n headerFontColor: tokens.tableHeaderFontColor || tokens.textPrimary,\n headerBackgroundColor: tokens.tableHeaderBackgroundColor || tokens.surfaceColor || 'transparent',\n hoverBodyBackgroundColor: tokens.tableHoverBodyBackgroundColor || withAlpha(accentColor, 0.18),\n hoverBodyInlineBackgroundColor: tokens.tableHoverBodyInlineBackgroundColor || withAlpha(accentColor, 0.08),\n hoverHeaderBackgroundColor: tokens.tableHoverHeaderBackgroundColor || withAlpha(accentColor, 0.18),\n hoverHeaderInlineBackgroundColor: tokens.tableHoverHeaderInlineBackgroundColor || withAlpha(accentColor, 0.08),\n selectedBorderColor: tokens.tableSelectedBorderColor || accentColor,\n selectedBackgroundColor: tokens.tableSelectedBackgroundColor || withAlpha(accentColor, 0.12),\n backgroundColor: tokens.surfaceBackgroundColor || 'transparent',\n barAxisColor: tokens.axisLineColor || tokens.borderColor,\n backgroundColorScale: {\n minColor: tokens.linearColorScheme[0],\n maxColor: tokens.linearColorScheme[1],\n },\n }\n}\n\nconst getChartPatch = (tokens: TokenThemeDefinition) => ({\n backgroundColor: 'transparent',\n fontFamily: tokens.fontFamily,\n color: {\n colorScheme: [...tokens.colorScheme],\n linearColorScheme: [...tokens.linearColorScheme],\n positiveColor: tokens.positiveColor,\n negativeColor: tokens.negativeColor,\n },\n label: {\n labelFontSize: tokens.labelFontSize,\n labelColor: tokens.labelColor || tokens.textPrimary,\n labelStroke: tokens.labelStroke,\n },\n legend: {\n labelColor: tokens.legendLabelColor || tokens.textSecondary,\n labelFontSize: tokens.legendFontSize,\n pagerIconColor: tokens.legendPagerIconColor || tokens.textSecondary,\n pagerIconDisableColor: tokens.legendPagerIconDisableColor || tokens.borderColor,\n },\n tooltip: {\n backgroundColor: tokens.tooltipBackgroundColor,\n borderColor: tokens.tooltipBorderColor || tokens.borderColor,\n fontSize: tokens.tooltipFontSize,\n keyColor: tokens.textSecondary,\n valueColor: tokens.textPrimary,\n titleColor: tokens.textPrimary,\n },\n})\n\nconst getAnnotationPatch = (tokens: TokenThemeDefinition) => ({\n annotationPoint: {\n textFontSize: tokens.labelFontSize,\n },\n annotationHorizontalLine: {\n textFontSize: tokens.labelFontSize,\n },\n annotationVerticalLine: {\n textFontSize: tokens.labelFontSize,\n },\n annotationDifferenceLine: {\n textFontSize: tokens.labelFontSize,\n },\n annotationArea: {\n textFontSize: tokens.labelFontSize,\n },\n})\n\nconst getRegressionLinePatch = (tokens: TokenThemeDefinition) => ({\n kdeRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n ecdfRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n linearRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n lowessRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n polynomialRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n logisticRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n})\n\nconst withAxesAndExtras = (\n chartType: ThemeConfigKey,\n chartConfig: NonNullable<ThemeConfigMap[ThemeConfigKey]>,\n tokens: TokenThemeDefinition,\n) => {\n let nextChartConfig = mergeThemeNode(chartConfig, getChartPatch(tokens))\n const chartRecord = nextChartConfig as Record<string, unknown>\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'xAxis')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { xAxis: getAxisPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'yAxis')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { yAxis: getAxisPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'primaryYAxis')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { primaryYAxis: getAxisPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'secondaryYAxis')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { secondaryYAxis: getAxisPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'pivotGrid')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { pivotGrid: getPivotGridPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'annotation')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { annotation: getAnnotationPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'regressionLine')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { regressionLine: getRegressionLinePatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (raceChartTypes.includes(chartType) && Object.prototype.hasOwnProperty.call(chartRecord, 'player')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { player: getPlayerPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n return nextChartConfig\n}\n\nexport const createTokenThemeConfig = (tokens: TokenThemeDefinition): CustomThemeConfig => {\n const baseTheme = tokens.baseTheme === 'dark' ? darkTheme() : lightTheme()\n const baseConfig = (baseTheme.config || {}) as ThemeConfigMap\n const nextConfig = {} as ThemeConfigMap\n\n for (const chartType of Object.keys(baseConfig) as ThemeConfigKey[]) {\n const chartConfig = baseConfig[chartType]\n if (!chartConfig) {\n continue\n }\n\n if (chartType === 'table' || chartType === 'pivotTable') {\n nextConfig[chartType] = mergeThemeNode(chartConfig, getTablePatch(tokens)) as ThemeConfigMap[ThemeConfigKey]\n continue\n }\n\n nextConfig[chartType] = withAxesAndExtras(chartType, chartConfig, tokens) as ThemeConfigMap[ThemeConfigKey]\n }\n\n return {\n config: nextConfig as Config,\n }\n}\n\nexport const registerTokenTheme = (\n themeName: string,\n tokens: TokenThemeDefinition,\n options?: RegisterTokenThemeOptions,\n) => {\n ensureRegisterAll(options)\n registerCustomTheme(themeName, createTokenThemeConfig(tokens))\n}\n\nexport const registerTokenThemes = (themes: TokenThemeRegistry, options?: RegisterTokenThemeOptions) => {\n ensureRegisterAll(options)\n\n for (const [themeName, tokens] of Object.entries(themes)) {\n registerCustomTheme(themeName, createTokenThemeConfig(tokens))\n }\n}\n"],"names":["raceChartTypes","hasEnsuredRegisterAll","isRecord","value","Array","mergeThemeNode","base","patch","result","key","patchValue","Object","undefined","currentValue","withAlpha","color","alpha","tinycolor","ensureRegisterAll","options","registerAll","getAccentColor","tokens","getAxisPatch","getPivotGridPatch","getPlayerPatch","accentColor","getTablePatch","getChartPatch","getAnnotationPatch","getRegressionLinePatch","withAxesAndExtras","chartType","chartConfig","nextChartConfig","chartRecord","createTokenThemeConfig","baseTheme","darkTheme","lightTheme","baseConfig","nextConfig","registerTokenTheme","themeName","registerCustomTheme","registerTokenThemes","themes"],"mappings":"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"}
1
+ {"version":3,"file":"theme/tokenTheme.js","sources":["../../../src/theme/tokenTheme.ts"],"sourcesContent":["import tinycolor from 'tinycolor2'\nimport type { Config, CustomThemeConfig } from 'src/types'\nimport { registerAll } from '../builder/register/all'\nimport { registerCustomTheme } from '../builder/register/theme'\nimport { darkTheme } from './dark'\nimport { lightTheme } from './light'\n\nexport type TokenThemeBase = 'light' | 'dark'\n\nexport type TokenThemeDefinition = {\n baseTheme: TokenThemeBase\n fontFamily?: string\n tableHeaderFontSize?: number\n tableBodyFontSize?: number\n labelFontSize?: number\n tooltipFontSize?: number\n axisFontSize?: number\n legendFontSize?: number\n playerFontSize?: number\n colorScheme: [string, string, ...string[]]\n linearColorScheme: [string, string]\n textPrimary: string\n textSecondary: string\n borderColor: string\n surfaceColor?: string\n surfaceBackgroundColor?: string\n accentColor?: string\n positiveColor?: string\n negativeColor?: string\n tooltipBackgroundColor: string\n tooltipBorderColor?: string\n axisLabelColor?: string\n axisTitleColor?: string\n axisGridColor?: string\n axisLineColor?: string\n labelColor?: string\n labelStroke?: string\n legendLabelColor?: string\n legendPagerIconColor?: string\n legendPagerIconDisableColor?: string\n playerRailColor?: string\n playerSliderHandleColor?: string\n playerSliderHandleBorderColor?: string\n tableBorderColor?: string\n tableBodyFontColor?: string\n tableHeaderFontColor?: string\n tableHeaderBackgroundColor?: string\n tableHoverBodyBackgroundColor?: string\n tableHoverBodyInlineBackgroundColor?: string\n tableHoverHeaderBackgroundColor?: string\n tableHoverHeaderInlineBackgroundColor?: string\n tableSelectedBorderColor?: string\n tableSelectedBackgroundColor?: string\n annotationLineColor?: string\n annotationLineStyle?: 'solid' | 'dashed' | 'dotted'\n annotationLineDash?: number[]\n annotationTextColor?: string\n annotationTextBackgroundColor?: string\n annotationTextBackgroundOpacity?: number\n}\n\nexport type TokenThemeRegistry = Record<string, TokenThemeDefinition>\n\nexport type RegisterTokenThemeOptions = {\n ensureRegisterAll?: boolean\n}\n\ntype ThemeConfigMap = NonNullable<CustomThemeConfig['config']>\ntype ThemeConfigKey = keyof ThemeConfigMap\n\nconst raceChartTypes: ThemeConfigKey[] = ['raceBar', 'raceColumn', 'raceScatter', 'raceLine', 'racePie', 'raceDonut']\n\nlet hasEnsuredRegisterAll = false\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nconst mergeThemeNode = <T>(base: T, patch: Partial<T>): T => {\n if (!isRecord(base) || !isRecord(patch)) {\n return patch as T\n }\n\n const result: Record<string, unknown> = { ...base }\n for (const [key, patchValue] of Object.entries(patch)) {\n if (patchValue === undefined) {\n continue\n }\n\n const currentValue = result[key]\n if (Array.isArray(patchValue)) {\n result[key] = [...patchValue]\n continue\n }\n\n if (isRecord(currentValue) && isRecord(patchValue)) {\n result[key] = mergeThemeNode(currentValue, patchValue)\n continue\n }\n\n result[key] = patchValue\n }\n\n return result as T\n}\n\nconst withAlpha = (color: string, alpha: number) => tinycolor(color).setAlpha(alpha).toRgbString()\n\nconst ensureRegisterAll = (options?: RegisterTokenThemeOptions) => {\n if (options?.ensureRegisterAll === false || hasEnsuredRegisterAll) {\n return\n }\n\n registerAll()\n hasEnsuredRegisterAll = true\n}\n\nconst getAccentColor = (tokens: TokenThemeDefinition) => tokens.accentColor || tokens.colorScheme[0]\n\nconst getAxisPatch = (tokens: TokenThemeDefinition) => ({\n label: {\n labelColor: tokens.axisLabelColor || tokens.textSecondary,\n labelFontSize: tokens.axisFontSize,\n },\n title: {\n titleColor: tokens.axisTitleColor || tokens.textSecondary,\n titleFontSize: tokens.axisFontSize,\n },\n grid: {\n gridColor: tokens.axisGridColor || tokens.borderColor,\n },\n tick: {\n tickColor: tokens.axisLineColor || tokens.borderColor,\n },\n line: {\n lineColor: tokens.axisLineColor || tokens.borderColor,\n },\n})\n\nconst getPivotGridPatch = (tokens: TokenThemeDefinition) => ({\n borderColor: tokens.tableBorderColor || tokens.borderColor,\n bodyFontSize: tokens.tableBodyFontSize,\n bodyFontColor: tokens.tableBodyFontColor || tokens.textPrimary,\n headerFontSize: tokens.tableHeaderFontSize,\n headerFontColor: tokens.tableHeaderFontColor || tokens.textPrimary,\n headerBackgroundColor: tokens.tableHeaderBackgroundColor || tokens.surfaceColor || 'transparent',\n hoverHeaderBackgroundColor: tokens.tableHoverHeaderBackgroundColor || withAlpha(getAccentColor(tokens), 0.18),\n hoverHeaderInlineBackgroundColor:\n tokens.tableHoverHeaderInlineBackgroundColor || withAlpha(getAccentColor(tokens), 0.08),\n titleFontColor: tokens.textPrimary,\n titleFontSize: tokens.tableHeaderFontSize,\n chartGridColor: tokens.axisGridColor || tokens.borderColor,\n axisLabelColor: tokens.axisLabelColor || tokens.textSecondary,\n axisLabelFontSize: tokens.axisFontSize,\n})\n\nconst getPlayerPatch = (tokens: TokenThemeDefinition) => {\n const accentColor = getAccentColor(tokens)\n\n return {\n fontFamily: tokens.fontFamily,\n fontSize: tokens.playerFontSize,\n railColor: tokens.playerRailColor || tokens.borderColor,\n trackColor: accentColor,\n sliderHandleColor: tokens.playerSliderHandleColor || tokens.surfaceColor || '#ffffff',\n sliderHandleBorderColor: tokens.playerSliderHandleBorderColor || accentColor,\n startButtonColor: accentColor,\n pauseButtonColor: accentColor,\n backwardButtonColor: accentColor,\n forwardButtonColor: accentColor,\n }\n}\n\nconst getTablePatch = (tokens: TokenThemeDefinition) => {\n const accentColor = getAccentColor(tokens)\n\n return {\n borderColor: tokens.tableBorderColor || tokens.borderColor,\n bodyFontSize: tokens.tableBodyFontSize,\n bodyFontFamily: tokens.fontFamily,\n bodyFontColor: tokens.tableBodyFontColor || tokens.textPrimary,\n headerFontSize: tokens.tableHeaderFontSize,\n headerFontFamily: tokens.fontFamily,\n headerFontColor: tokens.tableHeaderFontColor || tokens.textPrimary,\n headerBackgroundColor: tokens.tableHeaderBackgroundColor || tokens.surfaceColor || 'transparent',\n hoverBodyBackgroundColor: tokens.tableHoverBodyBackgroundColor || withAlpha(accentColor, 0.18),\n hoverBodyInlineBackgroundColor: tokens.tableHoverBodyInlineBackgroundColor || withAlpha(accentColor, 0.08),\n hoverHeaderBackgroundColor: tokens.tableHoverHeaderBackgroundColor || withAlpha(accentColor, 0.18),\n hoverHeaderInlineBackgroundColor: tokens.tableHoverHeaderInlineBackgroundColor || withAlpha(accentColor, 0.08),\n selectedBorderColor: tokens.tableSelectedBorderColor || accentColor,\n selectedBackgroundColor: tokens.tableSelectedBackgroundColor || withAlpha(accentColor, 0.12),\n backgroundColor: tokens.surfaceBackgroundColor || 'transparent',\n barAxisColor: tokens.axisLineColor || tokens.borderColor,\n backgroundColorScale: {\n minColor: tokens.linearColorScheme[0],\n maxColor: tokens.linearColorScheme[1],\n },\n }\n}\n\nconst getChartPatch = (tokens: TokenThemeDefinition) => ({\n backgroundColor: 'transparent',\n fontFamily: tokens.fontFamily,\n color: {\n colorScheme: [...tokens.colorScheme],\n linearColorScheme: [...tokens.linearColorScheme],\n positiveColor: tokens.positiveColor,\n negativeColor: tokens.negativeColor,\n },\n label: {\n labelFontSize: tokens.labelFontSize,\n labelColor: tokens.labelColor || tokens.textPrimary,\n labelStroke: tokens.labelStroke,\n },\n legend: {\n labelColor: tokens.legendLabelColor || tokens.textSecondary,\n labelFontSize: tokens.legendFontSize,\n pagerIconColor: tokens.legendPagerIconColor || tokens.textSecondary,\n pagerIconDisableColor: tokens.legendPagerIconDisableColor || tokens.borderColor,\n },\n tooltip: {\n backgroundColor: tokens.tooltipBackgroundColor,\n borderColor: tokens.tooltipBorderColor || tokens.borderColor,\n fontSize: tokens.tooltipFontSize,\n keyColor: tokens.textSecondary,\n valueColor: tokens.textPrimary,\n titleColor: tokens.textPrimary,\n },\n})\n\nconst getAnnotationLinePatch = (tokens: TokenThemeDefinition) => ({\n lineColor: tokens.annotationLineColor,\n lineStyle: tokens.annotationLineStyle,\n lineDash: tokens.annotationLineDash,\n textColor: tokens.annotationTextColor,\n textBackgroundColor: tokens.annotationTextBackgroundColor,\n textBackgroundBorderColor: tokens.annotationTextBackgroundColor,\n textBackgroundOpacity: tokens.annotationTextBackgroundOpacity,\n})\n\nconst getAnnotationTextPatch = (tokens: TokenThemeDefinition) => ({\n textColor: tokens.annotationTextColor,\n textBackgroundColor: tokens.annotationTextBackgroundColor,\n textBackgroundBorderColor: tokens.annotationTextBackgroundColor,\n textBackgroundOpacity: tokens.annotationTextBackgroundOpacity,\n})\n\nconst getAnnotationPatch = (tokens: TokenThemeDefinition) => {\n const annotationLinePatch = getAnnotationLinePatch(tokens)\n const annotationTextPatch = getAnnotationTextPatch(tokens)\n\n return {\n annotationPoint: {\n textFontSize: tokens.labelFontSize,\n ...annotationTextPatch,\n },\n annotationHorizontalLine: {\n textFontSize: tokens.labelFontSize,\n ...annotationLinePatch,\n },\n annotationVerticalLine: {\n textFontSize: tokens.labelFontSize,\n ...annotationLinePatch,\n },\n annotationDifferenceLine: {\n textFontSize: tokens.labelFontSize,\n lineColor: tokens.annotationLineColor,\n lineStyle: tokens.annotationLineStyle,\n lineDash: tokens.annotationLineDash,\n textColor: tokens.annotationTextColor,\n textBackgroundColor: tokens.annotationTextBackgroundColor,\n textBackgroundOpacity: tokens.annotationTextBackgroundOpacity,\n },\n annotationArea: {\n textFontSize: tokens.labelFontSize,\n ...annotationTextPatch,\n },\n }\n}\n\nconst getRegressionLinePatch = (tokens: TokenThemeDefinition) => ({\n kdeRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n ecdfRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n linearRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n lowessRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n polynomialRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n logisticRegressionLine: {\n textFontSize: tokens.labelFontSize,\n },\n})\n\nconst withAxesAndExtras = (\n chartType: ThemeConfigKey,\n chartConfig: NonNullable<ThemeConfigMap[ThemeConfigKey]>,\n tokens: TokenThemeDefinition,\n) => {\n let nextChartConfig = mergeThemeNode(chartConfig, getChartPatch(tokens))\n const chartRecord = nextChartConfig as Record<string, unknown>\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'xAxis')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { xAxis: getAxisPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'yAxis')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { yAxis: getAxisPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'primaryYAxis')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { primaryYAxis: getAxisPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'secondaryYAxis')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { secondaryYAxis: getAxisPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'pivotGrid')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { pivotGrid: getPivotGridPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'annotation')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { annotation: getAnnotationPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (Object.prototype.hasOwnProperty.call(chartRecord, 'regressionLine')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { regressionLine: getRegressionLinePatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n if (raceChartTypes.includes(chartType) && Object.prototype.hasOwnProperty.call(chartRecord, 'player')) {\n nextChartConfig = mergeThemeNode(nextChartConfig, { player: getPlayerPatch(tokens) } as Partial<\n typeof nextChartConfig\n >)\n }\n\n return nextChartConfig\n}\n\nexport const createTokenThemeConfig = (tokens: TokenThemeDefinition): CustomThemeConfig => {\n const baseTheme = tokens.baseTheme === 'dark' ? darkTheme() : lightTheme()\n const baseConfig = (baseTheme.config || {}) as ThemeConfigMap\n const nextConfig = {} as ThemeConfigMap\n\n for (const chartType of Object.keys(baseConfig) as ThemeConfigKey[]) {\n const chartConfig = baseConfig[chartType]\n if (!chartConfig) {\n continue\n }\n\n if (chartType === 'table' || chartType === 'pivotTable') {\n nextConfig[chartType] = mergeThemeNode(chartConfig, getTablePatch(tokens)) as ThemeConfigMap[ThemeConfigKey]\n continue\n }\n\n nextConfig[chartType] = withAxesAndExtras(chartType, chartConfig, tokens) as ThemeConfigMap[ThemeConfigKey]\n }\n\n return {\n config: nextConfig as Config,\n }\n}\n\nexport const registerTokenTheme = (\n themeName: string,\n tokens: TokenThemeDefinition,\n options?: RegisterTokenThemeOptions,\n) => {\n ensureRegisterAll(options)\n registerCustomTheme(themeName, createTokenThemeConfig(tokens))\n}\n\nexport const registerTokenThemes = (themes: TokenThemeRegistry, options?: RegisterTokenThemeOptions) => {\n ensureRegisterAll(options)\n\n for (const [themeName, tokens] of Object.entries(themes)) {\n registerCustomTheme(themeName, createTokenThemeConfig(tokens))\n }\n}\n"],"names":["raceChartTypes","hasEnsuredRegisterAll","isRecord","value","Array","mergeThemeNode","base","patch","result","key","patchValue","Object","undefined","currentValue","withAlpha","color","alpha","tinycolor","ensureRegisterAll","options","registerAll","getAccentColor","tokens","getAxisPatch","getPivotGridPatch","getPlayerPatch","accentColor","getTablePatch","getChartPatch","getAnnotationLinePatch","getAnnotationTextPatch","getAnnotationPatch","annotationLinePatch","annotationTextPatch","getRegressionLinePatch","withAxesAndExtras","chartType","chartConfig","nextChartConfig","chartRecord","createTokenThemeConfig","baseTheme","darkTheme","lightTheme","baseConfig","nextConfig","registerTokenTheme","themeName","registerCustomTheme","registerTokenThemes","themes"],"mappings":"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"}
@@ -20,6 +20,7 @@ export declare abstract class VSeedBuilder {
20
20
  id: string;
21
21
  alias: string;
22
22
  }>;
23
+ abstract getColorValueMap: () => Record<string, string> | undefined;
23
24
  abstract get spec(): Spec | null;
24
25
  abstract set spec(value: Spec | null);
25
26
  abstract get vseed(): VSeed;
@@ -1 +1 @@
1
- {"version":3,"file":"types/builder/builder.js","sources":["../../../../src/types/builder/builder.ts"],"sourcesContent":["import type { Spec } from 'src/types'\nimport type { ChartType, CustomThemeConfig } from '../properties'\nimport type { VSeed } from '../vseed'\nimport type { AdvancedPipeline, SpecPipeline } from '../pipeline'\nimport type { AdvancedVSeed } from '../advancedVSeed'\n\nexport abstract class VSeedBuilder {\n abstract build: () => Spec\n abstract buildAdvanced: () => AdvancedVSeed | null\n abstract buildSpec: (advancedVSeed: AdvancedVSeed) => Spec\n abstract prepare: () => Promise<void>\n\n static getAdvancedPipeline: (chartType: ChartType) => AdvancedPipeline\n static getSpecPipeline: (chartType: ChartType) => SpecPipeline\n static getTheme: (themeKey: string) => CustomThemeConfig\n static getThemeMap: () => Record<string, CustomThemeConfig>\n\n abstract getColorItems: () => { id: string; alias: string }[]\n abstract getColorIdMap: () => Record<string, { id: string; alias: string }>\n\n abstract get spec(): Spec | null\n abstract set spec(value: Spec | null)\n abstract get vseed(): VSeed\n abstract set vseed(value: VSeed)\n abstract get advancedVSeed(): AdvancedVSeed | null\n abstract set advancedVSeed(value: AdvancedVSeed | null)\n}\n"],"names":["VSeedBuilder"],"mappings":"AAMO,MAAeA;IAMpB,OAAO,oBAA+D;IACtE,OAAO,gBAAuD;IAC9D,OAAO,SAAiD;IACxD,OAAO,YAAoD;AAW7D"}
1
+ {"version":3,"file":"types/builder/builder.js","sources":["../../../../src/types/builder/builder.ts"],"sourcesContent":["import type { Spec } from 'src/types'\nimport type { ChartType, CustomThemeConfig } from '../properties'\nimport type { VSeed } from '../vseed'\nimport type { AdvancedPipeline, SpecPipeline } from '../pipeline'\nimport type { AdvancedVSeed } from '../advancedVSeed'\n\nexport abstract class VSeedBuilder {\n abstract build: () => Spec\n abstract buildAdvanced: () => AdvancedVSeed | null\n abstract buildSpec: (advancedVSeed: AdvancedVSeed) => Spec\n abstract prepare: () => Promise<void>\n\n static getAdvancedPipeline: (chartType: ChartType) => AdvancedPipeline\n static getSpecPipeline: (chartType: ChartType) => SpecPipeline\n static getTheme: (themeKey: string) => CustomThemeConfig\n static getThemeMap: () => Record<string, CustomThemeConfig>\n\n abstract getColorItems: () => { id: string; alias: string }[]\n abstract getColorIdMap: () => Record<string, { id: string; alias: string }>\n abstract getColorValueMap: () => Record<string, string> | undefined\n\n abstract get spec(): Spec | null\n abstract set spec(value: Spec | null)\n abstract get vseed(): VSeed\n abstract set vseed(value: VSeed)\n abstract get advancedVSeed(): AdvancedVSeed | null\n abstract set advancedVSeed(value: AdvancedVSeed | null)\n}\n"],"names":["VSeedBuilder"],"mappings":"AAMO,MAAeA;IAMpB,OAAO,oBAA+D;IACtE,OAAO,gBAAuD;IAC9D,OAAO,SAAiD;IACxD,OAAO,YAAoD;AAY7D"}
@@ -2556,6 +2556,11 @@ export declare const zArea: z.ZodObject<{
2556
2556
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2557
2557
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2558
2558
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2559
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
2560
+ solid: "solid";
2561
+ dashed: "dashed";
2562
+ dotted: "dotted";
2563
+ }>>>;
2559
2564
  }, z.core.$strip>>, z.ZodObject<{
2560
2565
  start: z.ZodObject<{
2561
2566
  selector: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodRecord<z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodAny>, z.ZodObject<{
@@ -2707,6 +2712,11 @@ export declare const zArea: z.ZodObject<{
2707
2712
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2708
2713
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2709
2714
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2715
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
2716
+ solid: "solid";
2717
+ dashed: "dashed";
2718
+ dotted: "dotted";
2719
+ }>>>;
2710
2720
  }, z.core.$strip>]>>>;
2711
2721
  dimensionLinkage: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2712
2722
  enable: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
@@ -1885,6 +1885,11 @@ export declare const zBar: z.ZodObject<{
1885
1885
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1886
1886
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1887
1887
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1888
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
1889
+ solid: "solid";
1890
+ dashed: "dashed";
1891
+ dotted: "dotted";
1892
+ }>>>;
1888
1893
  }, z.core.$strip>>, z.ZodObject<{
1889
1894
  start: z.ZodObject<{
1890
1895
  selector: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodRecord<z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodAny>, z.ZodObject<{
@@ -2036,6 +2041,11 @@ export declare const zBar: z.ZodObject<{
2036
2041
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2037
2042
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2038
2043
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2044
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
2045
+ solid: "solid";
2046
+ dashed: "dashed";
2047
+ dotted: "dotted";
2048
+ }>>>;
2039
2049
  }, z.core.$strip>]>>>;
2040
2050
  dimensionLinkage: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2041
2051
  enable: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
@@ -1882,6 +1882,11 @@ export declare const zBarParallel: z.ZodObject<{
1882
1882
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1883
1883
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1884
1884
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1885
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
1886
+ solid: "solid";
1887
+ dashed: "dashed";
1888
+ dotted: "dotted";
1889
+ }>>>;
1885
1890
  }, z.core.$strip>>, z.ZodObject<{
1886
1891
  start: z.ZodObject<{
1887
1892
  selector: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodRecord<z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodAny>, z.ZodObject<{
@@ -2033,6 +2038,11 @@ export declare const zBarParallel: z.ZodObject<{
2033
2038
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2034
2039
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2035
2040
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2041
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
2042
+ solid: "solid";
2043
+ dashed: "dashed";
2044
+ dotted: "dotted";
2045
+ }>>>;
2036
2046
  }, z.core.$strip>]>>>;
2037
2047
  dimensionLinkage: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2038
2048
  enable: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
@@ -1922,6 +1922,11 @@ export declare const zColumn: z.ZodObject<{
1922
1922
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1923
1923
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1924
1924
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1925
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
1926
+ solid: "solid";
1927
+ dashed: "dashed";
1928
+ dotted: "dotted";
1929
+ }>>>;
1925
1930
  }, z.core.$strip>>, z.ZodObject<{
1926
1931
  start: z.ZodObject<{
1927
1932
  selector: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodRecord<z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodAny>, z.ZodObject<{
@@ -2073,6 +2078,11 @@ export declare const zColumn: z.ZodObject<{
2073
2078
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2074
2079
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2075
2080
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2081
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
2082
+ solid: "solid";
2083
+ dashed: "dashed";
2084
+ dotted: "dotted";
2085
+ }>>>;
2076
2086
  }, z.core.$strip>]>>>;
2077
2087
  polynomialRegressionLine: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodArray<z.ZodObject<{
2078
2088
  enable: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
@@ -1907,6 +1907,11 @@ export declare const zColumnParallel: z.ZodObject<{
1907
1907
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1908
1908
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1909
1909
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1910
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
1911
+ solid: "solid";
1912
+ dashed: "dashed";
1913
+ dotted: "dotted";
1914
+ }>>>;
1910
1915
  }, z.core.$strip>>, z.ZodObject<{
1911
1916
  start: z.ZodObject<{
1912
1917
  selector: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodRecord<z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodAny>, z.ZodObject<{
@@ -2058,6 +2063,11 @@ export declare const zColumnParallel: z.ZodObject<{
2058
2063
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2059
2064
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2060
2065
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2066
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
2067
+ solid: "solid";
2068
+ dashed: "dashed";
2069
+ dotted: "dotted";
2070
+ }>>>;
2061
2071
  }, z.core.$strip>]>>>;
2062
2072
  dimensionLinkage: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2063
2073
  enable: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
@@ -2247,6 +2247,11 @@ export declare const zLine: z.ZodObject<{
2247
2247
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2248
2248
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2249
2249
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2250
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
2251
+ solid: "solid";
2252
+ dashed: "dashed";
2253
+ dotted: "dotted";
2254
+ }>>>;
2250
2255
  }, z.core.$strip>>, z.ZodObject<{
2251
2256
  start: z.ZodObject<{
2252
2257
  selector: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodRecord<z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodAny>, z.ZodObject<{
@@ -2398,6 +2403,11 @@ export declare const zLine: z.ZodObject<{
2398
2403
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2399
2404
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2400
2405
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2406
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
2407
+ solid: "solid";
2408
+ dashed: "dashed";
2409
+ dotted: "dotted";
2410
+ }>>>;
2401
2411
  }, z.core.$strip>]>>>;
2402
2412
  dimensionLinkage: z.ZodOptional<z.ZodNullable<z.ZodObject<{
2403
2413
  enable: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
@@ -917,6 +917,11 @@ export declare const zAnnotation: z.ZodObject<{
917
917
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
918
918
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
919
919
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
920
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
921
+ solid: "solid";
922
+ dashed: "dashed";
923
+ dotted: "dotted";
924
+ }>>>;
920
925
  }, z.core.$strip>, z.ZodArray<z.ZodObject<{
921
926
  start: z.ZodObject<{
922
927
  selector: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodRecord<z.ZodUnion<[z.ZodString, z.ZodNumber]>, z.ZodAny>, z.ZodObject<{
@@ -1068,6 +1073,11 @@ export declare const zAnnotation: z.ZodObject<{
1068
1073
  textColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1069
1074
  textBackgroundColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1070
1075
  lineColor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1076
+ lineStyle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
1077
+ solid: "solid";
1078
+ dashed: "dashed";
1079
+ dotted: "dotted";
1080
+ }>>>;
1071
1081
  }, z.core.$strip>>]>>>;
1072
1082
  }, z.core.$strip>;
1073
1083
  export type Annotation = z.infer<typeof zAnnotation>;