@awesome-flow/ecs 0.0.0

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.
package/dist/index.js ADDED
@@ -0,0 +1,605 @@
1
+ // src/ecs/ecs-flow-context.ts
2
+ import { createContext } from "react";
3
+ var EcsFlowContext = createContext({
4
+ ecsFlowRepository: null,
5
+ entityRepository: null,
6
+ entityEventsManager: null,
7
+ entityUpdateCounter: null,
8
+ systemsModuleRepository: null
9
+ });
10
+
11
+ // src/utils/id-generator.ts
12
+ var IdGenerator = class {
13
+ static entityProxy(proxy) {
14
+ return `${proxy.entityType}:${proxy.entityUid}`;
15
+ }
16
+ };
17
+
18
+ // src/ecs/ecs-flow-repository.ts
19
+ var EcsFlowRepository = class {
20
+ nodes;
21
+ constructor() {
22
+ this.nodes = /* @__PURE__ */ new Map();
23
+ }
24
+ get sizeNodes() {
25
+ return this.nodes.size;
26
+ }
27
+ addSystemModuleNode(node) {
28
+ this.nodes.set(node.data.entityType.toString(), node);
29
+ }
30
+ getSystemModuleNode(entityType) {
31
+ return this.nodes.get(entityType.toString());
32
+ }
33
+ addEntityNode(node) {
34
+ this.nodes.set(IdGenerator.entityProxy(node.data.entity), node);
35
+ }
36
+ getEntityNode(entity) {
37
+ return this.nodes.get(IdGenerator.entityProxy(entity));
38
+ }
39
+ listAllNodes() {
40
+ return Array.from(this.nodes.values());
41
+ }
42
+ };
43
+
44
+ // src/ecs/flow-ecs-state.tsx
45
+ import { useEffect as useEffect7, useContext as useContext10, useState as useState3 } from "react";
46
+
47
+ // src/ecs/flow-ecs-auto-layout.tsx
48
+ import { FlowContext } from "@awesome-flow/core/abstract";
49
+ import Dagre from "@dagrejs/dagre";
50
+ import { useReactFlow } from "@xyflow/react";
51
+ import { useCallback, useContext, useEffect, useMemo } from "react";
52
+ import { Fragment, jsx } from "react/jsx-runtime";
53
+ function FlowEcsAutoLayout(props) {
54
+ const { getNodes, getEdges } = useReactFlow();
55
+ const context = useContext(FlowContext);
56
+ const setNodes = context.useFlowStore((state) => state.setNodes);
57
+ const graph = useMemo(() => new Dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({})), []);
58
+ const getLayoutElements = useCallback(
59
+ (nodes, edges, options) => {
60
+ graph.setGraph(options);
61
+ edges.forEach((edge) => graph.setEdge(edge.source, edge.target));
62
+ nodes.forEach((node) => {
63
+ if (node.measured) {
64
+ graph.setNode(node.id, {
65
+ width: node.measured.width,
66
+ height: node.measured.height
67
+ });
68
+ }
69
+ });
70
+ Dagre.layout(graph);
71
+ return {
72
+ nodes: nodes.map((node) => {
73
+ const graphNode = graph.node(node.id);
74
+ if (graphNode) {
75
+ return { ...node, position: { x: graphNode.x, y: graphNode.y } };
76
+ }
77
+ return node;
78
+ }),
79
+ edges
80
+ };
81
+ },
82
+ [graph]
83
+ );
84
+ useEffect(() => {
85
+ if (props.needsLayout) {
86
+ const storeNodes = getNodes();
87
+ if (storeNodes?.length) {
88
+ const edges = getEdges();
89
+ const layout = getLayoutElements(storeNodes, edges, {
90
+ rankdir: "LR"
91
+ });
92
+ setNodes(layout.nodes);
93
+ }
94
+ }
95
+ }, [props.needsLayout]);
96
+ useEffect(() => {
97
+ if (props.needsLayout) {
98
+ props.setNeedsLayout(false);
99
+ }
100
+ });
101
+ return /* @__PURE__ */ jsx(Fragment, {});
102
+ }
103
+ var flow_ecs_auto_layout_default = FlowEcsAutoLayout;
104
+
105
+ // src/ecs/flow-ecs-entities.tsx
106
+ import { FlowContext as FlowContext4 } from "@awesome-flow/core/abstract";
107
+ import { useContext as useContext8, useEffect as useEffect5, useState as useState2 } from "react";
108
+
109
+ // src/nodes/node-systems-module.tsx
110
+ import { NodeContainer } from "@awesome-flow/core/layout";
111
+ import { useContext as useContext2 } from "react";
112
+
113
+ // src/layout/systems-module-layout.tsx
114
+ import { SystemType } from "@awesome-ecs/abstract/systems";
115
+ import { Accordion as Accordion2, Text } from "@mantine/core";
116
+ import { useMemo as useMemo3 } from "react";
117
+
118
+ // src/components/badge-list.tsx
119
+ import { Badge } from "@mantine/core";
120
+ import { memo as memo2 } from "react";
121
+
122
+ // src/components/formatter-camel-case.tsx
123
+ import { memo, useMemo as useMemo2 } from "react";
124
+ function CamelCaseFormatter(props) {
125
+ const value = useMemo2(
126
+ () => props.value?.toString().replace(/([a-z])([A-Z])/g, "$1 $2"),
127
+ [props.value]
128
+ );
129
+ return value;
130
+ }
131
+ var formatter_camel_case_default = memo(CamelCaseFormatter);
132
+
133
+ // src/components/badge-list.tsx
134
+ import { jsx as jsx2 } from "react/jsx-runtime";
135
+ function BadgeList(props) {
136
+ return props.items.map((value, i) => {
137
+ return /* @__PURE__ */ jsx2(Badge, { ...props.badge || [], children: /* @__PURE__ */ jsx2(formatter_camel_case_default, { value }) }, i);
138
+ });
139
+ }
140
+ var badge_list_default = memo2(BadgeList);
141
+
142
+ // src/components/pipeline-middleware-list.tsx
143
+ import { Accordion, Badge as Badge2, Stack } from "@mantine/core";
144
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
145
+ function PipelineMiddlewareList(props) {
146
+ let middleware = [];
147
+ if (props.pipeline) {
148
+ middleware = props.pipeline["middleware"];
149
+ }
150
+ const components = middleware.map((m) => {
151
+ return m.name || m.constructor.name;
152
+ });
153
+ return /* @__PURE__ */ jsxs(Accordion.Item, { value: props.label, children: [
154
+ /* @__PURE__ */ jsx3(Accordion.Control, { children: /* @__PURE__ */ jsx3(Badge2, { fullWidth: true, variant: "light", rightSection: components.length, children: props.label }) }),
155
+ /* @__PURE__ */ jsx3(Accordion.Panel, { children: /* @__PURE__ */ jsx3(Stack, { children: /* @__PURE__ */ jsx3(badge_list_default, { items: components, badge: { variant: "outline" } }) }) })
156
+ ] }, props.label);
157
+ }
158
+ var pipeline_middleware_list_default = PipelineMiddlewareList;
159
+
160
+ // src/layout/systems-module-layout.tsx
161
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
162
+ function SystemsModuleLayout(props) {
163
+ const { module } = props;
164
+ const runtimeContext = module["runtimeContext"];
165
+ const systemContext = runtimeContext.systemContext;
166
+ const { status } = useMemo3(() => {
167
+ return systemContext.runtime;
168
+ }, [systemContext.runtime.status]);
169
+ const init = runtimeContext.systemPipelines.get(SystemType.initialize);
170
+ const update = runtimeContext.systemPipelines.get(SystemType.update);
171
+ const render = runtimeContext.systemPipelines.get(SystemType.render);
172
+ const sync = runtimeContext.systemPipelines.get(SystemType.sync);
173
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
174
+ /* @__PURE__ */ jsxs2(Text, { children: [
175
+ "Status: ",
176
+ status
177
+ ] }),
178
+ /* @__PURE__ */ jsxs2(Accordion2, { children: [
179
+ init && /* @__PURE__ */ jsx4(pipeline_middleware_list_default, { pipeline: init, label: "Initialize" }),
180
+ update && /* @__PURE__ */ jsx4(pipeline_middleware_list_default, { pipeline: update, label: "Update" }),
181
+ render && /* @__PURE__ */ jsx4(pipeline_middleware_list_default, { pipeline: render, label: "Render" }),
182
+ sync && /* @__PURE__ */ jsx4(pipeline_middleware_list_default, { pipeline: sync, label: "Sync" })
183
+ ] })
184
+ ] });
185
+ }
186
+ var systems_module_layout_default = SystemsModuleLayout;
187
+
188
+ // src/nodes/node-systems-module.tsx
189
+ import { Badge as Badge3 } from "@mantine/core";
190
+ import { jsx as jsx5 } from "react/jsx-runtime";
191
+ function SystemsModuleNode({ id, data, selected, type }) {
192
+ const { systemsModuleRepository } = useContext2(EcsFlowContext);
193
+ const module = systemsModuleRepository.get(data.entityType);
194
+ return /* @__PURE__ */ jsx5(
195
+ NodeContainer,
196
+ {
197
+ id,
198
+ selected,
199
+ handles: data.handles,
200
+ title: /* @__PURE__ */ jsx5(Badge3, { fullWidth: true, color: "indigo", variant: "transparent", children: /* @__PURE__ */ jsx5(formatter_camel_case_default, { value: data.entityType }) }),
201
+ templateId: data.templateId,
202
+ type,
203
+ children: /* @__PURE__ */ jsx5(systems_module_layout_default, { type: data.entityType, module })
204
+ }
205
+ );
206
+ }
207
+ var node_systems_module_default = SystemsModuleNode;
208
+
209
+ // src/nodes/node-entity.tsx
210
+ import { NodeContainer as NodeContainer2 } from "@awesome-flow/core/layout";
211
+ import { Badge as Badge9 } from "@mantine/core";
212
+ import { useContext as useContext5, useMemo as useMemo8 } from "react";
213
+
214
+ // src/layout/entity-layout.tsx
215
+ import { Accordion as Accordion6, Badge as Badge8, Divider, Group } from "@mantine/core";
216
+
217
+ // src/components/entity-component-list.tsx
218
+ import { Accordion as Accordion3, Badge as Badge4, Stack as Stack2 } from "@mantine/core";
219
+ import { memo as memo5 } from "react";
220
+
221
+ // src/components/entity-component-inspector.tsx
222
+ import { Box, Button, Collapse } from "@mantine/core";
223
+ import { memo as memo4, useMemo as useMemo6 } from "react";
224
+ import { useDisclosure } from "@mantine/hooks";
225
+
226
+ // src/components/object-inspector.tsx
227
+ import { useComputedColorScheme } from "@mantine/core";
228
+ import { memo as memo3, useMemo as useMemo5 } from "react";
229
+ import { Inspector } from "react-inspector";
230
+ import { jsx as jsx6 } from "react/jsx-runtime";
231
+ function ObjectInspector(props) {
232
+ const colorScheme = useComputedColorScheme();
233
+ const theme = useMemo5(
234
+ () => colorScheme === "dark" ? "chromeDark" : "chromeLight",
235
+ [colorScheme]
236
+ );
237
+ return /* @__PURE__ */ jsx6(Inspector, { table: false, theme, data: props.data });
238
+ }
239
+ var object_inspector_default = memo3(ObjectInspector);
240
+
241
+ // src/components/entity-component-inspector.tsx
242
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
243
+ function EntityComponentInspector(props) {
244
+ const [opened, { toggle }] = useDisclosure(false);
245
+ const buttonColor = useMemo6(() => opened ? "light" : "indigo", [opened]);
246
+ return /* @__PURE__ */ jsxs3(Box, { children: [
247
+ /* @__PURE__ */ jsx7(Button, { variant: "outline", size: "xs", onClick: toggle, color: buttonColor, fullWidth: true, children: props.component.componentType }),
248
+ /* @__PURE__ */ jsx7(Collapse, { in: opened, children: opened && /* @__PURE__ */ jsx7(object_inspector_default, { data: props.component }) })
249
+ ] });
250
+ }
251
+ var entity_component_inspector_default = memo4(EntityComponentInspector);
252
+
253
+ // src/components/entity-component-list.tsx
254
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
255
+ function EntityComponentList(props) {
256
+ const components = Array.from(props.entity.components.values());
257
+ return /* @__PURE__ */ jsxs4(Accordion3.Item, { value: "components", children: [
258
+ /* @__PURE__ */ jsx8(Accordion3.Control, { children: /* @__PURE__ */ jsx8(Badge4, { fullWidth: true, variant: "light", rightSection: components.length, children: "Components" }) }),
259
+ /* @__PURE__ */ jsx8(Accordion3.Panel, { children: /* @__PURE__ */ jsx8(Stack2, { children: components.map((c, i) => /* @__PURE__ */ jsx8(entity_component_inspector_default, { component: c }, i)) }) })
260
+ ] }, "components");
261
+ }
262
+ var entity_component_list_default = memo5(EntityComponentList);
263
+
264
+ // src/components/entity-proxy-list.tsx
265
+ import { Accordion as Accordion4, Badge as Badge5, Stack as Stack3 } from "@mantine/core";
266
+ import { memo as memo6 } from "react";
267
+ import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
268
+ function EntityProxyList(props) {
269
+ const proxies = Array.from(props.entity.proxies.values()).map((c) => c.values());
270
+ const items = proxies.map((p) => Array.from(p).map((k) => IdGenerator.entityProxy(k))).flat();
271
+ return /* @__PURE__ */ jsxs5(Accordion4.Item, { value: "proxies", children: [
272
+ /* @__PURE__ */ jsx9(Accordion4.Control, { children: /* @__PURE__ */ jsx9(Badge5, { fullWidth: true, variant: "light", rightSection: items.length, children: "Proxies" }) }),
273
+ /* @__PURE__ */ jsx9(Accordion4.Panel, { children: /* @__PURE__ */ jsx9(Stack3, { children: /* @__PURE__ */ jsx9(badge_list_default, { items, badge: { variant: "outline" } }) }) })
274
+ ] }, "proxies");
275
+ }
276
+ var entity_proxy_list_default = memo6(EntityProxyList);
277
+
278
+ // src/components/entity-subscription-list.tsx
279
+ import { Accordion as Accordion5, Badge as Badge6, Stack as Stack4 } from "@mantine/core";
280
+ import { memo as memo7, useContext as useContext3 } from "react";
281
+ import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
282
+ function EntitySubscriptionList(props) {
283
+ const { entityEventsManager } = useContext3(EcsFlowContext);
284
+ const subscriptions = entityEventsManager.getSubscriptionsForEntity(props.entity.myProxy);
285
+ return /* @__PURE__ */ jsxs6(Accordion5.Item, { value: "subscriptions", children: [
286
+ /* @__PURE__ */ jsx10(Accordion5.Control, { children: /* @__PURE__ */ jsx10(Badge6, { fullWidth: true, variant: "light", rightSection: subscriptions.length, children: "Events" }) }),
287
+ /* @__PURE__ */ jsx10(Accordion5.Panel, { children: /* @__PURE__ */ jsx10(Stack4, { children: /* @__PURE__ */ jsx10(badge_list_default, { items: subscriptions, badge: { variant: "outline" } }) }) })
288
+ ] }, "subscriptions");
289
+ }
290
+ var entity_subscription_list_default = memo7(EntitySubscriptionList);
291
+
292
+ // src/components/entity-update-counter.tsx
293
+ import { Badge as Badge7 } from "@mantine/core";
294
+ import { memo as memo8, useContext as useContext4, useEffect as useEffect2, useState } from "react";
295
+ import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
296
+ function EntityUpdateCounter(props) {
297
+ const [, setRefresh] = useState(0);
298
+ const { entityUpdateCounter } = useContext4(EcsFlowContext);
299
+ const updates = entityUpdateCounter.getUpdateCount(props.entityUid) || 0;
300
+ const removes = entityUpdateCounter.getRemoveCount(props.entityUid) || 0;
301
+ useEffect2(() => {
302
+ const interval = setInterval(() => {
303
+ setRefresh((refresh) => refresh + 1);
304
+ }, 1e3);
305
+ return () => {
306
+ console.log("CLEAR INTERVAL");
307
+ clearInterval(interval);
308
+ };
309
+ }, []);
310
+ return /* @__PURE__ */ jsxs7(Fragment3, { children: [
311
+ /* @__PURE__ */ jsx11(Badge7, { variant: "light", children: updates }),
312
+ /* @__PURE__ */ jsx11(Badge7, { variant: "light", color: "orange", children: removes })
313
+ ] });
314
+ }
315
+ var entity_update_counter_default = memo8(EntityUpdateCounter);
316
+
317
+ // src/layout/entity-layout.tsx
318
+ import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
319
+ function EntityLayout({ entity }) {
320
+ return /* @__PURE__ */ jsxs8(Fragment4, { children: [
321
+ /* @__PURE__ */ jsxs8(Group, { children: [
322
+ /* @__PURE__ */ jsx12(Badge8, { variant: "outline", color: "orange", children: entity.myProxy.entityUid }),
323
+ /* @__PURE__ */ jsx12(entity_update_counter_default, { entityUid: entity.myProxy.entityUid })
324
+ ] }),
325
+ /* @__PURE__ */ jsx12(Divider, { my: 5 }),
326
+ /* @__PURE__ */ jsxs8(Accordion6, { children: [
327
+ /* @__PURE__ */ jsx12(entity_component_list_default, { entity }),
328
+ /* @__PURE__ */ jsx12(entity_proxy_list_default, { entity }),
329
+ /* @__PURE__ */ jsx12(entity_subscription_list_default, { entity })
330
+ ] })
331
+ ] });
332
+ }
333
+ var entity_layout_default = EntityLayout;
334
+
335
+ // src/nodes/node-entity.tsx
336
+ import { jsx as jsx13 } from "react/jsx-runtime";
337
+ function EntityNode({ id, data, selected, type }) {
338
+ const { entityRepository } = useContext5(EcsFlowContext);
339
+ const entity = useMemo8(() => entityRepository.get(data.entity), [data.entity]);
340
+ return /* @__PURE__ */ jsx13(
341
+ NodeContainer2,
342
+ {
343
+ id,
344
+ selected,
345
+ handles: data.handles,
346
+ title: /* @__PURE__ */ jsx13(Badge9, { fullWidth: true, variant: "transparent", children: /* @__PURE__ */ jsx13(formatter_camel_case_default, { value: entity.myProxy.entityType }) }),
347
+ templateId: data.templateId,
348
+ type,
349
+ children: /* @__PURE__ */ jsx13(entity_layout_default, { entity })
350
+ }
351
+ );
352
+ }
353
+ var node_entity_default = EntityNode;
354
+
355
+ // src/node-types.ts
356
+ var EcsNodeType = /* @__PURE__ */ ((EcsNodeType2) => {
357
+ EcsNodeType2["systemsModule"] = "systems-module-node";
358
+ EcsNodeType2["entity"] = "entity-node";
359
+ return EcsNodeType2;
360
+ })(EcsNodeType || {});
361
+ var ecsNodeTypes = {
362
+ ["systems-module-node" /* systemsModule */]: node_systems_module_default,
363
+ ["entity-node" /* entity */]: node_entity_default
364
+ };
365
+
366
+ // src/ecs/flow-ecs-edge-proxies.tsx
367
+ import { useContext as useContext6, useEffect as useEffect3 } from "react";
368
+ import { FlowContext as FlowContext2 } from "@awesome-flow/core/abstract";
369
+ import { Fragment as Fragment5, jsx as jsx14 } from "react/jsx-runtime";
370
+ function FlowEcsEdgeProxies(props) {
371
+ const { nodesToConnect } = props;
372
+ const context = useContext6(FlowContext2);
373
+ const onConnect = context.useFlowStore((state) => state.onConnect);
374
+ const { ecsFlowRepository, entityRepository } = useContext6(EcsFlowContext);
375
+ useEffect3(() => {
376
+ for (const node of nodesToConnect) {
377
+ const sourceHandle = node.data.handles.find((h) => h.type === "source");
378
+ const entity = entityRepository.get(node.data.entity);
379
+ for (const [, proxyMap] of entity.proxies) {
380
+ for (const proxy of proxyMap.values()) {
381
+ const proxyNode = ecsFlowRepository.getEntityNode(proxy);
382
+ if (proxyNode) {
383
+ const targetHandle = proxyNode.data.handles.find((h) => h.type === "target");
384
+ onConnect({
385
+ source: node.id,
386
+ target: proxyNode.id,
387
+ sourceHandle: sourceHandle.id,
388
+ targetHandle: targetHandle.id
389
+ });
390
+ }
391
+ }
392
+ }
393
+ }
394
+ }, [nodesToConnect]);
395
+ return /* @__PURE__ */ jsx14(Fragment5, {});
396
+ }
397
+ var flow_ecs_edge_proxies_default = FlowEcsEdgeProxies;
398
+
399
+ // src/ecs/flow-ecs-edge-modules.tsx
400
+ import { useContext as useContext7, useEffect as useEffect4 } from "react";
401
+ import { FlowContext as FlowContext3 } from "@awesome-flow/core/abstract";
402
+ import { Fragment as Fragment6, jsx as jsx15 } from "react/jsx-runtime";
403
+ function FlowEcsEdgeModules(props) {
404
+ const { nodesToConnect } = props;
405
+ const context = useContext7(FlowContext3);
406
+ const onConnect = context.useFlowStore((state) => state.onConnect);
407
+ const { ecsFlowRepository, entityRepository } = useContext7(EcsFlowContext);
408
+ useEffect4(() => {
409
+ for (const node of nodesToConnect) {
410
+ const sourceHandle = node.data.handles.find((h) => h.type === "source");
411
+ const entity = entityRepository.get(node.data.entity);
412
+ const systemModule = ecsFlowRepository.getSystemModuleNode(entity.myProxy.entityType);
413
+ const targetHandle = systemModule?.data.handles.find((h) => h.type === "target");
414
+ if (targetHandle) {
415
+ onConnect({
416
+ source: node.id,
417
+ target: systemModule.id,
418
+ sourceHandle: sourceHandle.id,
419
+ targetHandle: targetHandle.id
420
+ });
421
+ console.log("CONNECTING MODULE", node.id, systemModule.id);
422
+ }
423
+ }
424
+ }, [nodesToConnect]);
425
+ return /* @__PURE__ */ jsx15(Fragment6, {});
426
+ }
427
+ var flow_ecs_edge_modules_default = FlowEcsEdgeModules;
428
+
429
+ // src/ecs/flow-ecs-entities.tsx
430
+ import { Fragment as Fragment7, jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
431
+ function FlowEcsEntities() {
432
+ const context = useContext8(FlowContext4);
433
+ const addNodes = context.useFlowStore((state) => state.addNodes);
434
+ const { ecsFlowRepository, entityRepository } = useContext8(EcsFlowContext);
435
+ const [entityNodes, setEntityNodes] = useState2([]);
436
+ useEffect5(() => {
437
+ const entities = entityRepository.listAll();
438
+ const nodes = [];
439
+ for (const entity of entities) {
440
+ if (ecsFlowRepository.getEntityNode(entity.myProxy)) {
441
+ continue;
442
+ }
443
+ const node = context.nodeFactory.createNodeFromType("entity-node" /* entity */);
444
+ node.data.entity = entity.myProxy;
445
+ node.position = { x: 0, y: 0 };
446
+ ecsFlowRepository.addEntityNode(node);
447
+ nodes.push(node);
448
+ }
449
+ setEntityNodes(nodes);
450
+ addNodes(nodes);
451
+ }, [entityRepository.size]);
452
+ return /* @__PURE__ */ jsxs9(Fragment7, { children: [
453
+ /* @__PURE__ */ jsx16(flow_ecs_edge_proxies_default, { nodesToConnect: entityNodes }),
454
+ /* @__PURE__ */ jsx16(flow_ecs_edge_modules_default, { nodesToConnect: entityNodes })
455
+ ] });
456
+ }
457
+ var flow_ecs_entities_default = FlowEcsEntities;
458
+
459
+ // src/ecs/flow-ecs-modules.tsx
460
+ import { useEffect as useEffect6, useContext as useContext9 } from "react";
461
+ import { FlowContext as FlowContext5 } from "@awesome-flow/core/abstract";
462
+ import { Fragment as Fragment8, jsx as jsx17 } from "react/jsx-runtime";
463
+ function FlowEcsModules() {
464
+ const context = useContext9(FlowContext5);
465
+ const addNodes = context.useFlowStore((state) => state.addNodes);
466
+ const { ecsFlowRepository, systemsModuleRepository } = useContext9(EcsFlowContext);
467
+ useEffect6(() => {
468
+ const modules = Array.from(systemsModuleRepository.list()).filter((m) => !!m);
469
+ const keys = Array.from(modules.values()).map((v) => v[0]);
470
+ const nodesToAdd = [];
471
+ for (const element of keys) {
472
+ if (ecsFlowRepository.getSystemModuleNode(element)) {
473
+ continue;
474
+ }
475
+ const node = context.nodeFactory.createNodeFromType(
476
+ "systems-module-node" /* systemsModule */
477
+ );
478
+ node.data.entityType = element;
479
+ node.position = { x: 0, y: 0 };
480
+ ecsFlowRepository.addSystemModuleNode(node);
481
+ nodesToAdd.push(node);
482
+ }
483
+ if (nodesToAdd.length) {
484
+ addNodes(nodesToAdd);
485
+ }
486
+ }, [systemsModuleRepository.size]);
487
+ return /* @__PURE__ */ jsx17(Fragment8, {});
488
+ }
489
+ var flow_ecs_modules_default = FlowEcsModules;
490
+
491
+ // src/ecs/flow-ecs-state.tsx
492
+ import { Fragment as Fragment9, jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
493
+ function FlowEcsState(props) {
494
+ const [, setUpdates] = useState3(0);
495
+ const [needsLayout, setNeedsLayout] = useState3(false);
496
+ const { ecsFlowRepository } = useContext10(EcsFlowContext);
497
+ useEffect7(() => {
498
+ setNeedsLayout(true);
499
+ }, [ecsFlowRepository.sizeNodes]);
500
+ useEffect7(() => {
501
+ setInterval(() => {
502
+ setUpdates((updates) => updates + 1);
503
+ }, 1e3);
504
+ }, []);
505
+ return /* @__PURE__ */ jsxs10(Fragment9, { children: [
506
+ props.showSystemModules && /* @__PURE__ */ jsx18(flow_ecs_modules_default, {}),
507
+ props.showEntities && /* @__PURE__ */ jsx18(flow_ecs_entities_default, {}),
508
+ props.autoLayout && /* @__PURE__ */ jsx18(flow_ecs_auto_layout_default, { needsLayout, setNeedsLayout })
509
+ ] });
510
+ }
511
+ var flow_ecs_state_default = FlowEcsState;
512
+
513
+ // src/templates/template-entity-node.ts
514
+ import { IDGenerator } from "@awesome-flow/core/utils";
515
+
516
+ // src/handle-types.ts
517
+ var EcsHandleDataType = /* @__PURE__ */ ((EcsHandleDataType2) => {
518
+ EcsHandleDataType2[EcsHandleDataType2["proxy"] = 1] = "proxy";
519
+ EcsHandleDataType2[EcsHandleDataType2["module"] = 2] = "module";
520
+ return EcsHandleDataType2;
521
+ })(EcsHandleDataType || {});
522
+
523
+ // src/templates/template-entity-node.ts
524
+ import { Position } from "@xyflow/react";
525
+ var EntityNodeTemplate = class {
526
+ create() {
527
+ const data = {
528
+ title: "Entity",
529
+ entity: null
530
+ };
531
+ return {
532
+ id: IDGenerator.template(),
533
+ removable: false,
534
+ type: "entity-node" /* entity */,
535
+ data,
536
+ handles: [
537
+ {
538
+ dataType: 1 /* proxy */,
539
+ position: Position.Left,
540
+ type: "target",
541
+ disabled: true
542
+ },
543
+ {
544
+ dataType: 1 /* proxy */,
545
+ position: Position.Right,
546
+ type: "source",
547
+ disabled: true
548
+ }
549
+ ]
550
+ };
551
+ }
552
+ isHandleAllowed() {
553
+ return false;
554
+ }
555
+ getHandleAllowedDataType() {
556
+ return void 0;
557
+ }
558
+ };
559
+
560
+ // src/templates/template-systems-module.ts
561
+ import { IDGenerator as IDGenerator2 } from "@awesome-flow/core/utils";
562
+ import { Position as Position2 } from "@xyflow/react";
563
+ var SystemsModuleNodeTemplate = class {
564
+ create() {
565
+ const data = {
566
+ title: "Systems Module",
567
+ entityType: null,
568
+ handles: null,
569
+ templateId: null
570
+ };
571
+ return {
572
+ id: IDGenerator2.template(),
573
+ removable: false,
574
+ type: "systems-module-node" /* systemsModule */,
575
+ data,
576
+ handles: [
577
+ {
578
+ dataType: 2 /* module */,
579
+ position: Position2.Left,
580
+ type: "target",
581
+ disabled: true
582
+ }
583
+ ]
584
+ };
585
+ }
586
+ isHandleAllowed() {
587
+ return false;
588
+ }
589
+ getHandleAllowedDataType() {
590
+ return void 0;
591
+ }
592
+ };
593
+ export {
594
+ EcsFlowContext,
595
+ EcsFlowRepository,
596
+ EcsHandleDataType,
597
+ EcsNodeType,
598
+ node_entity_default as EntityNode,
599
+ EntityNodeTemplate,
600
+ flow_ecs_state_default as FlowEcsState,
601
+ node_systems_module_default as SystemsModuleNode,
602
+ SystemsModuleNodeTemplate,
603
+ ecsNodeTypes
604
+ };
605
+ //# sourceMappingURL=index.js.map