fragment-tools 0.2.10 → 0.2.11
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/package.json +2 -3
- package/src/cli/createConfig.js +37 -18
- package/src/cli/plugins/hot-shader-replacement.js +0 -5
- package/src/cli/run.js +27 -6
- package/src/client/app/state/rendering.svelte.js +1 -1
- package/src/index.js +12 -0
- package/src/types/config.d.ts +6 -0
- package/src/types/index.d.ts +1 -0
- package/src/types/props.d.ts +32 -5
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fragment-tools",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"description": "A web development environment for creative coding",
|
|
5
|
-
"main": "index.js",
|
|
5
|
+
"main": "./src/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"fragment": "bin/index.js"
|
|
8
8
|
},
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
"convert-length": "^1.0.1",
|
|
31
31
|
"get-port": "^7.1.0",
|
|
32
32
|
"gifenc": "^1.0.3",
|
|
33
|
-
"glslify": "^7.1.1",
|
|
34
33
|
"is-unicode-supported": "^2.0.0",
|
|
35
34
|
"kleur": "^4.1.4",
|
|
36
35
|
"mediabunny": "^1.13.3",
|
package/src/cli/createConfig.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
+
import url from 'node:url';
|
|
3
4
|
import { defineConfig, loadConfigFromFile, mergeConfig } from 'vite';
|
|
4
5
|
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
5
6
|
|
|
@@ -8,30 +9,47 @@ import { __dirname, file } from './utils.js';
|
|
|
8
9
|
import { log } from './log.js';
|
|
9
10
|
import sketches from './plugins/sketches.js';
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {{ cwd: string, filepath: string | undefined }} params
|
|
15
|
+
* @returns {Promise<import('../types/config.js').Config>}
|
|
16
|
+
*/
|
|
11
17
|
export async function loadConfig({ cwd, filepath }) {
|
|
12
18
|
try {
|
|
13
|
-
let filename = `fragment.config.js`;
|
|
14
|
-
let configFile = filepath ? filepath : filename;
|
|
15
19
|
let configRoot = cwd;
|
|
16
|
-
let
|
|
20
|
+
let filenames = [`fragment.config.js`, `fragment.config.ts`];
|
|
17
21
|
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
log.error(`Config file not found: ${resolvedPath}`);
|
|
21
|
-
}
|
|
22
|
-
return {};
|
|
22
|
+
if (filepath) {
|
|
23
|
+
filenames = [filepath, ...filenames];
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
let filepaths = filenames.map((filename) => {
|
|
27
|
+
return path.resolve(configRoot, filename);
|
|
28
|
+
});
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
command: 'build',
|
|
30
|
-
mode: 'dev',
|
|
31
|
-
},
|
|
32
|
-
configFile,
|
|
33
|
-
configRoot,
|
|
30
|
+
let resolvedIndex = filepaths.findIndex((filepath) =>
|
|
31
|
+
fs.existsSync(filepath),
|
|
34
32
|
);
|
|
33
|
+
/** @type {string|undefined} */
|
|
34
|
+
let resolvedPath = filepaths[resolvedIndex];
|
|
35
|
+
|
|
36
|
+
if (filepath && resolvedIndex !== 0) {
|
|
37
|
+
log.error(`Config file not found: ${filepath}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!resolvedPath) {
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let configFile = path.relative(cwd, resolvedPath);
|
|
45
|
+
|
|
46
|
+
log.info(`Extending configuration from ${configFile}`);
|
|
47
|
+
|
|
48
|
+
const config = (
|
|
49
|
+
await import(
|
|
50
|
+
`${url.pathToFileURL(configFile).href}?ts=${Date.now()}`
|
|
51
|
+
)
|
|
52
|
+
).default;
|
|
35
53
|
|
|
36
54
|
return config;
|
|
37
55
|
} catch (error) {
|
|
@@ -43,9 +61,10 @@ export async function loadConfig({ cwd, filepath }) {
|
|
|
43
61
|
/**
|
|
44
62
|
* Create Vite config from entries
|
|
45
63
|
* @param {string[]} entries
|
|
46
|
-
* @param {
|
|
64
|
+
* @param {object} [options]
|
|
47
65
|
* @param {boolean} [options.dev=false]
|
|
48
66
|
* @param {boolean} [options.build=false]
|
|
67
|
+
* @param {string} [configFilepath]
|
|
49
68
|
* @param {string} [cwd=process.cwd()]
|
|
50
69
|
* @returns {import('vite').UserConfig}
|
|
51
70
|
*/
|
|
@@ -63,8 +82,8 @@ export async function createConfig(
|
|
|
63
82
|
log.info(`Creating Vite configuration...`);
|
|
64
83
|
|
|
65
84
|
const config = await loadConfig({
|
|
66
|
-
filepath: configFilepath,
|
|
67
85
|
cwd,
|
|
86
|
+
filepath: configFilepath,
|
|
68
87
|
});
|
|
69
88
|
|
|
70
89
|
return mergeConfig(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import { readFile } from 'node:fs/promises';
|
|
4
|
-
import glslify from 'glslify';
|
|
5
4
|
import { log, dim, green, yellow } from '../log.js';
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -232,10 +231,6 @@ ${keyword}${shaderParts[1]}
|
|
|
232
231
|
shaderPath,
|
|
233
232
|
);
|
|
234
233
|
|
|
235
|
-
code = glslify(code, {
|
|
236
|
-
basedir: process.cwd(),
|
|
237
|
-
});
|
|
238
|
-
|
|
239
234
|
if (server) {
|
|
240
235
|
code = addShaderFilepath(code, shaderPath);
|
|
241
236
|
}
|
package/src/cli/run.js
CHANGED
|
@@ -26,17 +26,23 @@ import hotShaderReplacement from './plugins/hot-shader-replacement.js';
|
|
|
26
26
|
*/
|
|
27
27
|
export async function run(entry, options = {}) {
|
|
28
28
|
let fragmentServer;
|
|
29
|
+
/** @type {import('node:fs').FSWatcher} */
|
|
30
|
+
let watcher;
|
|
29
31
|
|
|
30
32
|
const cwd = process.cwd();
|
|
31
33
|
const command = `run`;
|
|
32
34
|
const prefix = log.prefix(command);
|
|
35
|
+
|
|
36
|
+
const stop = () => {
|
|
37
|
+
fragmentServer?.close();
|
|
38
|
+
watcher?.close();
|
|
39
|
+
};
|
|
40
|
+
|
|
33
41
|
const exit = () => {
|
|
34
42
|
process.off('SIGTERM', exit);
|
|
35
43
|
process.off('exit', exit);
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
fragmentServer.close();
|
|
39
|
-
}
|
|
45
|
+
stop();
|
|
40
46
|
|
|
41
47
|
console.log();
|
|
42
48
|
};
|
|
@@ -62,9 +68,10 @@ export async function run(entry, options = {}) {
|
|
|
62
68
|
);
|
|
63
69
|
}
|
|
64
70
|
|
|
71
|
+
const hasTSFiles = entries.some((entry) => entry.endsWith('ts'));
|
|
65
72
|
const tsConfigDirpath = path.join(cwd, FRAGMENT_DIRECTORY);
|
|
66
73
|
const tsConfigFilepath = path.join(tsConfigDirpath, 'tsconfig.json');
|
|
67
|
-
if (!fs.existsSync(tsConfigFilepath)) {
|
|
74
|
+
if (!fs.existsSync(tsConfigFilepath) && hasTSFiles) {
|
|
68
75
|
await createTsConfigFile(cwd);
|
|
69
76
|
}
|
|
70
77
|
|
|
@@ -106,6 +113,22 @@ export async function run(entry, options = {}) {
|
|
|
106
113
|
],
|
|
107
114
|
}),
|
|
108
115
|
);
|
|
116
|
+
|
|
117
|
+
watcher = fs.watch(cwd, (eventType, filename) => {
|
|
118
|
+
if (
|
|
119
|
+
['fragment.config.js', 'fragment.config.ts'].includes(
|
|
120
|
+
filename,
|
|
121
|
+
) ||
|
|
122
|
+
options.configFilepath?.includes(filename)
|
|
123
|
+
) {
|
|
124
|
+
log.warn(`${filename} has changed. Restarting...`);
|
|
125
|
+
console.log();
|
|
126
|
+
server.close();
|
|
127
|
+
stop();
|
|
128
|
+
run(entry, options);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
109
132
|
await server.listen();
|
|
110
133
|
|
|
111
134
|
// line break after logs
|
|
@@ -130,8 +153,6 @@ export async function run(entry, options = {}) {
|
|
|
130
153
|
|
|
131
154
|
// line break before fragment logs
|
|
132
155
|
log.message();
|
|
133
|
-
|
|
134
|
-
return server;
|
|
135
156
|
} catch (error) {
|
|
136
157
|
// line break before error
|
|
137
158
|
log.message();
|
package/src/index.js
ADDED
package/src/types/index.d.ts
CHANGED
package/src/types/props.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ type BaseProp<Value, Params, Type> = {
|
|
|
3
3
|
params?: Params;
|
|
4
4
|
type?: Type;
|
|
5
5
|
hidden?: boolean;
|
|
6
|
-
displayName?: string;
|
|
6
|
+
displayName?: string | null;
|
|
7
7
|
folder?: string;
|
|
8
8
|
group?: string;
|
|
9
9
|
onChange?: PropOnChange<Value, Params>;
|
|
@@ -25,11 +25,37 @@ type NumberProp = BaseProp<
|
|
|
25
25
|
{ disabled?: boolean; step?: number } | { min: number; max: number },
|
|
26
26
|
'number'
|
|
27
27
|
>;
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
type VecArray =
|
|
29
30
|
| [number, number]
|
|
30
31
|
| [number, number, number]
|
|
31
|
-
| [number, number, number, number]
|
|
32
|
-
|
|
32
|
+
| [number, number, number, number];
|
|
33
|
+
|
|
34
|
+
type VecObject = Record<string, number> & { [key: number]: never };
|
|
35
|
+
|
|
36
|
+
type VecValue = VecArray | VecObject;
|
|
37
|
+
|
|
38
|
+
type VecArrayParams<V extends VecArray> = {
|
|
39
|
+
min: { [K in keyof V]: number };
|
|
40
|
+
max: { [K in keyof V]: number };
|
|
41
|
+
step?: { [K in keyof V]: number };
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type VecObjectParams<V extends VecObject> = {
|
|
45
|
+
min: { [K in keyof V]: number };
|
|
46
|
+
max: { [K in keyof V]: number };
|
|
47
|
+
step?: { [K in keyof V]: number };
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type VecParams<V extends VecValue> = V extends readonly number[]
|
|
51
|
+
? VecArrayParams<V>
|
|
52
|
+
: V extends Record<string, number>
|
|
53
|
+
? VecObjectParams<V>
|
|
54
|
+
: never;
|
|
55
|
+
|
|
56
|
+
type VecProp<V extends VecValue = VecValue> = BaseProp<
|
|
57
|
+
V,
|
|
58
|
+
{ locked?: boolean } | VecParams<V>,
|
|
33
59
|
'vec'
|
|
34
60
|
>;
|
|
35
61
|
type CheckboxProp = BaseProp<boolean, never, 'checkbox'>;
|
|
@@ -50,7 +76,8 @@ type ImageProp = BaseProp<string, never, 'image'>;
|
|
|
50
76
|
type Prop =
|
|
51
77
|
| SelectProp
|
|
52
78
|
| NumberProp
|
|
53
|
-
| VecProp
|
|
79
|
+
| VecProp<VecObject>
|
|
80
|
+
| VecProp<VecArray>
|
|
54
81
|
| CheckboxProp
|
|
55
82
|
| TextProp
|
|
56
83
|
| ListProp
|