@sharpee/stdlib 0.9.113 → 1.0.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/actions/enhanced-context.d.ts.map +1 -1
- package/actions/enhanced-context.js +16 -0
- package/actions/enhanced-context.js.map +1 -1
- package/actions/enhanced-types.d.ts +35 -0
- package/actions/enhanced-types.d.ts.map +1 -1
- package/actions/enhanced-types.js.map +1 -1
- package/actions/index.d.ts +0 -1
- package/actions/index.d.ts.map +1 -1
- package/actions/index.js +0 -1
- package/actions/index.js.map +1 -1
- package/actions/standard/about/about-events.d.ts +2 -0
- package/actions/standard/about/about-events.d.ts.map +1 -1
- package/actions/standard/about/about.d.ts.map +1 -1
- package/actions/standard/about/about.js +4 -1
- package/actions/standard/about/about.js.map +1 -1
- package/actions/standard/examining/examining-data.d.ts.map +1 -1
- package/actions/standard/examining/examining-data.js +34 -0
- package/actions/standard/examining/examining-data.js.map +1 -1
- package/actions/standard/examining/examining-messages.d.ts +1 -0
- package/actions/standard/examining/examining-messages.d.ts.map +1 -1
- package/actions/standard/examining/examining-messages.js +1 -0
- package/actions/standard/examining/examining-messages.js.map +1 -1
- package/actions/standard/examining/examining.d.ts.map +1 -1
- package/actions/standard/examining/examining.js +1 -0
- package/actions/standard/examining/examining.js.map +1 -1
- package/channels/index.d.ts +40 -0
- package/channels/index.d.ts.map +1 -0
- package/channels/index.js +86 -0
- package/channels/index.js.map +1 -0
- package/channels/keys.d.ts +23 -0
- package/channels/keys.d.ts.map +1 -0
- package/channels/keys.js +36 -0
- package/channels/keys.js.map +1 -0
- package/channels/media.d.ts +135 -0
- package/channels/media.d.ts.map +1 -0
- package/channels/media.js +397 -0
- package/channels/media.js.map +1 -0
- package/channels/registry.d.ts +58 -0
- package/channels/registry.d.ts.map +1 -0
- package/channels/registry.js +84 -0
- package/channels/registry.js.map +1 -0
- package/channels/sound-events.d.ts +72 -0
- package/channels/sound-events.d.ts.map +1 -0
- package/channels/sound-events.js +88 -0
- package/channels/sound-events.js.map +1 -0
- package/channels/standard.d.ts +209 -0
- package/channels/standard.d.ts.map +1 -0
- package/channels/standard.js +403 -0
- package/channels/standard.js.map +1 -0
- package/channels/world-helpers.d.ts +43 -0
- package/channels/world-helpers.d.ts.map +1 -0
- package/channels/world-helpers.js +72 -0
- package/channels/world-helpers.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/package.json +7 -6
- package/validation/command-validator.d.ts +11 -1
- package/validation/command-validator.d.ts.map +1 -1
- package/validation/command-validator.js +31 -1
- package/validation/command-validator.js.map +1 -1
package/channels/keys.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @sharpee/stdlib/channels — block-key sets used by standard channels.
|
|
4
|
+
*
|
|
5
|
+
* Owner context: stdlib language layer. The standard `main` channel's
|
|
6
|
+
* closure routes prose-shaped blocks (room descriptions, action
|
|
7
|
+
* results, banners, etc.) into the append-mode main transcript.
|
|
8
|
+
* `MAIN_KEYS` names every `CORE_BLOCK_KEYS` entry that should land in
|
|
9
|
+
* the main channel.
|
|
10
|
+
*
|
|
11
|
+
* Block keys not in this set are NOT routed to main automatically —
|
|
12
|
+
* stories override or extend by registering their own `IOChannel`
|
|
13
|
+
* (last-write-wins on channel id) per ADR-163 §6.
|
|
14
|
+
*
|
|
15
|
+
* @see ADR-163 — Channel-Service Platform — §6, §7, §14
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.MAIN_KEYS = void 0;
|
|
19
|
+
const text_blocks_1 = require("../../text-blocks/index.js");
|
|
20
|
+
/**
|
|
21
|
+
* Block keys whose content flows into the `main` channel (append mode,
|
|
22
|
+
* decoration-preserving). Status blocks (`status.score`, `status.turns`,
|
|
23
|
+
* `status.room`) are intentionally absent — those values are now read
|
|
24
|
+
* from world state directly by the score/turn/location channels.
|
|
25
|
+
*/
|
|
26
|
+
exports.MAIN_KEYS = new Set([
|
|
27
|
+
text_blocks_1.CORE_BLOCK_KEYS.ROOM_NAME,
|
|
28
|
+
text_blocks_1.CORE_BLOCK_KEYS.ROOM_DESCRIPTION,
|
|
29
|
+
text_blocks_1.CORE_BLOCK_KEYS.ROOM_CONTENTS,
|
|
30
|
+
text_blocks_1.CORE_BLOCK_KEYS.ACTION_RESULT,
|
|
31
|
+
text_blocks_1.CORE_BLOCK_KEYS.ACTION_BLOCKED,
|
|
32
|
+
text_blocks_1.CORE_BLOCK_KEYS.ERROR,
|
|
33
|
+
text_blocks_1.CORE_BLOCK_KEYS.GAME_MESSAGE,
|
|
34
|
+
text_blocks_1.CORE_BLOCK_KEYS.GAME_BANNER,
|
|
35
|
+
]);
|
|
36
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/stdlib/src/channels/keys.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH,sDAAuD;AAEvD;;;;;GAKG;AACU,QAAA,SAAS,GAAwB,IAAI,GAAG,CAAS;IAC5D,6BAAe,CAAC,SAAS;IACzB,6BAAe,CAAC,gBAAgB;IAChC,6BAAe,CAAC,aAAa;IAC7B,6BAAe,CAAC,aAAa;IAC7B,6BAAe,CAAC,cAAc;IAC9B,6BAAe,CAAC,KAAK;IACrB,6BAAe,CAAC,YAAY;IAC5B,6BAAe,CAAC,WAAW;CAC5B,CAAC,CAAC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sharpee/stdlib/channels — media `IOChannel` definitions.
|
|
3
|
+
*
|
|
4
|
+
* Owner context: stdlib language layer. The platform media-channel
|
|
5
|
+
* vocabulary from ADR-163 §7. Each channel is capability-gated; the
|
|
6
|
+
* `ChannelService` filters gated channels out of the per-client
|
|
7
|
+
* manifest using `IOChannel.gatedBy`.
|
|
8
|
+
*
|
|
9
|
+
* Closures listen for the corresponding `media.*` event type on the
|
|
10
|
+
* turn's `events` array and project the event's payload (with the two
|
|
11
|
+
* ADR-163 §7 renames: `media.sound.play` `channel?` → `bus?`;
|
|
12
|
+
* `media.image.show` hotspots `action` → `command`; and the §9 drop
|
|
13
|
+
* of `media.animation.play.onComplete`).
|
|
14
|
+
*
|
|
15
|
+
* Hide/stop events (`media.image.hide`, `media.music.stop`,
|
|
16
|
+
* `media.ambient.stop`) emit `null` on the corresponding replace-mode
|
|
17
|
+
* media channel — the renderer interprets `null` as "hide / stop".
|
|
18
|
+
*
|
|
19
|
+
* **Dynamic channels** — `image:<layer>` (custom layer beyond
|
|
20
|
+
* `image:background`/`image:main`/`image:overlay`) and `ambient:<id>`
|
|
21
|
+
* are NOT registered here. Stories register them through their own
|
|
22
|
+
* `Story.registerChannels` hook; `createAmbientChannel(id)` and
|
|
23
|
+
* `createImageChannel(layer)` are convenience builders.
|
|
24
|
+
*
|
|
25
|
+
* @see ADR-163 — Channel-Service Platform — §6, §7, §9
|
|
26
|
+
*/
|
|
27
|
+
import type { IOChannel } from "../../if-domain/index";
|
|
28
|
+
import type { ISemanticEvent } from "../../core/index";
|
|
29
|
+
/**
|
|
30
|
+
* Media event types from ADR-101 (folded into channel emissions per
|
|
31
|
+
* ADR-163 §7).
|
|
32
|
+
*/
|
|
33
|
+
export declare const MEDIA_EVENT_TYPES: {
|
|
34
|
+
readonly IMAGE_SHOW: "media.image.show";
|
|
35
|
+
readonly IMAGE_HIDE: "media.image.hide";
|
|
36
|
+
readonly IMAGE_PRELOAD: "media.image.preload";
|
|
37
|
+
readonly SOUND_PLAY: "media.sound.play";
|
|
38
|
+
readonly MUSIC_PLAY: "media.music.play";
|
|
39
|
+
readonly MUSIC_STOP: "media.music.stop";
|
|
40
|
+
readonly AMBIENT_PLAY: "media.ambient.play";
|
|
41
|
+
readonly AMBIENT_STOP: "media.ambient.stop";
|
|
42
|
+
readonly ANIMATION_PLAY: "media.animation.play";
|
|
43
|
+
readonly ANIMATE: "media.animate";
|
|
44
|
+
readonly TRANSITION: "media.transition";
|
|
45
|
+
readonly LAYOUT_CONFIGURE: "media.layout.configure";
|
|
46
|
+
readonly CLEAR: "media.clear";
|
|
47
|
+
};
|
|
48
|
+
export type MediaEventType = (typeof MEDIA_EVENT_TYPES)[keyof typeof MEDIA_EVENT_TYPES];
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the `image:<layer>` channel id from a `media.image.show` /
|
|
51
|
+
* `media.image.hide` event payload. Defaults to `image:main`.
|
|
52
|
+
*/
|
|
53
|
+
export declare function imageChannelIdFromEvent(event: ISemanticEvent): string;
|
|
54
|
+
/**
|
|
55
|
+
* Construct an `image:<layer>` `IOChannel`. Standard layers
|
|
56
|
+
* (`background`, `main`, `overlay`) are pre-registered; stories add
|
|
57
|
+
* additional layers via this builder.
|
|
58
|
+
*/
|
|
59
|
+
export declare function createImageChannel(layer: string): IOChannel;
|
|
60
|
+
export declare const imageBackgroundChannel: IOChannel;
|
|
61
|
+
export declare const imageMainChannel: IOChannel;
|
|
62
|
+
export declare const imageOverlayChannel: IOChannel;
|
|
63
|
+
/**
|
|
64
|
+
* `image:preload` — event-mode preload trigger. Renderers download
|
|
65
|
+
* the asset; not displayed.
|
|
66
|
+
*/
|
|
67
|
+
export declare const imagePreloadChannel: IOChannel;
|
|
68
|
+
/**
|
|
69
|
+
* `sound` — event-mode sound effect.
|
|
70
|
+
*/
|
|
71
|
+
export declare const soundChannel: IOChannel;
|
|
72
|
+
/**
|
|
73
|
+
* `music` — replace-mode music track. `null` emission (from
|
|
74
|
+
* `media.music.stop`) signals "stop".
|
|
75
|
+
*/
|
|
76
|
+
export declare const musicChannel: IOChannel;
|
|
77
|
+
/**
|
|
78
|
+
* Construct an `ambient:<id>` `IOChannel`. Ambient channels are
|
|
79
|
+
* inherently story-defined (ADR-163 §7) — the platform has no
|
|
80
|
+
* predetermined ambient ids. Stories call this once per ambient
|
|
81
|
+
* layer they need.
|
|
82
|
+
*
|
|
83
|
+
* @param ambientId — suffix portion (e.g., `'wind'` registers
|
|
84
|
+
* `ambient:wind`).
|
|
85
|
+
*/
|
|
86
|
+
export declare function createAmbientChannel(ambientId: string): IOChannel;
|
|
87
|
+
/**
|
|
88
|
+
* `animation` — event-mode CSS-style animation. Drops `onComplete`
|
|
89
|
+
* per ADR-163 §9.
|
|
90
|
+
*/
|
|
91
|
+
export declare const animationChannel: IOChannel;
|
|
92
|
+
/**
|
|
93
|
+
* `animate` — event-mode generic animation directive.
|
|
94
|
+
*/
|
|
95
|
+
export declare const animateChannel: IOChannel;
|
|
96
|
+
/**
|
|
97
|
+
* `transition` — event-mode scene transition.
|
|
98
|
+
*/
|
|
99
|
+
export declare const transitionChannel: IOChannel;
|
|
100
|
+
/**
|
|
101
|
+
* `layout` — replace-mode layout configuration. Persistent across
|
|
102
|
+
* mid-session joins so a late-joining renderer sees the current
|
|
103
|
+
* layout without waiting for a re-emission.
|
|
104
|
+
*/
|
|
105
|
+
export declare const layoutChannel: IOChannel;
|
|
106
|
+
/**
|
|
107
|
+
* `clear` — event-mode truncation signal. Operates on append-mode
|
|
108
|
+
* channels (notably `main`); ungated because every renderer needs to
|
|
109
|
+
* be able to reset accumulated prose.
|
|
110
|
+
*/
|
|
111
|
+
export declare const clearChannel: IOChannel;
|
|
112
|
+
/**
|
|
113
|
+
* Static media channels in iteration order — the ones the platform
|
|
114
|
+
* pre-registers regardless of story. Dynamic image layers (beyond
|
|
115
|
+
* the three above) and ambient channels are story-registered.
|
|
116
|
+
*/
|
|
117
|
+
export declare const MEDIA_CHANNELS: ReadonlyArray<IOChannel>;
|
|
118
|
+
/**
|
|
119
|
+
* Channel id literals for the static media set.
|
|
120
|
+
*/
|
|
121
|
+
export declare const MEDIA_CHANNEL_IDS: {
|
|
122
|
+
readonly IMAGE_PRELOAD: "image:preload";
|
|
123
|
+
readonly IMAGE_BACKGROUND: "image:background";
|
|
124
|
+
readonly IMAGE_MAIN: "image:main";
|
|
125
|
+
readonly IMAGE_OVERLAY: "image:overlay";
|
|
126
|
+
readonly SOUND: "sound";
|
|
127
|
+
readonly MUSIC: "music";
|
|
128
|
+
readonly ANIMATION: "animation";
|
|
129
|
+
readonly ANIMATE: "animate";
|
|
130
|
+
readonly TRANSITION: "transition";
|
|
131
|
+
readonly LAYOUT: "layout";
|
|
132
|
+
readonly CLEAR: "clear";
|
|
133
|
+
};
|
|
134
|
+
export type MediaChannelId = (typeof MEDIA_CHANNEL_IDS)[keyof typeof MEDIA_CHANNEL_IDS];
|
|
135
|
+
//# sourceMappingURL=media.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/stdlib/src/channels/media.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAyB,MAAM,oBAAoB,CAAC;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;CAcpB,CAAC;AAEX,MAAM,MAAM,cAAc,GACxB,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AA4E7D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAIrE;AA2BD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAS3D;AAED,eAAO,MAAM,sBAAsB,EAAE,SAA4C,CAAC;AAClF,eAAO,MAAM,gBAAgB,EAAE,SAAsC,CAAC;AACtE,eAAO,MAAM,mBAAmB,EAAE,SAAyC,CAAC;AAE5E;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAUjC,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,SAW1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,SAmB1B,CAAC;AAMF;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAwBjE;AAMD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAW9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,SAU5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAU/B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,SAU3B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,SAU1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,aAAa,CAAC,SAAS,CAYnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;CAYpB,CAAC;AAEX,MAAM,MAAM,cAAc,GACxB,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC"}
|
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @sharpee/stdlib/channels — media `IOChannel` definitions.
|
|
4
|
+
*
|
|
5
|
+
* Owner context: stdlib language layer. The platform media-channel
|
|
6
|
+
* vocabulary from ADR-163 §7. Each channel is capability-gated; the
|
|
7
|
+
* `ChannelService` filters gated channels out of the per-client
|
|
8
|
+
* manifest using `IOChannel.gatedBy`.
|
|
9
|
+
*
|
|
10
|
+
* Closures listen for the corresponding `media.*` event type on the
|
|
11
|
+
* turn's `events` array and project the event's payload (with the two
|
|
12
|
+
* ADR-163 §7 renames: `media.sound.play` `channel?` → `bus?`;
|
|
13
|
+
* `media.image.show` hotspots `action` → `command`; and the §9 drop
|
|
14
|
+
* of `media.animation.play.onComplete`).
|
|
15
|
+
*
|
|
16
|
+
* Hide/stop events (`media.image.hide`, `media.music.stop`,
|
|
17
|
+
* `media.ambient.stop`) emit `null` on the corresponding replace-mode
|
|
18
|
+
* media channel — the renderer interprets `null` as "hide / stop".
|
|
19
|
+
*
|
|
20
|
+
* **Dynamic channels** — `image:<layer>` (custom layer beyond
|
|
21
|
+
* `image:background`/`image:main`/`image:overlay`) and `ambient:<id>`
|
|
22
|
+
* are NOT registered here. Stories register them through their own
|
|
23
|
+
* `Story.registerChannels` hook; `createAmbientChannel(id)` and
|
|
24
|
+
* `createImageChannel(layer)` are convenience builders.
|
|
25
|
+
*
|
|
26
|
+
* @see ADR-163 — Channel-Service Platform — §6, §7, §9
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.MEDIA_CHANNEL_IDS = exports.MEDIA_CHANNELS = exports.clearChannel = exports.layoutChannel = exports.transitionChannel = exports.animateChannel = exports.animationChannel = exports.musicChannel = exports.soundChannel = exports.imagePreloadChannel = exports.imageOverlayChannel = exports.imageMainChannel = exports.imageBackgroundChannel = exports.MEDIA_EVENT_TYPES = void 0;
|
|
30
|
+
exports.imageChannelIdFromEvent = imageChannelIdFromEvent;
|
|
31
|
+
exports.createImageChannel = createImageChannel;
|
|
32
|
+
exports.createAmbientChannel = createAmbientChannel;
|
|
33
|
+
/**
|
|
34
|
+
* Media event types from ADR-101 (folded into channel emissions per
|
|
35
|
+
* ADR-163 §7).
|
|
36
|
+
*/
|
|
37
|
+
exports.MEDIA_EVENT_TYPES = {
|
|
38
|
+
IMAGE_SHOW: 'media.image.show',
|
|
39
|
+
IMAGE_HIDE: 'media.image.hide',
|
|
40
|
+
IMAGE_PRELOAD: 'media.image.preload',
|
|
41
|
+
SOUND_PLAY: 'media.sound.play',
|
|
42
|
+
MUSIC_PLAY: 'media.music.play',
|
|
43
|
+
MUSIC_STOP: 'media.music.stop',
|
|
44
|
+
AMBIENT_PLAY: 'media.ambient.play',
|
|
45
|
+
AMBIENT_STOP: 'media.ambient.stop',
|
|
46
|
+
ANIMATION_PLAY: 'media.animation.play',
|
|
47
|
+
ANIMATE: 'media.animate',
|
|
48
|
+
TRANSITION: 'media.transition',
|
|
49
|
+
LAYOUT_CONFIGURE: 'media.layout.configure',
|
|
50
|
+
CLEAR: 'media.clear',
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Find the most recent event of the given type in this turn's events,
|
|
54
|
+
* or `undefined` if none. Last-wins per turn (replace mode) — when an
|
|
55
|
+
* action fires the same media event twice in one turn, the renderer
|
|
56
|
+
* sees the second one.
|
|
57
|
+
*/
|
|
58
|
+
function lastEventOfType(ctx, type) {
|
|
59
|
+
let last;
|
|
60
|
+
for (const event of ctx.events) {
|
|
61
|
+
if (event.type === type)
|
|
62
|
+
last = event;
|
|
63
|
+
}
|
|
64
|
+
return last;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Iterate every event of the given type — used by event-mode media
|
|
68
|
+
* channels where multiple firings within one turn collapse to the
|
|
69
|
+
* last (event channels carry the closure's last return value per
|
|
70
|
+
* ChannelService). For these the iteration order is irrelevant —
|
|
71
|
+
* `lastEventOfType` is sufficient.
|
|
72
|
+
*/
|
|
73
|
+
const _firstEventOfType = lastEventOfType;
|
|
74
|
+
void _firstEventOfType;
|
|
75
|
+
/**
|
|
76
|
+
* `media.sound.play` payload rename: `channel?` field on the event
|
|
77
|
+
* becomes `bus?` on the wire. Other fields pass through. The rename
|
|
78
|
+
* avoids confusion with the wire's "channel" concept (ADR-163 §7).
|
|
79
|
+
*/
|
|
80
|
+
function renameSoundChannelToBus(data) {
|
|
81
|
+
if (!data || typeof data !== 'object')
|
|
82
|
+
return data;
|
|
83
|
+
const record = data;
|
|
84
|
+
if (!('channel' in record))
|
|
85
|
+
return record;
|
|
86
|
+
const { channel, ...rest } = record;
|
|
87
|
+
return { ...rest, bus: channel };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* `media.image.show` hotspot rename: `hotspots[].action` → `command`
|
|
91
|
+
* (ADR-163 §7). Other hotspot and payload fields pass through.
|
|
92
|
+
*/
|
|
93
|
+
function renameImageHotspotsActionToCommand(data) {
|
|
94
|
+
if (!data || typeof data !== 'object')
|
|
95
|
+
return data;
|
|
96
|
+
const record = data;
|
|
97
|
+
const hotspots = record.hotspots;
|
|
98
|
+
if (!Array.isArray(hotspots))
|
|
99
|
+
return record;
|
|
100
|
+
return {
|
|
101
|
+
...record,
|
|
102
|
+
hotspots: hotspots.map((h) => {
|
|
103
|
+
if (!h || typeof h !== 'object')
|
|
104
|
+
return h;
|
|
105
|
+
const hotspot = h;
|
|
106
|
+
if (!('action' in hotspot))
|
|
107
|
+
return hotspot;
|
|
108
|
+
const { action, ...rest } = hotspot;
|
|
109
|
+
return { ...rest, command: action };
|
|
110
|
+
}),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* `media.animation.play` payload drop: remove `onComplete`. ADR-163
|
|
115
|
+
* §9 declares triggers one-way; the engine doesn't track UI
|
|
116
|
+
* completion, so the field has no semantic carrier.
|
|
117
|
+
*/
|
|
118
|
+
function dropOnComplete(data) {
|
|
119
|
+
if (!data || typeof data !== 'object')
|
|
120
|
+
return data;
|
|
121
|
+
const record = data;
|
|
122
|
+
if (!('onComplete' in record))
|
|
123
|
+
return record;
|
|
124
|
+
const { onComplete: _drop, ...rest } = record;
|
|
125
|
+
return rest;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Resolve the `image:<layer>` channel id from a `media.image.show` /
|
|
129
|
+
* `media.image.hide` event payload. Defaults to `image:main`.
|
|
130
|
+
*/
|
|
131
|
+
function imageChannelIdFromEvent(event) {
|
|
132
|
+
const data = event.data;
|
|
133
|
+
const layer = data?.layer ?? 'main';
|
|
134
|
+
return `image:${layer}`;
|
|
135
|
+
}
|
|
136
|
+
// ────────────────────────────────────────────────────────────────────
|
|
137
|
+
// Standard image-layer channels (image:background / :main / :overlay)
|
|
138
|
+
// ────────────────────────────────────────────────────────────────────
|
|
139
|
+
function imageLayerProduce(layer) {
|
|
140
|
+
const channelId = `image:${layer}`;
|
|
141
|
+
return (ctx) => {
|
|
142
|
+
let lastShow;
|
|
143
|
+
let lastHide;
|
|
144
|
+
for (const event of ctx.events) {
|
|
145
|
+
if (event.type === exports.MEDIA_EVENT_TYPES.IMAGE_SHOW) {
|
|
146
|
+
if (imageChannelIdFromEvent(event) === channelId)
|
|
147
|
+
lastShow = event;
|
|
148
|
+
}
|
|
149
|
+
else if (event.type === exports.MEDIA_EVENT_TYPES.IMAGE_HIDE) {
|
|
150
|
+
if (imageChannelIdFromEvent(event) === channelId)
|
|
151
|
+
lastHide = event;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Hide-after-show within the same turn → hide wins.
|
|
155
|
+
if (lastHide && (!lastShow || ctx.events.indexOf(lastHide) > ctx.events.indexOf(lastShow))) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
if (lastShow)
|
|
159
|
+
return renameImageHotspotsActionToCommand(lastShow.data);
|
|
160
|
+
return undefined;
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Construct an `image:<layer>` `IOChannel`. Standard layers
|
|
165
|
+
* (`background`, `main`, `overlay`) are pre-registered; stories add
|
|
166
|
+
* additional layers via this builder.
|
|
167
|
+
*/
|
|
168
|
+
function createImageChannel(layer) {
|
|
169
|
+
return {
|
|
170
|
+
id: `image:${layer}`,
|
|
171
|
+
contentType: 'json',
|
|
172
|
+
mode: 'replace',
|
|
173
|
+
emit: 'always',
|
|
174
|
+
gatedBy: 'images',
|
|
175
|
+
produce: imageLayerProduce(layer),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
exports.imageBackgroundChannel = createImageChannel('background');
|
|
179
|
+
exports.imageMainChannel = createImageChannel('main');
|
|
180
|
+
exports.imageOverlayChannel = createImageChannel('overlay');
|
|
181
|
+
/**
|
|
182
|
+
* `image:preload` — event-mode preload trigger. Renderers download
|
|
183
|
+
* the asset; not displayed.
|
|
184
|
+
*/
|
|
185
|
+
exports.imagePreloadChannel = {
|
|
186
|
+
id: 'image:preload',
|
|
187
|
+
contentType: 'json',
|
|
188
|
+
mode: 'event',
|
|
189
|
+
emit: 'sparse',
|
|
190
|
+
gatedBy: 'images',
|
|
191
|
+
produce: (ctx) => {
|
|
192
|
+
const event = lastEventOfType(ctx, exports.MEDIA_EVENT_TYPES.IMAGE_PRELOAD);
|
|
193
|
+
return event ? event.data : undefined;
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
// ────────────────────────────────────────────────────────────────────
|
|
197
|
+
// Audio channels
|
|
198
|
+
// ────────────────────────────────────────────────────────────────────
|
|
199
|
+
/**
|
|
200
|
+
* `sound` — event-mode sound effect.
|
|
201
|
+
*/
|
|
202
|
+
exports.soundChannel = {
|
|
203
|
+
id: 'sound',
|
|
204
|
+
contentType: 'json',
|
|
205
|
+
mode: 'event',
|
|
206
|
+
emit: 'sparse',
|
|
207
|
+
gatedBy: 'sound',
|
|
208
|
+
produce: (ctx) => {
|
|
209
|
+
const event = lastEventOfType(ctx, exports.MEDIA_EVENT_TYPES.SOUND_PLAY);
|
|
210
|
+
if (!event)
|
|
211
|
+
return undefined;
|
|
212
|
+
return renameSoundChannelToBus(event.data);
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* `music` — replace-mode music track. `null` emission (from
|
|
217
|
+
* `media.music.stop`) signals "stop".
|
|
218
|
+
*/
|
|
219
|
+
exports.musicChannel = {
|
|
220
|
+
id: 'music',
|
|
221
|
+
contentType: 'json',
|
|
222
|
+
mode: 'replace',
|
|
223
|
+
emit: 'always',
|
|
224
|
+
gatedBy: 'music',
|
|
225
|
+
produce: (ctx) => {
|
|
226
|
+
let lastPlay;
|
|
227
|
+
let lastStop;
|
|
228
|
+
for (const event of ctx.events) {
|
|
229
|
+
if (event.type === exports.MEDIA_EVENT_TYPES.MUSIC_PLAY)
|
|
230
|
+
lastPlay = event;
|
|
231
|
+
else if (event.type === exports.MEDIA_EVENT_TYPES.MUSIC_STOP)
|
|
232
|
+
lastStop = event;
|
|
233
|
+
}
|
|
234
|
+
if (lastStop && (!lastPlay || ctx.events.indexOf(lastStop) > ctx.events.indexOf(lastPlay))) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
if (lastPlay)
|
|
238
|
+
return lastPlay.data;
|
|
239
|
+
return undefined;
|
|
240
|
+
},
|
|
241
|
+
};
|
|
242
|
+
// ────────────────────────────────────────────────────────────────────
|
|
243
|
+
// Ambient channels — dynamic, story-registered
|
|
244
|
+
// ────────────────────────────────────────────────────────────────────
|
|
245
|
+
/**
|
|
246
|
+
* Construct an `ambient:<id>` `IOChannel`. Ambient channels are
|
|
247
|
+
* inherently story-defined (ADR-163 §7) — the platform has no
|
|
248
|
+
* predetermined ambient ids. Stories call this once per ambient
|
|
249
|
+
* layer they need.
|
|
250
|
+
*
|
|
251
|
+
* @param ambientId — suffix portion (e.g., `'wind'` registers
|
|
252
|
+
* `ambient:wind`).
|
|
253
|
+
*/
|
|
254
|
+
function createAmbientChannel(ambientId) {
|
|
255
|
+
const channelId = `ambient:${ambientId}`;
|
|
256
|
+
return {
|
|
257
|
+
id: channelId,
|
|
258
|
+
contentType: 'json',
|
|
259
|
+
mode: 'replace',
|
|
260
|
+
emit: 'always',
|
|
261
|
+
gatedBy: 'sound',
|
|
262
|
+
produce: (ctx) => {
|
|
263
|
+
let lastPlay;
|
|
264
|
+
let lastStop;
|
|
265
|
+
for (const event of ctx.events) {
|
|
266
|
+
const data = event.data;
|
|
267
|
+
if (data?.channel !== ambientId)
|
|
268
|
+
continue;
|
|
269
|
+
if (event.type === exports.MEDIA_EVENT_TYPES.AMBIENT_PLAY)
|
|
270
|
+
lastPlay = event;
|
|
271
|
+
else if (event.type === exports.MEDIA_EVENT_TYPES.AMBIENT_STOP)
|
|
272
|
+
lastStop = event;
|
|
273
|
+
}
|
|
274
|
+
if (lastStop && (!lastPlay || ctx.events.indexOf(lastStop) > ctx.events.indexOf(lastPlay))) {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
if (lastPlay)
|
|
278
|
+
return lastPlay.data;
|
|
279
|
+
return undefined;
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
// ────────────────────────────────────────────────────────────────────
|
|
284
|
+
// Animation / transition / layout / clear
|
|
285
|
+
// ────────────────────────────────────────────────────────────────────
|
|
286
|
+
/**
|
|
287
|
+
* `animation` — event-mode CSS-style animation. Drops `onComplete`
|
|
288
|
+
* per ADR-163 §9.
|
|
289
|
+
*/
|
|
290
|
+
exports.animationChannel = {
|
|
291
|
+
id: 'animation',
|
|
292
|
+
contentType: 'json',
|
|
293
|
+
mode: 'event',
|
|
294
|
+
emit: 'sparse',
|
|
295
|
+
gatedBy: 'animations',
|
|
296
|
+
produce: (ctx) => {
|
|
297
|
+
const event = lastEventOfType(ctx, exports.MEDIA_EVENT_TYPES.ANIMATION_PLAY);
|
|
298
|
+
if (!event)
|
|
299
|
+
return undefined;
|
|
300
|
+
return dropOnComplete(event.data);
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* `animate` — event-mode generic animation directive.
|
|
305
|
+
*/
|
|
306
|
+
exports.animateChannel = {
|
|
307
|
+
id: 'animate',
|
|
308
|
+
contentType: 'json',
|
|
309
|
+
mode: 'event',
|
|
310
|
+
emit: 'sparse',
|
|
311
|
+
gatedBy: 'animations',
|
|
312
|
+
produce: (ctx) => {
|
|
313
|
+
const event = lastEventOfType(ctx, exports.MEDIA_EVENT_TYPES.ANIMATE);
|
|
314
|
+
return event ? event.data : undefined;
|
|
315
|
+
},
|
|
316
|
+
};
|
|
317
|
+
/**
|
|
318
|
+
* `transition` — event-mode scene transition.
|
|
319
|
+
*/
|
|
320
|
+
exports.transitionChannel = {
|
|
321
|
+
id: 'transition',
|
|
322
|
+
contentType: 'json',
|
|
323
|
+
mode: 'event',
|
|
324
|
+
emit: 'sparse',
|
|
325
|
+
gatedBy: 'transitions',
|
|
326
|
+
produce: (ctx) => {
|
|
327
|
+
const event = lastEventOfType(ctx, exports.MEDIA_EVENT_TYPES.TRANSITION);
|
|
328
|
+
return event ? event.data : undefined;
|
|
329
|
+
},
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* `layout` — replace-mode layout configuration. Persistent across
|
|
333
|
+
* mid-session joins so a late-joining renderer sees the current
|
|
334
|
+
* layout without waiting for a re-emission.
|
|
335
|
+
*/
|
|
336
|
+
exports.layoutChannel = {
|
|
337
|
+
id: 'layout',
|
|
338
|
+
contentType: 'json',
|
|
339
|
+
mode: 'replace',
|
|
340
|
+
emit: 'always',
|
|
341
|
+
gatedBy: 'splitPane',
|
|
342
|
+
produce: (ctx) => {
|
|
343
|
+
const event = lastEventOfType(ctx, exports.MEDIA_EVENT_TYPES.LAYOUT_CONFIGURE);
|
|
344
|
+
return event ? event.data : undefined;
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
/**
|
|
348
|
+
* `clear` — event-mode truncation signal. Operates on append-mode
|
|
349
|
+
* channels (notably `main`); ungated because every renderer needs to
|
|
350
|
+
* be able to reset accumulated prose.
|
|
351
|
+
*/
|
|
352
|
+
exports.clearChannel = {
|
|
353
|
+
id: 'clear',
|
|
354
|
+
contentType: 'json',
|
|
355
|
+
mode: 'event',
|
|
356
|
+
emit: 'sparse',
|
|
357
|
+
// Intentionally not gated — clear must be available on every surface.
|
|
358
|
+
produce: (ctx) => {
|
|
359
|
+
const event = lastEventOfType(ctx, exports.MEDIA_EVENT_TYPES.CLEAR);
|
|
360
|
+
return event ? (event.data ?? {}) : undefined;
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
/**
|
|
364
|
+
* Static media channels in iteration order — the ones the platform
|
|
365
|
+
* pre-registers regardless of story. Dynamic image layers (beyond
|
|
366
|
+
* the three above) and ambient channels are story-registered.
|
|
367
|
+
*/
|
|
368
|
+
exports.MEDIA_CHANNELS = [
|
|
369
|
+
exports.imagePreloadChannel,
|
|
370
|
+
exports.imageBackgroundChannel,
|
|
371
|
+
exports.imageMainChannel,
|
|
372
|
+
exports.imageOverlayChannel,
|
|
373
|
+
exports.soundChannel,
|
|
374
|
+
exports.musicChannel,
|
|
375
|
+
exports.animationChannel,
|
|
376
|
+
exports.animateChannel,
|
|
377
|
+
exports.transitionChannel,
|
|
378
|
+
exports.layoutChannel,
|
|
379
|
+
exports.clearChannel,
|
|
380
|
+
];
|
|
381
|
+
/**
|
|
382
|
+
* Channel id literals for the static media set.
|
|
383
|
+
*/
|
|
384
|
+
exports.MEDIA_CHANNEL_IDS = {
|
|
385
|
+
IMAGE_PRELOAD: 'image:preload',
|
|
386
|
+
IMAGE_BACKGROUND: 'image:background',
|
|
387
|
+
IMAGE_MAIN: 'image:main',
|
|
388
|
+
IMAGE_OVERLAY: 'image:overlay',
|
|
389
|
+
SOUND: 'sound',
|
|
390
|
+
MUSIC: 'music',
|
|
391
|
+
ANIMATION: 'animation',
|
|
392
|
+
ANIMATE: 'animate',
|
|
393
|
+
TRANSITION: 'transition',
|
|
394
|
+
LAYOUT: 'layout',
|
|
395
|
+
CLEAR: 'clear',
|
|
396
|
+
};
|
|
397
|
+
//# sourceMappingURL=media.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../../../../../../repos/sharpee/packages/stdlib/src/channels/media.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sharpee/stdlib/channels — channel registry instance.
|
|
3
|
+
*
|
|
4
|
+
* Owner context: stdlib language layer. Hosts the canonical
|
|
5
|
+
* `IChannelRegistry` instance for Sharpee's channel-I/O system.
|
|
6
|
+
* Engine bootstrap imports this instance, lets stories register their
|
|
7
|
+
* channels onto it (`Story.registerChannels?.(registry)`), then hands
|
|
8
|
+
* it to a fresh `ChannelService` (per ADR-163 §13, §14).
|
|
9
|
+
*
|
|
10
|
+
* The instance is populated at module init with the ten standard
|
|
11
|
+
* channels and the eleven static media channels. The `Story.registerChannels`
|
|
12
|
+
* hook may add story-specific channels or override standards by
|
|
13
|
+
* re-registering with the same id (last-write-wins per ADR-163 §6).
|
|
14
|
+
*
|
|
15
|
+
* Lifecycle: a fresh `ChannelService` is created per session
|
|
16
|
+
* (engine restart, RESTART command). The registry itself is reused —
|
|
17
|
+
* stdlib's standard channels stay registered across sessions, and the
|
|
18
|
+
* `ChannelService`'s per-session `prevValues` map provides the
|
|
19
|
+
* isolation. The Story.registerChannels hook is invoked once per
|
|
20
|
+
* engine bootstrap; if a story overrides a standard channel, that
|
|
21
|
+
* override persists for the lifetime of the engine instance.
|
|
22
|
+
*
|
|
23
|
+
* Tests can construct their own `IChannelRegistry` instance for
|
|
24
|
+
* isolation (unit tests should not depend on this singleton's
|
|
25
|
+
* pre-populated state for behavior-specific assertions).
|
|
26
|
+
*
|
|
27
|
+
* @see ADR-163 — Channel-Service Platform — §6, §7, §13, §14
|
|
28
|
+
*/
|
|
29
|
+
import type { IChannelRegistry, IOChannel } from "../../if-domain/index";
|
|
30
|
+
/**
|
|
31
|
+
* In-memory `IChannelRegistry` implementation. Last-write-wins on
|
|
32
|
+
* `add(channel)` by `channel.id` — which is how stories override
|
|
33
|
+
* platform standards (ADR-163 §6).
|
|
34
|
+
*/
|
|
35
|
+
export declare class StdlibChannelRegistry implements IChannelRegistry {
|
|
36
|
+
private readonly channels;
|
|
37
|
+
add(channel: IOChannel): void;
|
|
38
|
+
get(id: string): IOChannel | undefined;
|
|
39
|
+
all(): readonly IOChannel[];
|
|
40
|
+
/**
|
|
41
|
+
* Test-only helper: snapshot the current channel ids. Stable
|
|
42
|
+
* iteration order matches insertion order (Map semantics).
|
|
43
|
+
*/
|
|
44
|
+
ids(): readonly string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The canonical channel registry instance for Sharpee. Pre-populated
|
|
48
|
+
* with ten standard channels (`main`, `prompt`, `score`, `turn`,
|
|
49
|
+
* `location`, `info`, `ifid`, `death`, `endgame`, `score_notify`)
|
|
50
|
+
* plus eleven static media channels (`image:preload`,
|
|
51
|
+
* `image:background`, `image:main`, `image:overlay`, `sound`,
|
|
52
|
+
* `music`, `animation`, `animate`, `transition`, `layout`, `clear`).
|
|
53
|
+
*
|
|
54
|
+
* Engine bootstrap consumes this directly; stories extend through
|
|
55
|
+
* the `Story.registerChannels?(registry)` hook.
|
|
56
|
+
*/
|
|
57
|
+
export declare const channelRegistry: IChannelRegistry;
|
|
58
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../../../../repos/sharpee/packages/stdlib/src/channels/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAKtE;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgC;IAEzD,GAAG,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI;IAI7B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAItC,GAAG,IAAI,SAAS,SAAS,EAAE;IAI3B;;;OAGG;IACH,GAAG,IAAI,SAAS,MAAM,EAAE;CAGzB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,EAAE,gBAY1B,CAAC"}
|