@react-scad/core 0.1.3

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 (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -0
  3. package/dist/index.d.ts +6 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +2 -0
  6. package/dist/primitives/circle.d.ts +14 -0
  7. package/dist/primitives/circle.d.ts.map +1 -0
  8. package/dist/primitives/circle.js +12 -0
  9. package/dist/primitives/cube.d.ts +13 -0
  10. package/dist/primitives/cube.d.ts.map +1 -0
  11. package/dist/primitives/cube.js +13 -0
  12. package/dist/primitives/cylinder.d.ts +16 -0
  13. package/dist/primitives/cylinder.d.ts.map +1 -0
  14. package/dist/primitives/cylinder.js +10 -0
  15. package/dist/primitives/difference.d.ts +11 -0
  16. package/dist/primitives/difference.d.ts.map +1 -0
  17. package/dist/primitives/difference.js +9 -0
  18. package/dist/primitives/group.d.ts +11 -0
  19. package/dist/primitives/group.d.ts.map +1 -0
  20. package/dist/primitives/group.js +9 -0
  21. package/dist/primitives/import.d.ts +14 -0
  22. package/dist/primitives/import.d.ts.map +1 -0
  23. package/dist/primitives/import.js +15 -0
  24. package/dist/primitives/index.d.ts +41 -0
  25. package/dist/primitives/index.d.ts.map +1 -0
  26. package/dist/primitives/index.js +20 -0
  27. package/dist/primitives/intersection.d.ts +11 -0
  28. package/dist/primitives/intersection.d.ts.map +1 -0
  29. package/dist/primitives/intersection.js +9 -0
  30. package/dist/primitives/linear-extrude.d.ts +18 -0
  31. package/dist/primitives/linear-extrude.d.ts.map +1 -0
  32. package/dist/primitives/linear-extrude.js +31 -0
  33. package/dist/primitives/polygon.d.ts +14 -0
  34. package/dist/primitives/polygon.d.ts.map +1 -0
  35. package/dist/primitives/polygon.js +14 -0
  36. package/dist/primitives/polyhedron.d.ts +14 -0
  37. package/dist/primitives/polyhedron.d.ts.map +1 -0
  38. package/dist/primitives/polyhedron.js +11 -0
  39. package/dist/primitives/primitive.d.ts +7 -0
  40. package/dist/primitives/primitive.d.ts.map +1 -0
  41. package/dist/primitives/primitive.js +5 -0
  42. package/dist/primitives/raw.d.ts +12 -0
  43. package/dist/primitives/raw.d.ts.map +1 -0
  44. package/dist/primitives/raw.js +12 -0
  45. package/dist/primitives/rotate-extrude.d.ts +14 -0
  46. package/dist/primitives/rotate-extrude.d.ts.map +1 -0
  47. package/dist/primitives/rotate-extrude.js +19 -0
  48. package/dist/primitives/rotate.d.ts +13 -0
  49. package/dist/primitives/rotate.d.ts.map +1 -0
  50. package/dist/primitives/rotate.js +11 -0
  51. package/dist/primitives/scale.d.ts +12 -0
  52. package/dist/primitives/scale.d.ts.map +1 -0
  53. package/dist/primitives/scale.js +10 -0
  54. package/dist/primitives/sphere.d.ts +14 -0
  55. package/dist/primitives/sphere.d.ts.map +1 -0
  56. package/dist/primitives/sphere.js +12 -0
  57. package/dist/primitives/square.d.ts +13 -0
  58. package/dist/primitives/square.d.ts.map +1 -0
  59. package/dist/primitives/square.js +13 -0
  60. package/dist/primitives/surface.d.ts +15 -0
  61. package/dist/primitives/surface.d.ts.map +1 -0
  62. package/dist/primitives/surface.js +17 -0
  63. package/dist/primitives/text.d.ts +20 -0
  64. package/dist/primitives/text.d.ts.map +1 -0
  65. package/dist/primitives/text.js +27 -0
  66. package/dist/primitives/translate.d.ts +12 -0
  67. package/dist/primitives/translate.d.ts.map +1 -0
  68. package/dist/primitives/translate.js +10 -0
  69. package/dist/primitives/union.d.ts +11 -0
  70. package/dist/primitives/union.d.ts.map +1 -0
  71. package/dist/primitives/union.js +9 -0
  72. package/dist/runtime/index.d.ts +62 -0
  73. package/dist/runtime/index.d.ts.map +1 -0
  74. package/dist/runtime/index.js +147 -0
  75. package/dist/runtime/node-ops.d.ts +6 -0
  76. package/dist/runtime/node-ops.d.ts.map +1 -0
  77. package/dist/runtime/node-ops.js +517 -0
  78. package/dist/runtime/reconciler.d.ts +5 -0
  79. package/dist/runtime/reconciler.d.ts.map +1 -0
  80. package/dist/runtime/reconciler.js +10 -0
  81. package/dist/runtime/root.d.ts +13 -0
  82. package/dist/runtime/root.d.ts.map +1 -0
  83. package/dist/runtime/root.js +26 -0
  84. package/dist/serialize/index.d.ts +5 -0
  85. package/dist/serialize/index.d.ts.map +1 -0
  86. package/dist/serialize/index.js +81 -0
  87. package/dist/types.d.ts +149 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +1 -0
  90. package/dist/utils.d.ts +7 -0
  91. package/dist/utils.d.ts.map +1 -0
  92. package/dist/utils.js +19 -0
  93. package/package.json +44 -0
@@ -0,0 +1,517 @@
1
+ const DEFAULT_VEC3 = [0, 0, 0];
2
+ const DEFAULT_SCALE = [1, 1, 1];
3
+ function toScadExpr(x) {
4
+ if (typeof x === "string")
5
+ return x;
6
+ const n = Number(x);
7
+ return Number.isFinite(n) ? n : 0;
8
+ }
9
+ function toVec2(v) {
10
+ if (typeof v === "number")
11
+ return v;
12
+ if (typeof v === "string")
13
+ return v;
14
+ if (Array.isArray(v) && v.length >= 2)
15
+ return [toScadExpr(v[0]), toScadExpr(v[1])];
16
+ return 1;
17
+ }
18
+ function toVec3(v) {
19
+ if (typeof v === "number")
20
+ return v;
21
+ if (typeof v === "string")
22
+ return v;
23
+ if (Array.isArray(v) && v.length >= 3)
24
+ return [toScadExpr(v[0]), toScadExpr(v[1]), toScadExpr(v[2])];
25
+ return DEFAULT_VEC3;
26
+ }
27
+ function num(x, fallback) {
28
+ if (typeof x === "string")
29
+ return fallback;
30
+ const n = Number(x);
31
+ return Number.isFinite(n) ? n : fallback;
32
+ }
33
+ function numOrExpr(x, fallback) {
34
+ if (typeof x === "string")
35
+ return x;
36
+ const n = Number(x);
37
+ return Number.isFinite(n) ? n : fallback;
38
+ }
39
+ function bool(x, fallback) {
40
+ if (typeof x === "boolean")
41
+ return x;
42
+ return fallback;
43
+ }
44
+ function toPoints3D(v) {
45
+ if (!Array.isArray(v))
46
+ return [];
47
+ return v.map((p) => {
48
+ if (!Array.isArray(p) || p.length < 3)
49
+ return [0, 0, 0];
50
+ return [num(p[0], 0), num(p[1], 0), num(p[2], 0)];
51
+ });
52
+ }
53
+ function toPoints2D(v) {
54
+ if (!Array.isArray(v))
55
+ return [];
56
+ return v.map((p) => {
57
+ if (!Array.isArray(p) || p.length < 2)
58
+ return [0, 0];
59
+ return [num(p[0], 0), num(p[1], 0)];
60
+ });
61
+ }
62
+ function toFaces(v) {
63
+ if (!Array.isArray(v))
64
+ return [];
65
+ return v.map((f) => (Array.isArray(f) ? f.map((i) => num(i, 0)) : []));
66
+ }
67
+ export function createScadNode(type, props) {
68
+ const children = [];
69
+ switch (type) {
70
+ case "cube": {
71
+ const size = props.size ?? 1;
72
+ return {
73
+ kind: "cube",
74
+ size: typeof size === "number" ? size : toVec3(size),
75
+ center: bool(props.center, false),
76
+ children,
77
+ };
78
+ }
79
+ case "sphere":
80
+ return {
81
+ kind: "sphere",
82
+ r: props.r != null
83
+ ? numOrExpr(props.r, 1)
84
+ : props.radius != null
85
+ ? numOrExpr(props.radius, 1)
86
+ : undefined,
87
+ d: props.d != null
88
+ ? numOrExpr(props.d, 2)
89
+ : props.diameter != null
90
+ ? numOrExpr(props.diameter, 2)
91
+ : undefined,
92
+ $fn: props.$fn != null ? num(props.$fn, 0) : props.fn != null ? num(props.fn, 0) : undefined,
93
+ children,
94
+ };
95
+ case "cylinder": {
96
+ const r1 = props.r1 ?? props.r ?? props.radius ?? 1;
97
+ const r2 = props.r2 ?? r1;
98
+ return {
99
+ kind: "cylinder",
100
+ h: numOrExpr(props.h ?? props.height, 1),
101
+ r1: numOrExpr(r1, 1),
102
+ r2: numOrExpr(r2, 1),
103
+ $fn: props.$fn != null ? num(props.$fn, 0) : props.fn != null ? num(props.fn, 0) : undefined,
104
+ children,
105
+ };
106
+ }
107
+ case "union":
108
+ return { kind: "union", children };
109
+ case "difference":
110
+ return { kind: "difference", children };
111
+ case "intersection":
112
+ return { kind: "intersection", children };
113
+ case "translate":
114
+ return {
115
+ kind: "translate",
116
+ v: toVec3(props.v ?? props.vector ?? DEFAULT_VEC3),
117
+ children,
118
+ };
119
+ case "rotate":
120
+ return {
121
+ kind: "rotate",
122
+ a: toVec3(props.a ?? props.angle ?? props.angles ?? DEFAULT_VEC3),
123
+ v: props.v != null || props.vector != null ? toVec3(props.v ?? props.vector) : undefined,
124
+ children,
125
+ };
126
+ case "scale":
127
+ return {
128
+ kind: "scale",
129
+ v: toVec3(props.v ?? props.vector ?? DEFAULT_SCALE),
130
+ children,
131
+ };
132
+ case "group":
133
+ return { kind: "group", children };
134
+ case "raw":
135
+ return {
136
+ kind: "raw",
137
+ code: props.code != null ? String(props.code) : "",
138
+ children,
139
+ };
140
+ case "polyhedron":
141
+ return {
142
+ kind: "polyhedron",
143
+ points: toPoints3D(props.points ?? []),
144
+ faces: toFaces(props.faces ?? []),
145
+ convexity: props.convexity != null ? num(props.convexity, 1) : undefined,
146
+ children,
147
+ };
148
+ case "square": {
149
+ const size = props.size ?? 1;
150
+ return {
151
+ kind: "square",
152
+ size: typeof size === "number" ? size : toVec2(size),
153
+ center: bool(props.center, false),
154
+ children,
155
+ };
156
+ }
157
+ case "circle":
158
+ return {
159
+ kind: "circle",
160
+ r: props.r != null ? numOrExpr(props.r, 1) : undefined,
161
+ d: props.d != null ? numOrExpr(props.d, 2) : undefined,
162
+ $fn: props.$fn != null ? num(props.$fn, 0) : undefined,
163
+ children,
164
+ };
165
+ case "polygon":
166
+ return {
167
+ kind: "polygon",
168
+ points: toPoints2D(props.points ?? []),
169
+ paths: props.paths != null ? toFaces(props.paths) : undefined,
170
+ convexity: props.convexity != null ? num(props.convexity, 1) : undefined,
171
+ children,
172
+ };
173
+ case "linear_extrude": {
174
+ const scale = props.scale;
175
+ return {
176
+ kind: "linear_extrude",
177
+ height: numOrExpr(props.height ?? props.h, 1),
178
+ center: props.center === true,
179
+ twist: props.twist != null ? numOrExpr(props.twist, 0) : undefined,
180
+ scale: scale != null
181
+ ? typeof scale === "number" || typeof scale === "string"
182
+ ? scale
183
+ : toVec2(scale)
184
+ : undefined,
185
+ convexity: props.convexity != null ? num(props.convexity, 1) : undefined,
186
+ slices: props.slices != null ? num(props.slices, 0) : undefined,
187
+ $fn: props.$fn != null ? num(props.$fn, 0) : undefined,
188
+ children,
189
+ };
190
+ }
191
+ case "rotate_extrude":
192
+ return {
193
+ kind: "rotate_extrude",
194
+ angle: props.angle != null ? numOrExpr(props.angle, 360) : undefined,
195
+ convexity: props.convexity != null ? num(props.convexity, 1) : undefined,
196
+ $fn: props.$fn != null ? num(props.$fn, 0) : undefined,
197
+ children,
198
+ };
199
+ case "text":
200
+ return {
201
+ kind: "text",
202
+ text: props.text != null ? String(props.text) : props.t != null ? String(props.t) : "",
203
+ size: props.size != null ? num(props.size, 10) : undefined,
204
+ font: props.font != null ? String(props.font) : undefined,
205
+ halign: props.halign != null ? props.halign : undefined,
206
+ valign: props.valign != null
207
+ ? props.valign
208
+ : undefined,
209
+ direction: props.direction != null ? props.direction : undefined,
210
+ language: props.language != null ? String(props.language) : undefined,
211
+ script: props.script != null ? String(props.script) : undefined,
212
+ spacing: props.spacing != null ? num(props.spacing, 1) : undefined,
213
+ children,
214
+ };
215
+ case "surface":
216
+ return {
217
+ kind: "surface",
218
+ file: props.file != null
219
+ ? String(props.file)
220
+ : props.filename != null
221
+ ? String(props.filename)
222
+ : "",
223
+ center: props.center === true,
224
+ invert: props.invert === true,
225
+ convexity: props.convexity != null ? num(props.convexity, 1) : undefined,
226
+ children,
227
+ };
228
+ case "import":
229
+ return {
230
+ kind: "import",
231
+ file: props.file != null
232
+ ? String(props.file)
233
+ : props.filename != null
234
+ ? String(props.filename)
235
+ : "",
236
+ convexity: props.convexity != null ? num(props.convexity, 1) : undefined,
237
+ layer: props.layer != null ? String(props.layer) : undefined,
238
+ children,
239
+ };
240
+ default:
241
+ return { kind: "unknown", type, props: { ...props }, children };
242
+ }
243
+ }
244
+ export function updateScadNode(node, nextProps) {
245
+ switch (node.kind) {
246
+ case "cube": {
247
+ const size = nextProps.size ?? node.size;
248
+ node.size = typeof size === "number" ? size : toVec3(size);
249
+ node.center = bool(nextProps.center, node.center);
250
+ break;
251
+ }
252
+ case "sphere":
253
+ if (nextProps.r != null)
254
+ node.r = numOrExpr(nextProps.r, 1);
255
+ if (nextProps.radius != null)
256
+ node.r = numOrExpr(nextProps.radius, 1);
257
+ if (nextProps.d != null)
258
+ node.d = numOrExpr(nextProps.d, 2);
259
+ if (nextProps.diameter != null)
260
+ node.d = numOrExpr(nextProps.diameter, 2);
261
+ if (nextProps.$fn != null)
262
+ node.$fn = num(nextProps.$fn, 0);
263
+ if (nextProps.fn != null)
264
+ node.$fn = num(nextProps.fn, 0);
265
+ break;
266
+ case "cylinder":
267
+ node.h = numOrExpr(nextProps.h ?? nextProps.height ?? node.h, 1);
268
+ if (nextProps.r1 != null)
269
+ node.r1 = numOrExpr(nextProps.r1, 1);
270
+ if (nextProps.r != null)
271
+ node.r1 = numOrExpr(nextProps.r, 1);
272
+ if (nextProps.radius != null)
273
+ node.r1 = numOrExpr(nextProps.radius, 1);
274
+ if (nextProps.r2 != null)
275
+ node.r2 = numOrExpr(nextProps.r2, typeof node.r1 === "number" ? node.r1 : 1);
276
+ if (nextProps.$fn != null)
277
+ node.$fn = num(nextProps.$fn, 0);
278
+ if (nextProps.fn != null)
279
+ node.$fn = num(nextProps.fn, 0);
280
+ break;
281
+ case "translate":
282
+ node.v = toVec3(nextProps.v ?? nextProps.vector ?? node.v);
283
+ break;
284
+ case "rotate":
285
+ node.a = toVec3(nextProps.a ?? nextProps.angle ?? nextProps.angles ?? node.a);
286
+ if (nextProps.v != null || nextProps.vector != null)
287
+ node.v = toVec3(nextProps.v ?? nextProps.vector);
288
+ break;
289
+ case "scale":
290
+ node.v = toVec3(nextProps.v ?? nextProps.vector ?? node.v);
291
+ break;
292
+ case "raw":
293
+ if (nextProps.code != null)
294
+ node.code = String(nextProps.code);
295
+ break;
296
+ case "polyhedron":
297
+ if (nextProps.points != null)
298
+ node.points = toPoints3D(nextProps.points);
299
+ if (nextProps.faces != null)
300
+ node.faces = toFaces(nextProps.faces);
301
+ if (nextProps.convexity != null)
302
+ node.convexity = num(nextProps.convexity, 1);
303
+ break;
304
+ case "square": {
305
+ const size = nextProps.size ?? node.size;
306
+ node.size = typeof size === "number" ? size : toVec2(size);
307
+ node.center = bool(nextProps.center, node.center);
308
+ break;
309
+ }
310
+ case "circle":
311
+ if (nextProps.r != null)
312
+ node.r = numOrExpr(nextProps.r, 1);
313
+ if (nextProps.d != null)
314
+ node.d = numOrExpr(nextProps.d, 2);
315
+ if (nextProps.$fn != null)
316
+ node.$fn = num(nextProps.$fn, 0);
317
+ break;
318
+ case "polygon":
319
+ if (nextProps.points != null)
320
+ node.points = toPoints2D(nextProps.points);
321
+ if (nextProps.paths != null)
322
+ node.paths = toFaces(nextProps.paths);
323
+ if (nextProps.convexity != null)
324
+ node.convexity = num(nextProps.convexity, 1);
325
+ break;
326
+ case "linear_extrude":
327
+ node.height = numOrExpr(nextProps.height ?? nextProps.h ?? node.height, 1);
328
+ if (nextProps.center !== undefined)
329
+ node.center = nextProps.center === true;
330
+ if (nextProps.twist != null)
331
+ node.twist = numOrExpr(nextProps.twist, 0);
332
+ if (nextProps.scale != null)
333
+ node.scale =
334
+ typeof nextProps.scale === "number" || typeof nextProps.scale === "string"
335
+ ? nextProps.scale
336
+ : toVec2(nextProps.scale);
337
+ if (nextProps.convexity != null)
338
+ node.convexity = num(nextProps.convexity, 1);
339
+ if (nextProps.slices != null)
340
+ node.slices = num(nextProps.slices, 0);
341
+ if (nextProps.$fn != null)
342
+ node.$fn = num(nextProps.$fn, 0);
343
+ break;
344
+ case "rotate_extrude":
345
+ if (nextProps.angle != null)
346
+ node.angle = numOrExpr(nextProps.angle, 360);
347
+ if (nextProps.convexity != null)
348
+ node.convexity = num(nextProps.convexity, 1);
349
+ if (nextProps.$fn != null)
350
+ node.$fn = num(nextProps.$fn, 0);
351
+ break;
352
+ case "text":
353
+ if (nextProps.text != null)
354
+ node.text = String(nextProps.text);
355
+ if (nextProps.t != null)
356
+ node.text = String(nextProps.t);
357
+ if (nextProps.size != null)
358
+ node.size = num(nextProps.size, 10);
359
+ if (nextProps.font != null)
360
+ node.font = String(nextProps.font);
361
+ if (nextProps.halign != null)
362
+ node.halign = nextProps.halign;
363
+ if (nextProps.valign != null)
364
+ node.valign = nextProps.valign;
365
+ if (nextProps.direction != null)
366
+ node.direction = nextProps.direction;
367
+ if (nextProps.language != null)
368
+ node.language = String(nextProps.language);
369
+ if (nextProps.script != null)
370
+ node.script = String(nextProps.script);
371
+ if (nextProps.spacing != null)
372
+ node.spacing = num(nextProps.spacing, 1);
373
+ break;
374
+ case "surface":
375
+ if (nextProps.file != null)
376
+ node.file = String(nextProps.file);
377
+ if (nextProps.filename != null)
378
+ node.file = String(nextProps.filename);
379
+ if (nextProps.center !== undefined)
380
+ node.center = nextProps.center === true;
381
+ if (nextProps.invert !== undefined)
382
+ node.invert = nextProps.invert === true;
383
+ if (nextProps.convexity != null)
384
+ node.convexity = num(nextProps.convexity, 1);
385
+ break;
386
+ case "import":
387
+ if (nextProps.file != null)
388
+ node.file = String(nextProps.file);
389
+ if (nextProps.filename != null)
390
+ node.file = String(nextProps.filename);
391
+ if (nextProps.convexity != null)
392
+ node.convexity = num(nextProps.convexity, 1);
393
+ if (nextProps.layer != null)
394
+ node.layer = String(nextProps.layer);
395
+ break;
396
+ case "unknown":
397
+ node.props = { ...nextProps };
398
+ break;
399
+ default:
400
+ break;
401
+ }
402
+ }
403
+ export function cloneScadNode(node, keepChildren) {
404
+ const children = keepChildren ? node.children.map((c) => cloneScadNode(c, true)) : [];
405
+ switch (node.kind) {
406
+ case "cube":
407
+ return { kind: "cube", size: node.size, center: node.center, children };
408
+ case "sphere":
409
+ return { kind: "sphere", r: node.r, d: node.d, $fn: node.$fn, children };
410
+ case "cylinder":
411
+ return {
412
+ kind: "cylinder",
413
+ h: node.h,
414
+ r1: node.r1,
415
+ r2: node.r2,
416
+ $fn: node.$fn,
417
+ children,
418
+ };
419
+ case "union":
420
+ return { kind: "union", children };
421
+ case "difference":
422
+ return { kind: "difference", children };
423
+ case "intersection":
424
+ return { kind: "intersection", children };
425
+ case "translate":
426
+ return { kind: "translate", v: node.v, children };
427
+ case "rotate":
428
+ return { kind: "rotate", a: node.a, v: node.v, children };
429
+ case "scale":
430
+ return { kind: "scale", v: node.v, children };
431
+ case "group":
432
+ return { kind: "group", children };
433
+ case "raw":
434
+ return { kind: "raw", code: node.code, children };
435
+ case "polyhedron":
436
+ return {
437
+ kind: "polyhedron",
438
+ points: node.points.map((p) => [...p]),
439
+ faces: node.faces.map((f) => [...f]),
440
+ convexity: node.convexity,
441
+ children,
442
+ };
443
+ case "square":
444
+ return { kind: "square", size: node.size, center: node.center, children };
445
+ case "circle":
446
+ return { kind: "circle", r: node.r, d: node.d, $fn: node.$fn, children };
447
+ case "polygon":
448
+ return {
449
+ kind: "polygon",
450
+ points: node.points.map((p) => [...p]),
451
+ paths: node.paths?.map((f) => [...f]),
452
+ convexity: node.convexity,
453
+ children,
454
+ };
455
+ case "linear_extrude":
456
+ return {
457
+ kind: "linear_extrude",
458
+ height: node.height,
459
+ center: node.center,
460
+ twist: node.twist,
461
+ scale: node.scale,
462
+ convexity: node.convexity,
463
+ slices: node.slices,
464
+ $fn: node.$fn,
465
+ children,
466
+ };
467
+ case "rotate_extrude":
468
+ return {
469
+ kind: "rotate_extrude",
470
+ angle: node.angle,
471
+ convexity: node.convexity,
472
+ $fn: node.$fn,
473
+ children,
474
+ };
475
+ case "text":
476
+ return {
477
+ kind: "text",
478
+ text: node.text,
479
+ size: node.size,
480
+ font: node.font,
481
+ halign: node.halign,
482
+ valign: node.valign,
483
+ direction: node.direction,
484
+ language: node.language,
485
+ script: node.script,
486
+ spacing: node.spacing,
487
+ children,
488
+ };
489
+ case "surface":
490
+ return {
491
+ kind: "surface",
492
+ file: node.file,
493
+ center: node.center,
494
+ invert: node.invert,
495
+ convexity: node.convexity,
496
+ children,
497
+ };
498
+ case "import":
499
+ return {
500
+ kind: "import",
501
+ file: node.file,
502
+ convexity: node.convexity,
503
+ layer: node.layer,
504
+ children,
505
+ };
506
+ case "unknown":
507
+ return {
508
+ kind: "unknown",
509
+ type: node.type,
510
+ props: { ...node.props },
511
+ children,
512
+ };
513
+ }
514
+ }
515
+ export function createScadContainer() {
516
+ return { children: [] };
517
+ }
@@ -0,0 +1,5 @@
1
+ import type React from "react";
2
+ import type { ScadContainer } from "../types.js";
3
+ export declare function createFiberRoot(container: ScadContainer): unknown;
4
+ export declare function updateContainer(element: React.ReactElement, fiberRoot: unknown, container: ScadContainer | null, callback: (() => void) | null): void;
5
+ //# sourceMappingURL=reconciler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconciler.d.ts","sourceRoot":"","sources":["../../src/runtime/reconciler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAmBjD,wBAAgB,eAAe,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAEjE;AAED,wBAAgB,eAAe,CAC9B,OAAO,EAAE,KAAK,CAAC,YAAY,EAC3B,SAAS,EAAE,OAAO,EAClB,SAAS,EAAE,aAAa,GAAG,IAAI,EAC/B,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAC3B,IAAI,CAEN"}
@@ -0,0 +1,10 @@
1
+ import ReactReconciler from "react-reconciler";
2
+ import * as HostConfig from "./index.js";
3
+ const Reconciler = ReactReconciler(HostConfig);
4
+ const CONTAINER_ARGS = [0, null, false, null, "", () => { }, null];
5
+ export function createFiberRoot(container) {
6
+ return Reconciler.createContainer(container, ...CONTAINER_ARGS);
7
+ }
8
+ export function updateContainer(element, fiberRoot, container, callback) {
9
+ Reconciler.updateContainer(element, fiberRoot, container, callback);
10
+ }
@@ -0,0 +1,13 @@
1
+ import type React from "react";
2
+ import type { ScadContainer } from "../types.js";
3
+ export type { ScadContainer };
4
+ export interface ScadRoot {
5
+ render(element: React.ReactElement): void;
6
+ toScad(): string;
7
+ }
8
+ export type Path = string;
9
+ export declare function createRoot(path?: Path): ScadRoot;
10
+ export declare function createContainer(): ScadContainer;
11
+ export declare function render(element: React.ReactElement, container: ScadContainer, callback?: () => void): void;
12
+ export { toScad } from "../serialize/index.js";
13
+ //# sourceMappingURL=root.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/runtime/root.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,YAAY,EAAE,aAAa,EAAE,CAAC;AAE9B,MAAM,WAAW,QAAQ;IACxB,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;IAC1C,MAAM,IAAI,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC;AAE1B,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,QAAQ,CAahD;AAED,wBAAgB,eAAe,IAAI,aAAa,CAE/C;AAED,wBAAgB,MAAM,CACrB,OAAO,EAAE,KAAK,CAAC,YAAY,EAC3B,SAAS,EAAE,aAAa,EACxB,QAAQ,CAAC,EAAE,MAAM,IAAI,GACnB,IAAI,CAGN;AAED,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import { toScad } from "../serialize/index.js";
3
+ import { createScadContainer } from "./node-ops.js";
4
+ import { createFiberRoot, updateContainer } from "./reconciler.js";
5
+ export function createRoot(path) {
6
+ const container = createScadContainer();
7
+ const fiberRoot = createFiberRoot(container);
8
+ return {
9
+ render(element) {
10
+ updateContainer(element, fiberRoot, null, null);
11
+ if (path)
12
+ writeFileSync(path, toScad(container), "utf8");
13
+ },
14
+ toScad() {
15
+ return toScad(container);
16
+ },
17
+ };
18
+ }
19
+ export function createContainer() {
20
+ return createScadContainer();
21
+ }
22
+ export function render(element, container, callback) {
23
+ const fiberRoot = createFiberRoot(container);
24
+ updateContainer(element, fiberRoot, null, callback ?? null);
25
+ }
26
+ export { toScad } from "../serialize/index.js";
@@ -0,0 +1,5 @@
1
+ import type { ScadNode } from "../types.js";
2
+ export declare function toScad(container: {
3
+ children: ScadNode[];
4
+ }): string;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/serialize/index.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,aAAa,CAAC;AA0D9D,wBAAgB,MAAM,CAAC,SAAS,EAAE;IAAE,QAAQ,EAAE,QAAQ,EAAE,CAAA;CAAE,GAAG,MAAM,CAMlE"}
@@ -0,0 +1,81 @@
1
+ import { serialize as serializeCircle } from "../primitives/circle.js";
2
+ import { serialize as serializeCube } from "../primitives/cube.js";
3
+ import { serialize as serializeCylinder } from "../primitives/cylinder.js";
4
+ import { serialize as serializeDifference } from "../primitives/difference.js";
5
+ import { serialize as serializeGroup } from "../primitives/group.js";
6
+ import { serialize as serializeImport } from "../primitives/import.js";
7
+ import { serialize as serializeIntersection } from "../primitives/intersection.js";
8
+ import { serialize as serializeLinearExtrude } from "../primitives/linear-extrude.js";
9
+ import { serialize as serializePolygon } from "../primitives/polygon.js";
10
+ import { serialize as serializePolyhedron } from "../primitives/polyhedron.js";
11
+ import { serialize as serializeRaw } from "../primitives/raw.js";
12
+ import { serialize as serializeRotate } from "../primitives/rotate.js";
13
+ import { serialize as serializeRotateExtrude } from "../primitives/rotate-extrude.js";
14
+ import { serialize as serializeScale } from "../primitives/scale.js";
15
+ import { serialize as serializeSphere } from "../primitives/sphere.js";
16
+ import { serialize as serializeSquare } from "../primitives/square.js";
17
+ import { serialize as serializeSurface } from "../primitives/surface.js";
18
+ import { serialize as serializeText } from "../primitives/text.js";
19
+ import { serialize as serializeTranslate } from "../primitives/translate.js";
20
+ import { serialize as serializeUnion } from "../primitives/union.js";
21
+ function serializeNode(node, indent, ctx) {
22
+ switch (node.kind) {
23
+ case "cube":
24
+ return serializeCube(node, indent, ctx);
25
+ case "sphere":
26
+ return serializeSphere(node, indent, ctx);
27
+ case "cylinder":
28
+ return serializeCylinder(node, indent, ctx);
29
+ case "polyhedron":
30
+ return serializePolyhedron(node, indent, ctx);
31
+ case "square":
32
+ return serializeSquare(node, indent, ctx);
33
+ case "circle":
34
+ return serializeCircle(node, indent, ctx);
35
+ case "polygon":
36
+ return serializePolygon(node, indent, ctx);
37
+ case "union":
38
+ return serializeUnion(node, indent, ctx);
39
+ case "difference":
40
+ return serializeDifference(node, indent, ctx);
41
+ case "intersection":
42
+ return serializeIntersection(node, indent, ctx);
43
+ case "translate":
44
+ return serializeTranslate(node, indent, ctx);
45
+ case "rotate":
46
+ return serializeRotate(node, indent, ctx);
47
+ case "scale":
48
+ return serializeScale(node, indent, ctx);
49
+ case "linear_extrude":
50
+ return serializeLinearExtrude(node, indent, ctx);
51
+ case "rotate_extrude":
52
+ return serializeRotateExtrude(node, indent, ctx);
53
+ case "text":
54
+ return serializeText(node, indent, ctx);
55
+ case "surface":
56
+ return serializeSurface(node, indent, ctx);
57
+ case "import":
58
+ return serializeImport(node, indent, ctx);
59
+ case "group":
60
+ return serializeGroup(node, indent, ctx);
61
+ case "raw":
62
+ return serializeRaw(node, indent, ctx);
63
+ case "unknown": {
64
+ const nextIndent = `${indent} `;
65
+ const inner = node.children
66
+ .map((c) => nextIndent + ctx.serializeNode(c, nextIndent))
67
+ .join("\n");
68
+ return inner
69
+ ? `// ${node.type}\n${indent}{\n${inner}\n${indent}}`
70
+ : `// ${node.type} (no children)`;
71
+ }
72
+ }
73
+ }
74
+ const CREDIT = "// Generated using react-scad (https://github.com/leonmeka/react-scad)";
75
+ export function toScad(container) {
76
+ const ctx = {
77
+ serializeNode: (n, i) => serializeNode(n, i, ctx),
78
+ };
79
+ const body = container.children.map((n) => serializeNode(n, "", ctx)).join("\n\n");
80
+ return body ? `${CREDIT}\n\n${body}` : CREDIT;
81
+ }