dazscript-framework 0.1.14 → 0.1.16

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 (82) hide show
  1. package/README.md +365 -93
  2. package/babel.config.js +33 -33
  3. package/dist/babel/trace-babel-plugin.js +243 -243
  4. package/dist/babel/trace-log-babel-plugin.js +164 -164
  5. package/dist/scripts/install-generator.js +185 -185
  6. package/package.json +72 -70
  7. package/src/common/dz-dump.ts +120 -120
  8. package/src/common/log.ts +56 -57
  9. package/src/common/trace.ts +26 -26
  10. package/src/core/action-decorator.ts +15 -15
  11. package/src/core/base-script.ts +30 -30
  12. package/src/core/custom-action.ts +11 -11
  13. package/src/core/global.ts +4 -4
  14. package/src/dialog/basic-dialog.ts +40 -32
  15. package/src/dialog/builders/button-builder.ts +52 -52
  16. package/src/dialog/builders/checkbox-builder.ts +29 -29
  17. package/src/dialog/builders/color-picker-builder.ts +36 -0
  18. package/src/dialog/builders/combo-box-builder.ts +38 -35
  19. package/src/dialog/builders/combo-edit-builder.ts +35 -35
  20. package/src/dialog/builders/dialog-builder.ts +49 -49
  21. package/src/dialog/builders/groupbox-builder.ts +121 -73
  22. package/src/dialog/builders/label-builder.ts +33 -29
  23. package/src/dialog/builders/layout-builder.ts +59 -59
  24. package/src/dialog/builders/line-edit-builder.ts +124 -119
  25. package/src/dialog/builders/list-box-builder.ts +103 -0
  26. package/src/dialog/builders/list-view-builder.ts +396 -328
  27. package/src/dialog/builders/node-selection-builder.ts +55 -55
  28. package/src/dialog/builders/path-combo-box-builder.ts +24 -24
  29. package/src/dialog/builders/popup-menu-builder.ts +46 -46
  30. package/src/dialog/builders/radio-builder.ts +42 -42
  31. package/src/dialog/builders/slider-builder.ts +40 -0
  32. package/src/dialog/builders/splitter-builder.ts +88 -88
  33. package/src/dialog/builders/tab-builder.ts +120 -106
  34. package/src/dialog/builders/widget-builder.ts +136 -124
  35. package/src/dialog/builders/widgets-builder.ts +140 -125
  36. package/src/dialog/input-dialog.ts +30 -27
  37. package/src/dialog/input-validator.ts +8 -8
  38. package/src/dialog/selection-dialog.ts +47 -0
  39. package/src/dialog/shared.ts +8 -8
  40. package/src/helpers/action-helper.ts +214 -81
  41. package/src/helpers/array-helper.ts +170 -145
  42. package/src/helpers/camera-helper.ts +12 -12
  43. package/src/helpers/custom-action-helper.ts +176 -176
  44. package/src/helpers/directory-helper.ts +14 -0
  45. package/src/helpers/file-helper.ts +90 -90
  46. package/src/helpers/http-helper.ts +186 -0
  47. package/src/helpers/input-helper.ts +18 -18
  48. package/src/helpers/list-view-helper.ts +105 -89
  49. package/src/helpers/menu-helper.ts +28 -28
  50. package/src/helpers/message-box-helper.ts +25 -15
  51. package/src/helpers/node-helper.ts +461 -236
  52. package/src/helpers/number-helper.ts +10 -10
  53. package/src/helpers/numeric-property-helper.ts +91 -91
  54. package/src/helpers/object-helper.ts +2 -2
  55. package/src/helpers/pane-helper.ts +28 -20
  56. package/src/helpers/progress-helper.ts +51 -33
  57. package/src/helpers/property-helper.ts +61 -52
  58. package/src/helpers/record-helper.ts +16 -16
  59. package/src/helpers/scene-helper.ts +144 -95
  60. package/src/helpers/script-helper.ts +15 -15
  61. package/src/helpers/skeleton-helper.ts +26 -26
  62. package/src/helpers/splitter-helper.ts +8 -8
  63. package/src/helpers/string-helper.ts +39 -31
  64. package/src/helpers/surface-helper.ts +5 -5
  65. package/src/helpers/undo-helper.ts +8 -7
  66. package/src/helpers/viewport-helper.ts +21 -8
  67. package/src/lib/delayed.ts +38 -38
  68. package/src/lib/dictionary.ts +3 -0
  69. package/src/lib/frame-keys.ts +67 -67
  70. package/src/lib/guid.ts +2 -2
  71. package/src/lib/menu-item.ts +10 -9
  72. package/src/lib/observable.ts +147 -94
  73. package/src/lib/set.ts +50 -25
  74. package/src/lib/settings.ts +112 -104
  75. package/src/lib/tree-node.ts +149 -145
  76. package/src/samples/config.ts +2 -2
  77. package/src/samples/hello-world.dsa.ts +12 -12
  78. package/src/samples/sample-dialog.dsa.ts +51 -51
  79. package/src/samples/sample-dialog.ts +48 -48
  80. package/src/shared/set-keyboard-shortcut.ts +146 -102
  81. package/tsconfig.json +116 -116
  82. package/webpack.config.js +70 -70
package/README.md CHANGED
@@ -1,93 +1,365 @@
1
- # DazScript Framework
2
-
3
- The **DazScript Framework** is a TypeScript-based framework for writing Daz Studio scripts. It provides all the advantages of a typed language such as autocompletion, error checking, and method parameter documentation and hinting. The framework also includes a set of dialog helpers for rapid UI development.
4
-
5
- ## Benefits
6
-
7
- - **Autocompletion:** Take advantage of IDE autocompletion for faster and more efficient script development.
8
- - **Error Checking:** Catch potential errors early in the development process with TypeScript's static analysis.
9
- - **Method Documentation & Hinting:** Get contextual documentation and hints for methods, classes, and parameters.
10
-
11
- ## Features
12
-
13
- - TypeScript support with full IntelliSense.
14
- - A powerful set of decorators and helper methods for building interactive scripts.
15
- - Easy integration with Daz Studio for quick script deployment.
16
-
17
- ## Installation
18
-
19
- To install the **DazScript Framework**, run the following command:
20
-
21
- ```bash
22
- npm install dazscript-framework
23
- ```
24
-
25
- ## Setup
26
-
27
- After installing the package, you will need to configure a few files for your project.
28
-
29
- 1. **babel.config.js**
30
-
31
- Create the file and add the following content:
32
-
33
- ```javascript
34
- const sharedBabelConfig = require('dazscript-framework/babel');
35
-
36
- module.exports = {
37
- ...sharedBabelConfig,
38
- presets: [...sharedBabelConfig.presets],
39
- plugins: [...sharedBabelConfig.plugins],
40
- };
41
- ```
42
-
43
- 2. **package.json**
44
-
45
- Add the following scripts to your package.json:
46
-
47
- ```json
48
- "scripts": {
49
- "prebuild": "npm run installer",
50
- "build": "webpack --env outputPath=./out",
51
- "postbuild": "npm run icons",
52
- "watch": "webpack --env outputPath=./out --watch",
53
- "icons": "copyfiles -u 1 src/**/*.png out/",
54
- "installer": "node ./node_modules/dazscript-framework/dist/scripts/install-generator.js -p ./src/scripts -m /My Scripts"
55
- }
56
- ```
57
-
58
- 3. **tsconfig.json**
59
-
60
- Create the file and add the following content:
61
-
62
- ```json
63
- {
64
- "extends": "./node_modules/dazscript-framework/tsconfig.json",
65
- "compilerOptions": {
66
- "baseUrl": "./",
67
- "paths": {
68
- "shared/*": ["src/shared/*"],
69
- "@dst/*": ["node_modules/dazscript-types/*"],
70
- "@dsf/*": ["node_modules/dazscript-framework/src/*"]
71
- }
72
- },
73
- "include": ["node_modules/dazscript-types/**/*", "src/**/*"]
74
- }
75
- ```
76
-
77
- 4. **webpack.config.js**
78
- Create the file and add the following content:
79
-
80
- ```javascript
81
- const sharedWebpackConfig = require('dazscript-framework/webpack');
82
-
83
- module.exports = (env, argv) => {
84
- const sharedConfig = sharedWebpackConfig(env, argv);
85
-
86
- return {
87
- ...sharedConfig,
88
- // You can override or add more customizations here if needed
89
- };
90
- };
91
- ```
92
-
93
- ## Usage
1
+ # DazScript Framework
2
+
3
+ > ⚠️ **EARLY VERSION** This framework is in active development (v0.1.15). The API is not yet stable and may change between releases. Not recommended for production use until v1.0 is released.
4
+
5
+ The **DazScript Framework** is a TypeScript-based framework for writing Daz Studio scripts. It provides all the advantages of a typed language such as autocompletion, error checking, and method parameter documentation and hinting. The framework also includes a set of dialog helpers for rapid UI development.
6
+
7
+ ## Benefits
8
+
9
+ - **Autocompletion:** Take advantage of IDE autocompletion for faster and more efficient script development.
10
+ - **Error Checking:** Catch potential errors early in the development process with TypeScript's static analysis.
11
+ - **Method Documentation & Hinting:** Get contextual documentation and hints for methods, classes, and parameters.
12
+
13
+ ## Features
14
+
15
+ - TypeScript support with full IntelliSense.
16
+ - A powerful set of decorators and helper methods for building interactive scripts.
17
+ - Easy integration with Daz Studio for quick script deployment.
18
+
19
+ ## Installation
20
+
21
+ To install the **DazScript Framework**, run the following command:
22
+
23
+ ```bash
24
+ npm install dazscript-framework
25
+ ```
26
+
27
+ ## Setup
28
+
29
+ After installing the package, you will need to configure a few files for your project.
30
+
31
+ 1. **babel.config.js**
32
+
33
+ Create the file and add the following content:
34
+
35
+ ```javascript
36
+ const sharedBabelConfig = require('dazscript-framework/babel');
37
+
38
+ module.exports = {
39
+ ...sharedBabelConfig,
40
+ presets: [...sharedBabelConfig.presets],
41
+ plugins: [...sharedBabelConfig.plugins],
42
+ };
43
+ ```
44
+
45
+ 2. **package.json**
46
+
47
+ Add the following scripts to your package.json:
48
+
49
+ ```json
50
+ "scripts": {
51
+ "prebuild": "npm run installer",
52
+ "build": "webpack --env outputPath=./out",
53
+ "postbuild": "npm run icons",
54
+ "watch": "webpack --env outputPath=./out --watch",
55
+ "icons": "copyfiles -u 1 src/**/*.png out/",
56
+ "installer": "node ./node_modules/dazscript-framework/dist/scripts/install-generator.js -p ./src/scripts -m /MyScripts"
57
+ }
58
+ ```
59
+
60
+ 3. **tsconfig.json**
61
+
62
+ Create the file and add the following content:
63
+
64
+ ```json
65
+ {
66
+ "extends": "./node_modules/dazscript-framework/tsconfig.json",
67
+ "compilerOptions": {
68
+ "baseUrl": "./",
69
+ "paths": {
70
+ "shared/*": ["src/shared/*"],
71
+ "@dst/*": ["node_modules/dazscript-types/*"],
72
+ "@dsf/*": ["node_modules/dazscript-framework/src/*"]
73
+ }
74
+ },
75
+ "include": ["node_modules/dazscript-types/**/*", "src/**/*"]
76
+ }
77
+ ```
78
+
79
+ 4. **webpack.config.js**
80
+ Create the file and add the following content:
81
+
82
+ ```javascript
83
+ const sharedWebpackConfig = require('dazscript-framework/webpack');
84
+
85
+ module.exports = (env, argv) => {
86
+ const sharedConfig = sharedWebpackConfig(env, argv);
87
+
88
+ return {
89
+ ...sharedConfig,
90
+ // You can override or add more customizations here if needed
91
+ };
92
+ };
93
+ ```
94
+
95
+ ## Usage
96
+
97
+ ### Quick Start: Hello World
98
+
99
+ Create a simple script that logs to the console:
100
+
101
+ ```typescript
102
+ import { debug } from '@dsf/common/log';
103
+ import { action } from '@dsf/core/action-decorator';
104
+ import { BaseScript } from '@dsf/core/base-script';
105
+ import { info } from '@dsf/helpers/message-box-helper';
106
+
107
+ @action({ text: 'Hello World' })
108
+ class HelloWorldScript extends BaseScript {
109
+ protected run(): void {
110
+ debug('Hello World!');
111
+ info('Hello World!');
112
+ }
113
+ }
114
+
115
+ new HelloWorldScript().exec();
116
+ ```
117
+
118
+ ### Building UIs with Observables & Dialogs
119
+
120
+ The framework uses a **Model-View pattern** with reactive data bindings:
121
+
122
+ #### 1. Define Your Model
123
+
124
+ ```typescript
125
+ import { BasicDialog } from '@dsf/dialog/basic-dialog';
126
+ import { Observable } from '@dsf/lib/observable';
127
+ import { AppSettings } from '@dsf/lib/settings';
128
+
129
+ // Model extends AppSettings for automatic persistence
130
+ export class MyDialogModel extends AppSettings {
131
+ constructor() {
132
+ super('MyAuthor/MyDialog'); // Namespace for saved settings
133
+ }
134
+
135
+ selectedNode$ = new Observable<DzNode>();
136
+ nodeLabel$ = new Observable<string>();
137
+ }
138
+ ```
139
+
140
+ #### 2. Build Your Dialog
141
+
142
+ ```typescript
143
+ import { BasicDialog } from '@dsf/dialog/basic-dialog';
144
+ import { MyDialogModel } from './my-dialog-model';
145
+
146
+ export class MyDialog extends BasicDialog {
147
+ constructor(private readonly model: MyDialogModel) {
148
+ super('My Dialog');
149
+ }
150
+
151
+ protected build(): void {
152
+ const add = this.add; // Fluent builder API
153
+ const model = this.model;
154
+
155
+ add.group('Node Properties').build(() => {
156
+ add.label('Label:');
157
+ add.edit().value(model.nodeLabel$); // Two-way binding
158
+ });
159
+ }
160
+ }
161
+ ```
162
+
163
+ #### 3. Connect & Use in Your Script
164
+
165
+ ```typescript
166
+ import { action } from '@dsf/core/action-decorator';
167
+ import { BaseScript } from '@dsf/core/base-script';
168
+ import { getSelectedNode } from '@dsf/helpers/scene-helper';
169
+ import { MyDialog, MyDialogModel } from './my-dialog';
170
+
171
+ @action({ text: 'My Dialog Script' })
172
+ class MyDialogScript extends BaseScript {
173
+ protected run(): void {
174
+ const model = new MyDialogModel();
175
+ const selectedNode = getSelectedNode();
176
+
177
+ if (!selectedNode) {
178
+ console.error('Please select a node');
179
+ return;
180
+ }
181
+
182
+ // Set initial model values
183
+ model.selectedNode$.value = selectedNode;
184
+ model.nodeLabel$.value = selectedNode.getLabel();
185
+
186
+ // React to model changes (two-way binding)
187
+ model.nodeLabel$.connect((label) => {
188
+ selectedNode.setLabel(label);
189
+ });
190
+
191
+ // Build and show dialog
192
+ const dialog = new MyDialog(model);
193
+ if (dialog.run()) {
194
+ console.log('Dialog accepted');
195
+ } else {
196
+ console.log('Dialog cancelled');
197
+ }
198
+ }
199
+ }
200
+
201
+ new MyDialogScript().exec();
202
+ ```
203
+
204
+ ### Core Concepts
205
+
206
+ #### Observables (`Observable<T>`)
207
+
208
+ Reactive state management with change notifications:
209
+
210
+ ```typescript
211
+ const name = new Observable<string>('John');
212
+
213
+ // Subscribe to changes
214
+ name.connect((value) => console.log(`Name: ${value}`));
215
+
216
+ // Set value (triggers callbacks)
217
+ name.value = 'Jane'; // Logs: "Name: Jane"
218
+
219
+ // Intercept/validate before change
220
+ name.intercept(
221
+ (prev, current) => current.toUpperCase() // Transform
222
+ );
223
+
224
+ // Pause/resume notifications
225
+ name.pause(() => {
226
+ name.value = 'A';
227
+ name.value = 'B'; // Won't trigger callbacks
228
+ });
229
+ ```
230
+
231
+ #### Available Helpers
232
+
233
+ The framework includes 29 helper modules for common Daz Studio tasks:
234
+
235
+ - **Scene**: `getRoot()`, `getSelectedNode()`, `getNodes()`, scene modification
236
+ - **Nodes**: Type checking (figure, bone, etc.), transforms, visibility, selection
237
+ - **Properties**: Finding, adjusting, interpolating property values
238
+ - **Dialogs**: `BasicDialog`, `InputDialog`, `SelectionDialog`
239
+ - **Arrays**: `distinct()`, `flatten()`, `groupBy()`, unique operations
240
+ - **Strings**: Upper/lowercase, trimming, splitting
241
+ - **Files & Paths**: Reading, writing, directory operations
242
+ - **UI Helpers**: Message boxes, progress dialogs, menus, keyboard shortcuts
243
+
244
+ Example:
245
+
246
+ ```typescript
247
+ import * as SceneHelper from '@dsf/helpers/scene-helper';
248
+ import * as NodeHelper from '@dsf/helpers/node-helper';
249
+ import * as ArrayHelper from '@dsf/helpers/array-helper';
250
+
251
+ const allNodes = SceneHelper.getNodes();
252
+ const figures = allNodes.filter(n => NodeHelper.isFigure(n));
253
+ const unique = ArrayHelper.distinct(figures);
254
+ ```
255
+
256
+ #### Builder Pattern for UIs
257
+
258
+ Fluent, chainable API for rapid dialog construction:
259
+
260
+ ```typescript
261
+ add.tab('Settings').build(() => {
262
+ add.group('Colors').build(() => {
263
+ add.colorPicker().value(colorObservable);
264
+ add.label('Opacity:');
265
+ add.slider(0, 100).value(opacityObservable);
266
+ });
267
+
268
+ add.horizontal((layout) => {
269
+ add.label('Name:');
270
+ add.edit().value(nameObservable);
271
+ });
272
+
273
+ add.listView()
274
+ .items(itemsObservable)
275
+ .value(selectedItemObservable)
276
+ .changed((item) => console.log(`Selected: ${item}`));
277
+ });
278
+ ```
279
+
280
+ Supported widgets:
281
+ - Basic: Label, Edit (text input), Button, Checkbox, Radio
282
+ - Selection: ComboBox, ListBox, Slider, ColorPicker
283
+ - Layout: Tab, Group, Horizontal, Vertical, Splitter
284
+ - Advanced: ListView, TreeView, Popup Menu
285
+
286
+ ### Two-Way Data Binding
287
+
288
+ The power of this framework is reactive data binding between models and UI:
289
+
290
+ ```typescript
291
+ // User types in UI → updates model → triggers logic
292
+ model.nodeLabel$ = new Observable<string>();
293
+
294
+ model.nodeLabel$.connect((newLabel) => {
295
+ // React to UI changes
296
+ selectedNode.setLabel(newLabel);
297
+ });
298
+
299
+ // Code updates model → UI automatically reflects
300
+ model.nodeLabel$.value = 'New Label'; // UI edit box updates
301
+ ```
302
+
303
+ This eliminates the need for manual synchronization between UI and data.
304
+
305
+ ### Directory Structure
306
+
307
+ For a typical project using this framework:
308
+
309
+ ```
310
+ my-daz-scripts/
311
+ ├── src/
312
+ │ ├── scripts/
313
+ │ │ ├── my-first-script.dsa.ts
314
+ │ │ ├── my-dialog-model.ts
315
+ │ │ ├── my-dialog.ts
316
+ │ │ └── my-dialog-script.dsa.ts
317
+ │ └── config.ts
318
+ ├── out/ # Generated .dsa files (build output)
319
+ ├── package.json
320
+ ├── tsconfig.json
321
+ ├── webpack.config.js
322
+ └── babel.config.js
323
+ ```
324
+
325
+ **Key points:**
326
+ - Scripts ending in `.dsa.ts` compile to `.dsa` files for Daz Studio
327
+ - Regular `.ts` files are utility, model, or helper classes
328
+ - Run `npm run build` to compile TypeScript → Daz Scripts
329
+ - Run `npm run watch` during development for live rebuild
330
+
331
+ ## Development & Publishing
332
+
333
+ This project uses **semantic-release** for automatic versioning and npm publishing.
334
+
335
+ ### Commit Message Conventions
336
+
337
+ Use conventional commit messages to control version bumping:
338
+
339
+ - **`fix: description`** → Patch version bump (0.1.15 → 0.1.16)
340
+ - Bug fixes, patches, or minor improvements
341
+ - Example: `fix: resolve dialog builder layout issue`
342
+
343
+ - **`feat: description`** → Minor version bump (0.1.15 → 0.2.0)
344
+ - New features or significant enhancements
345
+ - Example: `feat: add tree view builder component`
346
+
347
+ - **`BREAKING CHANGE: description`** → Major version bump (0.1.15 → 1.0.0)
348
+ - Add to commit body for breaking changes
349
+ - Example: `feat: refactor action decorator API\n\nBREAKING CHANGE: action() now requires explicit menu path`
350
+
351
+ - **No prefix** → No version bump
352
+ - Documentation, style, or non-publishing changes
353
+ - Example: `update README examples`
354
+
355
+ ### Publishing
356
+
357
+ Every push to the `master` branch automatically triggers:
358
+
359
+ 1. **Analyze** commit messages since last release
360
+ 2. **Update** version in `package.json`
361
+ 3. **Build** the project (`npm run build`)
362
+ 4. **Create** a GitHub release with changelog
363
+ 5. **Publish** to npm
364
+
365
+ No manual steps required—just commit with proper conventions and push!
package/babel.config.js CHANGED
@@ -1,33 +1,33 @@
1
- module.exports = {
2
- presets: [
3
- [
4
- '@babel/preset-env',
5
- {
6
- targets: {
7
- esmodules: true,
8
- ie: '11',
9
- },
10
- include: ['@babel/plugin-transform-class-properties'],
11
- },
12
- ],
13
- '@babel/preset-typescript',
14
- ],
15
- plugins: [
16
- '@babel/plugin-transform-class-properties',
17
- 'babel-plugin-transform-typescript-metadata',
18
- ['@babel/plugin-proposal-decorators', { version: 'legacy' }],
19
- ['@babel/plugin-transform-arrow-functions'],
20
- '@babel/plugin-transform-block-scoping',
21
- '@babel/plugin-proposal-class-properties',
22
- '@babel/plugin-transform-private-property-in-object',
23
- '@babel/plugin-transform-private-methods',
24
- [
25
- 'dazscript-framework/babel/trace-babel-plugin', // Ensure this path is correct
26
- { default: false, retainLines: false },
27
- ],
28
- [
29
- 'dazscript-framework/babel/trace-log-babel-plugin', // Ensure this path is correct
30
- { default: false, retainLines: false },
31
- ],
32
- ],
33
- };
1
+ module.exports = {
2
+ presets: [
3
+ [
4
+ '@babel/preset-env',
5
+ {
6
+ targets: {
7
+ esmodules: true,
8
+ ie: '11',
9
+ },
10
+ include: ['@babel/plugin-transform-class-properties'],
11
+ },
12
+ ],
13
+ '@babel/preset-typescript',
14
+ ],
15
+ plugins: [
16
+ '@babel/plugin-transform-class-properties',
17
+ 'babel-plugin-transform-typescript-metadata',
18
+ ['@babel/plugin-proposal-decorators', { version: 'legacy' }],
19
+ ['@babel/plugin-transform-arrow-functions'],
20
+ '@babel/plugin-transform-block-scoping',
21
+ '@babel/plugin-proposal-class-properties',
22
+ '@babel/plugin-transform-private-property-in-object',
23
+ '@babel/plugin-transform-private-methods',
24
+ [
25
+ 'dazscript-framework/babel/trace-babel-plugin', // Ensure this path is correct
26
+ { default: false, retainLines: false },
27
+ ],
28
+ [
29
+ 'dazscript-framework/babel/trace-log-babel-plugin', // Ensure this path is correct
30
+ { default: false, retainLines: false },
31
+ ],
32
+ ],
33
+ };