@idosgames/module-sdk 0.5.0 → 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/dist/index.cjs +1 -1
- package/dist/index.d.cts +63 -10
- package/dist/index.d.ts +63 -10
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
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 T(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,o){if(!u(t))return `${o||"payload"} must be an object`;for(let[n,r]of Object.entries(e)){let i=o?`${o}.${n}`:n,a=t[n];if(typeof r!="string"){let p=f(r,a,i);if(p)return p;continue}let d=c.exec(r);if(!d)return `${i}: invalid descriptor "${r}"`;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[o,n]of Object.entries(e)){let r=t?`${t}.${o}`:o;if(typeof n=="string"){if(!c.test(n))throw new Error(`shape(): field "${r}" has invalid type "${n}" \u2014 use "string" | "number" | "boolean", optionally with "[]" and/or a trailing "?"`)}else if(u(n))y(n,r);else throw new Error(`shape(): field "${r}" 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 b={modeChanged:v("host:mode-changed@1",h({from:"string?",to:"string"}))};var M=["currency-bar","wallet","status","account","menu","modes"];function R(e){return typeof e=="string"&&M.includes(e)}function D(e){return e}exports.SHARED_UI_ROLES=M;exports.TOPIC_NAME_RE=x;exports.defineModule=D;exports.defineTopic=v;exports.hostTopics=b;exports.isSharedUiRole=R;exports.isTopicName=S;exports.shape=h;exports.topicNamespace=T;
|
package/dist/index.d.cts
CHANGED
|
@@ -111,7 +111,7 @@ interface ModuleEventsManifest {
|
|
|
111
111
|
* each one has to mean the same thing across the whole catalog. A new role is a minor release of
|
|
112
112
|
* this package; anything that does not fit a role is plain events + SDK data.
|
|
113
113
|
*/
|
|
114
|
-
declare const SHARED_UI_ROLES: readonly ["currency-bar", "wallet", "status", "account", "menu"];
|
|
114
|
+
declare const SHARED_UI_ROLES: readonly ["currency-bar", "wallet", "status", "account", "menu", "modes"];
|
|
115
115
|
type SharedUiRole = (typeof SHARED_UI_ROLES)[number];
|
|
116
116
|
/** Static declaration on a module (`Module.sharedUi`). */
|
|
117
117
|
interface ModuleSharedUi {
|
|
@@ -125,8 +125,8 @@ interface ModuleSharedUi {
|
|
|
125
125
|
/**
|
|
126
126
|
* Roles this module draws INSIDE ITS OWN MODE while nobody `provides` them for everybody — a
|
|
127
127
|
* template with a full-screen UI (bottom tab bar) puts "Log out" and the player's ID into its own
|
|
128
|
-
* header instead of having the host float them over its layout. Only "account" and "
|
|
129
|
-
* host-drawn, so those are the roles this matters for: the host hides its floating copy while this
|
|
128
|
+
* header instead of having the host float them over its layout. Only "account", "menu" and "modes"
|
|
129
|
+
* are host-drawn, so those are the roles this matters for: the host hides its floating copy while this
|
|
130
130
|
* module's mode is on screen and keeps drawing it in every other mode. `shouldDraw` of every module
|
|
131
131
|
* is unchanged.
|
|
132
132
|
*/
|
|
@@ -215,7 +215,7 @@ interface FeatureScreenProps {
|
|
|
215
215
|
close(): void;
|
|
216
216
|
}
|
|
217
217
|
interface FeatureDefinition {
|
|
218
|
-
/** Unique across the game — conventionally the owning module's id
|
|
218
|
+
/** Unique across the game — conventionally the owning module's id ("store"). */
|
|
219
219
|
id: string;
|
|
220
220
|
/** Menu label, already in the player's language. */
|
|
221
221
|
label: string;
|
|
@@ -228,17 +228,27 @@ interface FeatureDefinition {
|
|
|
228
228
|
primary?: boolean;
|
|
229
229
|
/** The screen. Rendered by the presenter, inside the kit provider and the client provider. */
|
|
230
230
|
Screen: ComponentType<FeatureScreenProps>;
|
|
231
|
+
/**
|
|
232
|
+
* Whether the title has something for this screen yet. Default `true`. A screen that depends on
|
|
233
|
+
* title data (a shop without offers is an empty tab) registers with `false` and calls
|
|
234
|
+
* `setAvailable(id, true)` once it has checked — so the tab never flashes in and out.
|
|
235
|
+
*/
|
|
236
|
+
available?: boolean;
|
|
231
237
|
}
|
|
232
|
-
/** A registered feature plus its live badge. */
|
|
238
|
+
/** A registered feature plus its live badge and availability. */
|
|
233
239
|
interface FeatureEntry extends FeatureDefinition {
|
|
234
240
|
badge: number;
|
|
235
241
|
/** The module that registered it. */
|
|
236
242
|
moduleId: string;
|
|
243
|
+
/** Menus list only available features; `open()` of an unavailable one is refused. */
|
|
244
|
+
available: boolean;
|
|
245
|
+
/** Why it is hidden, in plain words — shown to the AI Coder's agent, never to players. */
|
|
246
|
+
unavailableReason?: string;
|
|
237
247
|
}
|
|
238
248
|
/**
|
|
239
249
|
* Shows a feature's screen. The menu owner registers one; the most recent presenter wins, and
|
|
240
250
|
* unregistering hands the job back to the previous one (the lobby unmounts when the player switches
|
|
241
|
-
* to
|
|
251
|
+
* to a game → the host's window presents again).
|
|
242
252
|
*/
|
|
243
253
|
type FeaturePresenter = (id: string, args?: Record<string, unknown>) => boolean;
|
|
244
254
|
/** `ctx.features` — the registry of the game's features, shared by every module of the session. */
|
|
@@ -248,10 +258,18 @@ interface FeatureRegistry {
|
|
|
248
258
|
/** Features in registration order (menus sort them themselves). */
|
|
249
259
|
list(): FeatureEntry[];
|
|
250
260
|
get(id: string): FeatureEntry | undefined;
|
|
251
|
-
/**
|
|
261
|
+
/**
|
|
262
|
+
* Opens a feature's screen through the current presenter. `false` — no such feature, it is not
|
|
263
|
+
* available on this title, or no presenter.
|
|
264
|
+
*/
|
|
252
265
|
open(id: string, args?: Record<string, unknown>): boolean;
|
|
253
266
|
/** The "something to claim" counter of a feature; 0 hides it. */
|
|
254
267
|
setBadge(id: string, count: number): void;
|
|
268
|
+
/**
|
|
269
|
+
* Show or hide a feature by what the title has (see `FeatureDefinition.available`). `reason` says
|
|
270
|
+
* why it is hidden ("no store offers configured on the title") — the agent reads it.
|
|
271
|
+
*/
|
|
272
|
+
setAvailable(id: string, available: boolean, reason?: string): void;
|
|
255
273
|
/** Called on every registration, removal and badge change. */
|
|
256
274
|
subscribe(listener: () => void): () => void;
|
|
257
275
|
/** For menu owners: become the one who shows screens. Returns an unregister function. */
|
|
@@ -309,6 +327,11 @@ interface ModuleManifest {
|
|
|
309
327
|
* `"feature"`.
|
|
310
328
|
*/
|
|
311
329
|
type?: "template" | "feature";
|
|
330
|
+
/**
|
|
331
|
+
* Part of the standard set: the platform installs this module into EVERY new project together with
|
|
332
|
+
* the base (login + lobby) — the shop, heroes, leaderboards… A creator removes it like any module.
|
|
333
|
+
*/
|
|
334
|
+
inBase?: boolean;
|
|
312
335
|
/** Overrides the catalog display name; defaults to `ModuleMeta.name` from `module.ts`. */
|
|
313
336
|
name?: string;
|
|
314
337
|
/** One-line pitch shown on the catalog card. */
|
|
@@ -409,8 +432,14 @@ interface ModuleContext {
|
|
|
409
432
|
*/
|
|
410
433
|
features: FeatureRegistry;
|
|
411
434
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
435
|
+
* The app's modes — every route any module registered, and which one is on screen. The lobby
|
|
436
|
+
* builds its "Play" buttons from it; a game can tell whether a lobby exists to return to.
|
|
437
|
+
*/
|
|
438
|
+
modes: ModeRegistry;
|
|
439
|
+
/**
|
|
440
|
+
* Switch the host to another mode (a route id registered by any module) — e.g. the lobby starts a
|
|
441
|
+
* game, the Workshop opens a world and hands the screen to the game. Unknown ids are ignored. Called
|
|
442
|
+
* inside `setup()` it picks the mode the app starts in.
|
|
414
443
|
*/
|
|
415
444
|
navigate(modeId: string): void;
|
|
416
445
|
/**
|
|
@@ -535,6 +564,30 @@ interface RouteEntry {
|
|
|
535
564
|
icon?: string;
|
|
536
565
|
order?: number;
|
|
537
566
|
}
|
|
567
|
+
/** A mode of the app as every module sees it (`ctx.modes`): a registered route plus its owner. */
|
|
568
|
+
interface ModeEntry {
|
|
569
|
+
id: string;
|
|
570
|
+
label: string;
|
|
571
|
+
icon?: string;
|
|
572
|
+
/** Resolved order (0 when the route gave none); the list is sorted by it. */
|
|
573
|
+
order: number;
|
|
574
|
+
/** The module that registered the route. */
|
|
575
|
+
moduleId: string;
|
|
576
|
+
/** That module's `meta.type` — a lobby offers "Play" for `game` modes. */
|
|
577
|
+
moduleType: ModuleType;
|
|
578
|
+
}
|
|
579
|
+
/** `ctx.modes` — the modes of the app, live. Switch with `ctx.navigate(id)`. */
|
|
580
|
+
interface ModeRegistry {
|
|
581
|
+
/**
|
|
582
|
+
* Every mode, sorted by `order`. Filled once every module's `setup()` has run — read it at render
|
|
583
|
+
* time or subscribe, not inside `setup()`.
|
|
584
|
+
*/
|
|
585
|
+
list(): ModeEntry[];
|
|
586
|
+
/** The mode on screen; `null` until the app is shown. */
|
|
587
|
+
current(): string | null;
|
|
588
|
+
/** Called when the list or the current mode changes. Returns the unsubscribe function. */
|
|
589
|
+
subscribe(listener: () => void): () => void;
|
|
590
|
+
}
|
|
538
591
|
/**
|
|
539
592
|
* @deprecated The pre-0.2 string-topic bus. `ctx.events` is now `ModuleEvents` (typed topic tokens,
|
|
540
593
|
* see `defineTopic`); this type stays only so older code that named it still compiles.
|
|
@@ -547,4 +600,4 @@ interface SharedEventBus<Events extends Record<string, unknown> = Record<string,
|
|
|
547
600
|
/** Identity helper that pins a module literal to the `Module` type for editor help and errors. */
|
|
548
601
|
declare function defineModule(module: Module): Module;
|
|
549
602
|
|
|
550
|
-
export { 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 LocalContentItem, 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 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 };
|
|
603
|
+
export { 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 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 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
|
@@ -111,7 +111,7 @@ interface ModuleEventsManifest {
|
|
|
111
111
|
* each one has to mean the same thing across the whole catalog. A new role is a minor release of
|
|
112
112
|
* this package; anything that does not fit a role is plain events + SDK data.
|
|
113
113
|
*/
|
|
114
|
-
declare const SHARED_UI_ROLES: readonly ["currency-bar", "wallet", "status", "account", "menu"];
|
|
114
|
+
declare const SHARED_UI_ROLES: readonly ["currency-bar", "wallet", "status", "account", "menu", "modes"];
|
|
115
115
|
type SharedUiRole = (typeof SHARED_UI_ROLES)[number];
|
|
116
116
|
/** Static declaration on a module (`Module.sharedUi`). */
|
|
117
117
|
interface ModuleSharedUi {
|
|
@@ -125,8 +125,8 @@ interface ModuleSharedUi {
|
|
|
125
125
|
/**
|
|
126
126
|
* Roles this module draws INSIDE ITS OWN MODE while nobody `provides` them for everybody — a
|
|
127
127
|
* template with a full-screen UI (bottom tab bar) puts "Log out" and the player's ID into its own
|
|
128
|
-
* header instead of having the host float them over its layout. Only "account" and "
|
|
129
|
-
* host-drawn, so those are the roles this matters for: the host hides its floating copy while this
|
|
128
|
+
* header instead of having the host float them over its layout. Only "account", "menu" and "modes"
|
|
129
|
+
* are host-drawn, so those are the roles this matters for: the host hides its floating copy while this
|
|
130
130
|
* module's mode is on screen and keeps drawing it in every other mode. `shouldDraw` of every module
|
|
131
131
|
* is unchanged.
|
|
132
132
|
*/
|
|
@@ -215,7 +215,7 @@ interface FeatureScreenProps {
|
|
|
215
215
|
close(): void;
|
|
216
216
|
}
|
|
217
217
|
interface FeatureDefinition {
|
|
218
|
-
/** Unique across the game — conventionally the owning module's id
|
|
218
|
+
/** Unique across the game — conventionally the owning module's id ("store"). */
|
|
219
219
|
id: string;
|
|
220
220
|
/** Menu label, already in the player's language. */
|
|
221
221
|
label: string;
|
|
@@ -228,17 +228,27 @@ interface FeatureDefinition {
|
|
|
228
228
|
primary?: boolean;
|
|
229
229
|
/** The screen. Rendered by the presenter, inside the kit provider and the client provider. */
|
|
230
230
|
Screen: ComponentType<FeatureScreenProps>;
|
|
231
|
+
/**
|
|
232
|
+
* Whether the title has something for this screen yet. Default `true`. A screen that depends on
|
|
233
|
+
* title data (a shop without offers is an empty tab) registers with `false` and calls
|
|
234
|
+
* `setAvailable(id, true)` once it has checked — so the tab never flashes in and out.
|
|
235
|
+
*/
|
|
236
|
+
available?: boolean;
|
|
231
237
|
}
|
|
232
|
-
/** A registered feature plus its live badge. */
|
|
238
|
+
/** A registered feature plus its live badge and availability. */
|
|
233
239
|
interface FeatureEntry extends FeatureDefinition {
|
|
234
240
|
badge: number;
|
|
235
241
|
/** The module that registered it. */
|
|
236
242
|
moduleId: string;
|
|
243
|
+
/** Menus list only available features; `open()` of an unavailable one is refused. */
|
|
244
|
+
available: boolean;
|
|
245
|
+
/** Why it is hidden, in plain words — shown to the AI Coder's agent, never to players. */
|
|
246
|
+
unavailableReason?: string;
|
|
237
247
|
}
|
|
238
248
|
/**
|
|
239
249
|
* Shows a feature's screen. The menu owner registers one; the most recent presenter wins, and
|
|
240
250
|
* unregistering hands the job back to the previous one (the lobby unmounts when the player switches
|
|
241
|
-
* to
|
|
251
|
+
* to a game → the host's window presents again).
|
|
242
252
|
*/
|
|
243
253
|
type FeaturePresenter = (id: string, args?: Record<string, unknown>) => boolean;
|
|
244
254
|
/** `ctx.features` — the registry of the game's features, shared by every module of the session. */
|
|
@@ -248,10 +258,18 @@ interface FeatureRegistry {
|
|
|
248
258
|
/** Features in registration order (menus sort them themselves). */
|
|
249
259
|
list(): FeatureEntry[];
|
|
250
260
|
get(id: string): FeatureEntry | undefined;
|
|
251
|
-
/**
|
|
261
|
+
/**
|
|
262
|
+
* Opens a feature's screen through the current presenter. `false` — no such feature, it is not
|
|
263
|
+
* available on this title, or no presenter.
|
|
264
|
+
*/
|
|
252
265
|
open(id: string, args?: Record<string, unknown>): boolean;
|
|
253
266
|
/** The "something to claim" counter of a feature; 0 hides it. */
|
|
254
267
|
setBadge(id: string, count: number): void;
|
|
268
|
+
/**
|
|
269
|
+
* Show or hide a feature by what the title has (see `FeatureDefinition.available`). `reason` says
|
|
270
|
+
* why it is hidden ("no store offers configured on the title") — the agent reads it.
|
|
271
|
+
*/
|
|
272
|
+
setAvailable(id: string, available: boolean, reason?: string): void;
|
|
255
273
|
/** Called on every registration, removal and badge change. */
|
|
256
274
|
subscribe(listener: () => void): () => void;
|
|
257
275
|
/** For menu owners: become the one who shows screens. Returns an unregister function. */
|
|
@@ -309,6 +327,11 @@ interface ModuleManifest {
|
|
|
309
327
|
* `"feature"`.
|
|
310
328
|
*/
|
|
311
329
|
type?: "template" | "feature";
|
|
330
|
+
/**
|
|
331
|
+
* Part of the standard set: the platform installs this module into EVERY new project together with
|
|
332
|
+
* the base (login + lobby) — the shop, heroes, leaderboards… A creator removes it like any module.
|
|
333
|
+
*/
|
|
334
|
+
inBase?: boolean;
|
|
312
335
|
/** Overrides the catalog display name; defaults to `ModuleMeta.name` from `module.ts`. */
|
|
313
336
|
name?: string;
|
|
314
337
|
/** One-line pitch shown on the catalog card. */
|
|
@@ -409,8 +432,14 @@ interface ModuleContext {
|
|
|
409
432
|
*/
|
|
410
433
|
features: FeatureRegistry;
|
|
411
434
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
435
|
+
* The app's modes — every route any module registered, and which one is on screen. The lobby
|
|
436
|
+
* builds its "Play" buttons from it; a game can tell whether a lobby exists to return to.
|
|
437
|
+
*/
|
|
438
|
+
modes: ModeRegistry;
|
|
439
|
+
/**
|
|
440
|
+
* Switch the host to another mode (a route id registered by any module) — e.g. the lobby starts a
|
|
441
|
+
* game, the Workshop opens a world and hands the screen to the game. Unknown ids are ignored. Called
|
|
442
|
+
* inside `setup()` it picks the mode the app starts in.
|
|
414
443
|
*/
|
|
415
444
|
navigate(modeId: string): void;
|
|
416
445
|
/**
|
|
@@ -535,6 +564,30 @@ interface RouteEntry {
|
|
|
535
564
|
icon?: string;
|
|
536
565
|
order?: number;
|
|
537
566
|
}
|
|
567
|
+
/** A mode of the app as every module sees it (`ctx.modes`): a registered route plus its owner. */
|
|
568
|
+
interface ModeEntry {
|
|
569
|
+
id: string;
|
|
570
|
+
label: string;
|
|
571
|
+
icon?: string;
|
|
572
|
+
/** Resolved order (0 when the route gave none); the list is sorted by it. */
|
|
573
|
+
order: number;
|
|
574
|
+
/** The module that registered the route. */
|
|
575
|
+
moduleId: string;
|
|
576
|
+
/** That module's `meta.type` — a lobby offers "Play" for `game` modes. */
|
|
577
|
+
moduleType: ModuleType;
|
|
578
|
+
}
|
|
579
|
+
/** `ctx.modes` — the modes of the app, live. Switch with `ctx.navigate(id)`. */
|
|
580
|
+
interface ModeRegistry {
|
|
581
|
+
/**
|
|
582
|
+
* Every mode, sorted by `order`. Filled once every module's `setup()` has run — read it at render
|
|
583
|
+
* time or subscribe, not inside `setup()`.
|
|
584
|
+
*/
|
|
585
|
+
list(): ModeEntry[];
|
|
586
|
+
/** The mode on screen; `null` until the app is shown. */
|
|
587
|
+
current(): string | null;
|
|
588
|
+
/** Called when the list or the current mode changes. Returns the unsubscribe function. */
|
|
589
|
+
subscribe(listener: () => void): () => void;
|
|
590
|
+
}
|
|
538
591
|
/**
|
|
539
592
|
* @deprecated The pre-0.2 string-topic bus. `ctx.events` is now `ModuleEvents` (typed topic tokens,
|
|
540
593
|
* see `defineTopic`); this type stays only so older code that named it still compiles.
|
|
@@ -547,4 +600,4 @@ interface SharedEventBus<Events extends Record<string, unknown> = Record<string,
|
|
|
547
600
|
/** Identity helper that pins a module literal to the `Module` type for editor help and errors. */
|
|
548
601
|
declare function defineModule(module: Module): Module;
|
|
549
602
|
|
|
550
|
-
export { 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 LocalContentItem, 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 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 };
|
|
603
|
+
export { 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 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 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
|
|
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 T(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,o){if(!u(t))return `${o||"payload"} must be an object`;for(let[n,r]of Object.entries(e)){let i=o?`${o}.${n}`:n,a=t[n];if(typeof r!="string"){let p=f(r,a,i);if(p)return p;continue}let d=c.exec(r);if(!d)return `${i}: invalid descriptor "${r}"`;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[o,n]of Object.entries(e)){let r=t?`${t}.${o}`:o;if(typeof n=="string"){if(!c.test(n))throw new Error(`shape(): field "${r}" has invalid type "${n}" \u2014 use "string" | "number" | "boolean", optionally with "[]" and/or a trailing "?"`)}else if(u(n))y(n,r);else throw new Error(`shape(): field "${r}" 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 b={modeChanged:v("host:mode-changed@1",h({from:"string?",to:"string"}))};var M=["currency-bar","wallet","status","account","menu","modes"];function R(e){return typeof e=="string"&&M.includes(e)}function D(e){return e}export{M as SHARED_UI_ROLES,x as TOPIC_NAME_RE,D as defineModule,v as defineTopic,b as hostTopics,R as isSharedUiRole,S as isTopicName,h as shape,T as topicNamespace};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idosgames/module-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "The composable-module contract for the iDosGames host shell: Module / ModuleContext types plus tiny authoring helpers. Framework-neutral at runtime
|
|
3
|
+
"version": "0.6.0",
|
|
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",
|
|
7
7
|
"author": "iDos Games",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"build": "tsup",
|
|
45
45
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
46
46
|
},
|
|
47
|
-
"//": "@idosgames/core is a real range, not '*': a published contract must name the version of core whose IDosGamesClient/SdkEvents shapes it references. Bump in step with core (see RELEASING.md). react is an OPTIONAL peer
|
|
47
|
+
"//": "@idosgames/core is a real range, not '*': a published contract must name the version of core whose IDosGamesClient/SdkEvents shapes it references. Bump in step with core (see RELEASING.md). react is an OPTIONAL peer — the contract references React's ComponentType type only (a UI panel is a React component), which is erased at build, so a runtime-only module needs no React.",
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@idosgames/core": "^0.19.0"
|
|
50
50
|
},
|