@auraindustry/aurajs 0.1.1 → 0.1.3

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 (41) hide show
  1. package/package.json +1 -1
  2. package/src/asset-pack.mjs +2 -1
  3. package/src/authored-runtime.mjs +14 -0
  4. package/src/bin-integrity.mjs +33 -26
  5. package/src/conformance/cases/systems-and-gameplay-cases.mjs +861 -6
  6. package/src/external-package-surface.mjs +1 -1
  7. package/src/package-integrity.mjs +18 -4
  8. package/src/publish-command.mjs +133 -13
  9. package/src/publish-validation.mjs +22 -11
  10. package/src/scaffold/project-docs.mjs +58 -40
  11. package/templates/create/2d/src/runtime/app.js +4 -0
  12. package/templates/create/2d-survivor/src/runtime/app.js +4 -0
  13. package/templates/create/3d/src/runtime/app.js +4 -0
  14. package/templates/create/3d-collectathon/src/runtime/app.js +4 -0
  15. package/templates/create/blank/assets/splash/aurajs-gg-wordmark.webp +0 -0
  16. package/templates/create/blank/assets/splash/bg.webp +0 -0
  17. package/templates/create/blank/assets/splash/boot-loop.wav +0 -0
  18. package/templates/create/blank/assets/splash/boot-sting.wav +0 -0
  19. package/templates/create/blank/assets/splash/logo-mascot-sheet.webp +0 -0
  20. package/templates/create/blank/assets/splash/logoholo.webp +0 -0
  21. package/templates/create/blank/src/main.js +5 -1
  22. package/templates/create/blank/src/runtime/splash.js +305 -0
  23. package/templates/create/local-multiplayer/scenes/gameplay.scene.js +186 -12
  24. package/templates/create/local-multiplayer/src/runtime/capabilities.js +8 -1
  25. package/templates/create/shared/assets/splash/aurajs-gg-wordmark.webp +0 -0
  26. package/templates/create/shared/assets/splash/bg.webp +0 -0
  27. package/templates/create/shared/assets/splash/boot-loop.wav +0 -0
  28. package/templates/create/shared/assets/splash/boot-sting.wav +0 -0
  29. package/templates/create/shared/assets/splash/logo-mascot-sheet.webp +0 -0
  30. package/templates/create/shared/assets/splash/logoholo.webp +0 -0
  31. package/templates/create/shared/src/runtime/splash.js +305 -0
  32. package/templates/create/video-cutscene/src/runtime/app.js +4 -0
  33. package/templates/create-bin/play.js +114 -2
  34. package/templates/starter/assets/splash/aurajs-gg-wordmark.webp +0 -0
  35. package/templates/starter/assets/splash/bg.webp +0 -0
  36. package/templates/starter/assets/splash/boot-loop.wav +0 -0
  37. package/templates/starter/assets/splash/boot-sting.wav +0 -0
  38. package/templates/starter/assets/splash/logo-mascot-sheet.webp +0 -0
  39. package/templates/starter/assets/splash/logoholo.webp +0 -0
  40. package/templates/starter/src/main.js +4 -0
  41. package/templates/starter/src/runtime/splash.js +305 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auraindustry/aurajs",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Write games in JavaScript, build native binaries.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -13,6 +13,7 @@ import { join, relative, resolve, sep } from 'node:path';
13
13
 
14
14
  const SUPPORTED = {
15
15
  png: 'image',
16
+ webp: 'image',
16
17
  jpg: 'image',
17
18
  jpeg: 'image',
18
19
  wav: 'audio',
@@ -40,7 +41,7 @@ const SUPPORTED = {
40
41
  };
41
42
 
42
43
  const APPROVED_FORMATS = [
43
- '.png', '.jpg', '.jpeg',
44
+ '.png', '.webp', '.jpg', '.jpeg',
44
45
  '.wav', '.ogg', '.mp3', '.mp4',
45
46
  '.gltf', '.glb',
46
47
  '.ttf', '.otf',
@@ -46,6 +46,14 @@ export function renderUiFormsModule() {
46
46
  export function renderAppStateModule() {
47
47
  return `export const APP_STATE_SCHEMA = ${JSON.stringify(APP_STATE_SCHEMA)};
48
48
 
49
+ // Shared mutable app/session state lives here.
50
+ //
51
+ // Example scene usage:
52
+ // const runFlags = context.ensureSessionState('runFlags', { DID_START: false });
53
+ // if (!runFlags.DID_START) {
54
+ // runFlags.DID_START = true;
55
+ // }
56
+
49
57
  function cloneAppStateValue(value) {
50
58
  if (Array.isArray(value)) {
51
59
  return value.map((entry) => cloneAppStateValue(entry));
@@ -69,7 +77,9 @@ export function createAppState({ projectTitle = 'AuraJS Game', template = 'blank
69
77
  schema: APP_STATE_SCHEMA,
70
78
  projectTitle,
71
79
  template,
80
+ // Cross-scene gameplay and session state.
72
81
  session: createStoreSection(),
82
+ // Cross-screen UI and presentation state.
73
83
  ui: createStoreSection(),
74
84
  runtime: {
75
85
  startSceneId: null,
@@ -803,6 +813,7 @@ import { createSceneRegistry } from './scene-registry.js';
803
813
  import { createSceneFlow } from './scene-flow.js';
804
814
  import { createScreenShell } from './screen-shell.js';
805
815
  import { assertRuntimeCapabilities } from './capabilities.js';
816
+ import { initSplash, updateSplash, drawSplash, isSplashActive } from './splash.js';
806
817
 
807
818
  const PROJECT_STATE_SCHEMA = ${JSON.stringify(PROJECT_STATE_SCHEMA)};
808
819
  const PROJECT_CONTINUITY_STATE_SCHEMA = 'aurajs.project-continuity-state.v1';
@@ -1813,12 +1824,14 @@ export function createApp() {
1813
1824
  },
1814
1825
  setup() {
1815
1826
  assertRuntimeCapabilities();
1827
+ initSplash();
1816
1828
  runtimeStarted = true;
1817
1829
  paused = false;
1818
1830
  activeScene()?.setup?.();
1819
1831
  syncAppStateRuntime();
1820
1832
  },
1821
1833
  update(dt) {
1834
+ if (isSplashActive()) { updateSplash(dt); return; }
1822
1835
  projectInspector.update();
1823
1836
  if (!paused) {
1824
1837
  activeScene()?.update?.(dt);
@@ -1826,6 +1839,7 @@ export function createApp() {
1826
1839
  syncAppStateRuntime();
1827
1840
  },
1828
1841
  draw() {
1842
+ if (isSplashActive()) { drawSplash(); return; }
1829
1843
  applySharedUiTheme(appState);
1830
1844
  activeScene()?.draw?.();
1831
1845
  const shellState = screenShell.getState();
@@ -1,4 +1,3 @@
1
- import { createHash } from 'node:crypto';
2
1
  import { existsSync, readdirSync, readFileSync } from 'node:fs';
3
2
  import { dirname, join, resolve } from 'node:path';
4
3
  import { fileURLToPath } from 'node:url';
@@ -28,14 +27,37 @@ function normalizeText(value) {
28
27
  return String(value || '').replace(/\r\n?/g, '\n');
29
28
  }
30
29
 
31
- function sha256Text(value) {
32
- return createHash('sha256').update(normalizeText(value)).digest('hex');
33
- }
34
-
35
30
  function readJsonFile(path) {
36
31
  return JSON.parse(readFileSync(path, 'utf8'));
37
32
  }
38
33
 
34
+ const PLAY_WRAPPER_REQUIRED_MARKERS = [
35
+ '#!/usr/bin/env node',
36
+ 'const fallbackAuraPackage =',
37
+ "const MINIMAL_COMMANDS = ['dev', 'join', 'play', 'fork', 'publish', 'session'];",
38
+ "const ALL_COMMANDS = ['dev', 'join', 'play', 'fork', 'publish', 'session', 'state', 'inspect', 'action'];",
39
+ "args: ['exec', '--yes', '--package', fallbackAuraPackage, '--', 'aura', ...commandArgs]",
40
+ ];
41
+
42
+ function assertPlayWrapperContract(relativePath, fileContent) {
43
+ const normalized = normalizeText(fileContent);
44
+ const missingMarkers = PLAY_WRAPPER_REQUIRED_MARKERS.filter((marker) => !normalized.includes(marker));
45
+ if (missingMarkers.length > 0) {
46
+ throw new ProjectBinIntegrityError(
47
+ 'project_bin_wrapper_contract_invalid',
48
+ `Bin target "${relativePath}" does not satisfy the AuraJS play wrapper contract.`,
49
+ {
50
+ relativePath,
51
+ missingMarkers,
52
+ },
53
+ );
54
+ }
55
+
56
+ return {
57
+ markers: [...PLAY_WRAPPER_REQUIRED_MARKERS],
58
+ };
59
+ }
60
+
39
61
  function listRelativeFiles(root, current = root, acc = []) {
40
62
  for (const entry of readdirSync(current, { withFileTypes: true })) {
41
63
  const fullPath = join(current, entry.name);
@@ -84,6 +106,7 @@ export function assertProjectBinIntegrity(
84
106
  aurajsPackageRoot = DEFAULT_AURAJS_PACKAGE_ROOT,
85
107
  expectedAurajsVersion = null,
86
108
  enforceExactAurajsDependency = true,
109
+ enforceResolvedAurajsVersionMatch = false,
87
110
  } = {},
88
111
  ) {
89
112
  const resolvedProjectRoot = resolve(projectRoot || process.cwd());
@@ -146,7 +169,7 @@ export function assertProjectBinIntegrity(
146
169
 
147
170
  const aurajsPackage = readJsonFile(aurajsPackageJsonPath);
148
171
  const resolvedAurajsVersion = String(aurajsPackage?.version || '').trim();
149
- if (expectedAurajsVersion && resolvedAurajsVersion !== expectedAurajsVersion) {
172
+ if (enforceResolvedAurajsVersionMatch && expectedAurajsVersion && resolvedAurajsVersion !== expectedAurajsVersion) {
150
173
  throw new ProjectBinIntegrityError(
151
174
  'project_aurajs_resolved_version_mismatch',
152
175
  `Resolved @auraindustry/aurajs ${resolvedAurajsVersion || '<missing>'}, expected ${expectedAurajsVersion}.`,
@@ -167,9 +190,6 @@ export function assertProjectBinIntegrity(
167
190
  );
168
191
  }
169
192
 
170
- const canonicalTemplate = normalizeText(readFileSync(templatePath, 'utf8'));
171
- const canonicalTemplateHash = sha256Text(canonicalTemplate);
172
-
173
193
  const binEntries = resolveProjectBinEntries(resolvedProjectPackage, resolvedPackageName);
174
194
  if (binEntries.length === 0) {
175
195
  throw new ProjectBinIntegrityError(
@@ -227,26 +247,13 @@ export function assertProjectBinIntegrity(
227
247
  );
228
248
  }
229
249
 
230
- const fileContent = normalizeText(readFileSync(absolutePath, 'utf8'));
231
- const fileHash = sha256Text(fileContent);
232
- if (fileContent !== canonicalTemplate) {
233
- throw new ProjectBinIntegrityError(
234
- 'project_bin_template_modified',
235
- `Bin target "${relativePath}" does not match the canonical AuraJS play.js template.`,
236
- {
237
- relativePath,
238
- absolutePath,
239
- expectedTemplatePath: templatePath,
240
- expectedTemplateHash: canonicalTemplateHash,
241
- actualHash: fileHash,
242
- },
243
- );
244
- }
250
+ const fileContent = readFileSync(absolutePath, 'utf8');
251
+ const wrapperContract = assertPlayWrapperContract(relativePath, fileContent);
245
252
 
246
253
  verifiedFiles.push({
247
254
  relativePath,
248
255
  absolutePath,
249
- hash: fileHash,
256
+ wrapperContract,
250
257
  });
251
258
  }
252
259
 
@@ -260,7 +267,7 @@ export function assertProjectBinIntegrity(
260
267
  resolvedVersion: resolvedAurajsVersion,
261
268
  packageRoot: aurajsPackageRoot,
262
269
  templatePath,
263
- templateHash: canonicalTemplateHash,
270
+ wrapperContract: 'aurajs.play-wrapper.v1',
264
271
  },
265
272
  bin: {
266
273
  entries: binEntries,