@idosgames/module-sdk 0.10.1 → 0.11.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/dist/index.cjs +1 -1
- package/dist/index.d.cts +103 -5
- package/dist/index.d.ts +103 -5
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var x=/^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*@[1-9]\d*$/;function S(e){return typeof e=="string"&&x.test(e)}function
|
|
1
|
+
'use strict';var x=/^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*@[1-9]\d*$/;function S(e){return typeof e=="string"&&x.test(e)}function M(e){let t=e.indexOf(":");return t<0?"":e.slice(0,t)}var c=/^(string|number|boolean)(\[\])?(\?)?$/;function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e,t){return e==="number"?typeof t=="number"&&Number.isFinite(t):typeof t===e}function f(e,t,r){if(!u(t))return `${r||"payload"} must be an object`;for(let[n,o]of Object.entries(e)){let i=r?`${r}.${n}`:n,a=t[n];if(typeof o!="string"){let p=f(o,a,i);if(p)return p;continue}let d=c.exec(o);if(!d)return `${i}: invalid descriptor "${o}"`;let[,s="",g,m]=d;if(a===void 0){if(m)continue;return `${i} is missing`}if(g){if(!Array.isArray(a))return `${i} must be ${s}[]`;if(!a.every(p=>l(s,p)))return `${i} must contain only ${s} values`;continue}if(!l(s,a))return `${i} must be a ${s}`}return null}function y(e,t){for(let[r,n]of Object.entries(e)){let o=t?`${t}.${r}`:r;if(typeof n=="string"){if(!c.test(n))throw new Error(`shape(): field "${o}" has invalid type "${n}" \u2014 use "string" | "number" | "boolean", optionally with "[]" and/or a trailing "?"`)}else if(u(n))y(n,o);else throw new Error(`shape(): field "${o}" must be a type string or an object`)}}function h(e){return y(e,""),{descriptor:e,check:t=>f(e,t,"")}}function v(e,t){if(!S(e))throw new Error(`defineTopic(): "${e}" is not a valid topic name \u2014 expected "<module-id>:<event>@<major>", e.g. "idle-rpg:character-upgraded@1"`);return {name:e,shape:t}}var T={modeChanged:v("host:mode-changed@1",h({from:"string?",to:"string"}))};var b=["currency-bar","wallet","status","account","menu","modes"];function R(e){return typeof e=="string"&&b.includes(e)}function D(e){return e}exports.SHARED_UI_ROLES=b;exports.TOPIC_NAME_RE=x;exports.defineModule=D;exports.defineTopic=v;exports.hostTopics=T;exports.isSharedUiRole=R;exports.isTopicName=S;exports.shape=h;exports.topicNamespace=M;
|
package/dist/index.d.cts
CHANGED
|
@@ -217,8 +217,12 @@ interface FeatureScreenProps {
|
|
|
217
217
|
interface FeatureDefinition {
|
|
218
218
|
/** Unique across the game — conventionally the owning module's id ("store"). */
|
|
219
219
|
id: string;
|
|
220
|
-
/**
|
|
221
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Menu label in the player's language. Prefer a function (`label: () => t("title")`): the lobby
|
|
222
|
+
* calls it on every render, so the tab follows the language switch (UI kit `setLanguage`) without
|
|
223
|
+
* a reload. A plain string stays as registered.
|
|
224
|
+
*/
|
|
225
|
+
label: string | (() => string);
|
|
222
226
|
/** Glyph name of @idosgames/react/ui ("shop", "hero"…), an emoji, or an image URL. */
|
|
223
227
|
icon?: string;
|
|
224
228
|
group?: FeatureGroup;
|
|
@@ -236,7 +240,9 @@ interface FeatureDefinition {
|
|
|
236
240
|
available?: boolean;
|
|
237
241
|
}
|
|
238
242
|
/** A registered feature plus its live badge and availability. */
|
|
239
|
-
interface FeatureEntry extends FeatureDefinition {
|
|
243
|
+
interface FeatureEntry extends Omit<FeatureDefinition, "label"> {
|
|
244
|
+
/** The label now — a function label is called on every read. */
|
|
245
|
+
readonly label: string;
|
|
240
246
|
badge: number;
|
|
241
247
|
/** The module that registered it. */
|
|
242
248
|
moduleId: string;
|
|
@@ -357,6 +363,84 @@ interface MultiplayerRegistry {
|
|
|
357
363
|
subscribe(listener: () => void): () => void;
|
|
358
364
|
}
|
|
359
365
|
|
|
366
|
+
/** A button under the showcase or on the "Play" card. */
|
|
367
|
+
interface LobbyHeroAction {
|
|
368
|
+
id: string;
|
|
369
|
+
/** Already in the player's language. */
|
|
370
|
+
label: string;
|
|
371
|
+
/** Glyph name of @idosgames/react/ui ("edit", "star"…), an emoji, or an image URL. */
|
|
372
|
+
icon?: string;
|
|
373
|
+
/** Pressed. Omit when the button only opens `menu`. */
|
|
374
|
+
run?(): void;
|
|
375
|
+
/** A short list shown when the button is pressed (an emote picker) — each entry runs on its own. */
|
|
376
|
+
menu?: LobbyHeroAction[];
|
|
377
|
+
disabled?: boolean;
|
|
378
|
+
}
|
|
379
|
+
/** What the lobby lays out around the showcase. Read through `view()`, redrawn on `subscribe`. */
|
|
380
|
+
interface LobbyHeroView {
|
|
381
|
+
/** Big name under the showcase (the character's name). */
|
|
382
|
+
title?: string;
|
|
383
|
+
/** A line under it. */
|
|
384
|
+
subtitle?: string;
|
|
385
|
+
/** Buttons under the name ("Edit", "Emote"). */
|
|
386
|
+
actions?: LobbyHeroAction[];
|
|
387
|
+
/**
|
|
388
|
+
* The card next to "Play" — WHAT will be played: a caption ("World"), a name ("Island"), buttons
|
|
389
|
+
* to change it ("Change", "New"). Omitted — "Play" alone.
|
|
390
|
+
*/
|
|
391
|
+
play?: {
|
|
392
|
+
caption?: string;
|
|
393
|
+
title?: string;
|
|
394
|
+
actions?: LobbyHeroAction[];
|
|
395
|
+
/** Overflow menu of the card ("⋯": download, upload…). */
|
|
396
|
+
more?: LobbyHeroAction[];
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
/** Handed to `mount`: where on the host the main figure should stand. */
|
|
400
|
+
interface LobbyHeroStage {
|
|
401
|
+
/**
|
|
402
|
+
* The free spot between the lobby's interface where the figure should stand, in CSS pixels of the
|
|
403
|
+
* host element (it moves with the layout — read it every frame). `null` — not laid out yet.
|
|
404
|
+
*/
|
|
405
|
+
spot(): {
|
|
406
|
+
x: number;
|
|
407
|
+
y: number;
|
|
408
|
+
w: number;
|
|
409
|
+
h: number;
|
|
410
|
+
} | null;
|
|
411
|
+
}
|
|
412
|
+
interface LobbyHeroDefinition {
|
|
413
|
+
/** The game mode "Play" starts (a route id of the game). */
|
|
414
|
+
mode: string;
|
|
415
|
+
/**
|
|
416
|
+
* Put the showcase into `host` — an element filling the lobby's home behind its interface. Called
|
|
417
|
+
* when the home is shown, the returned function when it is left (stop the render loop there). The
|
|
418
|
+
* same hero may be mounted again later.
|
|
419
|
+
*/
|
|
420
|
+
mount(host: HTMLElement, stage: LobbyHeroStage): () => void;
|
|
421
|
+
/** The current texts and buttons. Cheap — called on every redraw. */
|
|
422
|
+
view(): LobbyHeroView;
|
|
423
|
+
/** Called by the hero whenever `view()` would answer differently. Returns the unsubscribe. */
|
|
424
|
+
subscribe(listener: () => void): () => void;
|
|
425
|
+
/**
|
|
426
|
+
* "Play" was pressed: return false to stay in the lobby (nothing to play yet). Default: switch to
|
|
427
|
+
* `mode`.
|
|
428
|
+
*/
|
|
429
|
+
beforePlay?(): boolean;
|
|
430
|
+
}
|
|
431
|
+
/** `ctx.lobby` — the app's lobby as seen by a module. */
|
|
432
|
+
interface LobbyRegistry {
|
|
433
|
+
/** Put this game's showcase on the lobby's home. Returns the unregister function. */
|
|
434
|
+
setHero(hero: LobbyHeroDefinition): () => void;
|
|
435
|
+
/** The hero on the home now (the lobby reads it). */
|
|
436
|
+
hero(): LobbyHeroDefinition | null;
|
|
437
|
+
subscribe(listener: () => void): () => void;
|
|
438
|
+
/** Whether the app has a lobby to return to (the base is installed). */
|
|
439
|
+
available(): boolean;
|
|
440
|
+
/** Go to the lobby — a game's "To the lobby" in its pause menu. False — there is no lobby. */
|
|
441
|
+
open(): boolean;
|
|
442
|
+
}
|
|
443
|
+
|
|
360
444
|
/** One piece of work on the loading screen. Call `done()` exactly once, also on failure. */
|
|
361
445
|
interface LoadingTask {
|
|
362
446
|
/**
|
|
@@ -629,6 +713,12 @@ interface ModuleContext {
|
|
|
629
713
|
* builds its "Play" buttons from it; a game can tell whether a lobby exists to return to.
|
|
630
714
|
*/
|
|
631
715
|
modes: ModeRegistry;
|
|
716
|
+
/**
|
|
717
|
+
* The app's lobby: a game puts its showcase on the lobby's home (`setHero` — its character on a
|
|
718
|
+
* pedestal, "Play" next to it) and sends the player back to it from its pause menu (`open`). See
|
|
719
|
+
* `LobbyHeroDefinition`.
|
|
720
|
+
*/
|
|
721
|
+
lobby: LobbyRegistry;
|
|
632
722
|
/**
|
|
633
723
|
* Switch the host to another mode (a route id registered by any module) — e.g. the lobby starts a
|
|
634
724
|
* game, the Workshop opens a world and hands the screen to the game. Unknown ids are ignored. Called
|
|
@@ -790,9 +880,15 @@ interface RouteEntry {
|
|
|
790
880
|
* A game that lives INSIDE the lobby: the base keeps the lobby's balances on top and its tabs at
|
|
791
881
|
* the bottom around it, "Play" is this game, and the app starts in it after sign-in (idle-rpg).
|
|
792
882
|
* Without it (the default) a game takes the whole screen, launched by "Play" in the lobby, with a
|
|
793
|
-
* small button back (
|
|
883
|
+
* small button back (board-game).
|
|
794
884
|
*/
|
|
795
885
|
inLobby?: boolean;
|
|
886
|
+
/**
|
|
887
|
+
* A full-screen game with its OWN way back to the lobby (a pause menu with "To the lobby" that
|
|
888
|
+
* calls `ctx.lobby.open()` — voxelcraft): the base does not draw its round button back over it.
|
|
889
|
+
* The game must then offer that way on every device (a pause button on touch screens).
|
|
890
|
+
*/
|
|
891
|
+
ownExit?: boolean;
|
|
796
892
|
}
|
|
797
893
|
/** A mode of the app as every module sees it (`ctx.modes`): a registered route plus its owner. */
|
|
798
894
|
interface ModeEntry {
|
|
@@ -807,6 +903,8 @@ interface ModeEntry {
|
|
|
807
903
|
moduleType: ModuleType;
|
|
808
904
|
/** The route's `inLobby`: the game sits inside the lobby rather than taking the whole screen. */
|
|
809
905
|
inLobby?: boolean;
|
|
906
|
+
/** The route's `ownExit`: the game leads back to the lobby itself — no button back over it. */
|
|
907
|
+
ownExit?: boolean;
|
|
810
908
|
}
|
|
811
909
|
/** `ctx.modes` — the modes of the app, live. Switch with `ctx.navigate(id)`. */
|
|
812
910
|
interface ModeRegistry {
|
|
@@ -832,4 +930,4 @@ interface SharedEventBus<Events extends Record<string, unknown> = Record<string,
|
|
|
832
930
|
/** Identity helper that pins a module literal to the `Module` type for editor help and errors. */
|
|
833
931
|
declare function defineModule(module: Module): Module;
|
|
834
932
|
|
|
835
|
-
export { type AppNotifications, type CapturedContent, type ContentFileData, type ContentRegistry, type ContentTypeHandler, type DownloadedContent, type EngineScene, type FeatureDefinition, type FeatureEntry, type FeatureGroup, type FeaturePresenter, type FeatureRegistry, type FeatureScreenProps, type InferShape, type LoadingReporter, type LoadingTask, type LocalContentItem, type ModeEntry, type ModeRegistry, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleEventEmit, type ModuleEventListen, type ModuleEvents, type ModuleEventsManifest, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleSharedUi, type ModuleType, type MultiplayerGame, type MultiplayerRegistry, type MultiplayerRoom, type MultiplayerScreenArgs, type MultiplayerSetting, type NotificationAction, type NotificationInput, type NotificationLevel, type PanelSlot, type RouteEntry, SHARED_UI_ROLES, type SceneMountContext, type Shape, type ShapeDescriptor, type ShapeLeaf, type ShapeLeafSpec, type SharedEventBus, type SharedUiContext, type SharedUiRole, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, TOPIC_NAME_RE, type Topic, type TopicName, type TopicPayload, type UiPanel, defineModule, defineTopic, hostTopics, isSharedUiRole, isTopicName, shape, topicNamespace };
|
|
933
|
+
export { type AppNotifications, type CapturedContent, type ContentFileData, type ContentRegistry, type ContentTypeHandler, type DownloadedContent, type EngineScene, type FeatureDefinition, type FeatureEntry, type FeatureGroup, type FeaturePresenter, type FeatureRegistry, type FeatureScreenProps, type InferShape, type LoadingReporter, type LoadingTask, type LobbyHeroAction, type LobbyHeroDefinition, type LobbyHeroStage, type LobbyHeroView, type LobbyRegistry, type LocalContentItem, type ModeEntry, type ModeRegistry, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleEventEmit, type ModuleEventListen, type ModuleEvents, type ModuleEventsManifest, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleSharedUi, type ModuleType, type MultiplayerGame, type MultiplayerRegistry, type MultiplayerRoom, type MultiplayerScreenArgs, type MultiplayerSetting, type NotificationAction, type NotificationInput, type NotificationLevel, type PanelSlot, type RouteEntry, SHARED_UI_ROLES, type SceneMountContext, type Shape, type ShapeDescriptor, type ShapeLeaf, type ShapeLeafSpec, type SharedEventBus, type SharedUiContext, type SharedUiRole, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, TOPIC_NAME_RE, type Topic, type TopicName, type TopicPayload, type UiPanel, defineModule, defineTopic, hostTopics, isSharedUiRole, isTopicName, shape, topicNamespace };
|
package/dist/index.d.ts
CHANGED
|
@@ -217,8 +217,12 @@ interface FeatureScreenProps {
|
|
|
217
217
|
interface FeatureDefinition {
|
|
218
218
|
/** Unique across the game — conventionally the owning module's id ("store"). */
|
|
219
219
|
id: string;
|
|
220
|
-
/**
|
|
221
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Menu label in the player's language. Prefer a function (`label: () => t("title")`): the lobby
|
|
222
|
+
* calls it on every render, so the tab follows the language switch (UI kit `setLanguage`) without
|
|
223
|
+
* a reload. A plain string stays as registered.
|
|
224
|
+
*/
|
|
225
|
+
label: string | (() => string);
|
|
222
226
|
/** Glyph name of @idosgames/react/ui ("shop", "hero"…), an emoji, or an image URL. */
|
|
223
227
|
icon?: string;
|
|
224
228
|
group?: FeatureGroup;
|
|
@@ -236,7 +240,9 @@ interface FeatureDefinition {
|
|
|
236
240
|
available?: boolean;
|
|
237
241
|
}
|
|
238
242
|
/** A registered feature plus its live badge and availability. */
|
|
239
|
-
interface FeatureEntry extends FeatureDefinition {
|
|
243
|
+
interface FeatureEntry extends Omit<FeatureDefinition, "label"> {
|
|
244
|
+
/** The label now — a function label is called on every read. */
|
|
245
|
+
readonly label: string;
|
|
240
246
|
badge: number;
|
|
241
247
|
/** The module that registered it. */
|
|
242
248
|
moduleId: string;
|
|
@@ -357,6 +363,84 @@ interface MultiplayerRegistry {
|
|
|
357
363
|
subscribe(listener: () => void): () => void;
|
|
358
364
|
}
|
|
359
365
|
|
|
366
|
+
/** A button under the showcase or on the "Play" card. */
|
|
367
|
+
interface LobbyHeroAction {
|
|
368
|
+
id: string;
|
|
369
|
+
/** Already in the player's language. */
|
|
370
|
+
label: string;
|
|
371
|
+
/** Glyph name of @idosgames/react/ui ("edit", "star"…), an emoji, or an image URL. */
|
|
372
|
+
icon?: string;
|
|
373
|
+
/** Pressed. Omit when the button only opens `menu`. */
|
|
374
|
+
run?(): void;
|
|
375
|
+
/** A short list shown when the button is pressed (an emote picker) — each entry runs on its own. */
|
|
376
|
+
menu?: LobbyHeroAction[];
|
|
377
|
+
disabled?: boolean;
|
|
378
|
+
}
|
|
379
|
+
/** What the lobby lays out around the showcase. Read through `view()`, redrawn on `subscribe`. */
|
|
380
|
+
interface LobbyHeroView {
|
|
381
|
+
/** Big name under the showcase (the character's name). */
|
|
382
|
+
title?: string;
|
|
383
|
+
/** A line under it. */
|
|
384
|
+
subtitle?: string;
|
|
385
|
+
/** Buttons under the name ("Edit", "Emote"). */
|
|
386
|
+
actions?: LobbyHeroAction[];
|
|
387
|
+
/**
|
|
388
|
+
* The card next to "Play" — WHAT will be played: a caption ("World"), a name ("Island"), buttons
|
|
389
|
+
* to change it ("Change", "New"). Omitted — "Play" alone.
|
|
390
|
+
*/
|
|
391
|
+
play?: {
|
|
392
|
+
caption?: string;
|
|
393
|
+
title?: string;
|
|
394
|
+
actions?: LobbyHeroAction[];
|
|
395
|
+
/** Overflow menu of the card ("⋯": download, upload…). */
|
|
396
|
+
more?: LobbyHeroAction[];
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
/** Handed to `mount`: where on the host the main figure should stand. */
|
|
400
|
+
interface LobbyHeroStage {
|
|
401
|
+
/**
|
|
402
|
+
* The free spot between the lobby's interface where the figure should stand, in CSS pixels of the
|
|
403
|
+
* host element (it moves with the layout — read it every frame). `null` — not laid out yet.
|
|
404
|
+
*/
|
|
405
|
+
spot(): {
|
|
406
|
+
x: number;
|
|
407
|
+
y: number;
|
|
408
|
+
w: number;
|
|
409
|
+
h: number;
|
|
410
|
+
} | null;
|
|
411
|
+
}
|
|
412
|
+
interface LobbyHeroDefinition {
|
|
413
|
+
/** The game mode "Play" starts (a route id of the game). */
|
|
414
|
+
mode: string;
|
|
415
|
+
/**
|
|
416
|
+
* Put the showcase into `host` — an element filling the lobby's home behind its interface. Called
|
|
417
|
+
* when the home is shown, the returned function when it is left (stop the render loop there). The
|
|
418
|
+
* same hero may be mounted again later.
|
|
419
|
+
*/
|
|
420
|
+
mount(host: HTMLElement, stage: LobbyHeroStage): () => void;
|
|
421
|
+
/** The current texts and buttons. Cheap — called on every redraw. */
|
|
422
|
+
view(): LobbyHeroView;
|
|
423
|
+
/** Called by the hero whenever `view()` would answer differently. Returns the unsubscribe. */
|
|
424
|
+
subscribe(listener: () => void): () => void;
|
|
425
|
+
/**
|
|
426
|
+
* "Play" was pressed: return false to stay in the lobby (nothing to play yet). Default: switch to
|
|
427
|
+
* `mode`.
|
|
428
|
+
*/
|
|
429
|
+
beforePlay?(): boolean;
|
|
430
|
+
}
|
|
431
|
+
/** `ctx.lobby` — the app's lobby as seen by a module. */
|
|
432
|
+
interface LobbyRegistry {
|
|
433
|
+
/** Put this game's showcase on the lobby's home. Returns the unregister function. */
|
|
434
|
+
setHero(hero: LobbyHeroDefinition): () => void;
|
|
435
|
+
/** The hero on the home now (the lobby reads it). */
|
|
436
|
+
hero(): LobbyHeroDefinition | null;
|
|
437
|
+
subscribe(listener: () => void): () => void;
|
|
438
|
+
/** Whether the app has a lobby to return to (the base is installed). */
|
|
439
|
+
available(): boolean;
|
|
440
|
+
/** Go to the lobby — a game's "To the lobby" in its pause menu. False — there is no lobby. */
|
|
441
|
+
open(): boolean;
|
|
442
|
+
}
|
|
443
|
+
|
|
360
444
|
/** One piece of work on the loading screen. Call `done()` exactly once, also on failure. */
|
|
361
445
|
interface LoadingTask {
|
|
362
446
|
/**
|
|
@@ -629,6 +713,12 @@ interface ModuleContext {
|
|
|
629
713
|
* builds its "Play" buttons from it; a game can tell whether a lobby exists to return to.
|
|
630
714
|
*/
|
|
631
715
|
modes: ModeRegistry;
|
|
716
|
+
/**
|
|
717
|
+
* The app's lobby: a game puts its showcase on the lobby's home (`setHero` — its character on a
|
|
718
|
+
* pedestal, "Play" next to it) and sends the player back to it from its pause menu (`open`). See
|
|
719
|
+
* `LobbyHeroDefinition`.
|
|
720
|
+
*/
|
|
721
|
+
lobby: LobbyRegistry;
|
|
632
722
|
/**
|
|
633
723
|
* Switch the host to another mode (a route id registered by any module) — e.g. the lobby starts a
|
|
634
724
|
* game, the Workshop opens a world and hands the screen to the game. Unknown ids are ignored. Called
|
|
@@ -790,9 +880,15 @@ interface RouteEntry {
|
|
|
790
880
|
* A game that lives INSIDE the lobby: the base keeps the lobby's balances on top and its tabs at
|
|
791
881
|
* the bottom around it, "Play" is this game, and the app starts in it after sign-in (idle-rpg).
|
|
792
882
|
* Without it (the default) a game takes the whole screen, launched by "Play" in the lobby, with a
|
|
793
|
-
* small button back (
|
|
883
|
+
* small button back (board-game).
|
|
794
884
|
*/
|
|
795
885
|
inLobby?: boolean;
|
|
886
|
+
/**
|
|
887
|
+
* A full-screen game with its OWN way back to the lobby (a pause menu with "To the lobby" that
|
|
888
|
+
* calls `ctx.lobby.open()` — voxelcraft): the base does not draw its round button back over it.
|
|
889
|
+
* The game must then offer that way on every device (a pause button on touch screens).
|
|
890
|
+
*/
|
|
891
|
+
ownExit?: boolean;
|
|
796
892
|
}
|
|
797
893
|
/** A mode of the app as every module sees it (`ctx.modes`): a registered route plus its owner. */
|
|
798
894
|
interface ModeEntry {
|
|
@@ -807,6 +903,8 @@ interface ModeEntry {
|
|
|
807
903
|
moduleType: ModuleType;
|
|
808
904
|
/** The route's `inLobby`: the game sits inside the lobby rather than taking the whole screen. */
|
|
809
905
|
inLobby?: boolean;
|
|
906
|
+
/** The route's `ownExit`: the game leads back to the lobby itself — no button back over it. */
|
|
907
|
+
ownExit?: boolean;
|
|
810
908
|
}
|
|
811
909
|
/** `ctx.modes` — the modes of the app, live. Switch with `ctx.navigate(id)`. */
|
|
812
910
|
interface ModeRegistry {
|
|
@@ -832,4 +930,4 @@ interface SharedEventBus<Events extends Record<string, unknown> = Record<string,
|
|
|
832
930
|
/** Identity helper that pins a module literal to the `Module` type for editor help and errors. */
|
|
833
931
|
declare function defineModule(module: Module): Module;
|
|
834
932
|
|
|
835
|
-
export { type AppNotifications, type CapturedContent, type ContentFileData, type ContentRegistry, type ContentTypeHandler, type DownloadedContent, type EngineScene, type FeatureDefinition, type FeatureEntry, type FeatureGroup, type FeaturePresenter, type FeatureRegistry, type FeatureScreenProps, type InferShape, type LoadingReporter, type LoadingTask, type LocalContentItem, type ModeEntry, type ModeRegistry, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleEventEmit, type ModuleEventListen, type ModuleEvents, type ModuleEventsManifest, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleSharedUi, type ModuleType, type MultiplayerGame, type MultiplayerRegistry, type MultiplayerRoom, type MultiplayerScreenArgs, type MultiplayerSetting, type NotificationAction, type NotificationInput, type NotificationLevel, type PanelSlot, type RouteEntry, SHARED_UI_ROLES, type SceneMountContext, type Shape, type ShapeDescriptor, type ShapeLeaf, type ShapeLeafSpec, type SharedEventBus, type SharedUiContext, type SharedUiRole, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, TOPIC_NAME_RE, type Topic, type TopicName, type TopicPayload, type UiPanel, defineModule, defineTopic, hostTopics, isSharedUiRole, isTopicName, shape, topicNamespace };
|
|
933
|
+
export { type AppNotifications, type CapturedContent, type ContentFileData, type ContentRegistry, type ContentTypeHandler, type DownloadedContent, type EngineScene, type FeatureDefinition, type FeatureEntry, type FeatureGroup, type FeaturePresenter, type FeatureRegistry, type FeatureScreenProps, type InferShape, type LoadingReporter, type LoadingTask, type LobbyHeroAction, type LobbyHeroDefinition, type LobbyHeroStage, type LobbyHeroView, type LobbyRegistry, type LocalContentItem, type ModeEntry, type ModeRegistry, type Module, type ModuleAgentApi, type ModuleAuthor, type ModuleContext, type ModuleEngine, type ModuleEventEmit, type ModuleEventListen, type ModuleEvents, type ModuleEventsManifest, type ModuleManifest, type ModuleMedia, type ModuleMeta, type ModuleSharedUi, type ModuleType, type MultiplayerGame, type MultiplayerRegistry, type MultiplayerRoom, type MultiplayerScreenArgs, type MultiplayerSetting, type NotificationAction, type NotificationInput, type NotificationLevel, type PanelSlot, type RouteEntry, SHARED_UI_ROLES, type SceneMountContext, type Shape, type ShapeDescriptor, type ShapeLeaf, type ShapeLeafSpec, type SharedEventBus, type SharedUiContext, type SharedUiRole, type SurfaceAllocator, type SurfaceHandle, type SurfaceKind, TOPIC_NAME_RE, type Topic, type TopicName, type TopicPayload, type UiPanel, defineModule, defineTopic, hostTopics, isSharedUiRole, isTopicName, shape, topicNamespace };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var x=/^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*@[1-9]\d*$/;function S(e){return typeof e=="string"&&x.test(e)}function
|
|
1
|
+
var x=/^[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-]*@[1-9]\d*$/;function S(e){return typeof e=="string"&&x.test(e)}function M(e){let t=e.indexOf(":");return t<0?"":e.slice(0,t)}var c=/^(string|number|boolean)(\[\])?(\?)?$/;function u(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function l(e,t){return e==="number"?typeof t=="number"&&Number.isFinite(t):typeof t===e}function f(e,t,r){if(!u(t))return `${r||"payload"} must be an object`;for(let[n,o]of Object.entries(e)){let i=r?`${r}.${n}`:n,a=t[n];if(typeof o!="string"){let p=f(o,a,i);if(p)return p;continue}let d=c.exec(o);if(!d)return `${i}: invalid descriptor "${o}"`;let[,s="",g,m]=d;if(a===void 0){if(m)continue;return `${i} is missing`}if(g){if(!Array.isArray(a))return `${i} must be ${s}[]`;if(!a.every(p=>l(s,p)))return `${i} must contain only ${s} values`;continue}if(!l(s,a))return `${i} must be a ${s}`}return null}function y(e,t){for(let[r,n]of Object.entries(e)){let o=t?`${t}.${r}`:r;if(typeof n=="string"){if(!c.test(n))throw new Error(`shape(): field "${o}" has invalid type "${n}" \u2014 use "string" | "number" | "boolean", optionally with "[]" and/or a trailing "?"`)}else if(u(n))y(n,o);else throw new Error(`shape(): field "${o}" must be a type string or an object`)}}function h(e){return y(e,""),{descriptor:e,check:t=>f(e,t,"")}}function v(e,t){if(!S(e))throw new Error(`defineTopic(): "${e}" is not a valid topic name \u2014 expected "<module-id>:<event>@<major>", e.g. "idle-rpg:character-upgraded@1"`);return {name:e,shape:t}}var T={modeChanged:v("host:mode-changed@1",h({from:"string?",to:"string"}))};var b=["currency-bar","wallet","status","account","menu","modes"];function R(e){return typeof e=="string"&&b.includes(e)}function D(e){return e}export{b as SHARED_UI_ROLES,x as TOPIC_NAME_RE,D as defineModule,v as defineTopic,T as hostTopics,R as isSharedUiRole,S as isTopicName,h as shape,M as topicNamespace};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idosgames/module-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "The composable-module contract for the iDosGames host shell: Module / ModuleContext types plus tiny authoring helpers. Framework-neutral at runtime — a module can be a game (Three/Phaser), a plain app, or an AI app.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|