@meonode/canvas 1.5.6 → 1.6.0-beta.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 (61) hide show
  1. package/dist/cjs/canvas/canvas.type.d.ts +34 -1
  2. package/dist/cjs/canvas/canvas.type.d.ts.map +1 -1
  3. package/dist/cjs/canvas/chart.canvas.util.d.ts +2 -2
  4. package/dist/cjs/canvas/chart.canvas.util.d.ts.map +1 -1
  5. package/dist/cjs/canvas/chart.canvas.util.js +5 -2
  6. package/dist/cjs/canvas/chart.canvas.util.js.map +1 -1
  7. package/dist/cjs/canvas/grid.canvas.util.d.ts +3 -3
  8. package/dist/cjs/canvas/grid.canvas.util.d.ts.map +1 -1
  9. package/dist/cjs/canvas/grid.canvas.util.js +34 -1
  10. package/dist/cjs/canvas/grid.canvas.util.js.map +1 -1
  11. package/dist/cjs/canvas/image.canvas.util.d.ts +2 -2
  12. package/dist/cjs/canvas/image.canvas.util.d.ts.map +1 -1
  13. package/dist/cjs/canvas/image.canvas.util.js +4 -1
  14. package/dist/cjs/canvas/image.canvas.util.js.map +1 -1
  15. package/dist/cjs/canvas/layout.canvas.util.d.ts +4 -4
  16. package/dist/cjs/canvas/layout.canvas.util.d.ts.map +1 -1
  17. package/dist/cjs/canvas/layout.canvas.util.js +24 -3
  18. package/dist/cjs/canvas/layout.canvas.util.js.map +1 -1
  19. package/dist/cjs/canvas/root.canvas.util.d.ts +23 -4
  20. package/dist/cjs/canvas/root.canvas.util.d.ts.map +1 -1
  21. package/dist/cjs/canvas/root.canvas.util.js +147 -3
  22. package/dist/cjs/canvas/root.canvas.util.js.map +1 -1
  23. package/dist/cjs/canvas/text.canvas.util.d.ts +2 -2
  24. package/dist/cjs/canvas/text.canvas.util.d.ts.map +1 -1
  25. package/dist/cjs/canvas/text.canvas.util.js +5 -1
  26. package/dist/cjs/canvas/text.canvas.util.js.map +1 -1
  27. package/dist/cjs/index.d.ts +2 -1
  28. package/dist/cjs/index.d.ts.map +1 -1
  29. package/dist/cjs/index.js +2 -0
  30. package/dist/cjs/index.js.map +1 -1
  31. package/dist/cjs/render.worker.d.ts +2 -0
  32. package/dist/cjs/render.worker.d.ts.map +1 -0
  33. package/dist/cjs/render.worker.js +24 -0
  34. package/dist/cjs/render.worker.js.map +1 -0
  35. package/dist/esm/canvas/canvas.type.d.ts +34 -1
  36. package/dist/esm/canvas/canvas.type.d.ts.map +1 -1
  37. package/dist/esm/canvas/chart.canvas.util.d.ts +2 -2
  38. package/dist/esm/canvas/chart.canvas.util.d.ts.map +1 -1
  39. package/dist/esm/canvas/chart.canvas.util.js +6 -3
  40. package/dist/esm/canvas/grid.canvas.util.d.ts +3 -3
  41. package/dist/esm/canvas/grid.canvas.util.d.ts.map +1 -1
  42. package/dist/esm/canvas/grid.canvas.util.js +34 -3
  43. package/dist/esm/canvas/image.canvas.util.d.ts +2 -2
  44. package/dist/esm/canvas/image.canvas.util.d.ts.map +1 -1
  45. package/dist/esm/canvas/image.canvas.util.js +4 -1
  46. package/dist/esm/canvas/layout.canvas.util.d.ts +4 -4
  47. package/dist/esm/canvas/layout.canvas.util.d.ts.map +1 -1
  48. package/dist/esm/canvas/layout.canvas.util.js +24 -3
  49. package/dist/esm/canvas/root.canvas.util.d.ts +23 -4
  50. package/dist/esm/canvas/root.canvas.util.d.ts.map +1 -1
  51. package/dist/esm/canvas/root.canvas.util.js +146 -5
  52. package/dist/esm/canvas/text.canvas.util.d.ts +2 -2
  53. package/dist/esm/canvas/text.canvas.util.d.ts.map +1 -1
  54. package/dist/esm/canvas/text.canvas.util.js +5 -1
  55. package/dist/esm/index.d.ts +2 -1
  56. package/dist/esm/index.d.ts.map +1 -1
  57. package/dist/esm/index.js +2 -2
  58. package/dist/esm/render.worker.d.ts +2 -0
  59. package/dist/esm/render.worker.d.ts.map +1 -0
  60. package/dist/esm/render.worker.js +21 -0
  61. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import { BoxNode } from '../canvas/layout.canvas.util.js';
2
- import type { BaseProps, ChartProps, ChartType } from '../canvas/canvas.type.js';
2
+ import type { BaseProps, ChartProps, ChartType, NodeDescriptor } from '../canvas/canvas.type.js';
3
3
  import type { CanvasRenderingContext2D } from 'skia-canvas';
4
4
  export declare class ChartNode<T extends ChartType> extends BoxNode {
5
5
  private chartData;
@@ -17,5 +17,5 @@ export declare class ChartNode<T extends ChartType> extends BoxNode {
17
17
  private renderLegend;
18
18
  private generateColor;
19
19
  }
20
- export declare const Chart: <T extends ChartType>(props: ChartProps<T> & BaseProps) => ChartNode<T>;
20
+ export declare const Chart: <T extends ChartType>(props: ChartProps<T> & BaseProps) => NodeDescriptor;
21
21
  //# sourceMappingURL=chart.canvas.util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/chart.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAO,MAAM,gCAAgC,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAoC,UAAU,EAAE,SAAS,EAAqB,MAAM,yBAAyB,CAAA;AACpI,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAI3D,qBAAa,SAAS,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,OAAO;IACzD,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,YAAY,CAA0B;gBAElC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS;IAyB5C,OAAO,CAAC,aAAa;IAqBrB,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IA8B3G,OAAO,CAAC,sBAAsB;IA4B9B,OAAO,CAAC,eAAe;IAqGvB,OAAO,CAAC,cAAc;IA4ItB,OAAO,CAAC,eAAe;IAgIvB,OAAO,CAAC,cAAc;IAsEtB,OAAO,CAAC,mBAAmB;IAsE3B,OAAO,CAAC,YAAY;IA0HpB,OAAO,CAAC,aAAa;CAItB;AAED,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,SAAS,EAAE,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,KAAG,SAAS,CAAC,CAAC,CAAyB,CAAA"}
1
+ {"version":3,"file":"chart.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/chart.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAW,MAAM,gCAAgC,CAAA;AACjE,OAAO,KAAK,EAAE,SAAS,EAAoC,UAAU,EAAE,SAAS,EAAqB,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACpJ,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAI3D,qBAAa,SAAS,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,OAAO;IACzD,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,YAAY,CAA0B;gBAElC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS;IAyB5C,OAAO,CAAC,aAAa;IAqBrB,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IA8B3G,OAAO,CAAC,sBAAsB;IA4B9B,OAAO,CAAC,eAAe;IAqGvB,OAAO,CAAC,cAAc;IA4ItB,OAAO,CAAC,eAAe;IAgIvB,OAAO,CAAC,cAAc;IAsEtB,OAAO,CAAC,mBAAmB;IAsE3B,OAAO,CAAC,YAAY;IA0HpB,OAAO,CAAC,aAAa;CAItB;AAED,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,SAAS,EAAE,OAAO,UAAU,CAAC,CAAC,CAAC,GAAG,SAAS,KAAG,cAG5E,CAAA"}
@@ -1,4 +1,4 @@
1
- import { BoxNode, Row } from './layout.canvas.util.js';
1
+ import { BoxNode, RowNode } from './layout.canvas.util.js';
2
2
  import { Style } from '../constant/common.const.js';
3
3
  import { TextNode } from './text.canvas.util.js';
4
4
 
@@ -577,7 +577,7 @@ class ChartNode extends BoxNode {
577
577
  }
578
578
  const finalNodes = legendNodes.filter((node) => !!node);
579
579
  if (finalNodes.length > 0) {
580
- const legendContainer = Row({
580
+ const legendContainer = new RowNode({
581
581
  children: finalNodes,
582
582
  width,
583
583
  height,
@@ -666,6 +666,9 @@ class ChartNode extends BoxNode {
666
666
  return colors[index % colors.length];
667
667
  }
668
668
  }
669
- const Chart = (props) => new ChartNode(props);
669
+ const Chart = (props) => ({
670
+ __type: 'Chart',
671
+ props: props,
672
+ });
670
673
 
671
674
  export { Chart, ChartNode };
@@ -1,4 +1,4 @@
1
- import type { GridProps, GridItemProps } from '../canvas/canvas.type.js';
1
+ import type { GridProps, GridItemProps, NodeDescriptor } from '../canvas/canvas.type.js';
2
2
  import { BoxNode, RowNode } from '../canvas/layout.canvas.util.js';
3
3
  /**
4
4
  * GridItem Node. Theoretically just a BoxNode but typed differently in factory.
@@ -11,7 +11,7 @@ export declare class GridItemNode extends BoxNode {
11
11
  /**
12
12
  * Factory for GridItem.
13
13
  */
14
- export declare const GridItem: (props: GridItemProps) => GridItemNode;
14
+ export declare const GridItem: ({ children, ...rest }: GridItemProps) => NodeDescriptor;
15
15
  /**
16
16
  * Grid layout node that arranges children in a 2D grid.
17
17
  * Implements a simplified version of the CSS Grid Layout algorithm.
@@ -42,5 +42,5 @@ export declare class GridNode extends RowNode {
42
42
  /**
43
43
  * Factory function to create a new GridNode instance.
44
44
  */
45
- export declare const Grid: (props: GridProps) => GridNode;
45
+ export declare const Grid: ({ children, ...rest }: GridProps) => NodeDescriptor;
46
46
  //# sourceMappingURL=grid.canvas.util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grid.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/grid.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAiB,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAIjE;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,OAAO;gBAC3B,KAAK,EAAE,aAAa;CAMjC;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,OAAO,aAAa,iBAA4B,CAAA;AAEzE;;;GAGG;AACH,qBAAa,QAAS,SAAQ,OAAO;IACnC;;;OAGG;gBACS,KAAK,EAAE,SAAS;IAQ5B;;OAEG;IACH,OAAO,CAAC,UAAU;IAwBlB;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;OAEG;cACgB,+BAA+B;IAoTlD;;OAEG;IACH,OAAO,CAAC,aAAa;CAkCtB;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,GAAI,OAAO,SAAS,aAAwB,CAAA"}
1
+ {"version":3,"file":"grid.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/grid.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAiB,aAAa,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAEtG,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAUjE;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,OAAO;gBAC3B,KAAK,EAAE,aAAa;CAMjC;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,uBAAuB,aAAa,KAAG,cAI9D,CAAA;AAEF;;;GAGG;AACH,qBAAa,QAAS,SAAQ,OAAO;IACnC;;;OAGG;gBACS,KAAK,EAAE,SAAS;IAQ5B;;OAEG;IACH,OAAO,CAAC,UAAU;IAwBlB;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;OAEG;cACgB,+BAA+B;IAoTlD;;OAEG;IACH,OAAO,CAAC,aAAa;CAkCtB;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,GAAI,uBAAuB,SAAS,KAAG,cAItD,CAAA"}
@@ -1,7 +1,34 @@
1
- import { RowNode } from './layout.canvas.util.js';
1
+ import { BoxNode, RowNode } from './layout.canvas.util.js';
2
2
  import { Style } from '../constant/common.const.js';
3
3
  import { parsePercentage } from './canvas.helper.js';
4
4
 
5
+ function normalizeDescriptorChildren(children) {
6
+ if (children === undefined || children === null || children === false)
7
+ return undefined;
8
+ const arr = (Array.isArray(children) ? children : [children]).filter(Boolean);
9
+ return arr.length > 0 ? arr : undefined;
10
+ }
11
+ /**
12
+ * GridItem Node. Theoretically just a BoxNode but typed differently in factory.
13
+ * In runtime, it behaves almost like a BoxNode, but we can detect it if needed,
14
+ * or simply rely on the props being present in the instance.
15
+ */
16
+ class GridItemNode extends BoxNode {
17
+ constructor(props) {
18
+ super({
19
+ ...props,
20
+ name: 'GridItem',
21
+ });
22
+ }
23
+ }
24
+ /**
25
+ * Factory for GridItem.
26
+ */
27
+ const GridItem = ({ children, ...rest }) => ({
28
+ __type: 'GridItem',
29
+ props: rest,
30
+ children: normalizeDescriptorChildren(children),
31
+ });
5
32
  /**
6
33
  * Grid layout node that arranges children in a 2D grid.
7
34
  * Implements a simplified version of the CSS Grid Layout algorithm.
@@ -381,6 +408,10 @@ class GridNode extends RowNode {
381
408
  /**
382
409
  * Factory function to create a new GridNode instance.
383
410
  */
384
- const Grid = (props) => new GridNode(props);
411
+ const Grid = ({ children, ...rest }) => ({
412
+ __type: 'Grid',
413
+ props: rest,
414
+ children: normalizeDescriptorChildren(children),
415
+ });
385
416
 
386
- export { Grid, GridNode };
417
+ export { Grid, GridItem, GridItemNode, GridNode };
@@ -1,4 +1,4 @@
1
- import type { BaseProps, ImageProps } from '../canvas/canvas.type.js';
1
+ import type { BaseProps, ImageProps, NodeDescriptor } from '../canvas/canvas.type.js';
2
2
  import { type CanvasRenderingContext2D } from 'skia-canvas';
3
3
  import { BoxNode } from '../canvas/layout.canvas.util.js';
4
4
  /**
@@ -30,5 +30,5 @@ export declare class ImageNode extends BoxNode {
30
30
  /**
31
31
  * Factory function to create ImageNode instances
32
32
  */
33
- export declare const Image: (props: ImageProps) => ImageNode;
33
+ export declare const Image: (props: ImageProps) => NodeDescriptor;
34
34
  //# sourceMappingURL=image.canvas.util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"image.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/image.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpE,OAAO,EAAE,KAAK,wBAAwB,EAAmC,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAsBxD;;;GAGG;AACH,qBAAa,SAAU,SAAQ,OAAO;IAC5B,KAAK,EAAE,UAAU,GAAG,SAAS,CAAA;IACrC,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,cAAc,CAA6B;gBAEvC,KAAK,EAAE,UAAU;IAYtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;;;;OAKG;IACH,OAAO,CAAC,UAAU;IA8GX,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzC;;;OAGG;cACgB,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAoJrH;AAED;;GAEG;AACH,eAAO,MAAM,KAAK,GAAI,OAAO,UAAU,cAAyB,CAAA"}
1
+ {"version":3,"file":"image.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/image.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACpF,OAAO,EAAE,KAAK,wBAAwB,EAAmC,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAsBxD;;;GAGG;AACH,qBAAa,SAAU,SAAQ,OAAO;IAC5B,KAAK,EAAE,UAAU,GAAG,SAAS,CAAA;IACrC,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,cAAc,CAA6B;gBAEvC,KAAK,EAAE,UAAU;IAYtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;;;;OAKG;IACH,OAAO,CAAC,UAAU;IA8GX,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzC;;;OAGG;cACgB,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAoJrH;AAED;;GAEG;AACH,eAAO,MAAM,KAAK,GAAI,OAAO,UAAU,KAAG,cAGxC,CAAA"}
@@ -305,6 +305,9 @@ class ImageNode extends BoxNode {
305
305
  /**
306
306
  * Factory function to create ImageNode instances
307
307
  */
308
- const Image = (props) => new ImageNode(props);
308
+ const Image = (props) => ({
309
+ __type: 'Image',
310
+ props: props,
311
+ });
309
312
 
310
313
  export { Image, ImageNode };
@@ -1,5 +1,5 @@
1
1
  import { type CanvasRenderingContext2D } from 'skia-canvas';
2
- import type { BaseProps, BoxProps } from '../canvas/canvas.type.js';
2
+ import type { BaseProps, BoxProps, NodeDescriptor } from '../canvas/canvas.type.js';
3
3
  import { Node } from '../constant/common.const.js';
4
4
  /**
5
5
  * @class BoxNode
@@ -92,7 +92,7 @@ export declare class BoxNode {
92
92
  * @param {BoxProps} props Box properties and configuration.
93
93
  * @returns {BoxNode} New BoxNode instance.
94
94
  */
95
- export declare const Box: (props: BoxProps) => BoxNode;
95
+ export declare const Box: ({ children, ...rest }: BoxProps) => NodeDescriptor;
96
96
  /**
97
97
  * @class ColumnNode
98
98
  * Node class for vertical column layout
@@ -105,7 +105,7 @@ export declare class ColumnNode extends BoxNode {
105
105
  * @param {BoxProps} props Column properties and configuration.
106
106
  * @returns {ColumnNode} New ColumnNode instance.
107
107
  */
108
- export declare const Column: (props: BoxProps) => ColumnNode;
108
+ export declare const Column: ({ children, ...rest }: BoxProps) => NodeDescriptor;
109
109
  /**
110
110
  * @class RowNode
111
111
  * @classdesc Node class for horizontal row layout.
@@ -118,5 +118,5 @@ export declare class RowNode extends BoxNode {
118
118
  * @param {BoxProps} props Row properties and configuration.
119
119
  * @returns {RowNode} New RowNode instance.
120
120
  */
121
- export declare const Row: (props: BoxProps) => RowNode;
121
+ export declare const Row: ({ children, ...rest }: BoxProps) => NodeDescriptor;
122
122
  //# sourceMappingURL=layout.canvas.util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/layout.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,yBAAyB,CAAA;AAGlF,OAAa,EAAS,IAAI,EAAE,MAAM,4BAA4B,CAAA;AAE9D;;;;GAIG;AACH,qBAAa,OAAO;IAClB;;OAEG;IACH,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE/B;;OAEG;IACH,IAAI,EAAE,IAAI,CAAA;IAEV;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAA;IAEnB;;OAEG;IACH,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAA;IAE3B;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IAEtB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;OAGG;gBACS,KAAK,GAAE,QAAQ,GAAG,SAAc;IAqB5C;;OAEG;IACI,sBAAsB;IAW7B;;;OAGG;IACH,SAAS,CAAC,sBAAsB,CAAC,WAAW,EAAE,QAAQ,GAAG,SAAS;IAkClE;;OAEG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;IAI/B;;;;OAIG;IACH,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IAanD;;;OAGG;IACI,cAAc,IAAI,OAAO;IAiBhC;;OAEG;IACH,SAAS,CAAC,+BAA+B;IAIzC;;;OAGG;IACH,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ;IAqInC;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,wBAAwB,EAAE,OAAO,GAAE,MAAU,EAAE,OAAO,GAAE,MAAU;IA+J9E;;;;;;;;OAQG;IACH,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAoR5G;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,OAAO,QAAQ,KAAG,OAA6B,CAAA;AAEnE;;;GAGG;AACH,qBAAa,UAAW,SAAQ,OAAO;gBACzB,KAAK,GAAE,QAAQ,GAAG,SAAc;CAS7C;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,OAAO,QAAQ,KAAG,UAAmC,CAAA;AAE5E;;;GAGG;AACH,qBAAa,OAAQ,SAAQ,OAAO;gBACtB,KAAK,GAAE,QAAQ,GAAG,SAAc;CAS7C;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,OAAO,QAAQ,KAAG,OAA6B,CAAA"}
1
+ {"version":3,"file":"layout.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/layout.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAkB,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGlG,OAAa,EAAS,IAAI,EAAE,MAAM,4BAA4B,CAAA;AAE9D;;;;GAIG;AACH,qBAAa,OAAO;IAClB;;OAEG;IACH,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE/B;;OAEG;IACH,IAAI,EAAE,IAAI,CAAA;IAEV;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAA;IAEnB;;OAEG;IACH,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAA;IAE3B;;OAEG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IAEtB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ;;;OAGG;gBACS,KAAK,GAAE,QAAQ,GAAG,SAAc;IAqB5C;;OAEG;IACI,sBAAsB;IAW7B;;;OAGG;IACH,SAAS,CAAC,sBAAsB,CAAC,WAAW,EAAE,QAAQ,GAAG,SAAS;IAkClE;;OAEG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;IAI/B;;;;OAIG;IACH,SAAS,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;IAanD;;;OAGG;IACI,cAAc,IAAI,OAAO;IAiBhC;;OAEG;IACH,SAAS,CAAC,+BAA+B;IAIzC;;;OAGG;IACH,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ;IAqInC;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,wBAAwB,EAAE,OAAO,GAAE,MAAU,EAAE,OAAO,GAAE,MAAU;IA+J9E;;;;;;;;OAQG;IACH,SAAS,CAAC,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAoR5G;AAWD;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,uBAAuB,QAAQ,KAAG,cAIpD,CAAA;AAEF;;;GAGG;AACH,qBAAa,UAAW,SAAQ,OAAO;gBACzB,KAAK,GAAE,QAAQ,GAAG,SAAc;CAS7C;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,uBAAuB,QAAQ,KAAG,cAIvD,CAAA;AAEF;;;GAGG;AACH,qBAAa,OAAQ,SAAQ,OAAO;gBACtB,KAAK,GAAE,QAAQ,GAAG,SAAc;CAS7C;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,GAAI,uBAAuB,QAAQ,KAAG,cAIpD,CAAA"}
@@ -718,12 +718,25 @@ class BoxNode {
718
718
  });
719
719
  }
720
720
  }
721
+ /**
722
+ * Normalizes children into a flat NodeDescriptor array, filtering falsy values.
723
+ */
724
+ function normalizeDescriptorChildren(children) {
725
+ if (children === undefined || children === null || children === false)
726
+ return undefined;
727
+ const arr = (Array.isArray(children) ? children : [children]).filter(Boolean);
728
+ return arr.length > 0 ? arr : undefined;
729
+ }
721
730
  /**
722
731
  * Creates a new BoxNode instance.
723
732
  * @param {BoxProps} props Box properties and configuration.
724
733
  * @returns {BoxNode} New BoxNode instance.
725
734
  */
726
- const Box = (props) => new BoxNode(props);
735
+ const Box = ({ children, ...rest }) => ({
736
+ __type: 'Box',
737
+ props: rest,
738
+ children: normalizeDescriptorChildren(children),
739
+ });
727
740
  /**
728
741
  * @class ColumnNode
729
742
  * Node class for vertical column layout
@@ -744,7 +757,11 @@ class ColumnNode extends BoxNode {
744
757
  * @param {BoxProps} props Column properties and configuration.
745
758
  * @returns {ColumnNode} New ColumnNode instance.
746
759
  */
747
- const Column = (props) => new ColumnNode(props);
760
+ const Column = ({ children, ...rest }) => ({
761
+ __type: 'Column',
762
+ props: rest,
763
+ children: normalizeDescriptorChildren(children),
764
+ });
748
765
  /**
749
766
  * @class RowNode
750
767
  * @classdesc Node class for horizontal row layout.
@@ -765,6 +782,10 @@ class RowNode extends BoxNode {
765
782
  * @param {BoxProps} props Row properties and configuration.
766
783
  * @returns {RowNode} New RowNode instance.
767
784
  */
768
- const Row = (props) => new RowNode(props);
785
+ const Row = ({ children, ...rest }) => ({
786
+ __type: 'Row',
787
+ props: rest,
788
+ children: normalizeDescriptorChildren(children),
789
+ });
769
790
 
770
791
  export { Box, BoxNode, Column, ColumnNode, Row, RowNode };
@@ -1,7 +1,24 @@
1
1
  import { Canvas } from 'skia-canvas';
2
- import { ColumnNode } from '../canvas/layout.canvas.util.js';
3
- import type { BaseProps, RootProps } from '../canvas/canvas.type.js';
2
+ import { ColumnNode, BoxNode } from '../canvas/layout.canvas.util.js';
3
+ import type { BaseProps, RootProps, NodeDescriptor } from '../canvas/canvas.type.js';
4
4
  export declare const _clearRegisteredFonts: () => void;
5
+ export interface CanvasEngineConfig {
6
+ /** Run rendering in worker threads to avoid blocking the event loop (default: true) */
7
+ workerMode?: boolean;
8
+ /** Number of worker threads in the pool (default: os.cpus().length - 1) */
9
+ workers?: number;
10
+ }
11
+ /**
12
+ * Configure the canvas rendering engine.
13
+ * Call this once at application startup before rendering.
14
+ */
15
+ export declare function configure(options: CanvasEngineConfig): void;
16
+ /**
17
+ * Converts a NodeDescriptor tree into actual BoxNode instances.
18
+ * Used both for non-worker rendering (inline tree building) and inside
19
+ * the render worker (reconstructing the tree from serialized descriptors).
20
+ */
21
+ export declare function buildTree(descriptor: NodeDescriptor): BoxNode;
5
22
  /**
6
23
  * Root node that manages the canvas rendering context and coordinates overall layout and drawing.
7
24
  * Inherits from ColumnNode to provide vertical layout capabilities.
@@ -36,9 +53,11 @@ export declare class RootNode extends ColumnNode {
36
53
  render(): Promise<Canvas>;
37
54
  }
38
55
  /**
39
- * Creates and renders a new root node with the given properties
56
+ * Creates and renders a new root node with the given properties.
57
+ * When worker mode is enabled via configure(), rendering runs in a worker thread
58
+ * and the returned object implements the same toBuffer/toBufferSync interface.
40
59
  * @param props Configuration properties for the root node
41
- * @returns Promise resolving to the rendered Canvas instance
60
+ * @returns Promise resolving to the rendered Canvas (or WorkerCanvas in worker mode)
42
61
  */
43
62
  export declare const Root: (props: RootProps) => Promise<Canvas>;
44
63
  //# sourceMappingURL=root.canvas.util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"root.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/root.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA8C,MAAM,aAAa,CAAA;AAChF,OAAO,EAAE,UAAU,EAAW,MAAM,gCAAgC,CAAA;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAUnE,eAAO,MAAM,qBAAqB,YAEjC,CAAA;AAED;;;GAGG;AACH,qBAAa,QAAS,SAAQ,UAAU;IACtC,6CAA6C;IAC7C,OAAO,CAAC,MAAM,CAAoB;IAClC,8CAA8C;IAC9C,OAAO,CAAC,GAAG,CAAwC;IACnD,4CAA4C;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,6CAA6C;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B;;;;OAIG;gBACS,KAAK,EAAE,SAAS,GAAG,SAAS;IAyCxC;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAazB;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;CA2ChC;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI,GAAU,OAAO,SAAS,oBAAuC,CAAA"}
1
+ {"version":3,"file":"root.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/root.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA8C,MAAM,aAAa,CAAA;AAChF,OAAO,EAAE,UAAU,EAAE,OAAO,EAAW,MAAM,gCAAgC,CAAA;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAgBnF,eAAO,MAAM,qBAAqB,YAEjC,CAAA;AAOD,MAAM,WAAW,kBAAkB;IACjC,uFAAuF;IACvF,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,kBAAkB,QAMpD;AA4ED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAmB7D;AAED;;;GAGG;AACH,qBAAa,QAAS,SAAQ,UAAU;IACtC,6CAA6C;IAC7C,OAAO,CAAC,MAAM,CAAoB;IAClC,8CAA8C;IAC9C,OAAO,CAAC,GAAG,CAAwC;IACnD,4CAA4C;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IACpC,6CAA6C;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAQ;IACrC,4DAA4D;IAC5D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B;;;;OAIG;gBACS,KAAK,EAAE,SAAS,GAAG,SAAS;IAoDxC;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAazB;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;CA2ChC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,GAAU,OAAO,SAAS,KAAG,OAAO,CAAC,MAAM,CAS3D,CAAA"}
@@ -1,12 +1,132 @@
1
1
  import { FontLibrary, Canvas } from 'skia-canvas';
2
- import { ColumnNode } from './layout.canvas.util.js';
2
+ import { ColumnNode, RowNode, BoxNode } from './layout.canvas.util.js';
3
3
  import { ImageNode } from './image.canvas.util.js';
4
+ import { TextNode } from './text.canvas.util.js';
5
+ import { ChartNode } from './chart.canvas.util.js';
6
+ import { GridItemNode, GridNode } from './grid.canvas.util.js';
4
7
  import { Style } from '../constant/common.const.js';
5
8
  import * as path from 'node:path';
6
9
  import * as fs from 'node:fs';
10
+ import { cpus } from 'node:os';
11
+ import { Worker } from 'node:worker_threads';
12
+ import { fileURLToPath } from 'node:url';
7
13
 
8
14
  /** Registry to track fonts that have already been loaded */
9
15
  const registeredFonts = new Map();
16
+ /** Engine configuration */
17
+ let _workerMode = true;
18
+ let _workerPoolSize = Math.max(1, cpus().length - 1);
19
+ let _workerPool = null;
20
+ /**
21
+ * Configure the canvas rendering engine.
22
+ * Call this once at application startup before rendering.
23
+ */
24
+ function configure(options) {
25
+ if (options.workerMode !== undefined)
26
+ _workerMode = options.workerMode;
27
+ if (options.workers !== undefined)
28
+ _workerPoolSize = options.workers;
29
+ if (_workerMode) {
30
+ _workerPool = new WorkerPool(_workerPoolSize);
31
+ }
32
+ }
33
+ /**
34
+ * Minimal Canvas-compatible wrapper returned when rendering in worker mode.
35
+ * Exposes toBuffer / toBufferSync so callers can use the result identically.
36
+ */
37
+ class WorkerCanvas {
38
+ _buffer;
39
+ constructor(_buffer) {
40
+ this._buffer = _buffer;
41
+ }
42
+ toBufferSync(_format) {
43
+ return this._buffer;
44
+ }
45
+ toBuffer(_format) {
46
+ return Promise.resolve(this._buffer);
47
+ }
48
+ }
49
+ /** Lazy-instantiated worker pool singleton */
50
+ class WorkerPool {
51
+ workers = [];
52
+ idle = [];
53
+ queue = [];
54
+ pending = new Map();
55
+ nextId = 0;
56
+ constructor(size) {
57
+ this.init(size);
58
+ }
59
+ async init(size) {
60
+ const workerFile = path.join(path.dirname(fileURLToPath(import.meta.url)), '../render.worker.js');
61
+ for (let i = 0; i < size; i++) {
62
+ const worker = new Worker(workerFile);
63
+ worker.on('message', ({ id, buffer, error }) => {
64
+ const task = this.pending.get(id);
65
+ if (!task)
66
+ return;
67
+ this.pending.delete(id);
68
+ this.idle.push(worker);
69
+ this.drain();
70
+ if (error) {
71
+ task.reject(new Error(error));
72
+ }
73
+ else {
74
+ task.resolve(buffer);
75
+ }
76
+ });
77
+ this.workers.push(worker);
78
+ this.idle.push(worker);
79
+ }
80
+ }
81
+ drain() {
82
+ while (this.queue.length > 0 && this.idle.length > 0) {
83
+ const task = this.queue.shift();
84
+ const worker = this.idle.pop();
85
+ worker.postMessage({ id: task.id, props: task.props });
86
+ }
87
+ }
88
+ render(props) {
89
+ return new Promise((resolve, reject) => {
90
+ const id = this.nextId++;
91
+ this.pending.set(id, { resolve, reject });
92
+ if (this.idle.length > 0) {
93
+ const worker = this.idle.pop();
94
+ worker.postMessage({ id, props });
95
+ }
96
+ else {
97
+ this.queue.push({ id, props });
98
+ }
99
+ });
100
+ }
101
+ terminate() {
102
+ this.workers.forEach(w => w.terminate());
103
+ }
104
+ }
105
+ /**
106
+ * Converts a NodeDescriptor tree into actual BoxNode instances.
107
+ * Used both for non-worker rendering (inline tree building) and inside
108
+ * the render worker (reconstructing the tree from serialized descriptors).
109
+ */
110
+ function buildTree(descriptor) {
111
+ switch (descriptor.__type) {
112
+ case 'Box':
113
+ return new BoxNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) });
114
+ case 'Column':
115
+ return new ColumnNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) });
116
+ case 'Row':
117
+ return new RowNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) });
118
+ case 'Grid':
119
+ return new GridNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) });
120
+ case 'GridItem':
121
+ return new GridItemNode({ ...descriptor.props, children: descriptor.children?.map(buildTree) });
122
+ case 'Image':
123
+ return new ImageNode(descriptor.props);
124
+ case 'Text':
125
+ return new TextNode(descriptor.text, descriptor.props);
126
+ case 'Chart':
127
+ return new ChartNode(descriptor.props);
128
+ }
129
+ }
10
130
  /**
11
131
  * Root node that manages the canvas rendering context and coordinates overall layout and drawing.
12
132
  * Inherits from ColumnNode to provide vertical layout capabilities.
@@ -56,6 +176,16 @@ class RootNode extends ColumnNode {
56
176
  this.targetWidth = props.width;
57
177
  this.targetHeight = props.height;
58
178
  this.node.setWidth(this.targetWidth);
179
+ // Convert any NodeDescriptor children to actual BoxNode instances
180
+ if (this.props.children) {
181
+ const childArray = Array.isArray(this.props.children) ? this.props.children : [this.props.children];
182
+ this.props.children = childArray.map(child => {
183
+ if (child && typeof child === 'object' && '__type' in child) {
184
+ return buildTree(child);
185
+ }
186
+ return child;
187
+ });
188
+ }
59
189
  // Initialize children nodes
60
190
  this.processInitialChildren();
61
191
  }
@@ -118,10 +248,21 @@ class RootNode extends ColumnNode {
118
248
  }
119
249
  }
120
250
  /**
121
- * Creates and renders a new root node with the given properties
251
+ * Creates and renders a new root node with the given properties.
252
+ * When worker mode is enabled via configure(), rendering runs in a worker thread
253
+ * and the returned object implements the same toBuffer/toBufferSync interface.
122
254
  * @param props Configuration properties for the root node
123
- * @returns Promise resolving to the rendered Canvas instance
255
+ * @returns Promise resolving to the rendered Canvas (or WorkerCanvas in worker mode)
124
256
  */
125
- const Root = async (props) => await new RootNode(props).render();
257
+ const Root = async (props) => {
258
+ if (_workerMode) {
259
+ if (!_workerPool) {
260
+ _workerPool = new WorkerPool(_workerPoolSize);
261
+ }
262
+ const buffer = await _workerPool.render(props);
263
+ return new WorkerCanvas(buffer);
264
+ }
265
+ return new RootNode(props).render();
266
+ };
126
267
 
127
- export { Root, RootNode };
268
+ export { Root, RootNode, buildTree, configure };
@@ -1,4 +1,4 @@
1
- import type { TextProps } from '../canvas/canvas.type.js';
1
+ import type { TextProps, NodeDescriptor } from '../canvas/canvas.type.js';
2
2
  import { type CanvasRenderingContext2D } from 'skia-canvas';
3
3
  import { BoxNode } from '../canvas/layout.canvas.util.js';
4
4
  /**
@@ -161,5 +161,5 @@ export declare class TextNode extends BoxNode {
161
161
  /**
162
162
  * Creates a new TextNode instance with rich text support
163
163
  */
164
- export declare const Text: (text: number | string, props?: TextProps) => TextNode;
164
+ export declare const Text: (text: number | string, props?: TextProps) => NodeDescriptor;
165
165
  //# sourceMappingURL=text.canvas.util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"text.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/text.canvas.util.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,yBAAyB,CAAA;AACrE,OAAO,EAAU,KAAK,wBAAwB,EAA2B,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAGxD;;;GAGG;AACH,qBAAa,QAAS,SAAQ,OAAO;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAwC;IACzE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,kBAAkB,CAAe;IAEjC,KAAK,EAAE,SAAS,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;gBAElC,IAAI,GAAE,MAAM,GAAG,MAAW,EAAE,KAAK,GAAE,SAAc;IAuB7D;;;;;;;;OAQG;WACW,gBAAgB,CAC5B,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,MAAM,EACZ,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,GAAE;QACL,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,UAAU,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAA;QACpC,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,CAAA;QAClC,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,SAAS,CAAC,EAAE,wBAAwB,CAAC,WAAW,CAAC,CAAA;QACjD,YAAY,CAAC,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAAA;KACnD;cAwBW,aAAa,IAAI,IAAI;IAoDxC;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,sBAAsB;IA8B9B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,aAAa;IA+ErB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,gBAAgB;IAyBxB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAM7B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAiCrB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAQjC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,WAAW;IA+NnB;;;;;;;;;OASG;IACH,OAAO,CAAC,YAAY;IA6KpB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAmErB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;;;;;;;;;;;;;;;OAgBG;cACgB,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAkXrH;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,GAAG,MAAM,EAAE,QAAQ,SAAS,aAA8B,CAAA"}
1
+ {"version":3,"file":"text.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/text.canvas.util.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAe,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACrF,OAAO,EAAU,KAAK,wBAAwB,EAA2B,MAAM,aAAa,CAAA;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAGxD;;;GAGG;AACH,qBAAa,QAAS,SAAQ,OAAO;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;IAC7C,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAwC;IACzE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,kBAAkB,CAAe;IAEjC,KAAK,EAAE,SAAS,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;gBAElC,IAAI,GAAE,MAAM,GAAG,MAAW,EAAE,KAAK,GAAE,SAAc;IAuB7D;;;;;;;;OAQG;WACW,gBAAgB,CAC5B,GAAG,EAAE,wBAAwB,EAC7B,IAAI,EAAE,MAAM,EACZ,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,GAAE;QACL,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,UAAU,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,CAAA;QACpC,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,CAAC,CAAA;QAClC,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,SAAS,CAAC,EAAE,wBAAwB,CAAC,WAAW,CAAC,CAAA;QACjD,YAAY,CAAC,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAAA;KACnD;cAwBW,aAAa,IAAI,IAAI;IAoDxC;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,sBAAsB;IA8B9B;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,aAAa;IA+ErB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,gBAAgB;IAyBxB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAM7B;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAiCrB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAQjC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,WAAW;IA+NnB;;;;;;;;;OASG;IACH,OAAO,CAAC,YAAY;IA6KpB;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAmErB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;;;;;;;;;;;;;;;OAgBG;cACgB,cAAc,CAAC,GAAG,EAAE,wBAAwB,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAkXrH;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,GAAG,MAAM,EAAE,QAAQ,SAAS,KAAG,cAI9D,CAAA"}
@@ -1150,6 +1150,10 @@ class TextNode extends BoxNode {
1150
1150
  /**
1151
1151
  * Creates a new TextNode instance with rich text support
1152
1152
  */
1153
- const Text = (text, props) => new TextNode(text, props);
1153
+ const Text = (text, props) => ({
1154
+ __type: 'Text',
1155
+ text,
1156
+ props,
1157
+ });
1154
1158
 
1155
1159
  export { Text, TextNode };
@@ -3,7 +3,8 @@ export * from './canvas/canvas.type.js';
3
3
  export { Box, Column, Row, type BoxNode } from './canvas/layout.canvas.util.js';
4
4
  export { Image } from './canvas/image.canvas.util.js';
5
5
  export { Text } from './canvas/text.canvas.util.js';
6
- export { Root } from './canvas/root.canvas.util.js';
6
+ export { Root, configure } from './canvas/root.canvas.util.js';
7
+ export { GridItem } from './canvas/grid.canvas.util.js';
7
8
  export { Grid } from './canvas/grid.canvas.util.js';
8
9
  export { Chart } from './canvas/chart.canvas.util.js';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAA;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAA"}
package/dist/esm/index.js CHANGED
@@ -2,7 +2,7 @@ export { Border, Style } from './constant/common.const.js';
2
2
  export { Box, Column, Row } from './canvas/layout.canvas.util.js';
3
3
  export { Image } from './canvas/image.canvas.util.js';
4
4
  export { Text } from './canvas/text.canvas.util.js';
5
- export { Root } from './canvas/root.canvas.util.js';
6
- export { Grid } from './canvas/grid.canvas.util.js';
5
+ export { Root, configure } from './canvas/root.canvas.util.js';
6
+ export { Grid, GridItem } from './canvas/grid.canvas.util.js';
7
7
  export { Chart } from './canvas/chart.canvas.util.js';
8
8
  export * from 'yoga-layout';
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=render.worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.worker.d.ts","sourceRoot":"","sources":["../../src/render.worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import { parentPort } from 'worker_threads';
2
+ import { RootNode } from './canvas/root.canvas.util.js';
3
+
4
+ /**
5
+ * Worker thread entry point for off-main-thread canvas rendering.
6
+ * Receives serialized RootProps (with NodeDescriptor children), builds the
7
+ * node tree, renders to canvas, encodes to PNG, and posts the buffer back.
8
+ */
9
+ if (!parentPort) {
10
+ throw new Error('[render.worker] Must be run as a worker thread');
11
+ }
12
+ parentPort.on('message', async ({ id, props }) => {
13
+ try {
14
+ const canvas = await new RootNode(props).render();
15
+ const buffer = canvas.toBufferSync('png');
16
+ parentPort.postMessage({ id, buffer });
17
+ }
18
+ catch (err) {
19
+ parentPort.postMessage({ id, error: String(err) });
20
+ }
21
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meonode/canvas",
3
- "version": "1.5.6",
3
+ "version": "1.6.0-beta.1",
4
4
  "description": "A declarative, component-based library for server-side canvas image generation. Write complex visuals with simple functions, similar to the composition style of @meonode/ui.",
5
5
  "keywords": [
6
6
  "canvas",