@stevejtrettel/shader-sandbox 0.1.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.
Files changed (106) hide show
  1. package/README.md +391 -0
  2. package/bin/cli.js +389 -0
  3. package/dist-lib/app/App.d.ts +134 -0
  4. package/dist-lib/app/App.d.ts.map +1 -0
  5. package/dist-lib/app/App.js +570 -0
  6. package/dist-lib/app/types.d.ts +32 -0
  7. package/dist-lib/app/types.d.ts.map +1 -0
  8. package/dist-lib/app/types.js +6 -0
  9. package/dist-lib/editor/EditorPanel.d.ts +39 -0
  10. package/dist-lib/editor/EditorPanel.d.ts.map +1 -0
  11. package/dist-lib/editor/EditorPanel.js +274 -0
  12. package/dist-lib/editor/prism-editor.css +99 -0
  13. package/dist-lib/editor/prism-editor.d.ts +19 -0
  14. package/dist-lib/editor/prism-editor.d.ts.map +1 -0
  15. package/dist-lib/editor/prism-editor.js +96 -0
  16. package/dist-lib/embed.d.ts +17 -0
  17. package/dist-lib/embed.d.ts.map +1 -0
  18. package/dist-lib/embed.js +35 -0
  19. package/dist-lib/engine/ShadertoyEngine.d.ts +160 -0
  20. package/dist-lib/engine/ShadertoyEngine.d.ts.map +1 -0
  21. package/dist-lib/engine/ShadertoyEngine.js +704 -0
  22. package/dist-lib/engine/glHelpers.d.ts +79 -0
  23. package/dist-lib/engine/glHelpers.d.ts.map +1 -0
  24. package/dist-lib/engine/glHelpers.js +298 -0
  25. package/dist-lib/engine/types.d.ts +77 -0
  26. package/dist-lib/engine/types.d.ts.map +1 -0
  27. package/dist-lib/engine/types.js +7 -0
  28. package/dist-lib/index.d.ts +12 -0
  29. package/dist-lib/index.d.ts.map +1 -0
  30. package/dist-lib/index.js +9 -0
  31. package/dist-lib/layouts/DefaultLayout.d.ts +17 -0
  32. package/dist-lib/layouts/DefaultLayout.d.ts.map +1 -0
  33. package/dist-lib/layouts/DefaultLayout.js +27 -0
  34. package/dist-lib/layouts/FullscreenLayout.d.ts +17 -0
  35. package/dist-lib/layouts/FullscreenLayout.d.ts.map +1 -0
  36. package/dist-lib/layouts/FullscreenLayout.js +27 -0
  37. package/dist-lib/layouts/SplitLayout.d.ts +26 -0
  38. package/dist-lib/layouts/SplitLayout.d.ts.map +1 -0
  39. package/dist-lib/layouts/SplitLayout.js +61 -0
  40. package/dist-lib/layouts/TabbedLayout.d.ts +38 -0
  41. package/dist-lib/layouts/TabbedLayout.d.ts.map +1 -0
  42. package/dist-lib/layouts/TabbedLayout.js +305 -0
  43. package/dist-lib/layouts/index.d.ts +24 -0
  44. package/dist-lib/layouts/index.d.ts.map +1 -0
  45. package/dist-lib/layouts/index.js +36 -0
  46. package/dist-lib/layouts/split.css +196 -0
  47. package/dist-lib/layouts/tabbed.css +345 -0
  48. package/dist-lib/layouts/types.d.ts +48 -0
  49. package/dist-lib/layouts/types.d.ts.map +1 -0
  50. package/dist-lib/layouts/types.js +4 -0
  51. package/dist-lib/main.d.ts +15 -0
  52. package/dist-lib/main.d.ts.map +1 -0
  53. package/dist-lib/main.js +102 -0
  54. package/dist-lib/project/generatedLoader.d.ts +3 -0
  55. package/dist-lib/project/generatedLoader.d.ts.map +1 -0
  56. package/dist-lib/project/generatedLoader.js +17 -0
  57. package/dist-lib/project/loadProject.d.ts +22 -0
  58. package/dist-lib/project/loadProject.d.ts.map +1 -0
  59. package/dist-lib/project/loadProject.js +350 -0
  60. package/dist-lib/project/loaderHelper.d.ts +7 -0
  61. package/dist-lib/project/loaderHelper.d.ts.map +1 -0
  62. package/dist-lib/project/loaderHelper.js +240 -0
  63. package/dist-lib/project/types.d.ts +192 -0
  64. package/dist-lib/project/types.d.ts.map +1 -0
  65. package/dist-lib/project/types.js +7 -0
  66. package/dist-lib/styles/base.css +29 -0
  67. package/package.json +48 -0
  68. package/src/app/App.ts +699 -0
  69. package/src/app/app.css +208 -0
  70. package/src/app/types.ts +36 -0
  71. package/src/editor/EditorPanel.ts +340 -0
  72. package/src/editor/editor-panel.css +175 -0
  73. package/src/editor/prism-editor.css +99 -0
  74. package/src/editor/prism-editor.ts +124 -0
  75. package/src/embed.ts +55 -0
  76. package/src/engine/ShadertoyEngine.ts +929 -0
  77. package/src/engine/glHelpers.ts +432 -0
  78. package/src/engine/types.ts +118 -0
  79. package/src/index.ts +13 -0
  80. package/src/layouts/DefaultLayout.ts +40 -0
  81. package/src/layouts/FullscreenLayout.ts +40 -0
  82. package/src/layouts/SplitLayout.ts +81 -0
  83. package/src/layouts/TabbedLayout.ts +371 -0
  84. package/src/layouts/default.css +22 -0
  85. package/src/layouts/fullscreen.css +15 -0
  86. package/src/layouts/index.ts +44 -0
  87. package/src/layouts/split.css +196 -0
  88. package/src/layouts/tabbed.css +345 -0
  89. package/src/layouts/types.ts +58 -0
  90. package/src/main.ts +114 -0
  91. package/src/project/generatedLoader.ts +23 -0
  92. package/src/project/loadProject.ts +421 -0
  93. package/src/project/loaderHelper.ts +300 -0
  94. package/src/project/types.ts +243 -0
  95. package/src/styles/base.css +29 -0
  96. package/src/styles/embed.css +14 -0
  97. package/src/vite-env.d.ts +1 -0
  98. package/templates/index.html +28 -0
  99. package/templates/main.ts +126 -0
  100. package/templates/package.json +12 -0
  101. package/templates/shaders/example-buffer/bufferA.glsl +14 -0
  102. package/templates/shaders/example-buffer/config.json +10 -0
  103. package/templates/shaders/example-buffer/image.glsl +5 -0
  104. package/templates/shaders/example-gradient/config.json +4 -0
  105. package/templates/shaders/example-gradient/image.glsl +7 -0
  106. package/templates/vite.config.js +35 -0
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Project Layer - Type Definitions for Shadertoy Projects
3
+ *
4
+ * Pure TypeScript interfaces matching Shadertoy's mental model.
5
+ * Based on docs/project-spec.md
6
+ */
7
+ export type PassName = 'Image' | 'BufferA' | 'BufferB' | 'BufferC' | 'BufferD';
8
+ /**
9
+ * Reference to another buffer pass.
10
+ * By default, reads the previous frame (safe for all cases).
11
+ * Use current: true to read from a buffer that has already run this frame.
12
+ */
13
+ export interface ChannelJSONBuffer {
14
+ buffer: PassName;
15
+ current?: boolean;
16
+ }
17
+ /**
18
+ * Reference to external texture (image file).
19
+ */
20
+ export interface ChannelJSONTexture {
21
+ texture: string;
22
+ filter?: 'nearest' | 'linear';
23
+ wrap?: 'clamp' | 'repeat';
24
+ type?: '2d' | 'cubemap';
25
+ }
26
+ /**
27
+ * Reference to keyboard texture (runtime-provided).
28
+ */
29
+ export interface ChannelJSONKeyboard {
30
+ keyboard: true;
31
+ }
32
+ /**
33
+ * Union type for channel sources in JSON config (object form).
34
+ */
35
+ export type ChannelJSONObject = ChannelJSONBuffer | ChannelJSONTexture | ChannelJSONKeyboard;
36
+ /**
37
+ * Channel value in simplified config format.
38
+ * Can be a string shorthand or full object:
39
+ * - "BufferA", "BufferB", etc. → buffer reference
40
+ * - "keyboard" → keyboard input
41
+ * - "photo.jpg" (with extension) → texture file
42
+ * - { buffer: "BufferA" } → explicit buffer with options
43
+ * - { texture: "photo.jpg", filter: "nearest" } → texture with options
44
+ */
45
+ export type ChannelValue = string | ChannelJSONObject;
46
+ /**
47
+ * Pass configuration in simplified format.
48
+ * Channel bindings are directly on the pass object.
49
+ *
50
+ * Example:
51
+ * {
52
+ * "iChannel0": "BufferA",
53
+ * "iChannel1": "photo.jpg",
54
+ * "source": "custom.glsl" // optional
55
+ * }
56
+ */
57
+ export interface PassConfigSimplified {
58
+ /** Optional custom source file path */
59
+ source?: string;
60
+ /** Channel bindings - string shorthand or full object */
61
+ iChannel0?: ChannelValue;
62
+ iChannel1?: ChannelValue;
63
+ iChannel2?: ChannelValue;
64
+ iChannel3?: ChannelValue;
65
+ }
66
+ /**
67
+ * Top-level config.json structure (simplified flat format).
68
+ *
69
+ * Example:
70
+ * {
71
+ * "title": "My Shader",
72
+ * "layout": "split",
73
+ * "controls": true,
74
+ *
75
+ * "BufferA": {
76
+ * "iChannel0": "BufferA"
77
+ * },
78
+ * "Image": {
79
+ * "iChannel0": "BufferA"
80
+ * }
81
+ * }
82
+ */
83
+ export interface ShadertoyConfig {
84
+ title?: string;
85
+ author?: string;
86
+ description?: string;
87
+ layout?: 'fullscreen' | 'default' | 'split' | 'tabbed';
88
+ controls?: boolean;
89
+ common?: string;
90
+ Image?: PassConfigSimplified;
91
+ BufferA?: PassConfigSimplified;
92
+ BufferB?: PassConfigSimplified;
93
+ BufferC?: PassConfigSimplified;
94
+ BufferD?: PassConfigSimplified;
95
+ }
96
+ /**
97
+ * Normalized channel source for engine consumption.
98
+ * All channels are represented as one of these discriminated union variants.
99
+ */
100
+ export type ChannelSource = {
101
+ kind: 'none';
102
+ } | {
103
+ kind: 'buffer';
104
+ buffer: PassName;
105
+ current: boolean;
106
+ } | {
107
+ kind: 'texture';
108
+ name: string;
109
+ cubemap: boolean;
110
+ } | {
111
+ kind: 'keyboard';
112
+ };
113
+ /**
114
+ * Exactly 4 channels (iChannel0-3), matching Shadertoy's fixed channel count.
115
+ */
116
+ export type Channels = [ChannelSource, ChannelSource, ChannelSource, ChannelSource];
117
+ /**
118
+ * External 2D texture loaded from image file.
119
+ * Textures are deduplicated by (source, filter, wrap) tuple.
120
+ */
121
+ export interface ShadertoyTexture2D {
122
+ name: string;
123
+ filename?: string;
124
+ source: string;
125
+ filter: 'nearest' | 'linear';
126
+ wrap: 'clamp' | 'repeat';
127
+ }
128
+ /**
129
+ * A single shader pass in the rendering pipeline.
130
+ */
131
+ export interface ShadertoyPass {
132
+ name: PassName;
133
+ glslSource: string;
134
+ channels: Channels;
135
+ }
136
+ /**
137
+ * Project metadata (title, author, description).
138
+ */
139
+ export interface ShadertoyMeta {
140
+ title: string;
141
+ author: string | null;
142
+ description: string | null;
143
+ }
144
+ /**
145
+ * Complete in-memory representation of a Shadertoy project.
146
+ * Produced by loadProject() and consumed by ShadertoyEngine.
147
+ *
148
+ * Guarantees:
149
+ * - passes.Image always exists
150
+ * - All passes have exactly 4 channels (missing → kind: 'none')
151
+ * - Textures are deduplicated
152
+ * - All paths resolved and GLSL loaded
153
+ */
154
+ export interface ShadertoyProject {
155
+ /**
156
+ * Project root directory path.
157
+ */
158
+ root: string;
159
+ /**
160
+ * Project metadata.
161
+ */
162
+ meta: ShadertoyMeta;
163
+ /**
164
+ * Layout mode for the shader viewer.
165
+ */
166
+ layout: 'fullscreen' | 'default' | 'split' | 'tabbed';
167
+ /**
168
+ * Whether to show playback controls (play/pause, reset).
169
+ */
170
+ controls: boolean;
171
+ /**
172
+ * Common GLSL code (prepended to all shaders), or null if none.
173
+ */
174
+ commonSource: string | null;
175
+ /**
176
+ * Pass definitions.
177
+ * Image is always present, BufferA-D are optional.
178
+ */
179
+ passes: {
180
+ Image: ShadertoyPass;
181
+ BufferA?: ShadertoyPass;
182
+ BufferB?: ShadertoyPass;
183
+ BufferC?: ShadertoyPass;
184
+ BufferD?: ShadertoyPass;
185
+ };
186
+ /**
187
+ * Deduplicated list of external textures.
188
+ * All ChannelSource with kind: 'texture2D' refer to names in this list.
189
+ */
190
+ textures: ShadertoyTexture2D[];
191
+ }
192
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/project/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Project Layer - Type Definitions for Shadertoy Projects
3
+ *
4
+ * Pure TypeScript interfaces matching Shadertoy's mental model.
5
+ * Based on docs/project-spec.md
6
+ */
7
+ export {};
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Base Styles - Global resets and root element styling
3
+ */
4
+
5
+ * {
6
+ margin: 0;
7
+ padding: 0;
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ html, body {
12
+ width: 100%;
13
+ height: 100%;
14
+ overflow: hidden;
15
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
16
+ }
17
+
18
+ body {
19
+ background: #f5f5f5;
20
+ }
21
+
22
+ #app {
23
+ width: 100%;
24
+ height: 100%;
25
+ }
26
+
27
+ canvas {
28
+ display: block;
29
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@stevejtrettel/shader-sandbox",
3
+ "version": "0.1.0",
4
+ "description": "Local Shadertoy-compatible GLSL shader development environment with live editing",
5
+ "type": "module",
6
+ "main": "./dist-lib/index.js",
7
+ "types": "./dist-lib/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist-lib/index.js",
11
+ "types": "./dist-lib/index.d.ts"
12
+ }
13
+ },
14
+ "bin": {
15
+ "shader": "./bin/cli.js"
16
+ },
17
+ "files": [
18
+ "bin",
19
+ "dist-lib",
20
+ "templates",
21
+ "src"
22
+ ],
23
+ "scripts": {
24
+ "new": "node scripts/new-demo.cjs",
25
+ "dev": "vite",
26
+ "dev:demo": "node scripts/dev-demo.cjs",
27
+ "build": "tsc && vite build",
28
+ "build:demo": "node scripts/build-demo.cjs",
29
+ "build:embed": "node scripts/build-embed.cjs",
30
+ "build:embed:folder": "node scripts/build-embed-folder.cjs",
31
+ "build:embed:screenshots": "node scripts/build-folder-screenshots.cjs",
32
+ "build:lib": "node scripts/build-lib.cjs",
33
+ "prepublishOnly": "npm run build:lib",
34
+ "preview": "vite preview"
35
+ },
36
+ "dependencies": {
37
+ "prismjs": "^1.30.0",
38
+ "vite": "^5.0.0",
39
+ "vite-plugin-css-injected-by-js": "^3.5.2"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "^20.10.0",
43
+ "@types/prismjs": "^1.26.5",
44
+ "puppeteer-core": "^24.34.0",
45
+ "typescript": "^5.3.3",
46
+ "vite": "^5.0.8"
47
+ }
48
+ }