You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

generate.ts 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import Rectangle from './rectangle'
  2. import Ellipse from './ellipse'
  3. import Polyline from './polyline'
  4. import Dot from './dot'
  5. import Ray from './ray'
  6. import Line from './line'
  7. import Arrow from './arrow'
  8. import Draw from './draw'
  9. import Utils from './utils'
  10. import Vec from 'utils/vec'
  11. import { NumberControl, VectorControl, codeControls, controls } from './control'
  12. import { codeShapes } from './index'
  13. import { CodeControl, Data, Shape } from 'types'
  14. import { getPage } from 'utils'
  15. import { transform } from 'sucrase'
  16. const baseScope = {
  17. Dot,
  18. Ellipse,
  19. Ray,
  20. Line,
  21. Polyline,
  22. Rectangle,
  23. Vec,
  24. Utils,
  25. Arrow,
  26. Draw,
  27. VectorControl,
  28. NumberControl,
  29. }
  30. /**
  31. * Evaluate code, collecting generated shapes in the shape set. Return the
  32. * collected shapes as an array.
  33. * @param code
  34. */
  35. export function generateFromCode(
  36. data: Data,
  37. code: string
  38. ): {
  39. shapes: Shape[]
  40. controls: CodeControl[]
  41. } {
  42. codeControls.clear()
  43. codeShapes.clear()
  44. ;(window as any).isUpdatingCode = false
  45. ;(window as any).currentPageId = data.currentPageId
  46. const { currentPageId } = data
  47. const scope = { ...baseScope, controls, currentPageId }
  48. const transformed = transform(code, { transforms: ['typescript'] }).code
  49. new Function(...Object.keys(scope), `${transformed}`)(...Object.values(scope))
  50. const generatedShapes = Array.from(codeShapes.values()).map((instance) => ({
  51. ...instance.shape,
  52. isGenerated: true,
  53. parentId: getPage(data).id,
  54. }))
  55. const generatedControls = Array.from(codeControls.values())
  56. return { shapes: generatedShapes, controls: generatedControls }
  57. }
  58. /**
  59. * Evaluate code, collecting generated shapes in the shape set. Return the
  60. * collected shapes as an array.
  61. * @param code
  62. */
  63. export function updateFromCode(
  64. data: Data,
  65. code: string
  66. ): {
  67. shapes: Shape[]
  68. } {
  69. codeShapes.clear()
  70. ;(window as any).isUpdatingCode = true
  71. ;(window as any).currentPageId = data.currentPageId
  72. const { currentPageId } = data
  73. const scope = {
  74. ...baseScope,
  75. currentPageId,
  76. controls: Object.fromEntries(
  77. Object.entries(controls).map(([_, control]) => [
  78. control.label,
  79. control.value,
  80. ])
  81. ),
  82. }
  83. new Function(...Object.keys(scope), `${code}`)(...Object.values(scope))
  84. const generatedShapes = Array.from(codeShapes.values()).map(
  85. (instance) => instance.shape
  86. )
  87. return { shapes: generatedShapes }
  88. }