@react-arch/react 0.1.2 → 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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/tags.ts","../src/components.tsx","../src/registry.ts","../src/renderer.ts","../src/convert.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/tags.ts","../src/components.tsx","../src/registry.ts","../src/renderer.ts","../src/convert.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createElement, useEffect } from "react";
2
2
  import Reconciler from "react-reconciler";
3
- import { createId, round } from "@react-arch/shared";
4
- import { normalize, sub } from "@react-arch/geometry";
3
+ import { round } from "@react-arch/shared";
4
+ import { dot, normal, normalize, scale, sub } from "@react-arch/geometry";
5
5
  import { DEFAULT_MATERIALS, MODEL_VERSION } from "@react-arch/core";
6
6
  //#region src/tags.ts
7
7
  /**
@@ -174,6 +174,27 @@ function str(props, key) {
174
174
  function vec2(v) {
175
175
  if (Array.isArray(v) && v.length === 2 && typeof v[0] === "number" && typeof v[1] === "number") return [v[0], v[1]];
176
176
  }
177
+ function idPart(value, fallback = "item") {
178
+ return (typeof value === "string" && value.trim() ? value : fallback).toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || fallback;
179
+ }
180
+ function uniqueId(base, used) {
181
+ let id = idPart(base);
182
+ let suffix = 2;
183
+ while (used.has(id)) {
184
+ id = `${idPart(base)}-${suffix}`;
185
+ suffix += 1;
186
+ }
187
+ used.add(id);
188
+ return id;
189
+ }
190
+ function idFromProps(props, base, used) {
191
+ const explicit = str(props, "id");
192
+ if (explicit) {
193
+ used.add(explicit);
194
+ return explicit;
195
+ }
196
+ return uniqueId(base, used);
197
+ }
177
198
  /** Expand transparent <Group> nodes and drop text nodes. */
178
199
  function flatten(nodes) {
179
200
  const out = [];
@@ -184,10 +205,10 @@ function flatten(nodes) {
184
205
  }
185
206
  return out;
186
207
  }
187
- function toMaterial(node) {
208
+ function toMaterial(node, fallbackId, usedIds) {
188
209
  const p = node.props;
189
210
  return {
190
- id: str(p, "id") ?? createId("mat"),
211
+ id: idFromProps(p, fallbackId, usedIds),
191
212
  name: str(p, "name") ?? "Material",
192
213
  category: str(p, "category") ?? "custom",
193
214
  baseColor: str(p, "baseColor") ?? "#cccccc",
@@ -214,10 +235,10 @@ const OPENING_DEFAULTS = {
214
235
  sill: 0
215
236
  }
216
237
  };
217
- function toObject(node, floorId) {
238
+ function toObject(node, floorId, fallbackId, usedIds) {
218
239
  const p = node.props;
219
240
  return {
220
- id: str(p, "id") ?? createId("object"),
241
+ id: idFromProps(p, fallbackId, usedIds),
221
242
  floorId,
222
243
  type: str(p, "type") ?? "object",
223
244
  position: [
@@ -238,10 +259,10 @@ function toObject(node, floorId) {
238
259
  assetId: str(p, "assetId")
239
260
  };
240
261
  }
241
- function convertFloor(node, buildingId, materials) {
262
+ function convertFloor(node, buildingId, materials, floorIndex, usedIds) {
242
263
  const p = node.props;
243
264
  const floor = {
244
- id: str(p, "id") ?? createId("floor"),
265
+ id: idFromProps(p, `${buildingId}-floor-${floorIndex + 1}`, usedIds),
245
266
  buildingId,
246
267
  name: str(p, "name") ?? "Floor",
247
268
  elevation: num(p, "elevation", 0),
@@ -253,9 +274,12 @@ function convertFloor(node, buildingId, materials) {
253
274
  openings: [],
254
275
  objects: []
255
276
  };
256
- const makeWall = (start, end, thickness, materialId) => {
277
+ let wallIndex = 0;
278
+ let materialIndex = 0;
279
+ let objectIndex = 0;
280
+ const makeWall = (start, end, thickness, materialId, idBase, explicitId) => {
257
281
  const w = {
258
- id: createId("wall"),
282
+ id: explicitId ? (usedIds.add(explicitId), explicitId) : uniqueId(idBase, usedIds),
259
283
  floorId: floor.id,
260
284
  start,
261
285
  end,
@@ -268,20 +292,25 @@ function convertFloor(node, buildingId, materials) {
268
292
  };
269
293
  for (const child of flatten(node.children)) switch (child.tag) {
270
294
  case TAG.material:
271
- materials.push(toMaterial(child));
295
+ materialIndex += 1;
296
+ materials.push(toMaterial(child, `${floor.id}-material-${materialIndex}`, usedIds));
272
297
  break;
273
298
  case TAG.wall: {
274
- const w = makeWall(vec2(child.props.from) ?? [0, 0], vec2(child.props.to) ?? [0, 0], num(child.props, "thickness", .2), str(child.props, "materialId"));
275
- if (str(child.props, "id")) w.id = str(child.props, "id");
299
+ const from = vec2(child.props.from) ?? [0, 0];
300
+ const to = vec2(child.props.to) ?? [0, 0];
301
+ wallIndex += 1;
302
+ const w = makeWall(from, to, num(child.props, "thickness", .2), str(child.props, "materialId"), `${floor.id}-wall-${wallIndex}`, str(child.props, "id"));
276
303
  if (typeof child.props.height === "number") w.height = child.props.height;
277
304
  break;
278
305
  }
279
306
  case TAG.room: {
307
+ const roomIndex = floor.rooms.length + 1;
280
308
  const x = num(child.props, "x", 0);
281
309
  const y = num(child.props, "y", 0);
282
310
  const w = num(child.props, "width", 4);
283
311
  const d = num(child.props, "depth", 4);
284
312
  const thickness = num(child.props, "wallThickness", .2);
313
+ const roomId = idFromProps(child.props, `${floor.id}-room-${roomIndex}`, usedIds);
285
314
  const polygon = [
286
315
  [x, y],
287
316
  [x + w, y],
@@ -289,7 +318,7 @@ function convertFloor(node, buildingId, materials) {
289
318
  [x, y + d]
290
319
  ];
291
320
  const room = {
292
- id: str(child.props, "id") ?? createId("room"),
321
+ id: roomId,
293
322
  floorId: floor.id,
294
323
  name: str(child.props, "name") ?? "Room",
295
324
  polygon,
@@ -300,15 +329,19 @@ function convertFloor(node, buildingId, materials) {
300
329
  };
301
330
  floor.rooms.push(room);
302
331
  const sides = {
303
- north: makeWall([x, y], [x + w, y], thickness),
304
- south: makeWall([x, y + d], [x + w, y + d], thickness),
305
- west: makeWall([x, y], [x, y + d], thickness),
306
- east: makeWall([x + w, y], [x + w, y + d], thickness)
332
+ north: makeWall([x, y], [x + w, y], thickness, void 0, `${room.id}-wall-north`),
333
+ south: makeWall([x, y + d], [x + w, y + d], thickness, void 0, `${room.id}-wall-south`),
334
+ west: makeWall([x, y], [x, y + d], thickness, void 0, `${room.id}-wall-west`),
335
+ east: makeWall([x + w, y], [x + w, y + d], thickness, void 0, `${room.id}-wall-east`)
307
336
  };
308
337
  room.boundaryWallIds = Object.values(sides).map((s) => s.id);
338
+ let roomOpeningIndex = 0;
339
+ let roomObjectIndex = 0;
309
340
  for (const o of flatten(child.children)) {
310
341
  if (o.tag === TAG.furniture) {
311
- floor.objects.push(toObject(o, floor.id));
342
+ objectIndex += 1;
343
+ roomObjectIndex += 1;
344
+ floor.objects.push(toObject(o, floor.id, `${room.id}-object-${roomObjectIndex}`, usedIds));
312
345
  continue;
313
346
  }
314
347
  if (o.tag !== TAG.door && o.tag !== TAG.window && o.tag !== TAG.opening) continue;
@@ -317,8 +350,9 @@ function convertFloor(node, buildingId, materials) {
317
350
  const side = str(o.props, "wall") ?? "south";
318
351
  const wall = sides[side] ?? sides.south;
319
352
  const wallLen = side === "north" || side === "south" ? w : d;
353
+ roomOpeningIndex += 1;
320
354
  const opening = {
321
- id: str(o.props, "id") ?? createId("opening"),
355
+ id: idFromProps(o.props, `${room.id}-${type}-${side}-${roomOpeningIndex}`, usedIds),
322
356
  floorId: floor.id,
323
357
  wallId: wall.id,
324
358
  type,
@@ -332,7 +366,8 @@ function convertFloor(node, buildingId, materials) {
332
366
  break;
333
367
  }
334
368
  case TAG.furniture:
335
- floor.objects.push(toObject(child, floor.id));
369
+ objectIndex += 1;
370
+ floor.objects.push(toObject(child, floor.id, `${floor.id}-object-${objectIndex}`, usedIds));
336
371
  break;
337
372
  default: break;
338
373
  }
@@ -350,38 +385,98 @@ function convertFloor(node, buildingId, materials) {
350
385
  * so an interior door becomes a real passage between the rooms.
351
386
  */
352
387
  function mergeCoincidentWalls(floor) {
353
- const key = (w) => {
354
- const a = [round(w.start[0]), round(w.start[1])];
355
- const b = [round(w.end[0]), round(w.end[1])];
356
- const [p, q] = a[0] < b[0] || a[0] === b[0] && a[1] <= b[1] ? [a, b] : [b, a];
357
- return `${p[0]},${p[1]}|${q[0]},${q[1]}|${round(w.thickness)}`;
388
+ const intervalOf = (w) => {
389
+ let d = normalize(sub(w.end, w.start));
390
+ if (d[0] < 0 || d[0] === 0 && d[1] < 0) d = scale(d, -1);
391
+ const n = normal(d);
392
+ const lineOffset = dot(w.start, n);
393
+ const t0 = dot(w.start, d);
394
+ const t1 = dot(w.end, d);
395
+ return {
396
+ wall: w,
397
+ d,
398
+ n,
399
+ lineOffset,
400
+ a: Math.min(t0, t1),
401
+ b: Math.max(t0, t1)
402
+ };
403
+ };
404
+ const key = (i) => {
405
+ if (i.d[0] === 0 && i.d[1] === 0) return `point:${round(i.wall.start[0])},${round(i.wall.start[1])}|${round(i.wall.thickness)}`;
406
+ return `${round(i.d[0])},${round(i.d[1])}|${round(i.lineOffset)}|${round(i.wall.thickness)}`;
358
407
  };
408
+ const pointAt = (i, t) => [i.d[0] * t + i.n[0] * i.lineOffset, i.d[1] * t + i.n[1] * i.lineOffset];
409
+ const oldWallById = new Map(floor.walls.map((w) => [w.id, {
410
+ start: [...w.start],
411
+ end: [...w.end]
412
+ }]));
413
+ const openingCenters = /* @__PURE__ */ new Map();
414
+ for (const o of floor.openings) {
415
+ const w = oldWallById.get(o.wallId);
416
+ if (!w) continue;
417
+ const d = normalize(sub(w.end, w.start));
418
+ openingCenters.set(o.id, [w.start[0] + d[0] * o.offset, w.start[1] + d[1] * o.offset]);
419
+ }
359
420
  const groups = /* @__PURE__ */ new Map();
360
421
  for (const w of floor.walls) {
361
- const k = key(w);
422
+ const interval = intervalOf(w);
423
+ const k = key(interval);
362
424
  const g = groups.get(k);
363
- if (g) g.push(w);
364
- else groups.set(k, [w]);
425
+ if (g) g.push(interval);
426
+ else groups.set(k, [interval]);
365
427
  }
366
428
  const survivors = [];
367
429
  const survivorOf = /* @__PURE__ */ new Map();
368
- for (const group of groups.values()) {
369
- const survivor = group[0];
430
+ let mergedAny = false;
431
+ const flush = (active, a, b) => {
432
+ const survivor = active[0].wall;
433
+ if (active.length > 1) {
434
+ survivor.start = pointAt(active[0], a);
435
+ survivor.end = pointAt(active[0], b);
436
+ mergedAny = true;
437
+ }
370
438
  survivors.push(survivor);
371
- for (const w of group) survivorOf.set(w.id, survivor);
439
+ for (const i of active) survivorOf.set(i.wall.id, survivor);
440
+ };
441
+ for (const group of groups.values()) {
442
+ if (group.length === 1) {
443
+ const only = group[0];
444
+ survivors.push(only.wall);
445
+ survivorOf.set(only.wall.id, only.wall);
446
+ continue;
447
+ }
448
+ const sorted = [...group].sort((a, b) => a.a - b.a);
449
+ let active = [];
450
+ let activeA = 0;
451
+ let activeB = 0;
452
+ for (const interval of sorted) {
453
+ if (active.length === 0) {
454
+ active = [interval];
455
+ activeA = interval.a;
456
+ activeB = interval.b;
457
+ continue;
458
+ }
459
+ if (interval.a < activeB - 1e-6) {
460
+ active.push(interval);
461
+ activeA = Math.min(activeA, interval.a);
462
+ activeB = Math.max(activeB, interval.b);
463
+ } else {
464
+ flush(active, activeA, activeB);
465
+ active = [interval];
466
+ activeA = interval.a;
467
+ activeB = interval.b;
468
+ }
469
+ }
470
+ if (active.length > 0) flush(active, activeA, activeB);
372
471
  }
373
- if (survivors.length === floor.walls.length) return;
374
- const wallById = new Map(floor.walls.map((w) => [w.id, w]));
472
+ if (!mergedAny) return;
375
473
  for (const o of floor.openings) {
376
474
  const survivor = survivorOf.get(o.wallId);
377
- if (!survivor || survivor.id === o.wallId) continue;
378
- const orig = wallById.get(o.wallId);
379
- if (orig) {
380
- const od = normalize(sub(orig.end, orig.start));
381
- const cx = orig.start[0] + od[0] * o.offset;
382
- const cy = orig.start[1] + od[1] * o.offset;
475
+ if (!survivor) continue;
476
+ const center = openingCenters.get(o.id);
477
+ if (center) {
383
478
  const sd = normalize(sub(survivor.end, survivor.start));
384
- o.offset = (cx - survivor.start[0]) * sd[0] + (cy - survivor.start[1]) * sd[1];
479
+ o.offset = dot(sub(center, survivor.start), sd);
385
480
  }
386
481
  o.wallId = survivor.id;
387
482
  }
@@ -395,32 +490,36 @@ function mergeCoincidentWalls(floor) {
395
490
  */
396
491
  function convert(instances, fallbackName = "Untitled") {
397
492
  const tops = flatten(instances);
398
- const materials = [...DEFAULT_MATERIALS];
399
- for (const n of tops) if (n.tag === TAG.material) materials.push(toMaterial(n));
493
+ const usedIds = new Set(DEFAULT_MATERIALS.map((m) => m.id));
494
+ const materials = DEFAULT_MATERIALS.map((m) => ({ ...m }));
495
+ let topMaterialIndex = 0;
496
+ for (const n of tops) if (n.tag === TAG.material) {
497
+ topMaterialIndex += 1;
498
+ materials.push(toMaterial(n, `material-${topMaterialIndex}`, usedIds));
499
+ }
400
500
  const buildingNodes = tops.filter((n) => n.tag === TAG.building);
401
501
  const buildings = [];
402
502
  let units = "metric";
403
503
  let docName = fallbackName;
404
- const sources = buildingNodes.length > 0 ? buildingNodes : [{
504
+ (buildingNodes.length > 0 ? buildingNodes : [{
405
505
  tag: TAG.building,
406
506
  props: {},
407
507
  children: tops
408
- }];
409
- for (const bn of sources) {
410
- const buildingId = str(bn.props, "id") ?? createId("bld");
508
+ }]).forEach((bn, buildingIndex) => {
509
+ const buildingId = idFromProps(bn.props, `building-${buildingIndex + 1}`, usedIds);
411
510
  const name = str(bn.props, "name") ?? fallbackName;
412
511
  if (str(bn.props, "units") === "imperial") units = "imperial";
413
512
  docName = name;
414
- const floors = flatten(bn.children).filter((c) => c.tag === TAG.floor).map((fn) => convertFloor(fn, buildingId, materials));
513
+ const floors = flatten(bn.children).filter((c) => c.tag === TAG.floor).map((fn, floorIndex) => convertFloor(fn, buildingId, materials, floorIndex, usedIds));
415
514
  floors.sort((a, b) => a.elevation - b.elevation);
416
515
  buildings.push({
417
516
  id: buildingId,
418
517
  name,
419
518
  floors
420
519
  });
421
- }
520
+ });
422
521
  return {
423
- id: createId("doc"),
522
+ id: uniqueId(`doc-${docName}`, usedIds),
424
523
  version: MODEL_VERSION,
425
524
  name: docName,
426
525
  units,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/tags.ts","../src/components.tsx","../src/renderer.ts","../src/convert.ts","../src/registry.ts"],"sourcesContent":["/**\n * Internal host element tags. Users never type these — the public components\n * in `components.tsx` create them. The reconciler builds an instance tree of\n * these tags, which `convert.ts` turns into a BuildingDocument.\n */\nexport const TAG = {\n building: \"ra-building\",\n floor: \"ra-floor\",\n room: \"ra-room\",\n wall: \"ra-wall\",\n door: \"ra-door\",\n window: \"ra-window\",\n opening: \"ra-opening\",\n furniture: \"ra-furniture\",\n material: \"ra-material\",\n group: \"ra-group\",\n slab: \"ra-slab\",\n roof: \"ra-roof\",\n stairs: \"ra-stairs\",\n text: \"ra-text\",\n} as const;\n\nexport type Tag = (typeof TAG)[keyof typeof TAG];\n\n/** Side of a rectangular room a door/window attaches to. */\nexport type RoomSide = \"north\" | \"south\" | \"east\" | \"west\";\n","import { createElement, type ReactNode } from \"react\";\nimport { TAG, type RoomSide } from \"./tags.js\";\n\ntype WithChildren<T> = T & { children?: ReactNode };\nconst h = (tag: string, props: object) =>\n createElement(tag, props as Record<string, unknown>);\n\nexport interface BuildingProps {\n id?: string;\n name?: string;\n units?: \"metric\" | \"imperial\";\n}\nexport function Building(props: WithChildren<BuildingProps>) {\n return h(TAG.building, props);\n}\n\nexport interface FloorProps {\n id?: string;\n name?: string;\n elevation?: number;\n height?: number;\n}\nexport function Floor(props: WithChildren<FloorProps>) {\n return h(TAG.floor, props);\n}\n\nexport interface RoomProps {\n id?: string;\n name?: string;\n /** Top-left corner X (metres, X increases right). */\n x?: number;\n /** Top-left corner Y (metres, Y increases down). */\n y?: number;\n /** Extent along X. */\n width?: number;\n /** Extent along Y. */\n depth?: number;\n height?: number;\n wallThickness?: number;\n floorMaterial?: string;\n ceilingMaterial?: string;\n usage?: string;\n}\nexport function Room(props: WithChildren<RoomProps>) {\n return h(TAG.room, props);\n}\n\nexport interface WallProps {\n id?: string;\n from: [number, number];\n to: [number, number];\n thickness?: number;\n height?: number;\n materialId?: string;\n}\nexport function Wall(props: WallProps) {\n return h(TAG.wall, props);\n}\n\nexport interface OpeningCommonProps {\n id?: string;\n /** Which side of the parent room this attaches to. */\n wall?: RoomSide;\n /** Distance along the wall centerline from its start corner. */\n offset?: number;\n width?: number;\n height?: number;\n sillHeight?: number;\n}\nexport function Door(props: OpeningCommonProps) {\n return h(TAG.door, props);\n}\nexport function Window(props: OpeningCommonProps) {\n return h(TAG.window, props);\n}\nexport function Opening(props: OpeningCommonProps) {\n return h(TAG.opening, props);\n}\n\nexport interface FurnitureProps {\n id?: string;\n type: string;\n x?: number;\n y?: number;\n z?: number;\n rotation?: number;\n scaleX?: number;\n scaleY?: number;\n scaleZ?: number;\n assetId?: string;\n}\nexport function Furniture(props: FurnitureProps) {\n return h(TAG.furniture, props);\n}\n/** Alias used inside reusable room modules. */\nexport const Fixture = Furniture;\n\nexport interface MaterialProps {\n id: string;\n name?: string;\n category?: string;\n baseColor: string;\n roughness?: number;\n metalness?: number;\n opacity?: number;\n textureUrl?: string;\n}\nexport function Material(props: MaterialProps) {\n return h(TAG.material, props);\n}\n\nexport function Group(props: WithChildren<{ id?: string }>) {\n return h(TAG.group, props);\n}\n\n// Reserved primitives — accepted in the tree, modelled minimally for the MVP.\nexport function Slab(props: WithChildren<{ id?: string }>) {\n return h(TAG.slab, props);\n}\nexport function Roof(props: WithChildren<{ id?: string; type?: string }>) {\n return h(TAG.roof, props);\n}\nexport function Stairs(props: WithChildren<{ id?: string }>) {\n return h(TAG.stairs, props);\n}\n","import Reconciler from \"react-reconciler\";\nimport type { ReactElement } from \"react\";\n\n/** A node in the intermediate instance tree built by the reconciler. */\nexport interface Instance {\n tag: string;\n props: Record<string, unknown>;\n children: Instance[];\n}\n\nexport interface Container {\n children: Instance[];\n}\n\nfunction stripChildren(props: Record<string, unknown>): Record<string, unknown> {\n const { children, ...rest } = props;\n void children;\n return rest;\n}\n\n// react-reconciler's types are notoriously strict; the host config is plain.\nconst hostConfig: any = {\n supportsMutation: true,\n supportsPersistence: false,\n supportsHydration: false,\n isPrimaryRenderer: false,\n noTimeout: -1,\n now: () => 0,\n\n getRootHostContext: () => ({}),\n getChildHostContext: (parent: unknown) => parent,\n getPublicInstance: (instance: Instance) => instance,\n\n prepareForCommit: () => null,\n resetAfterCommit: () => {},\n preparePortalMount: () => {},\n\n createInstance(tag: string, props: Record<string, unknown>): Instance {\n return { tag, props: stripChildren(props), children: [] };\n },\n\n createTextInstance(text: string): Instance {\n return { tag: \"ra-text\", props: { text }, children: [] };\n },\n\n appendInitialChild(parent: Instance, child: Instance) {\n parent.children.push(child);\n },\n appendChild(parent: Instance, child: Instance) {\n parent.children.push(child);\n },\n appendChildToContainer(container: Container, child: Instance) {\n container.children.push(child);\n },\n\n insertBefore(parent: Instance, child: Instance, before: Instance) {\n const i = parent.children.indexOf(before);\n parent.children.splice(i, 0, child);\n },\n insertInContainerBefore(container: Container, child: Instance, before: Instance) {\n const i = container.children.indexOf(before);\n container.children.splice(i, 0, child);\n },\n\n removeChild(parent: Instance, child: Instance) {\n parent.children = parent.children.filter((c) => c !== child);\n },\n removeChildFromContainer(container: Container, child: Instance) {\n container.children = container.children.filter((c) => c !== child);\n },\n\n finalizeInitialChildren: () => false,\n shouldSetTextContent: () => false,\n clearContainer(container: Container) {\n container.children = [];\n },\n\n prepareUpdate: () => true,\n commitUpdate(instance: Instance, _payload: unknown, _tag: string, _old: unknown, newProps: Record<string, unknown>) {\n instance.props = stripChildren(newProps);\n },\n commitTextUpdate(instance: Instance, _old: string, text: string) {\n instance.props = { text };\n },\n\n getCurrentEventPriority: () => 16,\n detachDeletedInstance: () => {},\n prepareScopeUpdate: () => {},\n getInstanceFromScope: () => null,\n getInstanceFromNode: () => null,\n beforeActiveInstanceBlur: () => {},\n afterActiveInstanceBlur: () => {},\n scheduleTimeout: setTimeout,\n cancelTimeout: clearTimeout,\n};\n\nconst reconciler = Reconciler(hostConfig);\n\nconst LegacyRoot = 0;\n\n/**\n * Render a React element tree through the React Arch reconciler and return the\n * resulting intermediate instance tree. Synchronous (legacy root) so the tree\n * is fully built when this returns.\n */\nexport function renderToInstances(element: ReactElement): Instance[] {\n const container: Container = { children: [] };\n const root = reconciler.createContainer(\n container,\n LegacyRoot,\n null,\n false,\n null,\n \"react-arch\",\n (error: unknown) => {\n // Surface render errors loudly; the studio shows them as diagnostics.\n console.error(\"[react-arch] render error\", error);\n },\n null,\n );\n reconciler.updateContainer(element, root, null, null);\n return container.children;\n}\n","import { createId, round, type Units, type Vec2 } from \"@react-arch/shared\";\nimport { normalize, sub } from \"@react-arch/geometry\";\nimport {\n DEFAULT_MATERIALS,\n MODEL_VERSION,\n type Building,\n type BuildingDocument,\n type BuildingObject,\n type Floor,\n type Material,\n type Opening,\n type Room,\n type Wall,\n} from \"@react-arch/core\";\nimport { TAG, type RoomSide } from \"./tags.js\";\nimport type { Instance } from \"./renderer.js\";\n\nfunction num(props: Record<string, unknown>, key: string, fallback: number): number {\n const v = props[key];\n return typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n}\nfunction str(props: Record<string, unknown>, key: string): string | undefined {\n const v = props[key];\n return typeof v === \"string\" ? v : undefined;\n}\nfunction vec2(v: unknown): Vec2 | undefined {\n if (Array.isArray(v) && v.length === 2 && typeof v[0] === \"number\" && typeof v[1] === \"number\") {\n return [v[0], v[1]];\n }\n return undefined;\n}\n\n/** Expand transparent <Group> nodes and drop text nodes. */\nfunction flatten(nodes: Instance[]): Instance[] {\n const out: Instance[] = [];\n for (const n of nodes) {\n if (n.tag === TAG.text) continue;\n if (n.tag === TAG.group) out.push(...flatten(n.children));\n else out.push(n);\n }\n return out;\n}\n\nfunction toMaterial(node: Instance): Material {\n const p = node.props;\n return {\n id: str(p, \"id\") ?? createId(\"mat\"),\n name: str(p, \"name\") ?? \"Material\",\n category: (str(p, \"category\") as Material[\"category\"]) ?? \"custom\",\n baseColor: str(p, \"baseColor\") ?? \"#cccccc\",\n roughness: typeof p.roughness === \"number\" ? p.roughness : undefined,\n metalness: typeof p.metalness === \"number\" ? p.metalness : undefined,\n opacity: typeof p.opacity === \"number\" ? p.opacity : undefined,\n textureUrl: str(p, \"textureUrl\"),\n };\n}\n\ninterface OpeningDefaults {\n width: number;\n height: number;\n sill: number;\n}\nconst OPENING_DEFAULTS: Record<string, OpeningDefaults> = {\n door: { width: 0.9, height: 2.1, sill: 0 },\n window: { width: 1.2, height: 1.4, sill: 0.9 },\n opening: { width: 1.0, height: 2.1, sill: 0 },\n};\n\nfunction toObject(node: Instance, floorId: string): BuildingObject {\n const p = node.props;\n return {\n id: str(p, \"id\") ?? createId(\"object\"),\n floorId,\n type: str(p, \"type\") ?? \"object\",\n position: [num(p, \"x\", 0), num(p, \"y\", 0), num(p, \"z\", 0)],\n rotation: [0, 0, num(p, \"rotation\", 0)],\n scale: [num(p, \"scaleX\", 1), num(p, \"scaleY\", 1), num(p, \"scaleZ\", 1)],\n assetId: str(p, \"assetId\"),\n };\n}\n\nfunction convertFloor(node: Instance, buildingId: string, materials: Material[]): Floor {\n const p = node.props;\n const floor: Floor = {\n id: str(p, \"id\") ?? createId(\"floor\"),\n buildingId,\n name: str(p, \"name\") ?? \"Floor\",\n elevation: num(p, \"elevation\", 0),\n height: num(p, \"height\", 2.8),\n visible: true,\n locked: false,\n walls: [],\n rooms: [],\n openings: [],\n objects: [],\n };\n\n const makeWall = (start: Vec2, end: Vec2, thickness: number, materialId?: string): Wall => {\n const w: Wall = {\n id: createId(\"wall\"),\n floorId: floor.id,\n start,\n end,\n thickness,\n height: floor.height,\n materialId,\n };\n floor.walls.push(w);\n return w;\n };\n\n for (const child of flatten(node.children)) {\n switch (child.tag) {\n case TAG.material:\n materials.push(toMaterial(child));\n break;\n\n case TAG.wall: {\n const from = vec2(child.props.from) ?? [0, 0];\n const to = vec2(child.props.to) ?? [0, 0];\n const w = makeWall(from, to, num(child.props, \"thickness\", 0.2), str(child.props, \"materialId\"));\n if (str(child.props, \"id\")) w.id = str(child.props, \"id\")!;\n if (typeof child.props.height === \"number\") w.height = child.props.height;\n break;\n }\n\n case TAG.room: {\n const x = num(child.props, \"x\", 0);\n const y = num(child.props, \"y\", 0);\n const w = num(child.props, \"width\", 4);\n const d = num(child.props, \"depth\", 4);\n const thickness = num(child.props, \"wallThickness\", 0.2);\n const polygon: Vec2[] = [\n [x, y],\n [x + w, y],\n [x + w, y + d],\n [x, y + d],\n ];\n const room: Room = {\n id: str(child.props, \"id\") ?? createId(\"room\"),\n floorId: floor.id,\n name: str(child.props, \"name\") ?? \"Room\",\n polygon,\n floorMaterialId: str(child.props, \"floorMaterial\"),\n ceilingMaterialId: str(child.props, \"ceilingMaterial\"),\n usageType: str(child.props, \"usage\"),\n height: typeof child.props.height === \"number\" ? child.props.height : undefined,\n };\n floor.rooms.push(room);\n\n // Generate perimeter walls. Offsets increase in a natural reading\n // direction per side (L→R for horizontal, T→B for vertical).\n const sides: Record<RoomSide, Wall> = {\n north: makeWall([x, y], [x + w, y], thickness),\n south: makeWall([x, y + d], [x + w, y + d], thickness),\n west: makeWall([x, y], [x, y + d], thickness),\n east: makeWall([x + w, y], [x + w, y + d], thickness),\n };\n room.boundaryWallIds = Object.values(sides).map((s) => s.id);\n\n for (const o of flatten(child.children)) {\n // Furniture/fixtures are commonly declared inside a room.\n if (o.tag === TAG.furniture) {\n floor.objects.push(toObject(o, floor.id));\n continue;\n }\n if (o.tag !== TAG.door && o.tag !== TAG.window && o.tag !== TAG.opening) continue;\n const type = o.tag === TAG.door ? \"door\" : o.tag === TAG.window ? \"window\" : \"opening\";\n const def = OPENING_DEFAULTS[type]!;\n const side = (str(o.props, \"wall\") as RoomSide) ?? \"south\";\n const wall = sides[side] ?? sides.south;\n const wallLen = side === \"north\" || side === \"south\" ? w : d;\n const opening: Opening = {\n id: str(o.props, \"id\") ?? createId(\"opening\"),\n floorId: floor.id,\n wallId: wall.id,\n type,\n offset: num(o.props, \"offset\", wallLen / 2),\n width: num(o.props, \"width\", def.width),\n height: num(o.props, \"height\", def.height),\n sillHeight: num(o.props, \"sillHeight\", def.sill),\n };\n floor.openings.push(opening);\n }\n break;\n }\n\n case TAG.furniture:\n floor.objects.push(toObject(child, floor.id));\n break;\n\n default:\n // slab / roof / stairs are reserved; ignored for the MVP model.\n break;\n }\n }\n\n mergeCoincidentWalls(floor);\n return floor;\n}\n\n/**\n * Two adjacent rooms each generate their own perimeter walls, producing a pair\n * of coincident walls on their shared edge. Without merging, a door declared on\n * one room only cuts that room's wall and the neighbour's wall stays solid\n * behind it — the opening never passes through (and the walls z-fight in 3D).\n *\n * This collapses coincident, equal-thickness walls into one survivor and\n * re-points openings (re-projecting their offset) and room boundaries onto it,\n * so an interior door becomes a real passage between the rooms.\n */\nfunction mergeCoincidentWalls(floor: Floor): void {\n const key = (w: Wall): string => {\n const a: Vec2 = [round(w.start[0]), round(w.start[1])];\n const b: Vec2 = [round(w.end[0]), round(w.end[1])];\n // Order-insensitive so reversed walls share a key.\n const [p, q] = a[0] < b[0] || (a[0] === b[0] && a[1] <= b[1]) ? [a, b] : [b, a];\n return `${p[0]},${p[1]}|${q[0]},${q[1]}|${round(w.thickness)}`;\n };\n\n const groups = new Map<string, Wall[]>();\n for (const w of floor.walls) {\n const k = key(w);\n const g = groups.get(k);\n if (g) g.push(w);\n else groups.set(k, [w]);\n }\n\n const survivors: Wall[] = [];\n const survivorOf = new Map<string, Wall>(); // any wall id -> survivor wall\n for (const group of groups.values()) {\n const survivor = group[0]!;\n survivors.push(survivor);\n for (const w of group) survivorOf.set(w.id, survivor);\n }\n\n if (survivors.length === floor.walls.length) return; // nothing coincident\n\n const wallById = new Map(floor.walls.map((w) => [w.id, w]));\n for (const o of floor.openings) {\n const survivor = survivorOf.get(o.wallId);\n if (!survivor || survivor.id === o.wallId) continue;\n const orig = wallById.get(o.wallId);\n if (orig) {\n // World centre of the opening on its original wall.\n const od = normalize(sub(orig.end, orig.start));\n const cx = orig.start[0] + od[0] * o.offset;\n const cy = orig.start[1] + od[1] * o.offset;\n // Offset of that point along the survivor (handles reversed direction).\n const sd = normalize(sub(survivor.end, survivor.start));\n o.offset = (cx - survivor.start[0]) * sd[0] + (cy - survivor.start[1]) * sd[1];\n }\n o.wallId = survivor.id;\n }\n\n for (const r of floor.rooms) {\n if (r.boundaryWallIds) {\n r.boundaryWallIds = Array.from(\n new Set(r.boundaryWallIds.map((id) => survivorOf.get(id)?.id ?? id)),\n );\n }\n }\n\n floor.walls = survivors;\n}\n\n/**\n * Convert a rendered instance tree into the canonical BuildingDocument.\n * `fallbackName` is used when the <Building> has no `name` prop (e.g. the\n * registered composition name).\n */\nexport function convert(instances: Instance[], fallbackName = \"Untitled\"): BuildingDocument {\n const tops = flatten(instances);\n const materials: Material[] = [...DEFAULT_MATERIALS];\n for (const n of tops) if (n.tag === TAG.material) materials.push(toMaterial(n));\n\n const buildingNodes = tops.filter((n) => n.tag === TAG.building);\n const buildings: Building[] = [];\n let units: Units = \"metric\";\n let docName = fallbackName;\n\n const sources = buildingNodes.length > 0 ? buildingNodes : [{ tag: TAG.building, props: {}, children: tops }];\n\n for (const bn of sources) {\n const buildingId = str(bn.props, \"id\") ?? createId(\"bld\");\n const name = str(bn.props, \"name\") ?? fallbackName;\n if (str(bn.props, \"units\") === \"imperial\") units = \"imperial\";\n docName = name;\n const floors = flatten(bn.children)\n .filter((c) => c.tag === TAG.floor)\n .map((fn) => convertFloor(fn, buildingId, materials));\n // Keep floors ordered by elevation for stable stacking.\n floors.sort((a, b) => a.elevation - b.elevation);\n buildings.push({ id: buildingId, name, floors });\n }\n\n return {\n id: createId(\"doc\"),\n version: MODEL_VERSION,\n name: docName,\n units,\n buildings,\n materials,\n assets: [],\n metadata: { source: \"react\" },\n };\n}\n","import { createElement, useEffect, type ComponentType, type ReactElement } from \"react\";\nimport type { BuildingDocument } from \"@react-arch/core\";\nimport { renderToInstances } from \"./renderer.js\";\nimport { convert } from \"./convert.js\";\n\nexport interface BuildingComposition {\n id: string;\n name: string;\n component: ComponentType<Record<string, unknown>>;\n defaultProps?: Record<string, unknown>;\n}\n\n// --- module-level registry (Remotion-style) -------------------------------\n\nconst compositions = new Map<string, BuildingComposition>();\nconst listeners = new Set<() => void>();\nlet rootComponent: ComponentType | null = null;\n// Cached, referentially-stable snapshot for useSyncExternalStore consumers.\nlet snapshot: BuildingComposition[] = [];\nlet version = 0;\n\nfunction emit(): void {\n snapshot = [...compositions.values()];\n version += 1;\n for (const fn of listeners) fn();\n}\n\n/** Increments whenever the registry changes (incl. hot-reload re-registration). */\nexport function getCompositionsVersion(): number {\n return version;\n}\n\nexport function __registerComposition(c: BuildingComposition): void {\n compositions.set(c.id, c);\n emit();\n}\nexport function __unregisterComposition(id: string): void {\n compositions.delete(id);\n emit();\n}\n\nexport function getCompositions(): BuildingComposition[] {\n return snapshot;\n}\nexport function subscribeCompositions(fn: () => void): () => void {\n listeners.add(fn);\n return () => listeners.delete(fn);\n}\n\n/**\n * Register the root component (mirrors Remotion's registerRoot). The Studio\n * mounts this so its <Composition> children register themselves.\n */\nexport function registerRoot(component: ComponentType): void {\n rootComponent = component;\n emit();\n}\nexport function getRoot(): ComponentType | null {\n return rootComponent;\n}\n\n/**\n * Declares a building composition. Renders nothing visible; on mount it\n * registers itself into the module registry the Studio reads.\n */\nexport function Composition(props: BuildingComposition): null {\n const { id, name, component, defaultProps } = props;\n useEffect(() => {\n __registerComposition({ id, name, component, defaultProps });\n return () => __unregisterComposition(id);\n }, [id, name, component, defaultProps]);\n return null;\n}\n\n// --- rendering -------------------------------------------------------------\n\n/** Render any React Arch element tree to the canonical model. */\nexport function renderToDocument(element: ReactElement, fallbackName?: string): BuildingDocument {\n return convert(renderToInstances(element), fallbackName);\n}\n\n/** Render a registered composition (component + its default props) to a model. */\nexport function renderComposition(comp: BuildingComposition): BuildingDocument {\n const element = createElement(comp.component, comp.defaultProps ?? {});\n return renderToDocument(element, comp.name);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/tags.ts","../src/components.tsx","../src/renderer.ts","../src/convert.ts","../src/registry.ts"],"sourcesContent":["/**\n * Internal host element tags. Users never type these — the public components\n * in `components.tsx` create them. The reconciler builds an instance tree of\n * these tags, which `convert.ts` turns into a BuildingDocument.\n */\nexport const TAG = {\n building: \"ra-building\",\n floor: \"ra-floor\",\n room: \"ra-room\",\n wall: \"ra-wall\",\n door: \"ra-door\",\n window: \"ra-window\",\n opening: \"ra-opening\",\n furniture: \"ra-furniture\",\n material: \"ra-material\",\n group: \"ra-group\",\n slab: \"ra-slab\",\n roof: \"ra-roof\",\n stairs: \"ra-stairs\",\n text: \"ra-text\",\n} as const;\n\nexport type Tag = (typeof TAG)[keyof typeof TAG];\n\n/** Side of a rectangular room a door/window attaches to. */\nexport type RoomSide = \"north\" | \"south\" | \"east\" | \"west\";\n","import { createElement, type ReactNode } from \"react\";\nimport { TAG, type RoomSide } from \"./tags.js\";\n\ntype WithChildren<T> = T & { children?: ReactNode };\nconst h = (tag: string, props: object) =>\n createElement(tag, props as Record<string, unknown>);\n\nexport interface BuildingProps {\n id?: string;\n name?: string;\n units?: \"metric\" | \"imperial\";\n}\nexport function Building(props: WithChildren<BuildingProps>) {\n return h(TAG.building, props);\n}\n\nexport interface FloorProps {\n id?: string;\n name?: string;\n elevation?: number;\n height?: number;\n}\nexport function Floor(props: WithChildren<FloorProps>) {\n return h(TAG.floor, props);\n}\n\nexport interface RoomProps {\n id?: string;\n name?: string;\n /** Top-left corner X (metres, X increases right). */\n x?: number;\n /** Top-left corner Y (metres, Y increases down). */\n y?: number;\n /** Extent along X. */\n width?: number;\n /** Extent along Y. */\n depth?: number;\n height?: number;\n wallThickness?: number;\n floorMaterial?: string;\n ceilingMaterial?: string;\n usage?: string;\n}\nexport function Room(props: WithChildren<RoomProps>) {\n return h(TAG.room, props);\n}\n\nexport interface WallProps {\n id?: string;\n from: [number, number];\n to: [number, number];\n thickness?: number;\n height?: number;\n materialId?: string;\n}\nexport function Wall(props: WallProps) {\n return h(TAG.wall, props);\n}\n\nexport interface OpeningCommonProps {\n id?: string;\n /** Which side of the parent room this attaches to. */\n wall?: RoomSide;\n /** Distance along the wall centerline from its start corner. */\n offset?: number;\n width?: number;\n height?: number;\n sillHeight?: number;\n}\nexport function Door(props: OpeningCommonProps) {\n return h(TAG.door, props);\n}\nexport function Window(props: OpeningCommonProps) {\n return h(TAG.window, props);\n}\nexport function Opening(props: OpeningCommonProps) {\n return h(TAG.opening, props);\n}\n\nexport interface FurnitureProps {\n id?: string;\n type: string;\n x?: number;\n y?: number;\n z?: number;\n rotation?: number;\n scaleX?: number;\n scaleY?: number;\n scaleZ?: number;\n assetId?: string;\n}\nexport function Furniture(props: FurnitureProps) {\n return h(TAG.furniture, props);\n}\n/** Alias used inside reusable room modules. */\nexport const Fixture = Furniture;\n\nexport interface MaterialProps {\n id: string;\n name?: string;\n category?: string;\n baseColor: string;\n roughness?: number;\n metalness?: number;\n opacity?: number;\n textureUrl?: string;\n}\nexport function Material(props: MaterialProps) {\n return h(TAG.material, props);\n}\n\nexport function Group(props: WithChildren<{ id?: string }>) {\n return h(TAG.group, props);\n}\n\n// Reserved primitives — accepted in the tree, modelled minimally for the MVP.\nexport function Slab(props: WithChildren<{ id?: string }>) {\n return h(TAG.slab, props);\n}\nexport function Roof(props: WithChildren<{ id?: string; type?: string }>) {\n return h(TAG.roof, props);\n}\nexport function Stairs(props: WithChildren<{ id?: string }>) {\n return h(TAG.stairs, props);\n}\n","import Reconciler from \"react-reconciler\";\nimport type { ReactElement } from \"react\";\n\n/** A node in the intermediate instance tree built by the reconciler. */\nexport interface Instance {\n tag: string;\n props: Record<string, unknown>;\n children: Instance[];\n}\n\nexport interface Container {\n children: Instance[];\n}\n\nfunction stripChildren(props: Record<string, unknown>): Record<string, unknown> {\n const { children, ...rest } = props;\n void children;\n return rest;\n}\n\n// react-reconciler's types are notoriously strict; the host config is plain.\nconst hostConfig: any = {\n supportsMutation: true,\n supportsPersistence: false,\n supportsHydration: false,\n isPrimaryRenderer: false,\n noTimeout: -1,\n now: () => 0,\n\n getRootHostContext: () => ({}),\n getChildHostContext: (parent: unknown) => parent,\n getPublicInstance: (instance: Instance) => instance,\n\n prepareForCommit: () => null,\n resetAfterCommit: () => {},\n preparePortalMount: () => {},\n\n createInstance(tag: string, props: Record<string, unknown>): Instance {\n return { tag, props: stripChildren(props), children: [] };\n },\n\n createTextInstance(text: string): Instance {\n return { tag: \"ra-text\", props: { text }, children: [] };\n },\n\n appendInitialChild(parent: Instance, child: Instance) {\n parent.children.push(child);\n },\n appendChild(parent: Instance, child: Instance) {\n parent.children.push(child);\n },\n appendChildToContainer(container: Container, child: Instance) {\n container.children.push(child);\n },\n\n insertBefore(parent: Instance, child: Instance, before: Instance) {\n const i = parent.children.indexOf(before);\n parent.children.splice(i, 0, child);\n },\n insertInContainerBefore(container: Container, child: Instance, before: Instance) {\n const i = container.children.indexOf(before);\n container.children.splice(i, 0, child);\n },\n\n removeChild(parent: Instance, child: Instance) {\n parent.children = parent.children.filter((c) => c !== child);\n },\n removeChildFromContainer(container: Container, child: Instance) {\n container.children = container.children.filter((c) => c !== child);\n },\n\n finalizeInitialChildren: () => false,\n shouldSetTextContent: () => false,\n clearContainer(container: Container) {\n container.children = [];\n },\n\n prepareUpdate: () => true,\n commitUpdate(instance: Instance, _payload: unknown, _tag: string, _old: unknown, newProps: Record<string, unknown>) {\n instance.props = stripChildren(newProps);\n },\n commitTextUpdate(instance: Instance, _old: string, text: string) {\n instance.props = { text };\n },\n\n getCurrentEventPriority: () => 16,\n detachDeletedInstance: () => {},\n prepareScopeUpdate: () => {},\n getInstanceFromScope: () => null,\n getInstanceFromNode: () => null,\n beforeActiveInstanceBlur: () => {},\n afterActiveInstanceBlur: () => {},\n scheduleTimeout: setTimeout,\n cancelTimeout: clearTimeout,\n};\n\nconst reconciler = Reconciler(hostConfig);\n\nconst LegacyRoot = 0;\n\n/**\n * Render a React element tree through the React Arch reconciler and return the\n * resulting intermediate instance tree. Synchronous (legacy root) so the tree\n * is fully built when this returns.\n */\nexport function renderToInstances(element: ReactElement): Instance[] {\n const container: Container = { children: [] };\n const root = reconciler.createContainer(\n container,\n LegacyRoot,\n null,\n false,\n null,\n \"react-arch\",\n (error: unknown) => {\n // Surface render errors loudly; the studio shows them as diagnostics.\n console.error(\"[react-arch] render error\", error);\n },\n null,\n );\n reconciler.updateContainer(element, root, null, null);\n return container.children;\n}\n","import { round, type Units, type Vec2 } from \"@react-arch/shared\";\nimport { dot, normal, normalize, scale, sub } from \"@react-arch/geometry\";\nimport {\n DEFAULT_MATERIALS,\n MODEL_VERSION,\n type Building,\n type BuildingDocument,\n type BuildingObject,\n type Floor,\n type Material,\n type Opening,\n type Room,\n type Wall,\n} from \"@react-arch/core\";\nimport { TAG, type RoomSide } from \"./tags.js\";\nimport type { Instance } from \"./renderer.js\";\n\nfunction num(props: Record<string, unknown>, key: string, fallback: number): number {\n const v = props[key];\n return typeof v === \"number\" && Number.isFinite(v) ? v : fallback;\n}\nfunction str(props: Record<string, unknown>, key: string): string | undefined {\n const v = props[key];\n return typeof v === \"string\" ? v : undefined;\n}\nfunction vec2(v: unknown): Vec2 | undefined {\n if (Array.isArray(v) && v.length === 2 && typeof v[0] === \"number\" && typeof v[1] === \"number\") {\n return [v[0], v[1]];\n }\n return undefined;\n}\n\nfunction idPart(value: unknown, fallback = \"item\"): string {\n const raw = typeof value === \"string\" && value.trim() ? value : fallback;\n return raw.toLowerCase().replace(/[^a-z0-9_-]+/g, \"-\").replace(/^-+|-+$/g, \"\") || fallback;\n}\n\nfunction uniqueId(base: string, used: Set<string>): string {\n let id = idPart(base);\n let suffix = 2;\n while (used.has(id)) {\n id = `${idPart(base)}-${suffix}`;\n suffix += 1;\n }\n used.add(id);\n return id;\n}\n\nfunction idFromProps(props: Record<string, unknown>, base: string, used: Set<string>): string {\n const explicit = str(props, \"id\");\n if (explicit) {\n used.add(explicit);\n return explicit;\n }\n return uniqueId(base, used);\n}\n\n/** Expand transparent <Group> nodes and drop text nodes. */\nfunction flatten(nodes: Instance[]): Instance[] {\n const out: Instance[] = [];\n for (const n of nodes) {\n if (n.tag === TAG.text) continue;\n if (n.tag === TAG.group) out.push(...flatten(n.children));\n else out.push(n);\n }\n return out;\n}\n\nfunction toMaterial(node: Instance, fallbackId: string, usedIds: Set<string>): Material {\n const p = node.props;\n return {\n id: idFromProps(p, fallbackId, usedIds),\n name: str(p, \"name\") ?? \"Material\",\n category: (str(p, \"category\") as Material[\"category\"]) ?? \"custom\",\n baseColor: str(p, \"baseColor\") ?? \"#cccccc\",\n roughness: typeof p.roughness === \"number\" ? p.roughness : undefined,\n metalness: typeof p.metalness === \"number\" ? p.metalness : undefined,\n opacity: typeof p.opacity === \"number\" ? p.opacity : undefined,\n textureUrl: str(p, \"textureUrl\"),\n };\n}\n\ninterface OpeningDefaults {\n width: number;\n height: number;\n sill: number;\n}\nconst OPENING_DEFAULTS: Record<string, OpeningDefaults> = {\n door: { width: 0.9, height: 2.1, sill: 0 },\n window: { width: 1.2, height: 1.4, sill: 0.9 },\n opening: { width: 1.0, height: 2.1, sill: 0 },\n};\n\nfunction toObject(node: Instance, floorId: string, fallbackId: string, usedIds: Set<string>): BuildingObject {\n const p = node.props;\n return {\n id: idFromProps(p, fallbackId, usedIds),\n floorId,\n type: str(p, \"type\") ?? \"object\",\n position: [num(p, \"x\", 0), num(p, \"y\", 0), num(p, \"z\", 0)],\n rotation: [0, 0, num(p, \"rotation\", 0)],\n scale: [num(p, \"scaleX\", 1), num(p, \"scaleY\", 1), num(p, \"scaleZ\", 1)],\n assetId: str(p, \"assetId\"),\n };\n}\n\nfunction convertFloor(\n node: Instance,\n buildingId: string,\n materials: Material[],\n floorIndex: number,\n usedIds: Set<string>,\n): Floor {\n const p = node.props;\n const floor: Floor = {\n id: idFromProps(p, `${buildingId}-floor-${floorIndex + 1}`, usedIds),\n buildingId,\n name: str(p, \"name\") ?? \"Floor\",\n elevation: num(p, \"elevation\", 0),\n height: num(p, \"height\", 2.8),\n visible: true,\n locked: false,\n walls: [],\n rooms: [],\n openings: [],\n objects: [],\n };\n\n let wallIndex = 0;\n let materialIndex = 0;\n let objectIndex = 0;\n\n const makeWall = (start: Vec2, end: Vec2, thickness: number, materialId: string | undefined, idBase: string, explicitId?: string): Wall => {\n const w: Wall = {\n id: explicitId ? (usedIds.add(explicitId), explicitId) : uniqueId(idBase, usedIds),\n floorId: floor.id,\n start,\n end,\n thickness,\n height: floor.height,\n materialId,\n };\n floor.walls.push(w);\n return w;\n };\n\n for (const child of flatten(node.children)) {\n switch (child.tag) {\n case TAG.material:\n materialIndex += 1;\n materials.push(toMaterial(child, `${floor.id}-material-${materialIndex}`, usedIds));\n break;\n\n case TAG.wall: {\n const from = vec2(child.props.from) ?? [0, 0];\n const to = vec2(child.props.to) ?? [0, 0];\n wallIndex += 1;\n const w = makeWall(from, to, num(child.props, \"thickness\", 0.2), str(child.props, \"materialId\"), `${floor.id}-wall-${wallIndex}`, str(child.props, \"id\"));\n if (typeof child.props.height === \"number\") w.height = child.props.height;\n break;\n }\n\n case TAG.room: {\n const roomIndex = floor.rooms.length + 1;\n const x = num(child.props, \"x\", 0);\n const y = num(child.props, \"y\", 0);\n const w = num(child.props, \"width\", 4);\n const d = num(child.props, \"depth\", 4);\n const thickness = num(child.props, \"wallThickness\", 0.2);\n const roomId = idFromProps(child.props, `${floor.id}-room-${roomIndex}`, usedIds);\n const polygon: Vec2[] = [\n [x, y],\n [x + w, y],\n [x + w, y + d],\n [x, y + d],\n ];\n const room: Room = {\n id: roomId,\n floorId: floor.id,\n name: str(child.props, \"name\") ?? \"Room\",\n polygon,\n floorMaterialId: str(child.props, \"floorMaterial\"),\n ceilingMaterialId: str(child.props, \"ceilingMaterial\"),\n usageType: str(child.props, \"usage\"),\n height: typeof child.props.height === \"number\" ? child.props.height : undefined,\n };\n floor.rooms.push(room);\n\n // Generate perimeter walls. Offsets increase in a natural reading\n // direction per side (L→R for horizontal, T→B for vertical).\n const sides: Record<RoomSide, Wall> = {\n north: makeWall([x, y], [x + w, y], thickness, undefined, `${room.id}-wall-north`),\n south: makeWall([x, y + d], [x + w, y + d], thickness, undefined, `${room.id}-wall-south`),\n west: makeWall([x, y], [x, y + d], thickness, undefined, `${room.id}-wall-west`),\n east: makeWall([x + w, y], [x + w, y + d], thickness, undefined, `${room.id}-wall-east`),\n };\n room.boundaryWallIds = Object.values(sides).map((s) => s.id);\n\n let roomOpeningIndex = 0;\n let roomObjectIndex = 0;\n for (const o of flatten(child.children)) {\n // Furniture/fixtures are commonly declared inside a room.\n if (o.tag === TAG.furniture) {\n objectIndex += 1;\n roomObjectIndex += 1;\n floor.objects.push(toObject(o, floor.id, `${room.id}-object-${roomObjectIndex}`, usedIds));\n continue;\n }\n if (o.tag !== TAG.door && o.tag !== TAG.window && o.tag !== TAG.opening) continue;\n const type = o.tag === TAG.door ? \"door\" : o.tag === TAG.window ? \"window\" : \"opening\";\n const def = OPENING_DEFAULTS[type]!;\n const side = (str(o.props, \"wall\") as RoomSide) ?? \"south\";\n const wall = sides[side] ?? sides.south;\n const wallLen = side === \"north\" || side === \"south\" ? w : d;\n roomOpeningIndex += 1;\n const opening: Opening = {\n id: idFromProps(o.props, `${room.id}-${type}-${side}-${roomOpeningIndex}`, usedIds),\n floorId: floor.id,\n wallId: wall.id,\n type,\n offset: num(o.props, \"offset\", wallLen / 2),\n width: num(o.props, \"width\", def.width),\n height: num(o.props, \"height\", def.height),\n sillHeight: num(o.props, \"sillHeight\", def.sill),\n };\n floor.openings.push(opening);\n }\n break;\n }\n\n case TAG.furniture:\n objectIndex += 1;\n floor.objects.push(toObject(child, floor.id, `${floor.id}-object-${objectIndex}`, usedIds));\n break;\n\n default:\n // slab / roof / stairs are reserved; ignored for the MVP model.\n break;\n }\n }\n\n mergeCoincidentWalls(floor);\n return floor;\n}\n\n/**\n * Two adjacent rooms each generate their own perimeter walls, producing a pair\n * of coincident walls on their shared edge. Without merging, a door declared on\n * one room only cuts that room's wall and the neighbour's wall stays solid\n * behind it — the opening never passes through (and the walls z-fight in 3D).\n *\n * This collapses coincident, equal-thickness walls into one survivor and\n * re-points openings (re-projecting their offset) and room boundaries onto it,\n * so an interior door becomes a real passage between the rooms.\n */\nfunction mergeCoincidentWalls(floor: Floor): void {\n interface WallInterval {\n wall: Wall;\n d: Vec2;\n n: Vec2;\n lineOffset: number;\n a: number;\n b: number;\n }\n\n const intervalOf = (w: Wall): WallInterval => {\n let d = normalize(sub(w.end, w.start));\n if (d[0] < 0 || (d[0] === 0 && d[1] < 0)) d = scale(d, -1);\n const n = normal(d);\n const lineOffset = dot(w.start, n);\n const t0 = dot(w.start, d);\n const t1 = dot(w.end, d);\n return { wall: w, d, n, lineOffset, a: Math.min(t0, t1), b: Math.max(t0, t1) };\n };\n\n const key = (i: WallInterval): string => {\n if (i.d[0] === 0 && i.d[1] === 0) {\n return `point:${round(i.wall.start[0])},${round(i.wall.start[1])}|${round(i.wall.thickness)}`;\n }\n return `${round(i.d[0])},${round(i.d[1])}|${round(i.lineOffset)}|${round(i.wall.thickness)}`;\n };\n\n const pointAt = (i: WallInterval, t: number): Vec2 => [\n i.d[0] * t + i.n[0] * i.lineOffset,\n i.d[1] * t + i.n[1] * i.lineOffset,\n ];\n\n const oldWallById = new Map(\n floor.walls.map((w) => [w.id, { start: [...w.start] as Vec2, end: [...w.end] as Vec2 }]),\n );\n const openingCenters = new Map<string, Vec2>();\n for (const o of floor.openings) {\n const w = oldWallById.get(o.wallId);\n if (!w) continue;\n const d = normalize(sub(w.end, w.start));\n openingCenters.set(o.id, [w.start[0] + d[0] * o.offset, w.start[1] + d[1] * o.offset]);\n }\n\n const groups = new Map<string, WallInterval[]>();\n for (const w of floor.walls) {\n const interval = intervalOf(w);\n const k = key(interval);\n const g = groups.get(k);\n if (g) g.push(interval);\n else groups.set(k, [interval]);\n }\n\n const survivors: Wall[] = [];\n const survivorOf = new Map<string, Wall>(); // any wall id -> survivor wall\n let mergedAny = false;\n\n const flush = (active: WallInterval[], a: number, b: number) => {\n const survivor = active[0]!.wall;\n if (active.length > 1) {\n survivor.start = pointAt(active[0]!, a);\n survivor.end = pointAt(active[0]!, b);\n mergedAny = true;\n }\n survivors.push(survivor);\n for (const i of active) survivorOf.set(i.wall.id, survivor);\n };\n\n for (const group of groups.values()) {\n if (group.length === 1) {\n const only = group[0]!;\n survivors.push(only.wall);\n survivorOf.set(only.wall.id, only.wall);\n continue;\n }\n\n const sorted = [...group].sort((a, b) => a.a - b.a);\n let active: WallInterval[] = [];\n let activeA = 0;\n let activeB = 0;\n for (const interval of sorted) {\n if (active.length === 0) {\n active = [interval];\n activeA = interval.a;\n activeB = interval.b;\n continue;\n }\n if (interval.a < activeB - 1e-6) {\n active.push(interval);\n activeA = Math.min(activeA, interval.a);\n activeB = Math.max(activeB, interval.b);\n } else {\n flush(active, activeA, activeB);\n active = [interval];\n activeA = interval.a;\n activeB = interval.b;\n }\n }\n if (active.length > 0) flush(active, activeA, activeB);\n }\n\n if (!mergedAny) return;\n\n for (const o of floor.openings) {\n const survivor = survivorOf.get(o.wallId);\n if (!survivor) continue;\n const center = openingCenters.get(o.id);\n if (center) {\n // Offset of the original world centre along the survivor.\n const sd = normalize(sub(survivor.end, survivor.start));\n o.offset = dot(sub(center, survivor.start), sd);\n }\n o.wallId = survivor.id;\n }\n\n for (const r of floor.rooms) {\n if (r.boundaryWallIds) {\n r.boundaryWallIds = Array.from(\n new Set(r.boundaryWallIds.map((id) => survivorOf.get(id)?.id ?? id)),\n );\n }\n }\n\n floor.walls = survivors;\n}\n\n/**\n * Convert a rendered instance tree into the canonical BuildingDocument.\n * `fallbackName` is used when the <Building> has no `name` prop (e.g. the\n * registered composition name).\n */\nexport function convert(instances: Instance[], fallbackName = \"Untitled\"): BuildingDocument {\n const tops = flatten(instances);\n const usedIds = new Set(DEFAULT_MATERIALS.map((m) => m.id));\n const materials: Material[] = DEFAULT_MATERIALS.map((m) => ({ ...m }));\n let topMaterialIndex = 0;\n for (const n of tops) {\n if (n.tag === TAG.material) {\n topMaterialIndex += 1;\n materials.push(toMaterial(n, `material-${topMaterialIndex}`, usedIds));\n }\n }\n\n const buildingNodes = tops.filter((n) => n.tag === TAG.building);\n const buildings: Building[] = [];\n let units: Units = \"metric\";\n let docName = fallbackName;\n\n const sources = buildingNodes.length > 0 ? buildingNodes : [{ tag: TAG.building, props: {}, children: tops }];\n\n sources.forEach((bn, buildingIndex) => {\n const buildingId = idFromProps(bn.props, `building-${buildingIndex + 1}`, usedIds);\n const name = str(bn.props, \"name\") ?? fallbackName;\n if (str(bn.props, \"units\") === \"imperial\") units = \"imperial\";\n docName = name;\n const floors = flatten(bn.children)\n .filter((c) => c.tag === TAG.floor)\n .map((fn, floorIndex) => convertFloor(fn, buildingId, materials, floorIndex, usedIds));\n // Keep floors ordered by elevation for stable stacking.\n floors.sort((a, b) => a.elevation - b.elevation);\n buildings.push({ id: buildingId, name, floors });\n });\n\n return {\n id: uniqueId(`doc-${docName}`, usedIds),\n version: MODEL_VERSION,\n name: docName,\n units,\n buildings,\n materials,\n assets: [],\n metadata: { source: \"react\" },\n };\n}\n","import { createElement, useEffect, type ComponentType, type ReactElement } from \"react\";\nimport type { BuildingDocument } from \"@react-arch/core\";\nimport { renderToInstances } from \"./renderer.js\";\nimport { convert } from \"./convert.js\";\n\nexport interface BuildingComposition {\n id: string;\n name: string;\n component: ComponentType<Record<string, unknown>>;\n defaultProps?: Record<string, unknown>;\n}\n\n// --- module-level registry (Remotion-style) -------------------------------\n\nconst compositions = new Map<string, BuildingComposition>();\nconst listeners = new Set<() => void>();\nlet rootComponent: ComponentType | null = null;\n// Cached, referentially-stable snapshot for useSyncExternalStore consumers.\nlet snapshot: BuildingComposition[] = [];\nlet version = 0;\n\nfunction emit(): void {\n snapshot = [...compositions.values()];\n version += 1;\n for (const fn of listeners) fn();\n}\n\n/** Increments whenever the registry changes (incl. hot-reload re-registration). */\nexport function getCompositionsVersion(): number {\n return version;\n}\n\nexport function __registerComposition(c: BuildingComposition): void {\n compositions.set(c.id, c);\n emit();\n}\nexport function __unregisterComposition(id: string): void {\n compositions.delete(id);\n emit();\n}\n\nexport function getCompositions(): BuildingComposition[] {\n return snapshot;\n}\nexport function subscribeCompositions(fn: () => void): () => void {\n listeners.add(fn);\n return () => listeners.delete(fn);\n}\n\n/**\n * Register the root component (mirrors Remotion's registerRoot). The Studio\n * mounts this so its <Composition> children register themselves.\n */\nexport function registerRoot(component: ComponentType): void {\n rootComponent = component;\n emit();\n}\nexport function getRoot(): ComponentType | null {\n return rootComponent;\n}\n\n/**\n * Declares a building composition. Renders nothing visible; on mount it\n * registers itself into the module registry the Studio reads.\n */\nexport function Composition(props: BuildingComposition): null {\n const { id, name, component, defaultProps } = props;\n useEffect(() => {\n __registerComposition({ id, name, component, defaultProps });\n return () => __unregisterComposition(id);\n }, [id, name, component, defaultProps]);\n return null;\n}\n\n// --- rendering -------------------------------------------------------------\n\n/** Render any React Arch element tree to the canonical model. */\nexport function renderToDocument(element: ReactElement, fallbackName?: string): BuildingDocument {\n return convert(renderToInstances(element), fallbackName);\n}\n\n/** Render a registered composition (component + its default props) to a model. */\nexport function renderComposition(comp: BuildingComposition): BuildingDocument {\n const element = createElement(comp.component, comp.defaultProps ?? {});\n return renderToDocument(element, comp.name);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-arch/react",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -13,9 +13,9 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "react-reconciler": "^0.29.2",
16
- "@react-arch/core": "0.1.2",
17
- "@react-arch/geometry": "0.1.2",
18
- "@react-arch/shared": "0.1.2"
16
+ "@react-arch/core": "0.1.3",
17
+ "@react-arch/shared": "0.1.3",
18
+ "@react-arch/geometry": "0.1.3"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": "^18.3.0"