@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.
- package/package.json +1 -1
- package/src/asset-pack.mjs +2 -1
- package/src/authored-runtime.mjs +14 -0
- package/src/bin-integrity.mjs +33 -26
- package/src/conformance/cases/systems-and-gameplay-cases.mjs +861 -6
- package/src/external-package-surface.mjs +1 -1
- package/src/package-integrity.mjs +18 -4
- package/src/publish-command.mjs +133 -13
- package/src/publish-validation.mjs +22 -11
- package/src/scaffold/project-docs.mjs +58 -40
- package/templates/create/2d/src/runtime/app.js +4 -0
- package/templates/create/2d-survivor/src/runtime/app.js +4 -0
- package/templates/create/3d/src/runtime/app.js +4 -0
- package/templates/create/3d-collectathon/src/runtime/app.js +4 -0
- package/templates/create/blank/assets/splash/aurajs-gg-wordmark.webp +0 -0
- package/templates/create/blank/assets/splash/bg.webp +0 -0
- package/templates/create/blank/assets/splash/boot-loop.wav +0 -0
- package/templates/create/blank/assets/splash/boot-sting.wav +0 -0
- package/templates/create/blank/assets/splash/logo-mascot-sheet.webp +0 -0
- package/templates/create/blank/assets/splash/logoholo.webp +0 -0
- package/templates/create/blank/src/main.js +5 -1
- package/templates/create/blank/src/runtime/splash.js +305 -0
- package/templates/create/local-multiplayer/scenes/gameplay.scene.js +186 -12
- package/templates/create/local-multiplayer/src/runtime/capabilities.js +8 -1
- package/templates/create/shared/assets/splash/aurajs-gg-wordmark.webp +0 -0
- package/templates/create/shared/assets/splash/bg.webp +0 -0
- package/templates/create/shared/assets/splash/boot-loop.wav +0 -0
- package/templates/create/shared/assets/splash/boot-sting.wav +0 -0
- package/templates/create/shared/assets/splash/logo-mascot-sheet.webp +0 -0
- package/templates/create/shared/assets/splash/logoholo.webp +0 -0
- package/templates/create/shared/src/runtime/splash.js +305 -0
- package/templates/create/video-cutscene/src/runtime/app.js +4 -0
- package/templates/create-bin/play.js +114 -2
- package/templates/starter/assets/splash/aurajs-gg-wordmark.webp +0 -0
- package/templates/starter/assets/splash/bg.webp +0 -0
- package/templates/starter/assets/splash/boot-loop.wav +0 -0
- package/templates/starter/assets/splash/boot-sting.wav +0 -0
- package/templates/starter/assets/splash/logo-mascot-sheet.webp +0 -0
- package/templates/starter/assets/splash/logoholo.webp +0 -0
- package/templates/starter/src/main.js +4 -0
- package/templates/starter/src/runtime/splash.js +305 -0
package/package.json
CHANGED
package/src/asset-pack.mjs
CHANGED
|
@@ -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',
|
package/src/authored-runtime.mjs
CHANGED
|
@@ -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();
|
package/src/bin-integrity.mjs
CHANGED
|
@@ -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 =
|
|
231
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
270
|
+
wrapperContract: 'aurajs.play-wrapper.v1',
|
|
264
271
|
},
|
|
265
272
|
bin: {
|
|
266
273
|
entries: binEntries,
|