pixifact 0.1.3 → 0.1.4

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 (185) hide show
  1. package/README.md +3 -3
  2. package/dist/builtin-scenes/CenterContainer.d.ts +13 -0
  3. package/dist/builtin-scenes/CenterContainer.js +71 -0
  4. package/dist/builtin-scenes/CenterContainer.scene +3 -0
  5. package/dist/builtin-scenes/CenterContainer.ts +77 -0
  6. package/dist/builtin-scenes/Control.d.ts +44 -0
  7. package/dist/builtin-scenes/Control.js +206 -0
  8. package/dist/builtin-scenes/Control.scene +3 -0
  9. package/dist/builtin-scenes/Control.ts +233 -0
  10. package/dist/builtin-scenes/FlexItem.d.ts +45 -0
  11. package/dist/builtin-scenes/FlexItem.js +164 -0
  12. package/dist/builtin-scenes/FlexItem.scene +3 -0
  13. package/dist/builtin-scenes/FlexItem.ts +180 -0
  14. package/dist/builtin-scenes/FlexLayout.d.ts +29 -0
  15. package/dist/builtin-scenes/FlexLayout.js +358 -0
  16. package/dist/builtin-scenes/FlexLayout.scene +3 -0
  17. package/dist/builtin-scenes/FlexLayout.ts +409 -0
  18. package/dist/builtin-scenes/HBoxContainer.d.ts +15 -0
  19. package/dist/builtin-scenes/HBoxContainer.js +70 -0
  20. package/dist/builtin-scenes/HBoxContainer.scene +3 -0
  21. package/dist/builtin-scenes/HBoxContainer.ts +75 -0
  22. package/dist/builtin-scenes/MarginContainer.d.ts +23 -0
  23. package/dist/builtin-scenes/MarginContainer.js +131 -0
  24. package/dist/builtin-scenes/MarginContainer.scene +3 -0
  25. package/dist/builtin-scenes/MarginContainer.ts +139 -0
  26. package/dist/builtin-scenes/VBoxContainer.d.ts +15 -0
  27. package/dist/builtin-scenes/VBoxContainer.js +70 -0
  28. package/dist/builtin-scenes/VBoxContainer.scene +3 -0
  29. package/dist/builtin-scenes/VBoxContainer.ts +75 -0
  30. package/dist/builtin-scenes/controlLayout.d.ts +57 -0
  31. package/dist/builtin-scenes/controlLayout.js +202 -0
  32. package/dist/builtin-scenes/controlLayout.ts +270 -0
  33. package/dist/compiler/builtinScenes.d.ts +14 -0
  34. package/dist/compiler/builtinScenes.js +62 -0
  35. package/dist/compiler/compileScenes.js +126 -19
  36. package/dist/compiler/decorators.js +3 -0
  37. package/dist/compiler/index.d.ts +1 -0
  38. package/dist/compiler/index.js +1 -0
  39. package/dist/compiler/sceneAssetPair.js +19 -0
  40. package/dist/compiler/sceneRuntime.d.ts +5 -4
  41. package/dist/compiler/scriptInterfaceExtractor.d.ts +5 -0
  42. package/dist/compiler/scriptInterfaceExtractor.js +214 -8
  43. package/dist/compiler/spec.d.ts +2 -0
  44. package/dist/compiler/templateParser.js +4 -3
  45. package/dist/compiler/templateSerializer.js +2 -1
  46. package/dist/compiler/typescriptCompiler.js +87 -13
  47. package/dist/compiler-node/builtinSceneAssets.d.ts +8 -0
  48. package/dist/compiler-node/builtinSceneAssets.js +57 -0
  49. package/dist/compiler-node/index.d.ts +1 -0
  50. package/dist/compiler-node/index.js +1 -0
  51. package/dist/errors.d.ts +1 -0
  52. package/dist/errors.js +24 -0
  53. package/dist/index.d.ts +2 -5
  54. package/dist/index.js +2 -5
  55. package/dist/{authoring/ProjectConfig.d.ts → project/index.d.ts} +7 -0
  56. package/dist/{authoring/ProjectConfig.js → project/index.js} +22 -0
  57. package/dist/runtime/Group.d.ts +18 -0
  58. package/dist/runtime/Group.js +45 -0
  59. package/dist/runtime/index.d.ts +1 -9
  60. package/dist/runtime/index.js +1 -9
  61. package/package.json +4 -26
  62. package/dist/authoring/ActionRegistry.d.ts +0 -10
  63. package/dist/authoring/ActionRegistry.js +0 -26
  64. package/dist/authoring/ComponentPalette.d.ts +0 -16
  65. package/dist/authoring/ComponentPalette.js +0 -50
  66. package/dist/authoring/DesignToken.d.ts +0 -16
  67. package/dist/authoring/DesignToken.js +0 -33
  68. package/dist/authoring/DiffModel.d.ts +0 -10
  69. package/dist/authoring/DiffModel.js +0 -104
  70. package/dist/authoring/InspectorModel.d.ts +0 -27
  71. package/dist/authoring/InspectorModel.js +0 -139
  72. package/dist/authoring/LogicGraph.d.ts +0 -66
  73. package/dist/authoring/LogicGraph.js +0 -184
  74. package/dist/authoring/OverrideJournal.d.ts +0 -18
  75. package/dist/authoring/OverrideJournal.js +0 -23
  76. package/dist/authoring/PreferenceMemory.d.ts +0 -21
  77. package/dist/authoring/PreferenceMemory.js +0 -39
  78. package/dist/authoring/RuntimePreview.d.ts +0 -11
  79. package/dist/authoring/RuntimePreview.js +0 -25
  80. package/dist/authoring/SceneDocument.d.ts +0 -74
  81. package/dist/authoring/SceneDocument.js +0 -332
  82. package/dist/authoring/SceneProjectState.d.ts +0 -20
  83. package/dist/authoring/SceneProjectState.js +0 -8
  84. package/dist/authoring/SceneSelection.d.ts +0 -11
  85. package/dist/authoring/SceneSelection.js +0 -1
  86. package/dist/authoring/index.d.ts +0 -13
  87. package/dist/authoring/index.js +0 -13
  88. package/dist/commands/Command.d.ts +0 -63
  89. package/dist/commands/Command.js +0 -1
  90. package/dist/commands/CommandStack.d.ts +0 -14
  91. package/dist/commands/CommandStack.js +0 -45
  92. package/dist/commands/applyCommand.d.ts +0 -23
  93. package/dist/commands/applyCommand.js +0 -316
  94. package/dist/commands/index.d.ts +0 -4
  95. package/dist/commands/index.js +0 -4
  96. package/dist/commands/utils.d.ts +0 -17
  97. package/dist/commands/utils.js +0 -77
  98. package/dist/commands/validateCommand.d.ts +0 -12
  99. package/dist/commands/validateCommand.js +0 -285
  100. package/dist/nodes/Input.d.ts +0 -91
  101. package/dist/nodes/Input.js +0 -352
  102. package/dist/nodes/Textarea.d.ts +0 -10
  103. package/dist/nodes/Textarea.js +0 -38
  104. package/dist/nodes/components/Button.d.ts +0 -8
  105. package/dist/nodes/components/Button.js +0 -45
  106. package/dist/nodes/components/InputField.d.ts +0 -12
  107. package/dist/nodes/components/InputField.js +0 -53
  108. package/dist/nodes/components/ProgressBar.d.ts +0 -14
  109. package/dist/nodes/components/ProgressBar.js +0 -66
  110. package/dist/nodes/components/ScrollRect.d.ts +0 -23
  111. package/dist/nodes/components/ScrollRect.js +0 -108
  112. package/dist/nodes/components/Selectable.d.ts +0 -32
  113. package/dist/nodes/components/Selectable.js +0 -153
  114. package/dist/nodes/components/index.d.ts +0 -5
  115. package/dist/nodes/components/index.js +0 -5
  116. package/dist/nodes/graphics/Graphic.d.ts +0 -14
  117. package/dist/nodes/graphics/Graphic.js +0 -47
  118. package/dist/nodes/graphics/ImageGraphic.d.ts +0 -9
  119. package/dist/nodes/graphics/ImageGraphic.js +0 -42
  120. package/dist/nodes/graphics/RoundedRectGraphic.d.ts +0 -13
  121. package/dist/nodes/graphics/RoundedRectGraphic.js +0 -65
  122. package/dist/nodes/graphics/TextGraphic.d.ts +0 -13
  123. package/dist/nodes/graphics/TextGraphic.js +0 -70
  124. package/dist/nodes/graphics/index.d.ts +0 -4
  125. package/dist/nodes/graphics/index.js +0 -4
  126. package/dist/nodes/index.d.ts +0 -3
  127. package/dist/nodes/index.js +0 -3
  128. package/dist/runtime/Application.d.ts +0 -15
  129. package/dist/runtime/Application.js +0 -67
  130. package/dist/runtime/GameObject.d.ts +0 -100
  131. package/dist/runtime/GameObject.js +0 -297
  132. package/dist/runtime/GameObjectEvent.d.ts +0 -52
  133. package/dist/runtime/GameObjectEvent.js +0 -38
  134. package/dist/runtime/Transform.d.ts +0 -32
  135. package/dist/runtime/Transform.js +0 -157
  136. package/dist/runtime/component/Component.d.ts +0 -13
  137. package/dist/runtime/component/Component.js +0 -13
  138. package/dist/runtime/component/ComponentRegistry.d.ts +0 -49
  139. package/dist/runtime/component/ComponentRegistry.js +0 -25
  140. package/dist/runtime/component/Flex.d.ts +0 -6
  141. package/dist/runtime/component/Flex.js +0 -15
  142. package/dist/runtime/component/FlexGroup.d.ts +0 -26
  143. package/dist/runtime/component/FlexGroup.js +0 -136
  144. package/dist/runtime/component/GridLayout.d.ts +0 -47
  145. package/dist/runtime/component/GridLayout.js +0 -129
  146. package/dist/runtime/component/Layout.d.ts +0 -104
  147. package/dist/runtime/component/Layout.js +0 -248
  148. package/dist/runtime/component/decorators.d.ts +0 -4
  149. package/dist/runtime/component/decorators.js +0 -52
  150. package/dist/runtime/component/index.d.ts +0 -7
  151. package/dist/runtime/component/index.js +0 -7
  152. package/dist/runtime/graphics/index.d.ts +0 -11
  153. package/dist/runtime/graphics/index.js +0 -29
  154. package/dist/runtime/group/index.d.ts +0 -39
  155. package/dist/runtime/group/index.js +0 -102
  156. package/dist/runtime/image/Image.d.ts +0 -19
  157. package/dist/runtime/image/Image.js +0 -60
  158. package/dist/runtime/image/NineSliceImage.d.ts +0 -23
  159. package/dist/runtime/image/NineSliceImage.js +0 -64
  160. package/dist/runtime/image/index.d.ts +0 -2
  161. package/dist/runtime/image/index.js +0 -2
  162. package/dist/runtime/label/Label.d.ts +0 -11
  163. package/dist/runtime/label/Label.js +0 -26
  164. package/dist/runtime/label/LabelStyle.d.ts +0 -3
  165. package/dist/runtime/label/LabelStyle.js +0 -3
  166. package/dist/runtime/label/index.d.ts +0 -2
  167. package/dist/runtime/label/index.js +0 -2
  168. package/dist/runtime/utils/index.d.ts +0 -1
  169. package/dist/runtime/utils/index.js +0 -1
  170. package/dist/runtime/utils/onlyOnceQueueMicrotask.d.ts +0 -1
  171. package/dist/runtime/utils/onlyOnceQueueMicrotask.js +0 -12
  172. package/dist/runtime/utils/setProps.d.ts +0 -10
  173. package/dist/runtime/utils/setProps.js +0 -17
  174. package/dist/scene/dsl.d.ts +0 -25
  175. package/dist/scene/dsl.js +0 -112
  176. package/dist/scene/index.d.ts +0 -5
  177. package/dist/scene/index.js +0 -5
  178. package/dist/scene/instantiate.d.ts +0 -8
  179. package/dist/scene/instantiate.js +0 -208
  180. package/dist/scene/nodesDsl.d.ts +0 -42
  181. package/dist/scene/nodesDsl.js +0 -169
  182. package/dist/scene/spec.d.ts +0 -100
  183. package/dist/scene/spec.js +0 -1
  184. package/dist/scene/templates.d.ts +0 -21
  185. package/dist/scene/templates.js +0 -239
@@ -33,9 +33,9 @@ class CompileContext {
33
33
  const actionsParameter = this.options.actionsParameter || 'actions';
34
34
  const partsType = this.#formatPartsType();
35
35
  const textureLoads = this.#formatTextureLoads();
36
- this.#lines.push(`export function ${functionName}(root: Container${this.#hasEvents() ? `, ${actionsParameter}: Record<string, () => void> = {}` : ''}) {`);
36
+ this.#lines.push(`export function ${functionName}(root: Group${this.#hasEvents() ? `, ${actionsParameter}: Record<string, () => void> = {}` : ''}) {`);
37
37
  this.#lines.push(' const __pixifactSlots: Record<string, Container> = {};');
38
- this.#applyPixiProps('root', this.template.props);
38
+ this.#applyRootProps();
39
39
  for (const child of this.template.children) {
40
40
  this.#compileNode(child, 'root', actionsParameter);
41
41
  }
@@ -72,7 +72,7 @@ class CompileContext {
72
72
  ...[...this.#imports].filter((item) => item !== 'Container').sort(),
73
73
  ...[...this.#pixiImports].sort(),
74
74
  ])];
75
- const lines = [`import { ${imports.join(', ')} } from 'pixi.js';`];
75
+ const lines = [`import { ${imports.join(', ')} } from 'pixi.js';`, `import { Group } from 'pixifact/runtime';`];
76
76
  for (const [texture, variable] of this.#textureImportEntries()) {
77
77
  lines.push(`import ${variable} from ${JSON.stringify(this.options.textureImports?.[texture])};`);
78
78
  }
@@ -80,8 +80,13 @@ class CompileContext {
80
80
  const classImport = sceneImport.exportName === sceneImport.localName
81
81
  ? sceneImport.exportName
82
82
  : `${sceneImport.exportName} as ${sceneImport.localName}`;
83
- const imports = [classImport, ...this.#sceneStructImports(sceneImport)];
84
- lines.push(`import { ${imports.join(', ')} } from ${JSON.stringify(sceneImport.source)};`);
83
+ const imports = [
84
+ ...(this.#usesSceneClassImport(sceneImport) ? [classImport] : []),
85
+ ...this.#sceneStructImports(sceneImport),
86
+ ];
87
+ if (imports.length > 0) {
88
+ lines.push(`import { ${imports.join(', ')} } from ${JSON.stringify(sceneImport.source)};`);
89
+ }
85
90
  }
86
91
  if (this.options.scriptImport) {
87
92
  lines.push(`import { ${this.options.scriptImport.exportName} as ${this.options.scriptImport.localName} } from ${JSON.stringify(this.options.scriptImport.source)};`);
@@ -92,7 +97,7 @@ class CompileContext {
92
97
  return lines.join('\n');
93
98
  }
94
99
  #formatPartsType() {
95
- const lines = [`export type ${this.template.name}Parts = {`, ' root: Container;'];
100
+ const lines = [`export type ${this.template.name}Parts = {`, ' root: Group;'];
96
101
  lines.push(' parts: {');
97
102
  for (const part of this.#parts) {
98
103
  lines.push(` ${part.id}: ${part.type};`);
@@ -267,15 +272,73 @@ class CompileContext {
267
272
  return this.options.sceneClassAliases?.[node.scene] ?? node.type;
268
273
  }
269
274
  #sceneStructImports(sceneImport) {
270
- const sceneInterface = this.options.sceneInterfaces?.[Object.entries(this.options.sceneClassAliases ?? {})
271
- .find(([, alias]) => alias === sceneImport.localName)?.[0] ?? ''];
272
- if (!sceneInterface) {
275
+ const scene = this.#sceneImportScene(sceneImport);
276
+ if (!scene) {
273
277
  return [];
274
278
  }
275
- return [...new Set(Object.values(sceneInterface.props)
276
- .filter((contract) => contract.type === 'struct')
277
- .map((contract) => contract.struct))]
278
- .sort();
279
+ const structs = new Set();
280
+ this.#collectSceneStructImports(this.template.children, scene, structs);
281
+ return [...structs].sort();
282
+ }
283
+ #collectSceneStructImports(nodes, sourceScene, structs) {
284
+ for (const node of nodes) {
285
+ if (node.kind === 'slotOutlet') {
286
+ continue;
287
+ }
288
+ if (node.kind === 'pixi') {
289
+ this.#collectSceneStructImports(node.children, sourceScene, structs);
290
+ continue;
291
+ }
292
+ const sceneInterface = this.options.sceneInterfaces?.[node.scene];
293
+ for (const [key, value] of Object.entries(node.props)) {
294
+ const contract = value && typeof value === 'object' ? sceneInterface?.props[key] : undefined;
295
+ if (contract?.type === 'struct' && this.#structContractSourceScene(node.scene, contract) === sourceScene) {
296
+ structs.add(contract.struct);
297
+ }
298
+ }
299
+ for (const children of Object.values(node.slots)) {
300
+ this.#collectSceneStructImports(children, sourceScene, structs);
301
+ }
302
+ }
303
+ }
304
+ #usesSceneClassImport(sceneImport) {
305
+ const scene = this.#sceneImportScene(sceneImport);
306
+ if (!scene) {
307
+ return true;
308
+ }
309
+ const instanceScenes = this.#sceneInstanceScenes();
310
+ if (instanceScenes.has(scene)) {
311
+ return true;
312
+ }
313
+ return Object.entries(this.options.sceneClassAliases ?? {})
314
+ .some(([instanceScene, alias]) => alias === sceneImport.localName && instanceScenes.has(instanceScene));
315
+ }
316
+ #sceneInstanceScenes() {
317
+ const scenes = new Set();
318
+ this.#collectSceneInstanceScenes(this.template.children, scenes);
319
+ return scenes;
320
+ }
321
+ #collectSceneInstanceScenes(nodes, scenes) {
322
+ for (const node of nodes) {
323
+ if (node.kind === 'slotOutlet') {
324
+ continue;
325
+ }
326
+ if (node.kind === 'pixi') {
327
+ this.#collectSceneInstanceScenes(node.children, scenes);
328
+ continue;
329
+ }
330
+ scenes.add(node.scene);
331
+ for (const children of Object.values(node.slots)) {
332
+ this.#collectSceneInstanceScenes(children, scenes);
333
+ }
334
+ }
335
+ }
336
+ #sceneImportScene(sceneImport) {
337
+ return sceneImport.scene
338
+ ?? Object.entries(this.options.sceneClassAliases ?? {}).find(([, alias]) => alias === sceneImport.localName)?.[0];
339
+ }
340
+ #structContractSourceScene(instanceScene, contract) {
341
+ return contract.sourceScene ?? instanceScene;
279
342
  }
280
343
  #applyPixiProps(variable, props, instance = false, sceneInstance) {
281
344
  const x = props.x;
@@ -332,6 +395,17 @@ class CompileContext {
332
395
  }
333
396
  }
334
397
  }
398
+ #applyRootProps() {
399
+ const props = { ...this.template.props };
400
+ const width = props.width;
401
+ const height = props.height;
402
+ delete props.width;
403
+ delete props.height;
404
+ if (width !== undefined || height !== undefined) {
405
+ this.#lines.push(` root.setSize(${this.#value(width ?? 0)}, ${this.#value(height ?? 0)});`);
406
+ }
407
+ this.#applyPixiProps('root', props);
408
+ }
335
409
  #applyStructProp(variable, key, value, sceneInstance) {
336
410
  const contract = this.#sceneInstanceStructContract(sceneInstance, key);
337
411
  if (!contract) {
@@ -0,0 +1,8 @@
1
+ import { type BuiltinSceneScriptSources } from '../compiler/builtinScenes.js';
2
+ export declare function builtinSceneFilePath(assetId: string): string;
3
+ export declare function builtinSceneScriptPath(assetId: string): string;
4
+ export declare function readBuiltinSceneSource(assetId: string): Promise<string>;
5
+ export declare function readBuiltinSceneScriptSource(assetId: string): Promise<string>;
6
+ export declare function readBuiltinSceneScriptSources(): Promise<BuiltinSceneScriptSources>;
7
+ export declare function readBuiltinSceneScriptSourcesSync(): BuiltinSceneScriptSources;
8
+ export declare function assertBuiltinSceneScript(assetId: string): Promise<string>;
@@ -0,0 +1,57 @@
1
+ import fs from 'node:fs';
2
+ import { access, readFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import process from 'node:process';
6
+ import { builtinSceneNames, builtinSceneNameFromAssetId, } from '../compiler/builtinScenes.js';
7
+ const builtinScenesDir = resolveBuiltinScenesDir(import.meta.url);
8
+ function resolveBuiltinScenesDir(metaUrl) {
9
+ const url = new URL('../builtin-scenes/', metaUrl);
10
+ if (url.protocol === 'file:') {
11
+ return fileURLToPath(url);
12
+ }
13
+ const pathname = decodeURIComponent(url.pathname).replace(/^\/@fs\//, '/');
14
+ if (path.isAbsolute(pathname) && fs.existsSync(pathname)) {
15
+ return pathname;
16
+ }
17
+ return path.resolve(process.cwd(), 'packages/pixifact/src/builtin-scenes');
18
+ }
19
+ export function builtinSceneFilePath(assetId) {
20
+ return path.join(builtinScenesDir, `${builtinSceneNameFromAssetId(assetId)}.scene`);
21
+ }
22
+ export function builtinSceneScriptPath(assetId) {
23
+ const sourcePath = path.join(builtinScenesDir, `${builtinSceneNameFromAssetId(assetId)}.ts`);
24
+ if (fs.existsSync(sourcePath)) {
25
+ return sourcePath;
26
+ }
27
+ return path.join(builtinScenesDir, `${builtinSceneNameFromAssetId(assetId)}.js`);
28
+ }
29
+ export async function readBuiltinSceneSource(assetId) {
30
+ return readFile(builtinSceneFilePath(assetId), 'utf8');
31
+ }
32
+ export async function readBuiltinSceneScriptSource(assetId) {
33
+ return readFile(builtinSceneScriptPath(assetId), 'utf8');
34
+ }
35
+ export async function readBuiltinSceneScriptSources() {
36
+ const entries = await Promise.all(builtinSceneNames.map(async (name) => [name, await readFile(path.join(builtinScenesDir, `${name}.ts`), 'utf8')]));
37
+ return Object.fromEntries(entries);
38
+ }
39
+ export function readBuiltinSceneScriptSourcesSync() {
40
+ return Object.fromEntries(builtinSceneNames.map((name) => [name, fs.readFileSync(path.join(builtinScenesDir, `${name}.ts`), 'utf8')]));
41
+ }
42
+ export async function assertBuiltinSceneScript(assetId) {
43
+ const scriptPath = builtinSceneScriptPath(assetId);
44
+ if (!await exists(scriptPath)) {
45
+ throw new Error(`Built-in Scene "${assetId}" requires script "${scriptPath}".`);
46
+ }
47
+ return scriptPath;
48
+ }
49
+ async function exists(filePath) {
50
+ try {
51
+ await access(filePath);
52
+ return true;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
@@ -1,2 +1,3 @@
1
1
  export * from '../compiler/compileScenes.js';
2
+ export * from './builtinSceneAssets.js';
2
3
  export * from './vite.js';
@@ -1,2 +1,3 @@
1
1
  export * from '../compiler/compileScenes.js';
2
+ export * from './builtinSceneAssets.js';
2
3
  export * from './vite.js';
@@ -0,0 +1 @@
1
+ export declare function hintForCommandError(error: string): "Use a project-relative scene path that stays inside projectRoot." | "Choose a different scene path or inspect the existing file before writing." | "Use one of: button, progressBar, scrollView, loginForm." | "Re-run scene get or node inspect to refresh locators before regenerating the command." | "Choose a container node as the parent, or create a container template before adding children." | "Verify that the field belongs to the target node or component schema before retrying." | "Check the target schema and send a value with the expected type." | undefined;
package/dist/errors.js ADDED
@@ -0,0 +1,24 @@
1
+ export function hintForCommandError(error) {
2
+ if (error.includes('inside projectRoot')) {
3
+ return 'Use a project-relative scene path that stays inside projectRoot.';
4
+ }
5
+ if (error.includes('already exists')) {
6
+ return 'Choose a different scene path or inspect the existing file before writing.';
7
+ }
8
+ if (error.includes('Unknown template kind')) {
9
+ return 'Use one of: button, progressBar, scrollView, loginForm.';
10
+ }
11
+ if (error.includes('was not found')) {
12
+ return 'Re-run scene get or node inspect to refresh locators before regenerating the command.';
13
+ }
14
+ if (error.includes('Only container nodes')) {
15
+ return 'Choose a container node as the parent, or create a container template before adding children.';
16
+ }
17
+ if (error.includes('does not exist')) {
18
+ return 'Verify that the field belongs to the target node or component schema before retrying.';
19
+ }
20
+ if (error.includes('expects')) {
21
+ return 'Check the target schema and send a value with the expected type.';
22
+ }
23
+ return undefined;
24
+ }
package/dist/index.d.ts CHANGED
@@ -1,6 +1,3 @@
1
1
  export * from './runtime/index.js';
2
- export * from './nodes/index.js';
3
- export * from './scene/index.js';
4
- export * from './authoring/index.js';
5
- export * from './commands/index.js';
6
- export * from 'eventemitter3';
2
+ export * from './project/index.js';
3
+ export * from './errors.js';
package/dist/index.js CHANGED
@@ -1,6 +1,3 @@
1
1
  export * from './runtime/index.js';
2
- export * from './nodes/index.js';
3
- export * from './scene/index.js';
4
- export * from './authoring/index.js';
5
- export * from './commands/index.js';
6
- export * from 'eventemitter3';
2
+ export * from './project/index.js';
3
+ export * from './errors.js';
@@ -5,16 +5,23 @@ export interface PixifactProjectRunConfig {
5
5
  cwd: string;
6
6
  url?: string;
7
7
  }
8
+ export interface PixifactProjectResolution {
9
+ width: number;
10
+ height: number;
11
+ }
8
12
  export interface PixifactProjectConfig {
9
13
  version: 1;
10
14
  name: string;
15
+ resolution: PixifactProjectResolution;
11
16
  scenes: Record<string, string>;
12
17
  run?: PixifactProjectRunConfig;
13
18
  }
14
19
  export interface PixifactProjectSummary {
15
20
  name: string;
21
+ resolution: PixifactProjectResolution;
16
22
  scenes: Record<string, string>;
17
23
  run?: PixifactProjectRunConfig;
18
24
  }
25
+ export declare const defaultPixifactProjectResolution: PixifactProjectResolution;
19
26
  export declare function parsePixifactProjectConfig(value: unknown): PixifactProjectConfig;
20
27
  export declare function summarizePixifactProjectConfig(config: PixifactProjectConfig): PixifactProjectSummary;
@@ -1,4 +1,8 @@
1
1
  export const pixifactProjectConfigFileName = 'pixifact.project.json';
2
+ export const defaultPixifactProjectResolution = {
3
+ width: 750,
4
+ height: 1334,
5
+ };
2
6
  function isRecord(value) {
3
7
  return typeof value === 'object' && value !== null && !Array.isArray(value);
4
8
  }
@@ -14,6 +18,12 @@ function assertString(value, name) {
14
18
  }
15
19
  return value.trim();
16
20
  }
21
+ function assertPositiveNumber(value, name) {
22
+ if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
23
+ throw new Error(`${name} must be a positive number.`);
24
+ }
25
+ return value;
26
+ }
17
27
  function normalizeProjectPath(value, name) {
18
28
  const input = assertString(value, name).replaceAll('\\', '/');
19
29
  if (input.startsWith('/') || /^[A-Za-z]:\//.test(input)) {
@@ -42,6 +52,16 @@ function parseScenes(value) {
42
52
  normalizeProjectPath(scenePath, `scenes.${key}`),
43
53
  ]));
44
54
  }
55
+ function parseResolution(value) {
56
+ if (value === undefined) {
57
+ return defaultPixifactProjectResolution;
58
+ }
59
+ const resolution = assertRecord(value, 'resolution');
60
+ return {
61
+ width: assertPositiveNumber(resolution.width, 'resolution.width'),
62
+ height: assertPositiveNumber(resolution.height, 'resolution.height'),
63
+ };
64
+ }
45
65
  function parseRun(value) {
46
66
  if (value === undefined) {
47
67
  return undefined;
@@ -65,6 +85,7 @@ export function parsePixifactProjectConfig(value) {
65
85
  return {
66
86
  version: 1,
67
87
  name: assertString(config.name, 'name'),
88
+ resolution: parseResolution(config.resolution),
68
89
  scenes: parseScenes(config.scenes),
69
90
  run: parseRun(config.run),
70
91
  };
@@ -72,6 +93,7 @@ export function parsePixifactProjectConfig(value) {
72
93
  export function summarizePixifactProjectConfig(config) {
73
94
  return {
74
95
  name: config.name,
96
+ resolution: config.resolution,
75
97
  scenes: config.scenes,
76
98
  ...(config.run === undefined ? {} : { run: config.run }),
77
99
  };
@@ -0,0 +1,18 @@
1
+ import { Container, type ContainerOptions, type Size } from 'pixi.js';
2
+ export type GroupOptions = Omit<ContainerOptions, 'width' | 'height'> & {
3
+ width?: number;
4
+ height?: number;
5
+ };
6
+ export declare class Group extends Container {
7
+ #private;
8
+ constructor(options?: GroupOptions);
9
+ get width(): number;
10
+ set width(value: number);
11
+ get height(): number;
12
+ set height(value: number);
13
+ getSize(out?: Size): Size;
14
+ setSize(value: number | {
15
+ width: number;
16
+ height?: number;
17
+ }, height?: number): void;
18
+ }
@@ -0,0 +1,45 @@
1
+ import { Container, Rectangle } from 'pixi.js';
2
+ export class Group extends Container {
3
+ #width = 0;
4
+ #height = 0;
5
+ constructor(options = {}) {
6
+ const { width, height, ...containerOptions } = options;
7
+ super(containerOptions);
8
+ if (width !== undefined || height !== undefined) {
9
+ this.setSize(width ?? 0, height ?? 0);
10
+ }
11
+ }
12
+ get width() {
13
+ return this.#width;
14
+ }
15
+ set width(value) {
16
+ this.#width = value;
17
+ this.#syncHitArea();
18
+ }
19
+ get height() {
20
+ return this.#height;
21
+ }
22
+ set height(value) {
23
+ this.#height = value;
24
+ this.#syncHitArea();
25
+ }
26
+ getSize(out = { width: 0, height: 0 }) {
27
+ out.width = this.#width;
28
+ out.height = this.#height;
29
+ return out;
30
+ }
31
+ setSize(value, height) {
32
+ if (typeof value === 'number') {
33
+ this.#width = value;
34
+ this.#height = height ?? value;
35
+ }
36
+ else {
37
+ this.#width = value.width;
38
+ this.#height = value.height ?? value.width;
39
+ }
40
+ this.#syncHitArea();
41
+ }
42
+ #syncHitArea() {
43
+ this.hitArea = new Rectangle(0, 0, this.#width, this.#height);
44
+ }
45
+ }
@@ -1,9 +1 @@
1
- export * from './GameObject.js';
2
- export * from './GameObjectEvent.js';
3
- export * from './group/index.js';
4
- export * from './image/index.js';
5
- export * from './label/index.js';
6
- export * from './graphics/index.js';
7
- export * from './Application.js';
8
- export * from './component/index.js';
9
- export * from './utils/index.js';
1
+ export * from './Group.js';
@@ -1,9 +1 @@
1
- export * from './GameObject.js';
2
- export * from './GameObjectEvent.js';
3
- export * from './group/index.js';
4
- export * from './image/index.js';
5
- export * from './label/index.js';
6
- export * from './graphics/index.js';
7
- export * from './Application.js';
8
- export * from './component/index.js';
9
- export * from './utils/index.js';
1
+ export * from './Group.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pixifact",
3
- "version": "0.1.3",
4
- "description": "Pixif semantic framework for 2D UI and lightweight game scenes.",
3
+ "version": "0.1.4",
4
+ "description": "Pixifact 2D UI 和轻量游戏 Scene 语义框架。",
5
5
  "packageManager": "bun@1.3.13",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -12,7 +12,7 @@
12
12
  ],
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "git+https://github.com/hxg2050/pixifact.git",
15
+ "url": "https://github.com/hxg2050/pixifact",
16
16
  "directory": "packages/pixifact"
17
17
  },
18
18
  "keywords": [
@@ -26,7 +26,7 @@
26
26
  "author": "youxia <243802688@qq.com>",
27
27
  "license": "MIT",
28
28
  "scripts": {
29
- "build": "bun scripts/clean-dist.mjs && bunx --no-install tsc -p tsconfig.build.json && bun scripts/fix-dist-esm-imports.mjs"
29
+ "build": "bun scripts/clean-dist.mjs && bunx --no-install tsc -p tsconfig.build.json && bun scripts/fix-dist-esm-imports.mjs && bun scripts/copy-scene-assets.mjs"
30
30
  },
31
31
  "publishConfig": {
32
32
  "registry": "https://registry.npmjs.org/"
@@ -42,16 +42,6 @@
42
42
  "import": "./dist/runtime/index.js",
43
43
  "require": "./dist/runtime/index.js"
44
44
  },
45
- "./nodes": {
46
- "types": "./dist/nodes/index.d.ts",
47
- "import": "./dist/nodes/index.js",
48
- "require": "./dist/nodes/index.js"
49
- },
50
- "./scene": {
51
- "types": "./dist/scene/index.d.ts",
52
- "import": "./dist/scene/index.js",
53
- "require": "./dist/scene/index.js"
54
- },
55
45
  "./compiler": {
56
46
  "types": "./dist/compiler/index.d.ts",
57
47
  "import": "./dist/compiler/index.js",
@@ -61,24 +51,12 @@
61
51
  "types": "./dist/compiler-node/index.d.ts",
62
52
  "import": "./dist/compiler-node/index.js",
63
53
  "require": "./dist/compiler-node/index.js"
64
- },
65
- "./authoring": {
66
- "types": "./dist/authoring/index.d.ts",
67
- "import": "./dist/authoring/index.js",
68
- "require": "./dist/authoring/index.js"
69
- },
70
- "./commands": {
71
- "types": "./dist/commands/index.d.ts",
72
- "import": "./dist/commands/index.js",
73
- "require": "./dist/commands/index.js"
74
54
  }
75
55
  },
76
56
  "peerDependencies": {
77
57
  "pixi.js": ">=8.3.0"
78
58
  },
79
59
  "dependencies": {
80
- "@math.gl/core": "^4.0.1",
81
- "eventemitter3": "^5.0.1",
82
60
  "typescript": "^5.3.3"
83
61
  },
84
62
  "devDependencies": {
@@ -1,10 +0,0 @@
1
- export interface ActionSpec {
2
- key: string;
3
- label?: string;
4
- description?: string;
5
- source?: 'manual' | 'agent' | 'code';
6
- }
7
- export declare function actionExists(actions: readonly ActionSpec[] | undefined, key: string): boolean;
8
- export declare function upsertAction(actions: ActionSpec[], action: ActionSpec): ActionSpec;
9
- export declare function createRuntimeActions(actions: readonly ActionSpec[] | undefined, handler?: (action: ActionSpec, args: unknown[]) => void): Record<string, (...args: unknown[]) => void>;
10
- export declare function summarizeActionsForAgent(actions: readonly ActionSpec[] | undefined): string;
@@ -1,26 +0,0 @@
1
- export function actionExists(actions, key) {
2
- return (actions ?? []).some((action) => action.key === key);
3
- }
4
- export function upsertAction(actions, action) {
5
- const existing = actions.find((item) => item.key === action.key);
6
- if (existing) {
7
- Object.assign(existing, action);
8
- return existing;
9
- }
10
- actions.push(action);
11
- return action;
12
- }
13
- export function createRuntimeActions(actions, handler) {
14
- const runtimeActions = {};
15
- for (const action of actions ?? []) {
16
- runtimeActions[action.key] = (...args) => {
17
- handler?.(action, args);
18
- };
19
- }
20
- return runtimeActions;
21
- }
22
- export function summarizeActionsForAgent(actions) {
23
- return (actions ?? [])
24
- .map((action) => `- ${action.key}${action.label ? ` (${action.label})` : ''}${action.description ? `: ${action.description}` : ''}`)
25
- .join('\n');
26
- }
@@ -1,16 +0,0 @@
1
- import type { ComponentSchema } from "../runtime/index.js";
2
- import type { ComponentSpec, SceneSpec } from "../scene/index.js";
3
- export interface PaletteComponentItem {
4
- type: string;
5
- displayName: string;
6
- category: string;
7
- description?: string;
8
- disabledReason?: string;
9
- schema: ComponentSchema;
10
- }
11
- export interface ComponentPaletteOptions {
12
- scene?: SceneSpec;
13
- node?: string;
14
- }
15
- export declare function listPaletteComponents(options?: ComponentPaletteOptions): PaletteComponentItem[];
16
- export declare function createComponentSpecFromSchema(schemaOrType: ComponentSchema | string, id?: string): ComponentSpec;
@@ -1,50 +0,0 @@
1
- import { ComponentRegistry } from "../runtime/index.js";
2
- import { findNode } from "../commands/utils.js";
3
- function componentIdFromType(type) {
4
- const raw = type.split('.').at(-1) ?? type;
5
- return raw.charAt(0).toLowerCase() + raw.slice(1);
6
- }
7
- function disabledReason(schema, options) {
8
- if (!schema.disallowMultiple || !options.scene || !options.node) {
9
- return undefined;
10
- }
11
- const node = findNode(options.scene, options.node)?.node;
12
- if (!node) {
13
- return undefined;
14
- }
15
- return (node.components ?? []).some((component) => component.type === schema.type)
16
- ? `${schema.displayName ?? schema.type} already exists on this node.`
17
- : undefined;
18
- }
19
- export function listPaletteComponents(options = {}) {
20
- return ComponentRegistry.list()
21
- .filter((schema) => schema.category !== 'UI/Graphic')
22
- .map((schema) => ({
23
- type: schema.type,
24
- displayName: schema.displayName ?? schema.type,
25
- category: schema.category ?? 'Other',
26
- description: schema.description,
27
- disabledReason: disabledReason(schema, options),
28
- schema,
29
- }))
30
- .sort((a, b) => a.category.localeCompare(b.category) || a.displayName.localeCompare(b.displayName));
31
- }
32
- export function createComponentSpecFromSchema(schemaOrType, id) {
33
- const schema = typeof schemaOrType === 'string'
34
- ? ComponentRegistry.get(schemaOrType)
35
- : schemaOrType;
36
- if (!schema) {
37
- throw new Error(`Unknown component type "${schemaOrType}".`);
38
- }
39
- const props = {};
40
- for (const prop of schema.props) {
41
- if (prop.default !== undefined && prop.serialize !== false) {
42
- props[prop.key] = structuredClone(prop.default);
43
- }
44
- }
45
- return {
46
- id: id ?? componentIdFromType(schema.type),
47
- type: schema.type,
48
- props,
49
- };
50
- }
@@ -1,16 +0,0 @@
1
- export interface DesignTokenSpec {
2
- colors?: Record<string, number>;
3
- spacing?: Record<string, number>;
4
- radius?: Record<string, number>;
5
- typography?: Record<string, {
6
- fontFamily: string;
7
- fontSize: number;
8
- fontWeight?: string;
9
- }>;
10
- }
11
- export interface DesignTokenWarning {
12
- target: string;
13
- value: unknown;
14
- message: string;
15
- }
16
- export declare function validateDesignTokenValue(tokens: DesignTokenSpec | undefined, target: string, prop: string, value: unknown): DesignTokenWarning | undefined;