@sg-pattern-engine/react 1.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.
@@ -0,0 +1,19 @@
1
+
2
+ > @sg-pattern-engine/react@1.0.0 build /workspace/packages/react
3
+ > tsup src/index.ts --format cjs,esm --dts --clean
4
+
5
+ CLI Building entry: src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.5.1
8
+ CLI Target: es2020
9
+ CLI Cleaning output folder
10
+ CJS Build start
11
+ ESM Build start
12
+ CJS dist/index.js 4.19 KB
13
+ CJS ⚡️ Build success in 63ms
14
+ ESM dist/index.mjs 2.99 KB
15
+ ESM ⚡️ Build success in 64ms
16
+ DTS Build start
17
+ DTS ⚡️ Build success in 2508ms
18
+ DTS dist/index.d.ts 567.00 B
19
+ DTS dist/index.d.mts 567.00 B
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { PatternConfig, AlgorithmOutput, Tile, PatternEngine } from '@sg-pattern-engine/core';
3
+
4
+ interface Props {
5
+ config: PatternConfig;
6
+ workerFactory?: () => Worker;
7
+ }
8
+ declare const PatternCanvas: React.FC<Props>;
9
+
10
+ interface TileResult {
11
+ output: AlgorithmOutput;
12
+ tile: Tile;
13
+ }
14
+ declare const usePatternEngine: (workerFactory?: () => Worker, concurrency?: number) => {
15
+ engine: PatternEngine;
16
+ generate: (config: PatternConfig) => Promise<TileResult[]>;
17
+ };
18
+
19
+ export { PatternCanvas, type TileResult, usePatternEngine };
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { PatternConfig, AlgorithmOutput, Tile, PatternEngine } from '@sg-pattern-engine/core';
3
+
4
+ interface Props {
5
+ config: PatternConfig;
6
+ workerFactory?: () => Worker;
7
+ }
8
+ declare const PatternCanvas: React.FC<Props>;
9
+
10
+ interface TileResult {
11
+ output: AlgorithmOutput;
12
+ tile: Tile;
13
+ }
14
+ declare const usePatternEngine: (workerFactory?: () => Worker, concurrency?: number) => {
15
+ engine: PatternEngine;
16
+ generate: (config: PatternConfig) => Promise<TileResult[]>;
17
+ };
18
+
19
+ export { PatternCanvas, type TileResult, usePatternEngine };
package/dist/index.js ADDED
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ PatternCanvas: () => PatternCanvas,
24
+ usePatternEngine: () => usePatternEngine
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/components/PatternCanvas.tsx
29
+ var import_react2 = require("react");
30
+ var import_core2 = require("@sg-pattern-engine/core");
31
+ var import_renderers = require("@sg-pattern-engine/renderers");
32
+
33
+ // src/hooks/usePatternEngine.ts
34
+ var import_react = require("react");
35
+ var import_core = require("@sg-pattern-engine/core");
36
+ var import_algorithms = require("@sg-pattern-engine/algorithms");
37
+ var usePatternEngine = (workerFactory, concurrency) => {
38
+ const [engine] = (0, import_react.useState)(() => {
39
+ const e = new import_core.PatternEngine();
40
+ import_algorithms.algorithms.forEach((algo) => e.registerAlgorithm(algo));
41
+ return e;
42
+ });
43
+ const poolRef = (0, import_react.useRef)(null);
44
+ (0, import_react.useEffect)(() => {
45
+ if (!workerFactory) return;
46
+ const poolSize = concurrency ?? (navigator.hardwareConcurrency ?? 4);
47
+ poolRef.current = new import_core.WorkerPool(
48
+ workerFactory,
49
+ poolSize
50
+ );
51
+ return () => {
52
+ poolRef.current?.terminate();
53
+ poolRef.current = null;
54
+ };
55
+ }, [workerFactory, concurrency]);
56
+ const generate = (0, import_react.useCallback)(async (config) => {
57
+ const tiles = engine.getTiles(config);
58
+ const pool = poolRef.current;
59
+ if (pool) {
60
+ const outputs = await Promise.all(
61
+ tiles.map((tile) => pool.execute({ config, tile }))
62
+ );
63
+ return outputs.map((output, i) => ({ output, tile: tiles[i] }));
64
+ } else {
65
+ const results = [];
66
+ for (const tile of tiles) {
67
+ const output = await engine.generateTile(config, tile);
68
+ results.push({ output, tile });
69
+ }
70
+ return results;
71
+ }
72
+ }, [engine]);
73
+ return { engine, generate };
74
+ };
75
+
76
+ // src/components/PatternCanvas.tsx
77
+ var import_jsx_runtime = require("react/jsx-runtime");
78
+ var PatternCanvas = ({ config, workerFactory }) => {
79
+ const canvasRef = (0, import_react2.useRef)(null);
80
+ const loopRef = (0, import_react2.useRef)(null);
81
+ const { generate } = usePatternEngine(workerFactory);
82
+ const renderFrame = (0, import_react2.useCallback)(async (frameSeed) => {
83
+ const canvas = canvasRef.current;
84
+ if (!canvas) return;
85
+ const ctx = canvas.getContext("2d");
86
+ if (!ctx) return;
87
+ const frameConfig = frameSeed ? { ...config, seed: frameSeed } : config;
88
+ const results = await generate(frameConfig);
89
+ const renderer = new import_renderers.CanvasRenderer();
90
+ results.forEach(({ output, tile }) => {
91
+ renderer.render(ctx, output, tile, frameConfig);
92
+ });
93
+ }, [config, generate]);
94
+ (0, import_react2.useEffect)(() => {
95
+ loopRef.current?.stop();
96
+ if (config.animate) {
97
+ const loop = new import_core2.AnimationLoop(config);
98
+ loopRef.current = loop;
99
+ loop.start(async (frame) => {
100
+ const speed = config.evolutionSpeed ?? 0.1;
101
+ const seed = speed >= 1 ? frame.seed : `${config.seed}_${Math.floor(frame.frameIndex * speed)}`;
102
+ await renderFrame(seed);
103
+ });
104
+ } else {
105
+ renderFrame();
106
+ }
107
+ return () => {
108
+ loopRef.current?.stop();
109
+ };
110
+ }, [config, renderFrame]);
111
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("canvas", { ref: canvasRef, width: config.width, height: config.height });
112
+ };
113
+ // Annotate the CommonJS export names for ESM import in node:
114
+ 0 && (module.exports = {
115
+ PatternCanvas,
116
+ usePatternEngine
117
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,92 @@
1
+ // src/components/PatternCanvas.tsx
2
+ import { useRef as useRef2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
3
+ import { AnimationLoop } from "@sg-pattern-engine/core";
4
+ import { CanvasRenderer } from "@sg-pattern-engine/renderers";
5
+
6
+ // src/hooks/usePatternEngine.ts
7
+ import { useState, useCallback, useEffect, useRef } from "react";
8
+ import {
9
+ PatternEngine,
10
+ WorkerPool
11
+ } from "@sg-pattern-engine/core";
12
+ import { algorithms } from "@sg-pattern-engine/algorithms";
13
+ var usePatternEngine = (workerFactory, concurrency) => {
14
+ const [engine] = useState(() => {
15
+ const e = new PatternEngine();
16
+ algorithms.forEach((algo) => e.registerAlgorithm(algo));
17
+ return e;
18
+ });
19
+ const poolRef = useRef(null);
20
+ useEffect(() => {
21
+ if (!workerFactory) return;
22
+ const poolSize = concurrency ?? (navigator.hardwareConcurrency ?? 4);
23
+ poolRef.current = new WorkerPool(
24
+ workerFactory,
25
+ poolSize
26
+ );
27
+ return () => {
28
+ poolRef.current?.terminate();
29
+ poolRef.current = null;
30
+ };
31
+ }, [workerFactory, concurrency]);
32
+ const generate = useCallback(async (config) => {
33
+ const tiles = engine.getTiles(config);
34
+ const pool = poolRef.current;
35
+ if (pool) {
36
+ const outputs = await Promise.all(
37
+ tiles.map((tile) => pool.execute({ config, tile }))
38
+ );
39
+ return outputs.map((output, i) => ({ output, tile: tiles[i] }));
40
+ } else {
41
+ const results = [];
42
+ for (const tile of tiles) {
43
+ const output = await engine.generateTile(config, tile);
44
+ results.push({ output, tile });
45
+ }
46
+ return results;
47
+ }
48
+ }, [engine]);
49
+ return { engine, generate };
50
+ };
51
+
52
+ // src/components/PatternCanvas.tsx
53
+ import { jsx } from "react/jsx-runtime";
54
+ var PatternCanvas = ({ config, workerFactory }) => {
55
+ const canvasRef = useRef2(null);
56
+ const loopRef = useRef2(null);
57
+ const { generate } = usePatternEngine(workerFactory);
58
+ const renderFrame = useCallback2(async (frameSeed) => {
59
+ const canvas = canvasRef.current;
60
+ if (!canvas) return;
61
+ const ctx = canvas.getContext("2d");
62
+ if (!ctx) return;
63
+ const frameConfig = frameSeed ? { ...config, seed: frameSeed } : config;
64
+ const results = await generate(frameConfig);
65
+ const renderer = new CanvasRenderer();
66
+ results.forEach(({ output, tile }) => {
67
+ renderer.render(ctx, output, tile, frameConfig);
68
+ });
69
+ }, [config, generate]);
70
+ useEffect2(() => {
71
+ loopRef.current?.stop();
72
+ if (config.animate) {
73
+ const loop = new AnimationLoop(config);
74
+ loopRef.current = loop;
75
+ loop.start(async (frame) => {
76
+ const speed = config.evolutionSpeed ?? 0.1;
77
+ const seed = speed >= 1 ? frame.seed : `${config.seed}_${Math.floor(frame.frameIndex * speed)}`;
78
+ await renderFrame(seed);
79
+ });
80
+ } else {
81
+ renderFrame();
82
+ }
83
+ return () => {
84
+ loopRef.current?.stop();
85
+ };
86
+ }, [config, renderFrame]);
87
+ return /* @__PURE__ */ jsx("canvas", { ref: canvasRef, width: config.width, height: config.height });
88
+ };
89
+ export {
90
+ PatternCanvas,
91
+ usePatternEngine
92
+ };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@sg-pattern-engine/react",
3
+ "version": "1.0.0",
4
+ "main": "./dist/index.js",
5
+ "module": "./dist/index.mjs",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js"
12
+ }
13
+ },
14
+ "dependencies": {
15
+ "@sg-pattern-engine/core": "1.0.0",
16
+ "@sg-pattern-engine/renderers": "1.0.0",
17
+ "@sg-pattern-engine/algorithms": "1.0.0"
18
+ },
19
+ "peerDependencies": {
20
+ "react": "^18.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "tsup": "^8.0.0",
24
+ "typescript": "^5.4.0",
25
+ "@types/react": "^18.0.0"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "scripts": {
31
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean"
32
+ }
33
+ }
@@ -0,0 +1,48 @@
1
+ import React, { useRef, useEffect, useCallback } from 'react';
2
+ import { PatternConfig, AnimationLoop } from '@sg-pattern-engine/core';
3
+ import { CanvasRenderer } from '@sg-pattern-engine/renderers';
4
+ import { usePatternEngine } from '../hooks/usePatternEngine';
5
+
6
+ interface Props {
7
+ config: PatternConfig;
8
+ workerFactory?: () => Worker;
9
+ }
10
+
11
+ export const PatternCanvas: React.FC<Props> = ({ config, workerFactory }) => {
12
+ const canvasRef = useRef<HTMLCanvasElement>(null);
13
+ const loopRef = useRef<AnimationLoop | null>(null);
14
+ const { generate } = usePatternEngine(workerFactory);
15
+
16
+ const renderFrame = useCallback(async (frameSeed?: string) => {
17
+ const canvas = canvasRef.current;
18
+ if (!canvas) return;
19
+ const ctx = canvas.getContext('2d');
20
+ if (!ctx) return;
21
+ const frameConfig = frameSeed ? { ...config, seed: frameSeed } : config;
22
+ const results = await generate(frameConfig);
23
+ const renderer = new CanvasRenderer();
24
+ results.forEach(({ output, tile }) => {
25
+ renderer.render(ctx, output, tile, frameConfig);
26
+ });
27
+ }, [config, generate]);
28
+
29
+ useEffect(() => {
30
+ loopRef.current?.stop();
31
+ if (config.animate) {
32
+ const loop = new AnimationLoop(config);
33
+ loopRef.current = loop;
34
+ loop.start(async (frame) => {
35
+ const speed = config.evolutionSpeed ?? 0.1;
36
+ const seed = speed >= 1
37
+ ? frame.seed
38
+ : `${config.seed}_${Math.floor(frame.frameIndex * speed)}`;
39
+ await renderFrame(seed);
40
+ });
41
+ } else {
42
+ renderFrame();
43
+ }
44
+ return () => { loopRef.current?.stop(); };
45
+ }, [config, renderFrame]);
46
+
47
+ return <canvas ref={canvasRef} width={config.width} height={config.height} />;
48
+ };
@@ -0,0 +1,66 @@
1
+ import { useState, useCallback, useEffect, useRef } from 'react';
2
+ import {
3
+ PatternEngine,
4
+ PatternConfig,
5
+ Tile,
6
+ AlgorithmOutput,
7
+ WorkerPool,
8
+ } from '@sg-pattern-engine/core';
9
+ import { algorithms } from '@sg-pattern-engine/algorithms';
10
+
11
+ export interface TileResult {
12
+ output: AlgorithmOutput;
13
+ tile: Tile;
14
+ }
15
+
16
+ interface WorkerMessage {
17
+ config: PatternConfig;
18
+ tile: Tile;
19
+ }
20
+
21
+ export const usePatternEngine = (
22
+ workerFactory?: () => Worker,
23
+ concurrency?: number
24
+ ) => {
25
+ const [engine] = useState(() => {
26
+ const e = new PatternEngine();
27
+ algorithms.forEach(algo => e.registerAlgorithm(algo));
28
+ return e;
29
+ });
30
+
31
+ const poolRef = useRef<WorkerPool<WorkerMessage, AlgorithmOutput> | null>(null);
32
+
33
+ useEffect(() => {
34
+ if (!workerFactory) return;
35
+ const poolSize = concurrency ?? (navigator.hardwareConcurrency ?? 4);
36
+ poolRef.current = new WorkerPool<WorkerMessage, AlgorithmOutput>(
37
+ workerFactory,
38
+ poolSize
39
+ );
40
+ return () => {
41
+ poolRef.current?.terminate();
42
+ poolRef.current = null;
43
+ };
44
+ }, [workerFactory, concurrency]);
45
+
46
+ const generate = useCallback(async (config: PatternConfig): Promise<TileResult[]> => {
47
+ const tiles = engine.getTiles(config);
48
+ const pool = poolRef.current;
49
+
50
+ if (pool) {
51
+ const outputs = await Promise.all(
52
+ tiles.map(tile => pool.execute({ config, tile }))
53
+ );
54
+ return outputs.map((output, i) => ({ output, tile: tiles[i] }));
55
+ } else {
56
+ const results: TileResult[] = [];
57
+ for (const tile of tiles) {
58
+ const output = await engine.generateTile(config, tile);
59
+ results.push({ output, tile });
60
+ }
61
+ return results;
62
+ }
63
+ }, [engine]);
64
+
65
+ return { engine, generate };
66
+ };
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './components/PatternCanvas';
2
+ export * from './hooks/usePatternEngine';
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "moduleResolution": "bundler",
6
+ "jsx": "react-jsx",
7
+ "paths": {
8
+ "@sg-pattern-engine/core": ["../core/dist/index.d.ts"],
9
+ "@sg-pattern-engine/renderers": ["../renderers/dist/index.d.ts"],
10
+ "@sg-pattern-engine/algorithms": ["../algorithms/dist/index.d.ts"]
11
+ }
12
+ },
13
+ "include": ["src"]
14
+ }