@ankhorage/zora-game 0.4.1 → 0.6.0
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/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/dist/ZORA_GAME_COMPONENT_META.d.ts +177 -2
- package/dist/ZORA_GAME_COMPONENT_META.d.ts.map +1 -1
- package/dist/ZORA_GAME_COMPONENT_META.js +2 -0
- package/dist/ZORA_GAME_COMPONENT_META.js.map +1 -1
- package/dist/ZORA_GAME_PLUGIN.d.ts +182 -2
- package/dist/ZORA_GAME_PLUGIN.d.ts.map +1 -1
- package/dist/ZORA_GAME_PLUGIN.js +2 -0
- package/dist/ZORA_GAME_PLUGIN.js.map +1 -1
- package/dist/ZORA_PLUGIN_METADATA.d.ts +180 -2
- package/dist/ZORA_PLUGIN_METADATA.d.ts.map +1 -1
- package/dist/ZORA_PLUGIN_METADATA.js +4 -0
- package/dist/ZORA_PLUGIN_METADATA.js.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/Game.d.ts.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/Game.js +4 -1
- package/dist/features/game-presentation/adapters/inbound/Game.js.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/GameEntity.d.ts +2 -1
- package/dist/features/game-presentation/adapters/inbound/GameEntity.d.ts.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/GameEntity.js +14 -4
- package/dist/features/game-presentation/adapters/inbound/GameEntity.js.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/GameInputZone.d.ts +2 -2
- package/dist/features/game-presentation/adapters/inbound/GameInputZone.d.ts.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/GameInputZone.js +19 -5
- package/dist/features/game-presentation/adapters/inbound/GameInputZone.js.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/GameMeasurementProbe.d.ts +4 -0
- package/dist/features/game-presentation/adapters/inbound/GameMeasurementProbe.d.ts.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/GameMeasurementProbe.js +52 -0
- package/dist/features/game-presentation/adapters/inbound/GameMeasurementProbe.js.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/createGameKeyboardEvent.d.ts +16 -0
- package/dist/features/game-presentation/adapters/inbound/createGameKeyboardEvent.d.ts.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/createGameKeyboardEvent.js +16 -0
- package/dist/features/game-presentation/adapters/inbound/createGameKeyboardEvent.js.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/createGameMeasurementEvent.d.ts +14 -0
- package/dist/features/game-presentation/adapters/inbound/createGameMeasurementEvent.d.ts.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/createGameMeasurementEvent.js +25 -0
- package/dist/features/game-presentation/adapters/inbound/createGameMeasurementEvent.js.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/measureGameEntity.d.ts +5 -0
- package/dist/features/game-presentation/adapters/inbound/measureGameEntity.d.ts.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/measureGameEntity.js +22 -0
- package/dist/features/game-presentation/adapters/inbound/measureGameEntity.js.map +1 -0
- package/dist/features/game-presentation/adapters/inbound/useGameInputZoneResponder.d.ts +6 -0
- package/dist/features/game-presentation/adapters/inbound/useGameInputZoneResponder.d.ts.map +1 -1
- package/dist/features/game-presentation/adapters/inbound/useGameInputZoneResponder.js +15 -0
- package/dist/features/game-presentation/adapters/inbound/useGameInputZoneResponder.js.map +1 -1
- package/dist/features/game-presentation/composition/createGameMeasurementRegistry.d.ts +4 -0
- package/dist/features/game-presentation/composition/createGameMeasurementRegistry.d.ts.map +1 -0
- package/dist/features/game-presentation/composition/createGameMeasurementRegistry.js +15 -0
- package/dist/features/game-presentation/composition/createGameMeasurementRegistry.js.map +1 -0
- package/dist/features/game-presentation/composition/useGameRuntime.d.ts +2 -2
- package/dist/features/game-presentation/composition/useGameRuntime.d.ts.map +1 -1
- package/dist/features/game-presentation/composition/useGameRuntime.js.map +1 -1
- package/dist/features/game-presentation/meta/gameEntityMeta.d.ts +14 -0
- package/dist/features/game-presentation/meta/gameEntityMeta.d.ts.map +1 -1
- package/dist/features/game-presentation/meta/gameEntityMeta.js +7 -0
- package/dist/features/game-presentation/meta/gameEntityMeta.js.map +1 -1
- package/dist/features/game-presentation/meta/gameInputZoneMeta.d.ts +52 -1
- package/dist/features/game-presentation/meta/gameInputZoneMeta.d.ts.map +1 -1
- package/dist/features/game-presentation/meta/gameInputZoneMeta.js +47 -1
- package/dist/features/game-presentation/meta/gameInputZoneMeta.js.map +1 -1
- package/dist/features/game-presentation/meta/gameMeasurementProbeMeta.d.ts +112 -0
- package/dist/features/game-presentation/meta/gameMeasurementProbeMeta.d.ts.map +1 -0
- package/dist/features/game-presentation/meta/gameMeasurementProbeMeta.js +70 -0
- package/dist/features/game-presentation/meta/gameMeasurementProbeMeta.js.map +1 -0
- package/dist/features/game-presentation/meta/gameMeta.d.ts +1 -1
- package/dist/features/game-presentation/meta/gameMeta.d.ts.map +1 -1
- package/dist/features/game-presentation/meta/gameMeta.js +9 -1
- package/dist/features/game-presentation/meta/gameMeta.js.map +1 -1
- package/dist/features/game-presentation/public.d.ts +2 -1
- package/dist/features/game-presentation/public.d.ts.map +1 -1
- package/dist/features/game-presentation/public.js +1 -0
- package/dist/features/game-presentation/public.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/gamePresentation.d.ts +16 -0
- package/dist/types/gamePresentation.d.ts.map +1 -1
- package/dist/types/gamePresentation.js.map +1 -1
- package/dist/types/gameRuntime.d.ts +16 -1
- package/dist/types/gameRuntime.d.ts.map +1 -1
- package/dist/types/gameRuntime.js.map +1 -1
- package/package.json +1 -1
- package/src/ZORA_GAME_COMPONENT_META.ts +2 -0
- package/src/ZORA_GAME_PLUGIN.ts +2 -0
- package/src/ZORA_PLUGIN_METADATA.test.ts +37 -10
- package/src/ZORA_PLUGIN_METADATA.ts +4 -0
- package/src/features/game-presentation/adapters/inbound/Game.tsx +7 -1
- package/src/features/game-presentation/adapters/inbound/GameEntity.tsx +15 -2
- package/src/features/game-presentation/adapters/inbound/GameInputZone.tsx +36 -9
- package/src/features/game-presentation/adapters/inbound/GameMeasurementProbe.tsx +79 -0
- package/src/features/game-presentation/adapters/inbound/createGameKeyboardEvent.test.ts +51 -0
- package/src/features/game-presentation/adapters/inbound/createGameKeyboardEvent.ts +33 -0
- package/src/features/game-presentation/adapters/inbound/createGameMeasurementEvent.test.ts +56 -0
- package/src/features/game-presentation/adapters/inbound/createGameMeasurementEvent.ts +38 -0
- package/src/features/game-presentation/adapters/inbound/measureGameEntity.ts +28 -0
- package/src/features/game-presentation/adapters/inbound/useGameInputZoneResponder.ts +22 -0
- package/src/features/game-presentation/composition/createGameMeasurementRegistry.test.ts +35 -0
- package/src/features/game-presentation/composition/createGameMeasurementRegistry.ts +16 -0
- package/src/features/game-presentation/composition/useGameRuntime.ts +3 -3
- package/src/features/game-presentation/meta/gameEntityMeta.ts +7 -0
- package/src/features/game-presentation/meta/gameInputZoneMeta.ts +47 -1
- package/src/features/game-presentation/meta/gameMeasurementProbeMeta.ts +72 -0
- package/src/features/game-presentation/meta/gameMeta.ts +9 -1
- package/src/features/game-presentation/public.ts +3 -0
- package/src/index.ts +3 -0
- package/src/types/gamePresentation.ts +18 -0
- package/src/types/gameRuntime.ts +19 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*** Describe a non-visual source/target geometry sampling adapter for one Game instance. */
|
|
2
|
+
export const gameMeasurementProbeMeta = {
|
|
3
|
+
name: 'GameMeasurementProbe',
|
|
4
|
+
category: 'component',
|
|
5
|
+
description: 'Measures two registered game entities and reports their raw rendered bounds through a generic Game event.',
|
|
6
|
+
directManifestNode: true,
|
|
7
|
+
allowedChildren: [],
|
|
8
|
+
blueprint: {
|
|
9
|
+
label: 'Game measurement probe',
|
|
10
|
+
defaultProps: {
|
|
11
|
+
sourceId: 'source',
|
|
12
|
+
targetId: 'target',
|
|
13
|
+
eventType: 'game.measurement',
|
|
14
|
+
delayMs: 0,
|
|
15
|
+
enabled: true,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
bindings: {
|
|
19
|
+
props: {
|
|
20
|
+
sourceId: { value: { type: 'string' }, acceptsFallback: true },
|
|
21
|
+
targetId: { value: { type: 'string' }, acceptsFallback: true },
|
|
22
|
+
eventType: { value: { type: 'string' }, acceptsFallback: true },
|
|
23
|
+
entityId: { value: { type: 'string' }, acceptsFallback: true },
|
|
24
|
+
delayMs: { value: { type: 'number' }, acceptsFallback: true },
|
|
25
|
+
enabled: { value: { type: 'boolean' }, acceptsFallback: true },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
props: {
|
|
29
|
+
sourceId: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
category: 'Measurement',
|
|
32
|
+
label: 'Source id',
|
|
33
|
+
authoring: { authority: 'instance' },
|
|
34
|
+
},
|
|
35
|
+
targetId: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
category: 'Measurement',
|
|
38
|
+
label: 'Target id',
|
|
39
|
+
authoring: { authority: 'instance' },
|
|
40
|
+
},
|
|
41
|
+
eventType: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
category: 'Measurement',
|
|
44
|
+
label: 'Event type',
|
|
45
|
+
default: 'game.measurement',
|
|
46
|
+
authoring: { authority: 'instance' },
|
|
47
|
+
},
|
|
48
|
+
entityId: {
|
|
49
|
+
type: 'string',
|
|
50
|
+
category: 'Measurement',
|
|
51
|
+
label: 'Game entity id',
|
|
52
|
+
authoring: { authority: 'instance' },
|
|
53
|
+
},
|
|
54
|
+
delayMs: {
|
|
55
|
+
type: 'number',
|
|
56
|
+
category: 'Measurement',
|
|
57
|
+
label: 'Delay (ms)',
|
|
58
|
+
default: 0,
|
|
59
|
+
authoring: { authority: 'instance' },
|
|
60
|
+
},
|
|
61
|
+
enabled: {
|
|
62
|
+
type: 'boolean',
|
|
63
|
+
category: 'State',
|
|
64
|
+
label: 'Enabled',
|
|
65
|
+
default: true,
|
|
66
|
+
authoring: { authority: 'instance' },
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=gameMeasurementProbeMeta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gameMeasurementProbeMeta.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameMeasurementProbeMeta.ts"],"names":[],"mappings":"AAEA,4FAA4F;AAC5F,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,IAAI,EAAE,sBAAsB;IAC5B,QAAQ,EAAE,WAAW;IACrB,WAAW,EACT,2GAA2G;IAC7G,kBAAkB,EAAE,IAAI;IACxB,eAAe,EAAE,EAAE;IACnB,SAAS,EAAE;QACT,KAAK,EAAE,wBAAwB;QAC/B,YAAY,EAAE;YACZ,QAAQ,EAAE,QAAQ;YAClB,QAAQ,EAAE,QAAQ;YAClB,SAAS,EAAE,kBAAkB;YAC7B,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,IAAI;SACd;KACF;IACD,QAAQ,EAAE;QACR,KAAK,EAAE;YACL,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;YAC9D,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;YAC9D,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;YAC/D,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;YAC9D,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;YAC7D,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;SAC/D;KACF;IACD,KAAK,EAAE;QACL,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,WAAW;YAClB,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,SAAS,EAAE;YACT,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE,kBAAkB;YAC3B,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,gBAAgB;YACvB,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,OAAO,EAAE;YACP,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,SAAS;YAChB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;KACF;CACmC,CAAC","sourcesContent":["import type { ZoraComponentMeta } from '@ankhorage/zora/metadata';\n\n/*** Describe a non-visual source/target geometry sampling adapter for one Game instance. */\nexport const gameMeasurementProbeMeta = {\n name: 'GameMeasurementProbe',\n category: 'component',\n description:\n 'Measures two registered game entities and reports their raw rendered bounds through a generic Game event.',\n directManifestNode: true,\n allowedChildren: [],\n blueprint: {\n label: 'Game measurement probe',\n defaultProps: {\n sourceId: 'source',\n targetId: 'target',\n eventType: 'game.measurement',\n delayMs: 0,\n enabled: true,\n },\n },\n bindings: {\n props: {\n sourceId: { value: { type: 'string' }, acceptsFallback: true },\n targetId: { value: { type: 'string' }, acceptsFallback: true },\n eventType: { value: { type: 'string' }, acceptsFallback: true },\n entityId: { value: { type: 'string' }, acceptsFallback: true },\n delayMs: { value: { type: 'number' }, acceptsFallback: true },\n enabled: { value: { type: 'boolean' }, acceptsFallback: true },\n },\n },\n props: {\n sourceId: {\n type: 'string',\n category: 'Measurement',\n label: 'Source id',\n authoring: { authority: 'instance' },\n },\n targetId: {\n type: 'string',\n category: 'Measurement',\n label: 'Target id',\n authoring: { authority: 'instance' },\n },\n eventType: {\n type: 'string',\n category: 'Measurement',\n label: 'Event type',\n default: 'game.measurement',\n authoring: { authority: 'instance' },\n },\n entityId: {\n type: 'string',\n category: 'Measurement',\n label: 'Game entity id',\n authoring: { authority: 'instance' },\n },\n delayMs: {\n type: 'number',\n category: 'Measurement',\n label: 'Delay (ms)',\n default: 0,\n authoring: { authority: 'instance' },\n },\n enabled: {\n type: 'boolean',\n category: 'State',\n label: 'Enabled',\n default: true,\n authoring: { authority: 'instance' },\n },\n },\n} as const satisfies ZoraComponentMeta;\n"]}
|
|
@@ -4,7 +4,7 @@ export declare const gameMeta: {
|
|
|
4
4
|
readonly category: "pattern";
|
|
5
5
|
readonly description: "Embeds one config-driven game session inside ordinary ZORA layout and emits domain-neutral game outputs.";
|
|
6
6
|
readonly directManifestNode: true;
|
|
7
|
-
readonly allowedChildren: readonly ["GameEntity", "GameInputZone", "GameOverlay", "Gradient", "Image", "View"];
|
|
7
|
+
readonly allowedChildren: readonly ["GameEntity", "GameInputZone", "GameMeasurementProbe", "GameOverlay", "Gradient", "Image", "View"];
|
|
8
8
|
readonly blueprint: {
|
|
9
9
|
readonly label: "Game";
|
|
10
10
|
readonly defaultProps: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gameMeta.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameMeta.ts"],"names":[],"mappings":"AAEA,oGAAoG;AACpG,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"gameMeta.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameMeta.ts"],"names":[],"mappings":"AAEA,oGAAoG;AACpG,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuGiB,CAAC"}
|
|
@@ -4,7 +4,15 @@ export const gameMeta = {
|
|
|
4
4
|
category: 'pattern',
|
|
5
5
|
description: 'Embeds one config-driven game session inside ordinary ZORA layout and emits domain-neutral game outputs.',
|
|
6
6
|
directManifestNode: true,
|
|
7
|
-
allowedChildren: [
|
|
7
|
+
allowedChildren: [
|
|
8
|
+
'GameEntity',
|
|
9
|
+
'GameInputZone',
|
|
10
|
+
'GameMeasurementProbe',
|
|
11
|
+
'GameOverlay',
|
|
12
|
+
'Gradient',
|
|
13
|
+
'Image',
|
|
14
|
+
'View',
|
|
15
|
+
],
|
|
8
16
|
blueprint: {
|
|
9
17
|
label: 'Game',
|
|
10
18
|
defaultProps: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gameMeta.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameMeta.ts"],"names":[],"mappings":"AAEA,oGAAoG;AACpG,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,SAAS;IACnB,WAAW,EACT,0GAA0G;IAC5G,kBAAkB,EAAE,IAAI;IACxB,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"gameMeta.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/meta/gameMeta.ts"],"names":[],"mappings":"AAEA,oGAAoG;AACpG,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,SAAS;IACnB,WAAW,EACT,0GAA0G;IAC5G,kBAAkB,EAAE,IAAI;IACxB,eAAe,EAAE;QACf,YAAY;QACZ,eAAe;QACf,sBAAsB;QACtB,aAAa;QACb,UAAU;QACV,OAAO;QACP,MAAM;KACP;IACD,SAAS,EAAE;QACT,KAAK,EAAE,MAAM;QACb,YAAY,EAAE;YACZ,UAAU,EAAE;gBACV,EAAE,EAAE,MAAM;gBACV,YAAY,EAAE,SAAS;gBACvB,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;gBACxB,KAAK,EAAE,EAAE;aACV;YACD,IAAI,EAAE,CAAC;YACP,QAAQ,EAAE,EAAE;YACZ,eAAe,EAAE,IAAI;YACrB,SAAS,EAAE,GAAG;YACd,IAAI,EAAE,IAAI;SACX;KACF;IACD,QAAQ,EAAE;QACR,KAAK,EAAE;YACL,UAAU,EAAE;gBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,eAAe,EAAE,IAAI;aACtB;YACD,KAAK,EAAE;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,eAAe,EAAE,IAAI;aACtB;SACF;KACF;IACD,MAAM,EAAE;QACN,MAAM,EAAE;YACN,KAAK,EAAE,aAAa;YACpB,SAAS,EAAE,aAAa;YACxB,WAAW,EAAE,+EAA+E;YAC5F,aAAa,EAAE;gBACb,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAChC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE;aACpC;SACF;KACF;IACD,KAAK,EAAE;QACL,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,cAAc;YACrB,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,eAAe,EAAE;YACf,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,2BAA2B;YAClC,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,cAAc;YACrB,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,SAAS,EAAE;YACT,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,gBAAgB;YACvB,OAAO,EAAE,GAAG;YACZ,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE,eAAe;YACtB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;QACD,kBAAkB,EAAE;YAClB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,eAAe;YACzB,KAAK,EAAE,qBAAqB;YAC5B,SAAS,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE;SACrC;KACF;CACmC,CAAC","sourcesContent":["import type { ZoraComponentMeta } from '@ankhorage/zora/metadata';\n\n/*** Describe the embeddable config-driven Game runtime/presentation boundary for ZORA authoring. */\nexport const gameMeta = {\n name: 'Game',\n category: 'pattern',\n description:\n 'Embeds one config-driven game session inside ordinary ZORA layout and emits domain-neutral game outputs.',\n directManifestNode: true,\n allowedChildren: [\n 'GameEntity',\n 'GameInputZone',\n 'GameMeasurementProbe',\n 'GameOverlay',\n 'Gradient',\n 'Image',\n 'View',\n ],\n blueprint: {\n label: 'Game',\n defaultProps: {\n definition: {\n id: 'game',\n initialPhase: 'playing',\n stages: [{ id: 'main' }],\n rules: [],\n },\n seed: 0,\n resetKey: '',\n autoAdvanceTime: true,\n minHeight: 320,\n clip: true,\n },\n },\n bindings: {\n props: {\n definition: {\n value: { type: 'object' },\n acceptsFallback: true,\n },\n input: {\n value: { type: 'record' },\n acceptsFallback: true,\n },\n },\n },\n events: {\n output: {\n label: 'Game output',\n eventType: 'game.output',\n description: 'Emitted when the platform-neutral game runtime produces an app/domain output.',\n payloadFields: [\n { path: 'type', type: 'string' },\n { path: 'payload', type: 'record' },\n ],\n },\n },\n props: {\n seed: {\n type: 'number',\n category: 'Runtime',\n label: 'Initial seed',\n default: 0,\n authoring: { authority: 'instance' },\n },\n resetKey: {\n type: 'string',\n category: 'Runtime',\n label: 'Reset key',\n default: '',\n authoring: { authority: 'instance' },\n },\n autoAdvanceTime: {\n type: 'boolean',\n category: 'Runtime',\n label: 'Advance scheduled effects',\n default: true,\n authoring: { authority: 'instance' },\n },\n aspectRatio: {\n type: 'number',\n category: 'Layout',\n label: 'Aspect ratio',\n authoring: { authority: 'instance' },\n },\n minHeight: {\n type: 'number',\n category: 'Layout',\n label: 'Minimum height',\n default: 320,\n authoring: { authority: 'instance' },\n },\n clip: {\n type: 'boolean',\n category: 'Layout',\n label: 'Clip overflow',\n default: true,\n authoring: { authority: 'instance' },\n },\n accessibilityLabel: {\n type: 'string',\n category: 'Accessibility',\n label: 'Accessibility label',\n authoring: { authority: 'instance' },\n },\n },\n} as const satisfies ZoraComponentMeta;\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export type { GameEntityProps, GameFieldProps, GameInputZoneProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from '../../types/gamePresentation';
|
|
1
|
+
export type { GameEntityProps, GameFieldProps, GameInputZoneProps, GameKeyboardBinding, GameMeasurementProbeProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from '../../types/gamePresentation';
|
|
2
2
|
export { Game } from './adapters/inbound/Game';
|
|
3
3
|
export { GameEntity } from './adapters/inbound/GameEntity';
|
|
4
4
|
export { GameField } from './adapters/inbound/GameField';
|
|
5
5
|
export { GameInputZone } from './adapters/inbound/GameInputZone';
|
|
6
|
+
export { GameMeasurementProbe } from './adapters/inbound/GameMeasurementProbe';
|
|
6
7
|
export { GameOverlay } from './adapters/inbound/GameOverlay';
|
|
7
8
|
//# sourceMappingURL=public.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -2,5 +2,6 @@ export { Game } from './adapters/inbound/Game';
|
|
|
2
2
|
export { GameEntity } from './adapters/inbound/GameEntity';
|
|
3
3
|
export { GameField } from './adapters/inbound/GameField';
|
|
4
4
|
export { GameInputZone } from './adapters/inbound/GameInputZone';
|
|
5
|
+
export { GameMeasurementProbe } from './adapters/inbound/GameMeasurementProbe';
|
|
5
6
|
export { GameOverlay } from './adapters/inbound/GameOverlay';
|
|
6
7
|
//# sourceMappingURL=public.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC","sourcesContent":["export type {\n GameEntityProps,\n GameFieldProps,\n GameInputZoneProps,\n GameKeyboardBinding,\n GameMeasurementProbeProps,\n GameOverlayPlacement,\n GameOverlayProps,\n GamePointerEvents,\n GameProps,\n} from '../../types/gamePresentation';\nexport { Game } from './adapters/inbound/Game';\nexport { GameEntity } from './adapters/inbound/GameEntity';\nexport { GameField } from './adapters/inbound/GameField';\nexport { GameInputZone } from './adapters/inbound/GameInputZone';\nexport { GameMeasurementProbe } from './adapters/inbound/GameMeasurementProbe';\nexport { GameOverlay } from './adapters/inbound/GameOverlay';\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { GameEntityProps, GameFieldProps, GameInputZoneProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from './features/game-presentation/public';
|
|
2
|
-
export { Game, GameEntity, GameField, GameInputZone, GameOverlay, } from './features/game-presentation/public';
|
|
1
|
+
export type { GameEntityProps, GameFieldProps, GameInputZoneProps, GameKeyboardBinding, GameMeasurementProbeProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from './features/game-presentation/public';
|
|
2
|
+
export { Game, GameEntity, GameField, GameInputZone, GameMeasurementProbe, GameOverlay, } from './features/game-presentation/public';
|
|
3
3
|
export { ZORA_GAME_PLUGIN } from './ZORA_GAME_PLUGIN';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,aAAa,EACb,WAAW,GACZ,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,WAAW,GACZ,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Game, GameEntity, GameField, GameInputZone, GameOverlay, } from './features/game-presentation/public';
|
|
1
|
+
export { Game, GameEntity, GameField, GameInputZone, GameMeasurementProbe, GameOverlay, } from './features/game-presentation/public';
|
|
2
2
|
export { ZORA_GAME_PLUGIN } from './ZORA_GAME_PLUGIN';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,IAAI,EACJ,UAAU,EACV,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,WAAW,GACZ,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export type {\n GameEntityProps,\n GameFieldProps,\n GameInputZoneProps,\n GameKeyboardBinding,\n GameMeasurementProbeProps,\n GameOverlayPlacement,\n GameOverlayProps,\n GamePointerEvents,\n GameProps,\n} from './features/game-presentation/public';\nexport {\n Game,\n GameEntity,\n GameField,\n GameInputZone,\n GameMeasurementProbe,\n GameOverlay,\n} from './features/game-presentation/public';\nexport { ZORA_GAME_PLUGIN } from './ZORA_GAME_PLUGIN';\n"]}
|
|
@@ -23,9 +23,16 @@ export interface GameEntityProps {
|
|
|
23
23
|
readonly zIndex?: number;
|
|
24
24
|
readonly hidden?: boolean;
|
|
25
25
|
readonly pointerEvents?: GamePointerEvents;
|
|
26
|
+
readonly measurementId?: string;
|
|
26
27
|
readonly accessibilityLabel?: string;
|
|
27
28
|
readonly testID?: string;
|
|
28
29
|
}
|
|
30
|
+
export interface GameKeyboardBinding {
|
|
31
|
+
readonly key: string;
|
|
32
|
+
readonly eventType?: string;
|
|
33
|
+
readonly entityId?: string;
|
|
34
|
+
readonly preventDefault?: boolean;
|
|
35
|
+
}
|
|
29
36
|
export interface GameInputZoneProps {
|
|
30
37
|
readonly eventType: string;
|
|
31
38
|
readonly entityId?: string;
|
|
@@ -36,9 +43,18 @@ export interface GameInputZoneProps {
|
|
|
36
43
|
readonly zIndex?: number;
|
|
37
44
|
readonly enabled?: boolean;
|
|
38
45
|
readonly continuous?: boolean;
|
|
46
|
+
readonly keyboardBindings?: readonly GameKeyboardBinding[];
|
|
39
47
|
readonly accessibilityLabel?: string;
|
|
40
48
|
readonly testID?: string;
|
|
41
49
|
}
|
|
50
|
+
export interface GameMeasurementProbeProps {
|
|
51
|
+
readonly sourceId: string;
|
|
52
|
+
readonly targetId: string;
|
|
53
|
+
readonly eventType?: string;
|
|
54
|
+
readonly entityId?: string;
|
|
55
|
+
readonly delayMs?: number;
|
|
56
|
+
readonly enabled?: boolean;
|
|
57
|
+
}
|
|
42
58
|
export interface GameOverlayProps {
|
|
43
59
|
readonly children?: React.ReactNode;
|
|
44
60
|
readonly placement?: GameOverlayPlacement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gamePresentation.d.ts","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gamePresentation.d.ts","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gamePresentation.js","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"","sourcesContent":["import type { GameDefinition, GameInput, GameOutput } from '@ankhorage/game';\nimport type React from 'react';\n\ntype GameOverlayCornerPlacement = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\nexport type GamePointerEvents = 'auto' | 'box-none' | 'box-only' | 'none';\nexport type GameOverlayPlacement =\n 'fill' | 'center' | 'top' | 'bottom' | GameOverlayCornerPlacement;\n\nexport interface GameFieldProps {\n readonly children?: React.ReactNode;\n readonly aspectRatio?: number;\n readonly minHeight?: number;\n readonly clip?: boolean;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameEntityProps {\n readonly children?: React.ReactNode;\n readonly x?: number;\n readonly y?: number;\n readonly width?: number;\n readonly height?: number;\n readonly opacity?: number;\n readonly scale?: number;\n readonly rotation?: number;\n readonly zIndex?: number;\n readonly hidden?: boolean;\n readonly pointerEvents?: GamePointerEvents;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameInputZoneProps {\n readonly eventType: string;\n readonly entityId?: string;\n readonly x?: number;\n readonly y?: number;\n readonly width?: number;\n readonly height?: number;\n readonly zIndex?: number;\n readonly enabled?: boolean;\n readonly continuous?: boolean;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameOverlayProps {\n readonly children?: React.ReactNode;\n readonly placement?: GameOverlayPlacement;\n readonly blocking?: boolean;\n readonly padding?: number;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameProps extends GameFieldProps {\n readonly definition: GameDefinition;\n readonly input?: GameInput;\n readonly seed?: number;\n readonly resetKey?: string;\n readonly autoAdvanceTime?: boolean;\n readonly onOutput?: (output: GameOutput) => void;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"gamePresentation.js","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"","sourcesContent":["import type { GameDefinition, GameInput, GameOutput } from '@ankhorage/game';\nimport type React from 'react';\n\ntype GameOverlayCornerPlacement = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\nexport type GamePointerEvents = 'auto' | 'box-none' | 'box-only' | 'none';\nexport type GameOverlayPlacement =\n 'fill' | 'center' | 'top' | 'bottom' | GameOverlayCornerPlacement;\n\nexport interface GameFieldProps {\n readonly children?: React.ReactNode;\n readonly aspectRatio?: number;\n readonly minHeight?: number;\n readonly clip?: boolean;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameEntityProps {\n readonly children?: React.ReactNode;\n readonly x?: number;\n readonly y?: number;\n readonly width?: number;\n readonly height?: number;\n readonly opacity?: number;\n readonly scale?: number;\n readonly rotation?: number;\n readonly zIndex?: number;\n readonly hidden?: boolean;\n readonly pointerEvents?: GamePointerEvents;\n readonly measurementId?: string;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameKeyboardBinding {\n readonly key: string;\n readonly eventType?: string;\n readonly entityId?: string;\n readonly preventDefault?: boolean;\n}\n\nexport interface GameInputZoneProps {\n readonly eventType: string;\n readonly entityId?: string;\n readonly x?: number;\n readonly y?: number;\n readonly width?: number;\n readonly height?: number;\n readonly zIndex?: number;\n readonly enabled?: boolean;\n readonly continuous?: boolean;\n readonly keyboardBindings?: readonly GameKeyboardBinding[];\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameMeasurementProbeProps {\n readonly sourceId: string;\n readonly targetId: string;\n readonly eventType?: string;\n readonly entityId?: string;\n readonly delayMs?: number;\n readonly enabled?: boolean;\n}\n\nexport interface GameOverlayProps {\n readonly children?: React.ReactNode;\n readonly placement?: GameOverlayPlacement;\n readonly blocking?: boolean;\n readonly padding?: number;\n readonly accessibilityLabel?: string;\n readonly testID?: string;\n}\n\nexport interface GameProps extends GameFieldProps {\n readonly definition: GameDefinition;\n readonly input?: GameInput;\n readonly seed?: number;\n readonly resetKey?: string;\n readonly autoAdvanceTime?: boolean;\n readonly onOutput?: (output: GameOutput) => void;\n}\n"]}
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import type { GameEvent, GameOutput, GameSession } from '@ankhorage/game';
|
|
2
|
-
export interface
|
|
2
|
+
export interface GameMeasurementBounds {
|
|
3
|
+
readonly left: number;
|
|
4
|
+
readonly right: number;
|
|
5
|
+
readonly top: number;
|
|
6
|
+
readonly bottom: number;
|
|
7
|
+
readonly width: number;
|
|
8
|
+
readonly height: number;
|
|
9
|
+
}
|
|
10
|
+
export type GameMeasurementReader = () => Promise<GameMeasurementBounds | undefined>;
|
|
11
|
+
export interface GameMeasurementRegistry {
|
|
12
|
+
readonly registerMeasurement: (id: string, reader: GameMeasurementReader) => () => void;
|
|
13
|
+
readonly measure: (id: string) => Promise<GameMeasurementBounds | undefined>;
|
|
14
|
+
}
|
|
15
|
+
export interface GameRuntimeValue {
|
|
3
16
|
readonly session: GameSession;
|
|
4
17
|
readonly dispatch: (event: GameEvent) => void;
|
|
5
18
|
}
|
|
19
|
+
export interface GameRuntimeContextValue extends GameRuntimeValue, GameMeasurementRegistry {
|
|
20
|
+
}
|
|
6
21
|
export interface GameRuntimeState {
|
|
7
22
|
readonly key: string;
|
|
8
23
|
readonly session: GameSession;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gameRuntime.d.ts","sourceRoot":"","sources":["../../src/types/gameRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE1E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B"}
|
|
1
|
+
{"version":3,"file":"gameRuntime.d.ts","sourceRoot":"","sources":["../../src/types/gameRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE1E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,qBAAqB,GAAG,MAAM,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAAC;AAErF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,KAAK,MAAM,IAAI,CAAC;IACxF,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAAC,CAAC;CAC9E;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB,EAAE,uBAAuB;CAAG;AAE7F,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gameRuntime.js","sourceRoot":"","sources":["../../src/types/gameRuntime.ts"],"names":[],"mappings":"","sourcesContent":["import type { GameEvent, GameOutput, GameSession } from '@ankhorage/game';\n\nexport interface
|
|
1
|
+
{"version":3,"file":"gameRuntime.js","sourceRoot":"","sources":["../../src/types/gameRuntime.ts"],"names":[],"mappings":"","sourcesContent":["import type { GameEvent, GameOutput, GameSession } from '@ankhorage/game';\n\nexport interface GameMeasurementBounds {\n readonly left: number;\n readonly right: number;\n readonly top: number;\n readonly bottom: number;\n readonly width: number;\n readonly height: number;\n}\n\nexport type GameMeasurementReader = () => Promise<GameMeasurementBounds | undefined>;\n\nexport interface GameMeasurementRegistry {\n readonly registerMeasurement: (id: string, reader: GameMeasurementReader) => () => void;\n readonly measure: (id: string) => Promise<GameMeasurementBounds | undefined>;\n}\n\nexport interface GameRuntimeValue {\n readonly session: GameSession;\n readonly dispatch: (event: GameEvent) => void;\n}\n\nexport interface GameRuntimeContextValue extends GameRuntimeValue, GameMeasurementRegistry {}\n\nexport interface GameRuntimeState {\n readonly key: string;\n readonly session: GameSession;\n readonly outputs: readonly GameOutput[];\n readonly revision: number;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora-game",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Generic game presentation primitives for React Native and React Native Web apps built on ZORA.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/zora-game#readme",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { gameEntityMeta } from './features/game-presentation/meta/gameEntityMeta';
|
|
2
2
|
import { gameFieldMeta } from './features/game-presentation/meta/gameFieldMeta';
|
|
3
3
|
import { gameInputZoneMeta } from './features/game-presentation/meta/gameInputZoneMeta';
|
|
4
|
+
import { gameMeasurementProbeMeta } from './features/game-presentation/meta/gameMeasurementProbeMeta';
|
|
4
5
|
import { gameMeta } from './features/game-presentation/meta/gameMeta';
|
|
5
6
|
import { gameOverlayMeta } from './features/game-presentation/meta/gameOverlayMeta';
|
|
6
7
|
|
|
@@ -10,5 +11,6 @@ export const ZORA_GAME_COMPONENT_META = {
|
|
|
10
11
|
GameEntity: gameEntityMeta,
|
|
11
12
|
GameField: gameFieldMeta,
|
|
12
13
|
GameInputZone: gameInputZoneMeta,
|
|
14
|
+
GameMeasurementProbe: gameMeasurementProbeMeta,
|
|
13
15
|
GameOverlay: gameOverlayMeta,
|
|
14
16
|
} as const;
|
package/src/ZORA_GAME_PLUGIN.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Game } from './features/game-presentation/adapters/inbound/Game';
|
|
|
2
2
|
import { GameEntity } from './features/game-presentation/adapters/inbound/GameEntity';
|
|
3
3
|
import { GameField } from './features/game-presentation/adapters/inbound/GameField';
|
|
4
4
|
import { GameInputZone } from './features/game-presentation/adapters/inbound/GameInputZone';
|
|
5
|
+
import { GameMeasurementProbe } from './features/game-presentation/adapters/inbound/GameMeasurementProbe';
|
|
5
6
|
import { GameOverlay } from './features/game-presentation/adapters/inbound/GameOverlay';
|
|
6
7
|
import { ZORA_PLUGIN_METADATA } from './ZORA_PLUGIN_METADATA';
|
|
7
8
|
|
|
@@ -13,6 +14,7 @@ export const ZORA_GAME_PLUGIN = {
|
|
|
13
14
|
GameEntity,
|
|
14
15
|
GameField,
|
|
15
16
|
GameInputZone,
|
|
17
|
+
GameMeasurementProbe,
|
|
16
18
|
GameOverlay,
|
|
17
19
|
},
|
|
18
20
|
} as const;
|
|
@@ -19,19 +19,10 @@ describe('ZORA game plugin metadata', () => {
|
|
|
19
19
|
expect(gameField.allowedChildren).toContain('GameOverlay');
|
|
20
20
|
expect(game.allowedChildren).toContain('GameEntity');
|
|
21
21
|
expect(game.allowedChildren).toContain('GameInputZone');
|
|
22
|
+
expect(game.allowedChildren).toContain('GameMeasurementProbe');
|
|
22
23
|
expect(game.allowedChildren).toContain('GameOverlay');
|
|
23
24
|
});
|
|
24
25
|
|
|
25
|
-
test('keeps Game input zones scoped to runtime-owning Game parents', () => {
|
|
26
|
-
const catalog = composeZoraPluginMetadata([ZORA_CORE_PLUGIN_METADATA, ZORA_PLUGIN_METADATA]);
|
|
27
|
-
const gameInputZone = readComponentMeta(catalog.componentMeta.GameInputZone, 'GameInputZone');
|
|
28
|
-
|
|
29
|
-
expect(gameInputZone.props.eventType?.type).toBe('string');
|
|
30
|
-
expect(gameInputZone.props.continuous?.type).toBe('boolean');
|
|
31
|
-
expect(catalog.componentMeta.Game?.allowedChildren).toContain('GameInputZone');
|
|
32
|
-
expect(catalog.componentMeta.GameField?.allowedChildren).not.toContain('GameInputZone');
|
|
33
|
-
});
|
|
34
|
-
|
|
35
26
|
test('describes bindable Game inputs and domain-neutral outputs', () => {
|
|
36
27
|
const catalog = composeZoraPluginMetadata([ZORA_CORE_PLUGIN_METADATA, ZORA_PLUGIN_METADATA]);
|
|
37
28
|
const game = readComponentMeta(catalog.componentMeta.Game, 'Game');
|
|
@@ -48,6 +39,7 @@ describe('ZORA game plugin metadata', () => {
|
|
|
48
39
|
expect(gameEntity.bindings?.props?.x?.value.type).toBe('number');
|
|
49
40
|
expect(gameEntity.bindings?.props?.y?.value.type).toBe('number');
|
|
50
41
|
expect(gameEntity.bindings?.props?.hidden?.value.type).toBe('boolean');
|
|
42
|
+
expect(gameEntity.bindings?.props?.measurementId?.value.type).toBe('string');
|
|
51
43
|
});
|
|
52
44
|
|
|
53
45
|
test('keeps the generic presentation vocabulary free of product-specific concepts', () => {
|
|
@@ -60,6 +52,41 @@ describe('ZORA game plugin metadata', () => {
|
|
|
60
52
|
});
|
|
61
53
|
});
|
|
62
54
|
|
|
55
|
+
describe('ZORA game measurement metadata', () => {
|
|
56
|
+
test('keeps measurement probes scoped to runtime-owning Game parents', () => {
|
|
57
|
+
const catalog = composeZoraPluginMetadata([ZORA_CORE_PLUGIN_METADATA, ZORA_PLUGIN_METADATA]);
|
|
58
|
+
const probe = readComponentMeta(
|
|
59
|
+
catalog.componentMeta.GameMeasurementProbe,
|
|
60
|
+
'GameMeasurementProbe',
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
expect(probe.props.sourceId?.type).toBe('string');
|
|
64
|
+
expect(probe.props.targetId?.type).toBe('string');
|
|
65
|
+
expect(probe.props.delayMs?.type).toBe('number');
|
|
66
|
+
expect(catalog.componentMeta.Game?.allowedChildren).toContain('GameMeasurementProbe');
|
|
67
|
+
expect(catalog.componentMeta.GameField?.allowedChildren).not.toContain('GameMeasurementProbe');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('ZORA game input zone metadata', () => {
|
|
72
|
+
test('keeps input zones scoped to runtime-owning Game parents', () => {
|
|
73
|
+
const catalog = composeZoraPluginMetadata([ZORA_CORE_PLUGIN_METADATA, ZORA_PLUGIN_METADATA]);
|
|
74
|
+
const gameInputZone = readComponentMeta(catalog.componentMeta.GameInputZone, 'GameInputZone');
|
|
75
|
+
|
|
76
|
+
expect(gameInputZone.props.eventType?.type).toBe('string');
|
|
77
|
+
expect(gameInputZone.props.continuous?.type).toBe('boolean');
|
|
78
|
+
expect(gameInputZone.props.keyboardBindings?.type).toBe('array');
|
|
79
|
+
expect(gameInputZone.props.keyboardBindings?.itemSchema?.map(({ key }) => key)).toEqual([
|
|
80
|
+
'key',
|
|
81
|
+
'eventType',
|
|
82
|
+
'entityId',
|
|
83
|
+
'preventDefault',
|
|
84
|
+
]);
|
|
85
|
+
expect(catalog.componentMeta.Game?.allowedChildren).toContain('GameInputZone');
|
|
86
|
+
expect(catalog.componentMeta.GameField?.allowedChildren).not.toContain('GameInputZone');
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
63
90
|
/*** Require one composed component metadata entry for focused assertions. */
|
|
64
91
|
function readComponentMeta<TValue>(value: TValue | undefined, name: string): TValue {
|
|
65
92
|
if (value === undefined) throw new Error(`Missing composed component metadata for ${name}.`);
|
|
@@ -3,6 +3,7 @@ import React from 'react';
|
|
|
3
3
|
|
|
4
4
|
import type { GameProps } from '../../../../types/gamePresentation';
|
|
5
5
|
import { createGameBindingContext } from '../../composition/createGameBindingContext';
|
|
6
|
+
import { createGameMeasurementRegistry } from '../../composition/createGameMeasurementRegistry';
|
|
6
7
|
import { GameRuntimeContext } from '../../composition/GameRuntimeContext';
|
|
7
8
|
import { useGameRuntime } from '../../composition/useGameRuntime';
|
|
8
9
|
import { GameField } from './GameField';
|
|
@@ -10,13 +11,18 @@ import { GameField } from './GameField';
|
|
|
10
11
|
/*** Bind one serializable game definition to a local transient session and presentation field. */
|
|
11
12
|
export function Game(props: GameProps) {
|
|
12
13
|
const runtime = useGameRuntime(props);
|
|
14
|
+
const [measurementRegistry] = React.useState(createGameMeasurementRegistry);
|
|
15
|
+
const runtimeContext = React.useMemo(
|
|
16
|
+
() => ({ ...runtime, ...measurementRegistry }),
|
|
17
|
+
[measurementRegistry, runtime],
|
|
18
|
+
);
|
|
13
19
|
const runtimeBindingConfig = React.useMemo(
|
|
14
20
|
() => ({ bindingContext: createGameBindingContext(runtime.session) }),
|
|
15
21
|
[runtime.session],
|
|
16
22
|
);
|
|
17
23
|
|
|
18
24
|
return (
|
|
19
|
-
<GameRuntimeContext.Provider value={
|
|
25
|
+
<GameRuntimeContext.Provider value={runtimeContext}>
|
|
20
26
|
<RuntimeRendererConfigProvider value={runtimeBindingConfig}>
|
|
21
27
|
<GameField
|
|
22
28
|
{...(props.aspectRatio === undefined ? {} : { aspectRatio: props.aspectRatio })}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { StyleSheet, type ViewStyle } from 'react-native';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleSheet, View, type ViewStyle } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import type { GameEntityProps } from '../../../../types/gamePresentation';
|
|
5
|
+
import { GameRuntimeContext } from '../../composition/GameRuntimeContext';
|
|
5
6
|
import { toGamePercentage } from '../../utils/toGamePercentage';
|
|
7
|
+
import { measureGameEntity } from './measureGameEntity';
|
|
6
8
|
|
|
7
9
|
/*** Render one generic positioned game entity without owning gameplay semantics. */
|
|
8
10
|
export function GameEntity({
|
|
@@ -17,11 +19,22 @@ export function GameEntity({
|
|
|
17
19
|
zIndex = 0,
|
|
18
20
|
hidden = false,
|
|
19
21
|
pointerEvents = 'auto',
|
|
22
|
+
measurementId,
|
|
20
23
|
accessibilityLabel,
|
|
21
24
|
testID,
|
|
22
25
|
}: GameEntityProps) {
|
|
26
|
+
const elementRef = React.useRef<View | null>(null);
|
|
27
|
+
const runtime = React.useContext(GameRuntimeContext);
|
|
28
|
+
const registerMeasurement = runtime?.registerMeasurement;
|
|
29
|
+
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
if (measurementId === undefined || registerMeasurement === undefined) return undefined;
|
|
32
|
+
return registerMeasurement(measurementId, () => measureGameEntity(elementRef.current));
|
|
33
|
+
}, [measurementId, registerMeasurement]);
|
|
34
|
+
|
|
23
35
|
return (
|
|
24
36
|
<View
|
|
37
|
+
ref={elementRef}
|
|
25
38
|
{...(accessibilityLabel === undefined ? {} : { accessibilityLabel })}
|
|
26
39
|
{...(testID === undefined ? {} : { testID })}
|
|
27
40
|
pointerEvents={pointerEvents}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { StyleSheet, View, type ViewStyle } from 'react-native';
|
|
1
|
+
import { Platform, StyleSheet, View, type ViewStyle } from 'react-native';
|
|
2
2
|
|
|
3
3
|
import type { GameInputZoneProps } from '../../../../types/gamePresentation';
|
|
4
4
|
import { toGamePercentage } from '../../utils/toGamePercentage';
|
|
5
5
|
import { useGameInputZoneResponder } from './useGameInputZoneResponder';
|
|
6
6
|
|
|
7
|
-
/*** Capture pointer/touch geometry and
|
|
7
|
+
/*** Capture pointer/touch geometry and optional keyboard input as normalized generic Game events. */
|
|
8
8
|
export function GameInputZone({
|
|
9
9
|
x = 0,
|
|
10
10
|
y = 0,
|
|
@@ -13,22 +13,31 @@ export function GameInputZone({
|
|
|
13
13
|
zIndex = 0,
|
|
14
14
|
enabled = true,
|
|
15
15
|
continuous = true,
|
|
16
|
+
keyboardBindings,
|
|
16
17
|
accessibilityLabel,
|
|
17
18
|
testID,
|
|
18
19
|
...inputProps
|
|
19
20
|
}: GameInputZoneProps) {
|
|
20
|
-
const { dispatchPointer, handleLayout, shouldSetResponder } =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
const { dispatchKeyboard, dispatchPointer, handleLayout, shouldSetResponder } =
|
|
22
|
+
useGameInputZoneResponder({
|
|
23
|
+
...inputProps,
|
|
24
|
+
x,
|
|
25
|
+
y,
|
|
26
|
+
width,
|
|
27
|
+
height,
|
|
28
|
+
enabled,
|
|
29
|
+
continuous,
|
|
30
|
+
...(keyboardBindings === undefined ? {} : { keyboardBindings }),
|
|
31
|
+
});
|
|
32
|
+
const keyboardProps = createGameInputZoneKeyboardProps({
|
|
33
|
+
dispatchKeyboard,
|
|
26
34
|
enabled,
|
|
27
|
-
|
|
35
|
+
keyboardBindings,
|
|
28
36
|
});
|
|
29
37
|
|
|
30
38
|
return (
|
|
31
39
|
<View
|
|
40
|
+
{...keyboardProps}
|
|
32
41
|
{...(accessibilityLabel === undefined ? {} : { accessibilityLabel })}
|
|
33
42
|
{...(testID === undefined ? {} : { testID })}
|
|
34
43
|
{...(continuous
|
|
@@ -43,6 +52,24 @@ export function GameInputZone({
|
|
|
43
52
|
);
|
|
44
53
|
}
|
|
45
54
|
|
|
55
|
+
interface GameInputZoneKeyboardPropsInput {
|
|
56
|
+
readonly dispatchKeyboard: (event: { readonly key: string; preventDefault(): void }) => void;
|
|
57
|
+
readonly enabled: boolean;
|
|
58
|
+
readonly keyboardBindings: GameInputZoneProps['keyboardBindings'];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/*** Add a focusable web keyboard target only when the input zone owns key bindings. */
|
|
62
|
+
function createGameInputZoneKeyboardProps({
|
|
63
|
+
dispatchKeyboard,
|
|
64
|
+
enabled,
|
|
65
|
+
keyboardBindings,
|
|
66
|
+
}: GameInputZoneKeyboardPropsInput) {
|
|
67
|
+
if (Platform.OS !== 'web' || !enabled || keyboardBindings === undefined) return {};
|
|
68
|
+
if (keyboardBindings.length === 0) return {};
|
|
69
|
+
|
|
70
|
+
return { onKeyDown: dispatchKeyboard, tabIndex: 0 as const };
|
|
71
|
+
}
|
|
72
|
+
|
|
46
73
|
interface InputZoneStyleInput {
|
|
47
74
|
readonly x: number;
|
|
48
75
|
readonly y: number;
|