@ankhorage/zora-game 0.1.0 → 0.2.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.
Files changed (63) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +2 -1
  3. package/dist/ZORA_GAME_COMPONENT_META.d.ts +118 -0
  4. package/dist/ZORA_GAME_COMPONENT_META.d.ts.map +1 -1
  5. package/dist/ZORA_GAME_COMPONENT_META.js +2 -0
  6. package/dist/ZORA_GAME_COMPONENT_META.js.map +1 -1
  7. package/dist/ZORA_GAME_PLUGIN.d.ts +126 -3
  8. package/dist/ZORA_GAME_PLUGIN.d.ts.map +1 -1
  9. package/dist/ZORA_GAME_PLUGIN.js +2 -0
  10. package/dist/ZORA_GAME_PLUGIN.js.map +1 -1
  11. package/dist/ZORA_PLUGIN_METADATA.d.ts +124 -3
  12. package/dist/ZORA_PLUGIN_METADATA.d.ts.map +1 -1
  13. package/dist/ZORA_PLUGIN_METADATA.js +7 -3
  14. package/dist/ZORA_PLUGIN_METADATA.js.map +1 -1
  15. package/dist/features/game-presentation/adapters/inbound/Game.d.ts +5 -0
  16. package/dist/features/game-presentation/adapters/inbound/Game.d.ts.map +1 -0
  17. package/dist/features/game-presentation/adapters/inbound/Game.js +16 -0
  18. package/dist/features/game-presentation/adapters/inbound/Game.js.map +1 -0
  19. package/dist/features/game-presentation/composition/GameRuntimeContext.d.ts +5 -0
  20. package/dist/features/game-presentation/composition/GameRuntimeContext.d.ts.map +1 -0
  21. package/dist/features/game-presentation/composition/GameRuntimeContext.js +4 -0
  22. package/dist/features/game-presentation/composition/GameRuntimeContext.js.map +1 -0
  23. package/dist/features/game-presentation/composition/useGameRuntime.d.ts +5 -0
  24. package/dist/features/game-presentation/composition/useGameRuntime.d.ts.map +1 -0
  25. package/dist/features/game-presentation/composition/useGameRuntime.js +103 -0
  26. package/dist/features/game-presentation/composition/useGameRuntime.js.map +1 -0
  27. package/dist/features/game-presentation/composition/useGameScheduledEffects.d.ts +17 -0
  28. package/dist/features/game-presentation/composition/useGameScheduledEffects.d.ts.map +1 -0
  29. package/dist/features/game-presentation/composition/useGameScheduledEffects.js +40 -0
  30. package/dist/features/game-presentation/composition/useGameScheduledEffects.js.map +1 -0
  31. package/dist/features/game-presentation/meta/gameMeta.d.ts +120 -0
  32. package/dist/features/game-presentation/meta/gameMeta.d.ts.map +1 -0
  33. package/dist/features/game-presentation/meta/gameMeta.js +97 -0
  34. package/dist/features/game-presentation/meta/gameMeta.js.map +1 -0
  35. package/dist/features/game-presentation/public.d.ts +2 -1
  36. package/dist/features/game-presentation/public.d.ts.map +1 -1
  37. package/dist/features/game-presentation/public.js +1 -0
  38. package/dist/features/game-presentation/public.js.map +1 -1
  39. package/dist/index.d.ts +2 -2
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +1 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/types/gamePresentation.d.ts +9 -0
  44. package/dist/types/gamePresentation.d.ts.map +1 -1
  45. package/dist/types/gamePresentation.js.map +1 -1
  46. package/dist/types/gameRuntime.d.ts +12 -0
  47. package/dist/types/gameRuntime.d.ts.map +1 -0
  48. package/dist/types/gameRuntime.js +2 -0
  49. package/dist/types/gameRuntime.js.map +1 -0
  50. package/package.json +5 -2
  51. package/src/ZORA_GAME_COMPONENT_META.ts +2 -0
  52. package/src/ZORA_GAME_PLUGIN.ts +2 -0
  53. package/src/ZORA_PLUGIN_METADATA.test.ts +28 -5
  54. package/src/ZORA_PLUGIN_METADATA.ts +7 -3
  55. package/src/features/game-presentation/adapters/inbound/Game.tsx +27 -0
  56. package/src/features/game-presentation/composition/GameRuntimeContext.ts +6 -0
  57. package/src/features/game-presentation/composition/useGameRuntime.ts +181 -0
  58. package/src/features/game-presentation/composition/useGameScheduledEffects.ts +85 -0
  59. package/src/features/game-presentation/meta/gameMeta.ts +99 -0
  60. package/src/features/game-presentation/public.ts +2 -0
  61. package/src/index.ts +2 -1
  62. package/src/types/gamePresentation.ts +10 -0
  63. package/src/types/gameRuntime.ts +13 -0
@@ -0,0 +1,103 @@
1
+ import { advanceGameTime, applyGameEvent, createGameSession, } from '@ankhorage/game';
2
+ import React from 'react';
3
+ import { useGameScheduledEffects } from './useGameScheduledEffects';
4
+ const EMPTY_GAME_INPUT = {};
5
+ /*** Own one local transient Game session while delegating all domain transitions to @ankhorage/game. */
6
+ export function useGameRuntime(props) {
7
+ const { definition, input = EMPTY_GAME_INPUT, seed = 0, resetKey = '' } = props;
8
+ const definitionRef = useLatestValue(definition);
9
+ const inputRef = useLatestValue(input);
10
+ const outputRef = useLatestValue(props.onOutput);
11
+ const autoAdvanceTime = props.autoAdvanceTime ?? true;
12
+ const clockRef = React.useRef(0);
13
+ const runtimeKey = createRuntimeKey(definition.id, resetKey, seed);
14
+ const [runtime, setRuntime] = React.useState(() => createRuntimeState(definition, input, seed, runtimeKey, 0));
15
+ useGameRuntimeReset({
16
+ clockRef,
17
+ definitionRef,
18
+ inputRef,
19
+ runtimeKey,
20
+ seed,
21
+ setRuntime,
22
+ });
23
+ useGameOutputEmitter(runtime, outputRef);
24
+ const dispatch = React.useCallback((event) => {
25
+ const now = Date.now();
26
+ setRuntime((current) => applyRuntimeEvent({
27
+ autoAdvanceTime,
28
+ current,
29
+ definition: definitionRef.current,
30
+ elapsedMs: Math.max(0, now - clockRef.current),
31
+ event,
32
+ input: inputRef.current,
33
+ runtimeKey,
34
+ seed,
35
+ }));
36
+ clockRef.current = now;
37
+ }, [autoAdvanceTime, definitionRef, inputRef, runtimeKey, seed]);
38
+ useGameScheduledEffects({
39
+ clockRef,
40
+ definitionRef,
41
+ enabled: autoAdvanceTime,
42
+ inputRef,
43
+ runtimeKey,
44
+ scheduled: runtime.session.scheduled,
45
+ setRuntime,
46
+ });
47
+ return React.useMemo(() => ({ session: runtime.session, dispatch }), [dispatch, runtime.session]);
48
+ }
49
+ /*** Reset the transient session only when its explicit serializable runtime identity changes. */
50
+ function useGameRuntimeReset({ clockRef, definitionRef, inputRef, runtimeKey, seed, setRuntime, }) {
51
+ React.useEffect(() => {
52
+ clockRef.current = Date.now();
53
+ setRuntime((current) => current.key === runtimeKey
54
+ ? current
55
+ : createRuntimeState(definitionRef.current, inputRef.current, seed, runtimeKey, current.revision + 1));
56
+ }, [clockRef, definitionRef, inputRef, runtimeKey, seed, setRuntime]);
57
+ }
58
+ /*** Emit each runtime output exactly when one execution revision becomes current. */
59
+ function useGameOutputEmitter(runtime, outputRef) {
60
+ React.useEffect(() => {
61
+ emitGameOutputs(runtime.outputs, outputRef.current);
62
+ }, [outputRef, runtime.outputs, runtime.revision]);
63
+ }
64
+ /*** Apply elapsed time and one explicit game event against the matching local session. */
65
+ function applyRuntimeEvent(args) {
66
+ const base = args.current.key === args.runtimeKey
67
+ ? args.current
68
+ : createRuntimeState(args.definition, args.input, args.seed, args.runtimeKey, args.current.revision);
69
+ const timed = args.autoAdvanceTime
70
+ ? advanceGameTime(args.definition, base.session, args.elapsedMs, args.input)
71
+ : { session: base.session, outputs: [] };
72
+ const result = applyGameEvent(args.definition, timed.session, args.event, args.input);
73
+ return {
74
+ key: args.runtimeKey,
75
+ session: result.session,
76
+ outputs: [...(base === args.current ? [] : base.outputs), ...timed.outputs, ...result.outputs],
77
+ revision: args.current.revision + 1,
78
+ };
79
+ }
80
+ /*** Create one transient runtime state through the published Game owner API. */
81
+ function createRuntimeState(definition, input, seed, key, revision) {
82
+ const result = createGameSession(definition, { input, seed });
83
+ return { key, session: result.session, outputs: result.outputs, revision };
84
+ }
85
+ /*** Create one runtime identity from serializable definition/session initialization inputs. */
86
+ function createRuntimeKey(definitionId, resetKey, seed) {
87
+ return `${definitionId}:${resetKey}:${seed}`;
88
+ }
89
+ /*** Emit runtime outputs through the ZORA event callback boundary. */
90
+ function emitGameOutputs(outputs, onOutput) {
91
+ if (onOutput === undefined)
92
+ return;
93
+ outputs.forEach((output) => onOutput(output));
94
+ }
95
+ /*** Keep a stable ref object updated with the latest adapter input. */
96
+ function useLatestValue(value) {
97
+ const ref = React.useRef(value);
98
+ React.useEffect(() => {
99
+ ref.current = value;
100
+ }, [value]);
101
+ return ref;
102
+ }
103
+ //# sourceMappingURL=useGameRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGameRuntime.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/composition/useGameRuntime.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n advanceGameTime,\n applyGameEvent,\n createGameSession,\n type GameInput,\n type GameOutput,\n} from '@ankhorage/game';\nimport React from 'react';\n\nimport type { GameProps } from '../../../types/gamePresentation';\nimport type { GameRuntimeContextValue, GameRuntimeState } from '../../../types/gameRuntime';\nimport { useGameScheduledEffects } from './useGameScheduledEffects';\n\nconst EMPTY_GAME_INPUT: GameInput = {};\n\n/*** Own one local transient Game session while delegating all domain transitions to @ankhorage/game. */\nexport function useGameRuntime(props: GameProps): GameRuntimeContextValue {\n const { definition, input = EMPTY_GAME_INPUT, seed = 0, resetKey = '' } = props;\n const definitionRef = useLatestValue(definition);\n const inputRef = useLatestValue(input);\n const outputRef = useLatestValue(props.onOutput);\n const autoAdvanceTime = props.autoAdvanceTime ?? true;\n const clockRef = React.useRef(0);\n const runtimeKey = createRuntimeKey(definition.id, resetKey, seed);\n const [runtime, setRuntime] = React.useState<GameRuntimeState>(() =>\n createRuntimeState(definition, input, seed, runtimeKey, 0),\n );\n\n useGameRuntimeReset({\n clockRef,\n definitionRef,\n inputRef,\n runtimeKey,\n seed,\n setRuntime,\n });\n useGameOutputEmitter(runtime, outputRef);\n\n const dispatch = React.useCallback<GameRuntimeContextValue['dispatch']>(\n (event) => {\n const now = Date.now();\n setRuntime((current) =>\n applyRuntimeEvent({\n autoAdvanceTime,\n current,\n definition: definitionRef.current,\n elapsedMs: Math.max(0, now - clockRef.current),\n event,\n input: inputRef.current,\n runtimeKey,\n seed,\n }),\n );\n clockRef.current = now;\n },\n [autoAdvanceTime, definitionRef, inputRef, runtimeKey, seed],\n );\n\n useGameScheduledEffects({\n clockRef,\n definitionRef,\n enabled: autoAdvanceTime,\n inputRef,\n runtimeKey,\n scheduled: runtime.session.scheduled,\n setRuntime,\n });\n\n return React.useMemo(() => ({ session: runtime.session, dispatch }), [dispatch, runtime.session]);\n}\n\ninterface GameRuntimeResetArgs {\n readonly clockRef: React.RefObject<number>;\n readonly definitionRef: React.RefObject<GameProps['definition']>;\n readonly inputRef: React.RefObject<GameInput>;\n readonly runtimeKey: string;\n readonly seed: number;\n readonly setRuntime: React.Dispatch<React.SetStateAction<GameRuntimeState>>;\n}\n\n/*** Reset the transient session only when its explicit serializable runtime identity changes. */\nfunction useGameRuntimeReset({\n clockRef,\n definitionRef,\n inputRef,\n runtimeKey,\n seed,\n setRuntime,\n}: GameRuntimeResetArgs): void {\n React.useEffect(() => {\n clockRef.current = Date.now();\n setRuntime((current) =>\n current.key === runtimeKey\n ? current\n : createRuntimeState(\n definitionRef.current,\n inputRef.current,\n seed,\n runtimeKey,\n current.revision + 1,\n ),\n );\n }, [clockRef, definitionRef, inputRef, runtimeKey, seed, setRuntime]);\n}\n\n/*** Emit each runtime output exactly when one execution revision becomes current. */\nfunction useGameOutputEmitter(\n runtime: GameRuntimeState,\n outputRef: React.RefObject<GameProps['onOutput']>,\n): void {\n React.useEffect(() => {\n emitGameOutputs(runtime.outputs, outputRef.current);\n }, [outputRef, runtime.outputs, runtime.revision]);\n}\n\ninterface ApplyRuntimeEventArgs {\n readonly autoAdvanceTime: boolean;\n readonly current: GameRuntimeState;\n readonly definition: GameProps['definition'];\n readonly elapsedMs: number;\n readonly event: Parameters<typeof applyGameEvent>[2];\n readonly input: GameInput;\n readonly runtimeKey: string;\n readonly seed: number;\n}\n\n/*** Apply elapsed time and one explicit game event against the matching local session. */\nfunction applyRuntimeEvent(args: ApplyRuntimeEventArgs): GameRuntimeState {\n const base =\n args.current.key === args.runtimeKey\n ? args.current\n : createRuntimeState(\n args.definition,\n args.input,\n args.seed,\n args.runtimeKey,\n args.current.revision,\n );\n const timed = args.autoAdvanceTime\n ? advanceGameTime(args.definition, base.session, args.elapsedMs, args.input)\n : { session: base.session, outputs: [] };\n const result = applyGameEvent(args.definition, timed.session, args.event, args.input);\n return {\n key: args.runtimeKey,\n session: result.session,\n outputs: [...(base === args.current ? [] : base.outputs), ...timed.outputs, ...result.outputs],\n revision: args.current.revision + 1,\n };\n}\n\n/*** Create one transient runtime state through the published Game owner API. */\nfunction createRuntimeState(\n definition: GameProps['definition'],\n input: GameInput,\n seed: number,\n key: string,\n revision: number,\n): GameRuntimeState {\n const result = createGameSession(definition, { input, seed });\n return { key, session: result.session, outputs: result.outputs, revision };\n}\n\n/*** Create one runtime identity from serializable definition/session initialization inputs. */\nfunction createRuntimeKey(definitionId: string, resetKey: string, seed: number): string {\n return `${definitionId}:${resetKey}:${seed}`;\n}\n\n/*** Emit runtime outputs through the ZORA event callback boundary. */\nfunction emitGameOutputs(outputs: readonly GameOutput[], onOutput: GameProps['onOutput']): void {\n if (onOutput === undefined) return;\n outputs.forEach((output) => onOutput(output));\n}\n\n/*** Keep a stable ref object updated with the latest adapter input. */\nfunction useLatestValue<TValue>(value: TValue): React.RefObject<TValue> {\n const ref = React.useRef(value);\n React.useEffect(() => {\n ref.current = value;\n }, [value]);\n return ref;\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { type GameDefinition, type GameInput } from '@ankhorage/game';
2
+ import React from 'react';
3
+ import type { GameRuntimeState } from '../../../types/gameRuntime';
4
+ type SetGameRuntime = React.Dispatch<React.SetStateAction<GameRuntimeState>>;
5
+ /*** Advance the nearest scheduled game effects through one platform timer. */
6
+ export declare function useGameScheduledEffects({ clockRef, definitionRef, enabled, inputRef, runtimeKey, scheduled, setRuntime, }: UseGameScheduledEffectsArgs): void;
7
+ interface UseGameScheduledEffectsArgs {
8
+ readonly clockRef: React.RefObject<number>;
9
+ readonly definitionRef: React.RefObject<GameDefinition>;
10
+ readonly enabled: boolean;
11
+ readonly inputRef: React.RefObject<GameInput>;
12
+ readonly runtimeKey: string;
13
+ readonly scheduled: GameRuntimeState['session']['scheduled'];
14
+ readonly setRuntime: SetGameRuntime;
15
+ }
16
+ export {};
17
+ //# sourceMappingURL=useGameScheduledEffects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGameScheduledEffects.d.ts","sourceRoot":"","sources":["../../../../src/features/game-presentation/composition/useGameScheduledEffects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,KAAK,cAAc,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAE7E,8EAA8E;AAC9E,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,aAAa,EACb,OAAO,EACP,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,GACX,EAAE,2BAA2B,GAAG,IAAI,CAsBpC;AAED,UAAU,2BAA2B;IACnC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACxD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,CAAC;IAC7D,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;CACrC"}
@@ -0,0 +1,40 @@
1
+ import { advanceGameTime } from '@ankhorage/game';
2
+ import React from 'react';
3
+ /*** Advance the nearest scheduled game effects through one platform timer. */
4
+ export function useGameScheduledEffects({ clockRef, definitionRef, enabled, inputRef, runtimeKey, scheduled, setRuntime, }) {
5
+ React.useEffect(() => {
6
+ if (!enabled || scheduled.length === 0)
7
+ return undefined;
8
+ const delayMs = resolveNextScheduledDelay(scheduled);
9
+ const timer = setTimeout(() => {
10
+ const now = Date.now();
11
+ const elapsedMs = Math.max(0, now - clockRef.current);
12
+ clockRef.current = now;
13
+ setRuntime((current) => advanceScheduledRuntime({
14
+ current,
15
+ definition: definitionRef.current,
16
+ elapsedMs,
17
+ input: inputRef.current,
18
+ runtimeKey,
19
+ }));
20
+ }, delayMs);
21
+ return () => clearTimeout(timer);
22
+ }, [clockRef, definitionRef, enabled, inputRef, runtimeKey, scheduled, setRuntime]);
23
+ }
24
+ /*** Advance one matching runtime state while preserving sessions that have already reset. */
25
+ function advanceScheduledRuntime({ current, definition, elapsedMs, input, runtimeKey, }) {
26
+ if (current.key !== runtimeKey)
27
+ return current;
28
+ const result = advanceGameTime(definition, current.session, elapsedMs, input);
29
+ return {
30
+ key: runtimeKey,
31
+ session: result.session,
32
+ outputs: result.outputs,
33
+ revision: current.revision + 1,
34
+ };
35
+ }
36
+ /*** Resolve the nearest scheduled game consequence without owning domain timing rules. */
37
+ function resolveNextScheduledDelay(scheduledEffects) {
38
+ return scheduledEffects.reduce((nearest, scheduled) => Math.min(nearest, scheduled.remainingMs), Number.POSITIVE_INFINITY);
39
+ }
40
+ //# sourceMappingURL=useGameScheduledEffects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGameScheduledEffects.js","sourceRoot":"","sources":["../../../../src/features/game-presentation/composition/useGameScheduledEffects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAuC,MAAM,iBAAiB,CAAC;AACvF,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,8EAA8E;AAC9E,MAAM,UAAU,uBAAuB,CAAC,EACtC,QAAQ,EACR,aAAa,EACb,OAAO,EACP,QAAQ,EACR,UAAU,EACV,SAAS,EACT,UAAU,GACkB;IAC5B,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACzD,MAAM,OAAO,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;QAErD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;YACtD,QAAQ,CAAC,OAAO,GAAG,GAAG,CAAC;YACvB,UAAU,CAAC,CAAC,OAAO,EAAE,EAAE,CACrB,uBAAuB,CAAC;gBACtB,OAAO;gBACP,UAAU,EAAE,aAAa,CAAC,OAAO;gBACjC,SAAS;gBACT,KAAK,EAAE,QAAQ,CAAC,OAAO;gBACvB,UAAU;aACX,CAAC,CACH,CAAC;QACJ,CAAC,EAAE,OAAO,CAAC,CAAC;QAEZ,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;AACtF,CAAC;AAoBD,6FAA6F;AAC7F,SAAS,uBAAuB,CAAC,EAC/B,OAAO,EACP,UAAU,EACV,SAAS,EACT,KAAK,EACL,UAAU,GACkB;IAC5B,IAAI,OAAO,CAAC,GAAG,KAAK,UAAU;QAAE,OAAO,OAAO,CAAC;IAC/C,MAAM,MAAM,GAAG,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9E,OAAO;QACL,GAAG,EAAE,UAAU;QACf,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,QAAQ,EAAE,OAAO,CAAC,QAAQ,GAAG,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED,0FAA0F;AAC1F,SAAS,yBAAyB,CAChC,gBAA0D;IAE1D,OAAO,gBAAgB,CAAC,MAAM,CAC5B,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,EAChE,MAAM,CAAC,iBAAiB,CACzB,CAAC;AACJ,CAAC","sourcesContent":["import { advanceGameTime, type GameDefinition, type GameInput } from '@ankhorage/game';\nimport React from 'react';\n\nimport type { GameRuntimeState } from '../../../types/gameRuntime';\n\ntype SetGameRuntime = React.Dispatch<React.SetStateAction<GameRuntimeState>>;\n\n/*** Advance the nearest scheduled game effects through one platform timer. */\nexport function useGameScheduledEffects({\n clockRef,\n definitionRef,\n enabled,\n inputRef,\n runtimeKey,\n scheduled,\n setRuntime,\n}: UseGameScheduledEffectsArgs): void {\n React.useEffect(() => {\n if (!enabled || scheduled.length === 0) return undefined;\n const delayMs = resolveNextScheduledDelay(scheduled);\n\n const timer = setTimeout(() => {\n const now = Date.now();\n const elapsedMs = Math.max(0, now - clockRef.current);\n clockRef.current = now;\n setRuntime((current) =>\n advanceScheduledRuntime({\n current,\n definition: definitionRef.current,\n elapsedMs,\n input: inputRef.current,\n runtimeKey,\n }),\n );\n }, delayMs);\n\n return () => clearTimeout(timer);\n }, [clockRef, definitionRef, enabled, inputRef, runtimeKey, scheduled, setRuntime]);\n}\n\ninterface UseGameScheduledEffectsArgs {\n readonly clockRef: React.RefObject<number>;\n readonly definitionRef: React.RefObject<GameDefinition>;\n readonly enabled: boolean;\n readonly inputRef: React.RefObject<GameInput>;\n readonly runtimeKey: string;\n readonly scheduled: GameRuntimeState['session']['scheduled'];\n readonly setRuntime: SetGameRuntime;\n}\n\ninterface AdvanceScheduledRuntimeArgs {\n readonly current: GameRuntimeState;\n readonly definition: GameDefinition;\n readonly elapsedMs: number;\n readonly input: GameInput;\n readonly runtimeKey: string;\n}\n\n/*** Advance one matching runtime state while preserving sessions that have already reset. */\nfunction advanceScheduledRuntime({\n current,\n definition,\n elapsedMs,\n input,\n runtimeKey,\n}: AdvanceScheduledRuntimeArgs): GameRuntimeState {\n if (current.key !== runtimeKey) return current;\n const result = advanceGameTime(definition, current.session, elapsedMs, input);\n return {\n key: runtimeKey,\n session: result.session,\n outputs: result.outputs,\n revision: current.revision + 1,\n };\n}\n\n/*** Resolve the nearest scheduled game consequence without owning domain timing rules. */\nfunction resolveNextScheduledDelay(\n scheduledEffects: GameRuntimeState['session']['scheduled'],\n): number {\n return scheduledEffects.reduce(\n (nearest, scheduled) => Math.min(nearest, scheduled.remainingMs),\n Number.POSITIVE_INFINITY,\n );\n}\n"]}
@@ -0,0 +1,120 @@
1
+ /*** Describe the embeddable config-driven Game runtime/presentation boundary for ZORA authoring. */
2
+ export declare const gameMeta: {
3
+ readonly name: "Game";
4
+ readonly category: "pattern";
5
+ readonly description: "Embeds one config-driven game session inside ordinary ZORA layout and emits domain-neutral game outputs.";
6
+ readonly directManifestNode: true;
7
+ readonly allowedChildren: readonly ["GameEntity", "GameOverlay", "Gradient", "Image", "View"];
8
+ readonly blueprint: {
9
+ readonly label: "Game";
10
+ readonly defaultProps: {
11
+ readonly definition: {
12
+ readonly id: "game";
13
+ readonly initialPhase: "playing";
14
+ readonly stages: readonly [{
15
+ readonly id: "main";
16
+ }];
17
+ readonly rules: readonly [];
18
+ };
19
+ readonly seed: 0;
20
+ readonly resetKey: "";
21
+ readonly autoAdvanceTime: true;
22
+ readonly minHeight: 320;
23
+ readonly clip: true;
24
+ };
25
+ };
26
+ readonly bindings: {
27
+ readonly props: {
28
+ readonly definition: {
29
+ readonly value: {
30
+ readonly type: "object";
31
+ };
32
+ readonly acceptsFallback: true;
33
+ };
34
+ readonly input: {
35
+ readonly value: {
36
+ readonly type: "record";
37
+ };
38
+ readonly acceptsFallback: true;
39
+ };
40
+ };
41
+ };
42
+ readonly events: {
43
+ readonly output: {
44
+ readonly label: "Game output";
45
+ readonly eventType: "game.output";
46
+ readonly description: "Emitted when the platform-neutral game runtime produces an app/domain output.";
47
+ readonly payloadFields: readonly [{
48
+ readonly path: "type";
49
+ readonly type: "string";
50
+ }, {
51
+ readonly path: "payload";
52
+ readonly type: "record";
53
+ }];
54
+ };
55
+ };
56
+ readonly props: {
57
+ readonly seed: {
58
+ readonly type: "number";
59
+ readonly category: "Runtime";
60
+ readonly label: "Initial seed";
61
+ readonly default: 0;
62
+ readonly authoring: {
63
+ readonly authority: "instance";
64
+ };
65
+ };
66
+ readonly resetKey: {
67
+ readonly type: "string";
68
+ readonly category: "Runtime";
69
+ readonly label: "Reset key";
70
+ readonly default: "";
71
+ readonly authoring: {
72
+ readonly authority: "instance";
73
+ };
74
+ };
75
+ readonly autoAdvanceTime: {
76
+ readonly type: "boolean";
77
+ readonly category: "Runtime";
78
+ readonly label: "Advance scheduled effects";
79
+ readonly default: true;
80
+ readonly authoring: {
81
+ readonly authority: "instance";
82
+ };
83
+ };
84
+ readonly aspectRatio: {
85
+ readonly type: "number";
86
+ readonly category: "Layout";
87
+ readonly label: "Aspect ratio";
88
+ readonly authoring: {
89
+ readonly authority: "instance";
90
+ };
91
+ };
92
+ readonly minHeight: {
93
+ readonly type: "number";
94
+ readonly category: "Layout";
95
+ readonly label: "Minimum height";
96
+ readonly default: 320;
97
+ readonly authoring: {
98
+ readonly authority: "instance";
99
+ };
100
+ };
101
+ readonly clip: {
102
+ readonly type: "boolean";
103
+ readonly category: "Layout";
104
+ readonly label: "Clip overflow";
105
+ readonly default: true;
106
+ readonly authoring: {
107
+ readonly authority: "instance";
108
+ };
109
+ };
110
+ readonly accessibilityLabel: {
111
+ readonly type: "string";
112
+ readonly category: "Accessibility";
113
+ readonly label: "Accessibility label";
114
+ readonly authoring: {
115
+ readonly authority: "instance";
116
+ };
117
+ };
118
+ };
119
+ };
120
+ //# sourceMappingURL=gameMeta.d.ts.map
@@ -0,0 +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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+FiB,CAAC"}
@@ -0,0 +1,97 @@
1
+ /*** Describe the embeddable config-driven Game runtime/presentation boundary for ZORA authoring. */
2
+ export const gameMeta = {
3
+ name: 'Game',
4
+ category: 'pattern',
5
+ description: 'Embeds one config-driven game session inside ordinary ZORA layout and emits domain-neutral game outputs.',
6
+ directManifestNode: true,
7
+ allowedChildren: ['GameEntity', 'GameOverlay', 'Gradient', 'Image', 'View'],
8
+ blueprint: {
9
+ label: 'Game',
10
+ defaultProps: {
11
+ definition: {
12
+ id: 'game',
13
+ initialPhase: 'playing',
14
+ stages: [{ id: 'main' }],
15
+ rules: [],
16
+ },
17
+ seed: 0,
18
+ resetKey: '',
19
+ autoAdvanceTime: true,
20
+ minHeight: 320,
21
+ clip: true,
22
+ },
23
+ },
24
+ bindings: {
25
+ props: {
26
+ definition: {
27
+ value: { type: 'object' },
28
+ acceptsFallback: true,
29
+ },
30
+ input: {
31
+ value: { type: 'record' },
32
+ acceptsFallback: true,
33
+ },
34
+ },
35
+ },
36
+ events: {
37
+ output: {
38
+ label: 'Game output',
39
+ eventType: 'game.output',
40
+ description: 'Emitted when the platform-neutral game runtime produces an app/domain output.',
41
+ payloadFields: [
42
+ { path: 'type', type: 'string' },
43
+ { path: 'payload', type: 'record' },
44
+ ],
45
+ },
46
+ },
47
+ props: {
48
+ seed: {
49
+ type: 'number',
50
+ category: 'Runtime',
51
+ label: 'Initial seed',
52
+ default: 0,
53
+ authoring: { authority: 'instance' },
54
+ },
55
+ resetKey: {
56
+ type: 'string',
57
+ category: 'Runtime',
58
+ label: 'Reset key',
59
+ default: '',
60
+ authoring: { authority: 'instance' },
61
+ },
62
+ autoAdvanceTime: {
63
+ type: 'boolean',
64
+ category: 'Runtime',
65
+ label: 'Advance scheduled effects',
66
+ default: true,
67
+ authoring: { authority: 'instance' },
68
+ },
69
+ aspectRatio: {
70
+ type: 'number',
71
+ category: 'Layout',
72
+ label: 'Aspect ratio',
73
+ authoring: { authority: 'instance' },
74
+ },
75
+ minHeight: {
76
+ type: 'number',
77
+ category: 'Layout',
78
+ label: 'Minimum height',
79
+ default: 320,
80
+ authoring: { authority: 'instance' },
81
+ },
82
+ clip: {
83
+ type: 'boolean',
84
+ category: 'Layout',
85
+ label: 'Clip overflow',
86
+ default: true,
87
+ authoring: { authority: 'instance' },
88
+ },
89
+ accessibilityLabel: {
90
+ type: 'string',
91
+ category: 'Accessibility',
92
+ label: 'Accessibility label',
93
+ authoring: { authority: 'instance' },
94
+ },
95
+ },
96
+ };
97
+ //# sourceMappingURL=gameMeta.js.map
@@ -0,0 +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,CAAC,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC;IAC3E,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: ['GameEntity', 'GameOverlay', 'Gradient', 'Image', 'View'],\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,4 +1,5 @@
1
- export type { GameEntityProps, GameFieldProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, } from '../../types/gamePresentation';
1
+ export type { GameEntityProps, GameFieldProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from '../../types/gamePresentation';
2
+ export { Game } from './adapters/inbound/Game';
2
3
  export { GameEntity } from './adapters/inbound/GameEntity';
3
4
  export { GameField } from './adapters/inbound/GameField';
4
5
  export { GameOverlay } from './adapters/inbound/GameOverlay';
@@ -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,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,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,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,WAAW,EAAE,MAAM,gCAAgC,CAAC"}
@@ -1,3 +1,4 @@
1
+ export { Game } from './adapters/inbound/Game';
1
2
  export { GameEntity } from './adapters/inbound/GameEntity';
2
3
  export { GameField } from './adapters/inbound/GameField';
3
4
  export { GameOverlay } from './adapters/inbound/GameOverlay';
@@ -1 +1 @@
1
- {"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC","sourcesContent":["export type {\n GameEntityProps,\n GameFieldProps,\n GameOverlayPlacement,\n GameOverlayProps,\n GamePointerEvents,\n} from '../../types/gamePresentation';\nexport { GameEntity } from './adapters/inbound/GameEntity';\nexport { GameField } from './adapters/inbound/GameField';\nexport { GameOverlay } from './adapters/inbound/GameOverlay';\n"]}
1
+ {"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/game-presentation/public.ts"],"names":[],"mappings":"AAQA,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,WAAW,EAAE,MAAM,gCAAgC,CAAC","sourcesContent":["export type {\n GameEntityProps,\n GameFieldProps,\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 { GameOverlay } from './adapters/inbound/GameOverlay';\n"]}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type { GameEntityProps, GameFieldProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, } from './features/game-presentation/public';
2
- export { GameEntity, GameField, GameOverlay } from './features/game-presentation/public';
1
+ export type { GameEntityProps, GameFieldProps, GameOverlayPlacement, GameOverlayProps, GamePointerEvents, GameProps, } from './features/game-presentation/public';
2
+ export { Game, GameEntity, GameField, GameOverlay } from './features/game-presentation/public';
3
3
  export { ZORA_GAME_PLUGIN } from './ZORA_GAME_PLUGIN';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AACzF,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,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { GameEntity, GameField, GameOverlay } from './features/game-presentation/public';
1
+ export { Game, GameEntity, GameField, 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":"AAOA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export type {\n GameEntityProps,\n GameFieldProps,\n GameOverlayPlacement,\n GameOverlayProps,\n GamePointerEvents,\n} from './features/game-presentation/public';\nexport { GameEntity, GameField, GameOverlay } from './features/game-presentation/public';\nexport { ZORA_GAME_PLUGIN } from './ZORA_GAME_PLUGIN';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["export type {\n GameEntityProps,\n GameFieldProps,\n GameOverlayPlacement,\n GameOverlayProps,\n GamePointerEvents,\n GameProps,\n} from './features/game-presentation/public';\nexport { Game, GameEntity, GameField, GameOverlay } from './features/game-presentation/public';\nexport { ZORA_GAME_PLUGIN } from './ZORA_GAME_PLUGIN';\n"]}
@@ -1,3 +1,4 @@
1
+ import type { GameDefinition, GameInput, GameOutput } from '@ankhorage/game';
1
2
  import type React from 'react';
2
3
  type GameOverlayCornerPlacement = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
3
4
  export type GamePointerEvents = 'auto' | 'box-none' | 'box-only' | 'none';
@@ -33,5 +34,13 @@ export interface GameOverlayProps {
33
34
  readonly accessibilityLabel?: string;
34
35
  readonly testID?: string;
35
36
  }
37
+ export interface GameProps extends GameFieldProps {
38
+ readonly definition: GameDefinition;
39
+ readonly input?: GameInput;
40
+ readonly seed?: number;
41
+ readonly resetKey?: string;
42
+ readonly autoAdvanceTime?: boolean;
43
+ readonly onOutput?: (output: GameOutput) => void;
44
+ }
36
45
  export {};
37
46
  //# sourceMappingURL=gamePresentation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gamePresentation.d.ts","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,KAAK,0BAA0B,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,CAAC;AAE5F,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAC1E,MAAM,MAAM,oBAAoB,GAC9B,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,0BAA0B,CAAC;AAEpE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAC3C,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B"}
1
+ {"version":3,"file":"gamePresentation.d.ts","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,KAAK,0BAA0B,GAAG,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,CAAC;AAE5F,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAC1E,MAAM,MAAM,oBAAoB,GAC9B,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,0BAA0B,CAAC;AAEpE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAC3C,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,SAAU,SAAQ,cAAc;IAC/C,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CAClD"}
@@ -1 +1 @@
1
- {"version":3,"file":"gamePresentation.js","sourceRoot":"","sources":["../../src/types/gamePresentation.ts"],"names":[],"mappings":"","sourcesContent":["import 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 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"]}
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 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"]}
@@ -0,0 +1,12 @@
1
+ import type { GameEvent, GameOutput, GameSession } from '@ankhorage/game';
2
+ export interface GameRuntimeContextValue {
3
+ readonly session: GameSession;
4
+ readonly dispatch: (event: GameEvent) => void;
5
+ }
6
+ export interface GameRuntimeState {
7
+ readonly key: string;
8
+ readonly session: GameSession;
9
+ readonly outputs: readonly GameOutput[];
10
+ readonly revision: number;
11
+ }
12
+ //# sourceMappingURL=gameRuntime.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=gameRuntime.js.map
@@ -0,0 +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 GameRuntimeContextValue {\n readonly session: GameSession;\n readonly dispatch: (event: GameEvent) => void;\n}\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.1.0",
3
+ "version": "0.2.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",
@@ -91,5 +91,8 @@
91
91
  "react-native-web": "~0.21.0",
92
92
  "typescript": "~6.0.3"
93
93
  },
94
- "packageManager": "bun@1.4.2"
94
+ "packageManager": "bun@1.4.2",
95
+ "dependencies": {
96
+ "@ankhorage/game": "^0.1.0"
97
+ }
95
98
  }
@@ -1,9 +1,11 @@
1
1
  import { gameEntityMeta } from './features/game-presentation/meta/gameEntityMeta';
2
2
  import { gameFieldMeta } from './features/game-presentation/meta/gameFieldMeta';
3
+ import { gameMeta } from './features/game-presentation/meta/gameMeta';
3
4
  import { gameOverlayMeta } from './features/game-presentation/meta/gameOverlayMeta';
4
5
 
5
6
  /*** Register the generic game presentation metadata owned by this package. */
6
7
  export const ZORA_GAME_COMPONENT_META = {
8
+ Game: gameMeta,
7
9
  GameEntity: gameEntityMeta,
8
10
  GameField: gameFieldMeta,
9
11
  GameOverlay: gameOverlayMeta,
@@ -1,3 +1,4 @@
1
+ import { Game } from './features/game-presentation/adapters/inbound/Game';
1
2
  import { GameEntity } from './features/game-presentation/adapters/inbound/GameEntity';
2
3
  import { GameField } from './features/game-presentation/adapters/inbound/GameField';
3
4
  import { GameOverlay } from './features/game-presentation/adapters/inbound/GameOverlay';
@@ -7,6 +8,7 @@ import { ZORA_PLUGIN_METADATA } from './ZORA_PLUGIN_METADATA';
7
8
  export const ZORA_GAME_PLUGIN = {
8
9
  ...ZORA_PLUGIN_METADATA,
9
10
  componentRegistry: {
11
+ Game,
10
12
  GameEntity,
11
13
  GameField,
12
14
  GameOverlay,