@realnation/builder-shared-sdk 1.1.1 → 1.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.
package/README.md CHANGED
@@ -7,6 +7,7 @@
7
7
  - **HTTP客户端共享**: 提供统一的`axios`实例,自动处理鉴权Token,避免在每个Remote中重复配置。
8
8
  - **全局事件总线**: 一个简单的发布/订阅系统,用于在Host和Remotes之间或Remotes彼此之间进行解耦的通信。
9
9
  - **动态流程控制**: 一个极其灵活的事件驱动流程控制机制,允许Host动态注册回调,由任意Remote在特定时机触发。
10
+ - **交互态 (Interaction State)**: Builder 里配的两态外观与四种触发方式的唯一实现,模块自渲染的元件调一下就和平台表现一致。见 [`src/interaction/README.md`](src/interaction/README.md)。
10
11
 
11
12
  ## 📦 安装
12
13
 
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Interaction State — the two-appearance model shared by the platform editor,
3
+ * the runner and every module.
4
+ *
5
+ * An element configured in the Builder carries a normal appearance and a
6
+ * "selected" one. This module owns the single definition of what those
7
+ * properties mean and how they turn into CSS, so a module never has to
8
+ * reverse-engineer the runner to make its own elements behave the same way.
9
+ *
10
+ * Framework-free by construction: pure functions over the property bag. The
11
+ * Vue adapter (`@realnation/builder-shared-sdk/interaction/vue`) adds the
12
+ * trigger state machine on top and is the entry point most modules want.
13
+ */
14
+ /** Property keys written by the Builder's Interaction State section. */
15
+ export declare const INTERACTION_KEYS: {
16
+ readonly easing: "transition-easing";
17
+ readonly trigger: "transition-trigger";
18
+ readonly duration: "transition-duration";
19
+ readonly hold: "transition-hold";
20
+ readonly bgColor: "selected-bg-color";
21
+ readonly borderColor: "selected-border-color";
22
+ readonly rotation: "selected-rotation";
23
+ readonly scale: "selected-scale";
24
+ readonly opacity: "selected-opacity";
25
+ };
26
+ export type InteractionTrigger = 'hover' | 'click' | 'appear' | 'loop';
27
+ export declare const INTERACTION_TRIGGERS: readonly InteractionTrigger[];
28
+ /** Anything the Builder stores for one element. Values arrive untyped from the API. */
29
+ export type InteractionProperty = Record<string, unknown>;
30
+ /** The CSS properties this feature is allowed to touch, in camelCase for Vue's :style. */
31
+ export interface InteractionStyle {
32
+ transition?: string;
33
+ transform?: string;
34
+ backgroundColor?: string;
35
+ borderColor?: string;
36
+ opacity?: string;
37
+ }
38
+ /**
39
+ * Whether the element has an interaction state at all.
40
+ *
41
+ * Easing is the section's master switch: `none` (the default) means the
42
+ * element behaves exactly as it did before this feature existed. Every entry
43
+ * point checks this first so unconfigured elements stay untouched.
44
+ */
45
+ export declare function isInteractionEnabled(property: InteractionProperty | null | undefined): boolean;
46
+ export declare function interactionTriggerOf(property: InteractionProperty | null | undefined): InteractionTrigger;
47
+ export declare function interactionDurationOf(property: InteractionProperty | null | undefined): number;
48
+ /**
49
+ * How long Loop rests in each state before easing into the other one.
50
+ *
51
+ * The floor exists because a 0/0 configuration would otherwise flip on every
52
+ * timer tick, which reads as a flicker rather than an animation.
53
+ */
54
+ export declare function interactionPeriodOf(property: InteractionProperty | null | undefined): number;
55
+ export interface InteractionStyleOptions {
56
+ /**
57
+ * Suppresses the transition for this call. On Appear needs one painted frame
58
+ * in the selected state with no transition, otherwise the element starts
59
+ * easing towards normal immediately and the starting point is never seen.
60
+ */
61
+ instant?: boolean;
62
+ }
63
+ /**
64
+ * The style to merge onto an element for a given state.
65
+ *
66
+ * Returns only the properties this feature owns, so callers can spread it over
67
+ * their own base style without losing layout or typography.
68
+ *
69
+ * Each selected-* value is applied only when it was actually configured —
70
+ * an unset colour must inherit the normal appearance rather than reset it.
71
+ */
72
+ export declare function interactionStyle(property: InteractionProperty | null | undefined, active: boolean, options?: InteractionStyleOptions): InteractionStyle;
73
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interaction/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,wEAAwE;AACxE,eAAO,MAAM,gBAAgB;;;;;;;;;;CAUnB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AACvE,eAAO,MAAM,oBAAoB,EAAE,SAAS,kBAAkB,EAAyC,CAAC;AAExG,uFAAuF;AACvF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1D,0FAA0F;AAC1F,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAOD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG9F;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,kBAAkB,CAGzG;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAE9F;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAG5F;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAChD,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,uBAA4B,GACpC,gBAAgB,CAgClB"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Interaction State — the two-appearance model shared by the platform editor,
3
+ * the runner and every module.
4
+ *
5
+ * An element configured in the Builder carries a normal appearance and a
6
+ * "selected" one. This module owns the single definition of what those
7
+ * properties mean and how they turn into CSS, so a module never has to
8
+ * reverse-engineer the runner to make its own elements behave the same way.
9
+ *
10
+ * Framework-free by construction: pure functions over the property bag. The
11
+ * Vue adapter (`@realnation/builder-shared-sdk/interaction/vue`) adds the
12
+ * trigger state machine on top and is the entry point most modules want.
13
+ */
14
+ /** Property keys written by the Builder's Interaction State section. */
15
+ export const INTERACTION_KEYS = {
16
+ easing: 'transition-easing',
17
+ trigger: 'transition-trigger',
18
+ duration: 'transition-duration',
19
+ hold: 'transition-hold',
20
+ bgColor: 'selected-bg-color',
21
+ borderColor: 'selected-border-color',
22
+ rotation: 'selected-rotation',
23
+ scale: 'selected-scale',
24
+ opacity: 'selected-opacity',
25
+ };
26
+ export const INTERACTION_TRIGGERS = ['hover', 'click', 'appear', 'loop'];
27
+ const num = (value, fallback) => {
28
+ const n = Number(value);
29
+ return Number.isFinite(n) ? n : fallback;
30
+ };
31
+ /**
32
+ * Whether the element has an interaction state at all.
33
+ *
34
+ * Easing is the section's master switch: `none` (the default) means the
35
+ * element behaves exactly as it did before this feature existed. Every entry
36
+ * point checks this first so unconfigured elements stay untouched.
37
+ */
38
+ export function isInteractionEnabled(property) {
39
+ if (!property)
40
+ return false;
41
+ return String(property[INTERACTION_KEYS.easing] ?? 'none') !== 'none';
42
+ }
43
+ export function interactionTriggerOf(property) {
44
+ const raw = String(property?.[INTERACTION_KEYS.trigger] ?? 'hover');
45
+ return INTERACTION_TRIGGERS.includes(raw) ? raw : 'hover';
46
+ }
47
+ export function interactionDurationOf(property) {
48
+ return num(property?.[INTERACTION_KEYS.duration], 400);
49
+ }
50
+ /**
51
+ * How long Loop rests in each state before easing into the other one.
52
+ *
53
+ * The floor exists because a 0/0 configuration would otherwise flip on every
54
+ * timer tick, which reads as a flicker rather than an animation.
55
+ */
56
+ export function interactionPeriodOf(property) {
57
+ const hold = Math.max(0, num(property?.[INTERACTION_KEYS.hold], 600));
58
+ return Math.max(120, interactionDurationOf(property) + hold);
59
+ }
60
+ /**
61
+ * The style to merge onto an element for a given state.
62
+ *
63
+ * Returns only the properties this feature owns, so callers can spread it over
64
+ * their own base style without losing layout or typography.
65
+ *
66
+ * Each selected-* value is applied only when it was actually configured —
67
+ * an unset colour must inherit the normal appearance rather than reset it.
68
+ */
69
+ export function interactionStyle(property, active, options = {}) {
70
+ if (!isInteractionEnabled(property))
71
+ return {};
72
+ const bag = property;
73
+ const easing = String(bag[INTERACTION_KEYS.easing]);
74
+ const duration = interactionDurationOf(bag);
75
+ const style = {};
76
+ if (options.instant) {
77
+ style.transition = 'none';
78
+ }
79
+ else if (duration > 0) {
80
+ style.transition = ['transform', 'background-color', 'border-color', 'opacity']
81
+ .map((prop) => `${prop} ${duration}ms ${easing}`)
82
+ .join(', ');
83
+ }
84
+ if (!active)
85
+ return style;
86
+ const bg = bag[INTERACTION_KEYS.bgColor];
87
+ if (bg && bg !== 'transparent')
88
+ style.backgroundColor = String(bg);
89
+ const border = bag[INTERACTION_KEYS.borderColor];
90
+ if (border)
91
+ style.borderColor = String(border);
92
+ // Rotation and scale share one CSS property, so either one being configured
93
+ // means both have to be written — the other falls back to its neutral value.
94
+ const rotation = bag[INTERACTION_KEYS.rotation];
95
+ const scale = bag[INTERACTION_KEYS.scale];
96
+ if (rotation != null || scale != null) {
97
+ style.transform = `rotate(${num(rotation, 0)}deg) scale(${num(scale, 100) / 100})`;
98
+ }
99
+ const opacity = bag[INTERACTION_KEYS.opacity];
100
+ if (opacity != null)
101
+ style.opacity = String(num(opacity, 100) / 100);
102
+ return style;
103
+ }
@@ -0,0 +1,38 @@
1
+ import type { InteractionProperty, InteractionStyle } from './index.js';
2
+ /** One element to drive: a stable key plus the properties the Builder stored for it. */
3
+ export interface InteractionEntry {
4
+ key: string;
5
+ property: InteractionProperty | null | undefined;
6
+ }
7
+ export interface UseInteractionStateOptions {
8
+ /** Timer injection points, for tests and for hosts with their own scheduler. */
9
+ setTimer?: (fn: () => void, ms: number) => unknown;
10
+ clearTimer?: (handle: unknown) => void;
11
+ /** Schedules the frame after next. Defaults to double rAF, or a macrotask. */
12
+ nextFrame?: (fn: () => void) => void;
13
+ }
14
+ export interface InteractionStateApi {
15
+ /**
16
+ * The style to merge onto an element.
17
+ *
18
+ * `active` overrides the internal state — that is the hook for modules whose
19
+ * selection has its own meaning. Leave it out to follow the configured trigger.
20
+ */
21
+ style(property: InteractionProperty | null | undefined, key: string, active?: boolean): InteractionStyle;
22
+ /** Event handlers to v-bind. Empty unless the trigger is Hover / Press or Click. */
23
+ bind(property: InteractionProperty | null | undefined, key: string): Record<string, () => void>;
24
+ /**
25
+ * Restarts the timed triggers for exactly these elements.
26
+ *
27
+ * Call whenever the visible set changes — a new page, a new ratio. On Appear
28
+ * replays and Loop re-times, which is what "appears" means to a player who
29
+ * navigated back to a page they have already seen.
30
+ */
31
+ sync(entries: InteractionEntry[]): void;
32
+ /** Drops every timer and state. Called automatically on unmount. */
33
+ stop(): void;
34
+ isActive(key: string): boolean;
35
+ setActive(key: string, on: boolean): void;
36
+ }
37
+ export declare function useInteractionState(options?: UseInteractionStateOptions): InteractionStateApi;
38
+ //# sourceMappingURL=vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../../src/interaction/vue.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAExE,wFAAwF;AACxF,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC;CAClD;AAED,MAAM,WAAW,0BAA0B;IACzC,gFAAgF;IAChF,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;IACzG,oFAAoF;IACpF,IAAI,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;IAChG;;;;;;OAMG;IACH,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACxC,oEAAoE;IACpE,IAAI,IAAI,IAAI,CAAC;IACb,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3C;AAUD,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,0BAA+B,GAAG,mBAAmB,CA8EjG"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Vue 3 adapter for Interaction State.
3
+ *
4
+ * Import from '@realnation/builder-shared-sdk/interaction/vue'. The core at
5
+ * '/interaction' is framework-free; the trigger state machine lives here
6
+ * because it needs reactivity to repaint when a timer flips a state.
7
+ *
8
+ * Two kinds of caller, one implementation:
9
+ *
10
+ * • The runner and any module that lets the platform drive the state —
11
+ * bind() wires the pointer events, sync() starts the timed triggers.
12
+ *
13
+ * • A module whose "selected" means something of its own (which answer the
14
+ * player picked, which card is face up) — pass that boolean to style() and
15
+ * skip bind()/sync() entirely. The appearance still matches the platform.
16
+ *
17
+ * Returned by a factory rather than by a per-element composable: modules render
18
+ * their elements in a v-for, and a composable cannot be called from a loop.
19
+ */
20
+ import { getCurrentInstance, onUnmounted, reactive } from 'vue';
21
+ import { interactionPeriodOf, interactionStyle, interactionTriggerOf, isInteractionEnabled, } from './index.js';
22
+ const defaultNextFrame = (fn) => {
23
+ if (typeof requestAnimationFrame === 'function') {
24
+ requestAnimationFrame(() => requestAnimationFrame(fn));
25
+ return;
26
+ }
27
+ setTimeout(fn, 0);
28
+ };
29
+ export function useInteractionState(options = {}) {
30
+ const setTimer = options.setTimer ?? ((fn, ms) => setInterval(fn, ms));
31
+ const clearTimer = options.clearTimer ?? ((handle) => clearInterval(handle));
32
+ const nextFrame = options.nextFrame ?? defaultNextFrame;
33
+ const active = reactive({});
34
+ // Separate from `active` because On Appear is active *without* a transition
35
+ // for its first frame; one boolean cannot say both things.
36
+ const instant = reactive({});
37
+ const timers = new Map();
38
+ // Guards the deferred On Appear callback: by the time the frame lands the
39
+ // player may already have navigated on, and the element is gone.
40
+ let generation = 0;
41
+ const stop = () => {
42
+ timers.forEach((handle) => clearTimer(handle));
43
+ timers.clear();
44
+ generation += 1;
45
+ };
46
+ const api = {
47
+ style(property, key, forced) {
48
+ const on = forced ?? active[key] ?? false;
49
+ return interactionStyle(property, on, { instant: instant[key] === true });
50
+ },
51
+ bind(property, key) {
52
+ if (!isInteractionEnabled(property))
53
+ return {};
54
+ const trigger = interactionTriggerOf(property);
55
+ if (trigger === 'click') {
56
+ // Deliberately not stopping propagation: the element may also carry a
57
+ // link or a node connection, and the visual state is only a layer on top.
58
+ return { onClick: () => { active[key] = !active[key]; } };
59
+ }
60
+ if (trigger !== 'hover')
61
+ return {};
62
+ const on = () => { active[key] = true; };
63
+ const off = () => { active[key] = false; };
64
+ return {
65
+ onPointerenter: on,
66
+ onPointerdown: on,
67
+ onPointerleave: off,
68
+ onPointerup: off,
69
+ onPointercancel: off,
70
+ };
71
+ },
72
+ sync(entries) {
73
+ stop();
74
+ const mine = generation;
75
+ for (const { key, property } of entries) {
76
+ if (!isInteractionEnabled(property))
77
+ continue;
78
+ const trigger = interactionTriggerOf(property);
79
+ if (trigger === 'appear') {
80
+ instant[key] = true;
81
+ active[key] = true;
82
+ nextFrame(() => {
83
+ if (generation !== mine)
84
+ return;
85
+ instant[key] = false;
86
+ active[key] = false;
87
+ });
88
+ }
89
+ else if (trigger === 'loop') {
90
+ active[key] = false;
91
+ timers.set(key, setTimer(() => { active[key] = !active[key]; }, interactionPeriodOf(property)));
92
+ }
93
+ else {
94
+ active[key] = false;
95
+ }
96
+ }
97
+ },
98
+ stop,
99
+ isActive: (key) => active[key] === true,
100
+ setActive: (key, on) => { active[key] = on; },
101
+ };
102
+ // Usable outside a component too (tests, a plain store); onUnmounted would
103
+ // only warn there. Those callers own the lifetime and call stop() themselves.
104
+ if (getCurrentInstance())
105
+ onUnmounted(stop);
106
+ return api;
107
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../../src/runtime/facade.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../../src/runtime/facade.ts"],"names":[],"mappings":"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"}
@@ -291,10 +291,15 @@ export class RuntimeFacade {
291
291
  * callers get a MediaStream.
292
292
  */
293
293
  async openStream() {
294
+ // A Runtime session has one colour-stream receiver. Replacing an active
295
+ // receiver would silently freeze the first consumer, so callers must
296
+ // explicitly release it with camera.stopStream() before another component
297
+ // can acquire the stream.
298
+ if (this.pc)
299
+ throw new Error('camera stream is already in use');
294
300
  const RTC = globalThis.RTCPeerConnection;
295
301
  if (!RTC)
296
302
  throw new Error('WebRTC is not available in this environment');
297
- this.closeStream(); // one receiver per Runtime session
298
303
  const pc = new RTC({ iceServers: [] }); // local-only: no STUN needed
299
304
  this.pc = pc;
300
305
  pc.addTransceiver('video', { direction: 'recvonly' });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realnation/builder-shared-sdk",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "exports": {
@@ -16,6 +16,14 @@
16
16
  "./runtime/vue": {
17
17
  "types": "./dist/runtime/vue/index.d.ts",
18
18
  "import": "./dist/runtime/vue/index.js"
19
+ },
20
+ "./interaction": {
21
+ "types": "./dist/interaction/index.d.ts",
22
+ "import": "./dist/interaction/index.js"
23
+ },
24
+ "./interaction/vue": {
25
+ "types": "./dist/interaction/vue.d.ts",
26
+ "import": "./dist/interaction/vue.js"
19
27
  }
20
28
  },
21
29
  "files": [