@appstrata/player-lib 0.1.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 ADDED
@@ -0,0 +1,147 @@
1
+ # @appstrata/player-lib
2
+
3
+ Player implementation library for AppStrata digital signage platform.
4
+
5
+ ## Overview
6
+
7
+ This package provides helpers for platform vendors implementing AppStrata-compliant players. It handles the host side of the message protocol and provides a high-level API for hosting apps.
8
+
9
+ ## Installation
10
+
11
+ > **Note:** This is a private npm package. Requires an npm access token — contact the AppStrata team to get one, then add it to your `~/.npmrc`:
12
+ >
13
+ > ```
14
+ > //registry.npmjs.org/:_authToken=YOUR_TOKEN
15
+ > ```
16
+
17
+ ```bash
18
+ npm install @appstrata/player-lib
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### Session scope
24
+
25
+ `createAppHost` (and the underlying `MessageBridge`) are **single-session**: one instance covers one App page load, from the initial handshake through `fireStop()` / `destroy()`. When the App reloads (e.g. due to a config change), you **must** destroy the old host and create a new one:
26
+
27
+ ```typescript
28
+ // App reloads → tear down old, create fresh
29
+ host.destroy();
30
+ host = createAppHost({ ... });
31
+ ```
32
+
33
+ Reusing a host across reloads is not supported. The handshake state is not reset between sessions.
34
+
35
+ ### Using createAppHost (Recommended)
36
+
37
+ The `createAppHost` helper is the easiest way to host an AppStrata app. It automatically handles:
38
+ - Protocol handshake (HELLO/READY/READY_ACK)
39
+ - Lifecycle event routing via the message bridge
40
+ - RPC operations for capability APIs
41
+
42
+ ```typescript
43
+ import { createAppHost } from "@appstrata/player-lib";
44
+
45
+ // Create app host
46
+ const host = createAppHost({
47
+ services: { storage, proxy },
48
+ target: iframe.contentWindow!,
49
+ targetOrigin: "*",
50
+ notifyComplete: () => { /* handle playback complete */ },
51
+ notifyNoContent: (options) => { /* handle no content */ },
52
+ notifyEstimatedEnd: (expectedFinishTime) => { /* handle estimation */ },
53
+ log: (level, msg, data) => console.log(`[${level}]`, msg, data),
54
+ });
55
+
56
+ // Fire lifecycle events as needed
57
+ const context = buildAppContext();
58
+ host.fireInit(context);
59
+ host.fireShow();
60
+ host.fireStart();
61
+ // ... later ...
62
+ host.fireHide();
63
+ host.fireStop();
64
+
65
+ // Update context
66
+ host.updateContext(newContext);
67
+
68
+ // Cleanup when done
69
+ host.destroy();
70
+ ```
71
+
72
+ ### Using MessageBridge (Advanced)
73
+
74
+ For advanced use cases, you can use `MessageBridge` directly from `@appstrata/protocol`:
75
+
76
+ ```typescript
77
+ import { MessageBridge, createPostMessageTransport } from "@appstrata/protocol";
78
+
79
+ const transport = createPostMessageTransport({
80
+ targetWindow: iframe.contentWindow!,
81
+ targetOrigin: "*",
82
+ });
83
+
84
+ const bridge = new MessageBridge({
85
+ transport,
86
+ player: myPlayer,
87
+ getContext: async () => buildAppContext(),
88
+ });
89
+
90
+ bridge.start();
91
+
92
+ // Fire lifecycle events
93
+ bridge.fireShow();
94
+ bridge.fireStart();
95
+ ```
96
+
97
+ ## API Reference
98
+
99
+ ### createAppHost
100
+
101
+ High-level helper for hosting an AppStrata app.
102
+
103
+ **Options:**
104
+ - `services: CapabilityServices` - Capability service implementations (storage, proxy, etc.)
105
+ - `target: Window` - Target window (typically `iframe.contentWindow`)
106
+ - `transport?: Transport` - Optional transport (auto-created from target/targetOrigin if not provided)
107
+ - `targetOrigin?: string` - Target origin for the default transport (default: `"*"`)
108
+ - `notifyComplete: () => void` - Callback when app signals playback complete
109
+ - `notifyEstimatedEnd: (expectedFinishTime: number) => void` - Callback when app provides estimated finish time (Unix ms)
110
+ - `notifyNoContent: (options?) => void` - Callback when app signals no content (`{ retryNotBefore?: number; reason?: string }`)
111
+ - `log: (level, message, data?) => void` - Logging callback
112
+ - `debug?: boolean` - Enable debug logging (default: `false`)
113
+ - `retryInterval?: number` - READY retry interval in ms (default: `1000`)
114
+ - `maxRetries?: number` - Max READY retries (default: `10`)
115
+
116
+ **Returns:** `AppHost` with methods:
117
+ - `fireInit(context)`: Initialize with AppContext
118
+ - `fireShow()`: Fire show event
119
+ - `fireStart()`: Fire start event
120
+ - `fireHide()`: Fire hide event
121
+ - `fireStop()`: Fire stop event
122
+ - `updateContext(context)`: Update context
123
+ - `destroy()`: Cleanup resources
124
+ - `player`: Direct access to the underlying SignagePlayer
125
+
126
+ ## Protocol Details
127
+
128
+ The library implements the AppStrata message protocol:
129
+
130
+ 1. **Handshake:**
131
+ - App sends HELLO (optional)
132
+ - Host sends READY with AppContext
133
+ - If no HELLO received, host retries READY until READY_ACK
134
+ - App sends READY_ACK
135
+
136
+ 2. **RPC:**
137
+ - App sends REQUEST
138
+ - Host routes to SignagePlayer capability methods
139
+ - Host sends RESPONSE
140
+
141
+ 3. **Events:**
142
+ - Host sends EVENT (show, start, hide, stop, contextChange)
143
+ - Events are queued if sent before READY_ACK, then flushed
144
+
145
+ ## License
146
+
147
+ MIT
@@ -0,0 +1,161 @@
1
+ /**
2
+ * AppHost - Host-side player controller.
3
+ *
4
+ * Encapsulates the SignagePlayer and player-side state such as the current AppContext and
5
+ * registeredlifecycle handlers.
6
+ * Provides fire methods for Players to trigger lifecycle events.
7
+ */
8
+ import { type SignagePlayer, type AppContext, type LogLevel, type StorageApi, type ProxyApi, type MediaCacheApi, type StaticApi } from "@appstrata/core";
9
+ import type { Transport } from "@appstrata/protocol";
10
+ /**
11
+ * Capability services that can be provided to the host.
12
+ */
13
+ export interface CapabilityServices {
14
+ storage?: StorageApi;
15
+ proxy?: ProxyApi;
16
+ mediaCache?: MediaCacheApi;
17
+ static?: StaticApi;
18
+ }
19
+ /**
20
+ * AppHost interface - Host-side player controller.
21
+ *
22
+ * **Single-session:** one `AppHost` instance covers one App page load. The
23
+ * handshake state is not reset between sessions. When the App reloads (e.g.
24
+ * the iframe navigates), call `destroy()` on the old host and create a new
25
+ * instance for the incoming session. Reusing an `AppHost` across sessions is
26
+ * not supported and will result in protocol errors (duplicate / stale READY).
27
+ *
28
+ * > Future versions may introduce multi-session support.
29
+ */
30
+ export interface AppHost {
31
+ /**
32
+ * Direct access to the underlying SignagePlayer interface.
33
+ *
34
+ * This property is primarily useful for testing and debugging.
35
+ */
36
+ readonly player: SignagePlayer;
37
+ /**
38
+ * Fire init lifecycle event with the given AppContext.
39
+ */
40
+ fireInit(context: AppContext): void;
41
+ /**
42
+ * Fire show lifecycle event (app is about to become visible).
43
+ */
44
+ fireShow(): void;
45
+ /**
46
+ * Fire start lifecycle event (app is visible and should start playback).
47
+ */
48
+ fireStart(): void;
49
+ /**
50
+ * Fire hide lifecycle event (app is about to be hidden).
51
+ */
52
+ fireHide(): void;
53
+ /**
54
+ * Fire stop lifecycle event (app is hidden and should stop playback).
55
+ */
56
+ fireStop(): void;
57
+ /**
58
+ * Fire context change event with the given context.
59
+ * Should only be called after fireInit() has been called.
60
+ */
61
+ updateContext(context: AppContext): void;
62
+ /**
63
+ * Hot-swap capability services at runtime.
64
+ * Updates the player's service references and rebuilds the internal
65
+ * capabilities array so that subsequent RPC calls route correctly.
66
+ * This is useful for development players that need to hot-swap services at runtime.
67
+ */
68
+ updateServices(services: CapabilityServices): void;
69
+ /**
70
+ * Cleanup resources.
71
+ */
72
+ destroy(): void;
73
+ }
74
+ /**
75
+ * Options for creating an AppHost.
76
+ */
77
+ export interface CreateAppHostOptions {
78
+ /**
79
+ * Capability service implementations.
80
+ */
81
+ services: CapabilityServices;
82
+ /**
83
+ * Transport to use. If not provided, a postMessage transport
84
+ * will be created by default based on the target window and target origin.
85
+ */
86
+ transport?: Transport;
87
+ /**
88
+ * Target window to use when creating the default transport.
89
+ */
90
+ target: Window;
91
+ /**
92
+ * Target origin to use when creating the default transport.
93
+ * @default "*"
94
+ */
95
+ targetOrigin?: string;
96
+ /**
97
+ * Retry interval in milliseconds for sending READY messages.
98
+ * @default 1000 (1 second)
99
+ */
100
+ retryInterval?: number;
101
+ /**
102
+ * Maximum number of retries for sending READY messages.
103
+ * @default 10
104
+ */
105
+ maxRetries?: number;
106
+ /**
107
+ * Called when the app signals it has finished playback.
108
+ * Vendors MUST provide their own implementation.
109
+ */
110
+ notifyComplete: () => void;
111
+ /**
112
+ * Called when the app provides an estimated finish time.
113
+ * Vendors MUST provide their own implementation.
114
+ *
115
+ * @param expectedFinishTime - Absolute epoch timestamp in ms (already
116
+ * converted from the app-facing totalDuration/finishTime by the SDK)
117
+ */
118
+ notifyEstimatedEnd: (expectedFinishTime: number) => void;
119
+ /**
120
+ * Called when the app signals it has no content to display.
121
+ * Vendors MUST provide their own implementation.
122
+ *
123
+ * @param options - Optional retry and reason info
124
+ * @param options.retryNotBefore - Earliest time to retry (epoch timestamp in ms)
125
+ * @param options.reason - Human-readable reason
126
+ */
127
+ notifyNoContent: (options?: {
128
+ retryNotBefore?: number;
129
+ reason?: string;
130
+ }) => void;
131
+ /**
132
+ * Implementation for logging.
133
+ * Vendors MUST provide their own implementation.
134
+ *
135
+ * @param level - Log level
136
+ * @param message - Log message
137
+ * @param data - Optional data to log
138
+ */
139
+ log: (level: LogLevel, message: string, data?: unknown) => void;
140
+ }
141
+ /**
142
+ * Create an AppHost for managing an app instance.
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const host = createAppHost({
147
+ * services: { storage, proxy },
148
+ * target: iframe.contentWindow!,
149
+ * notifyComplete: () => { ... },
150
+ * log: (level, msg) => console.log(msg),
151
+ * });
152
+ *
153
+ * // Fire lifecycle events with AppContext
154
+ * const appContext = buildContextFromVendor(vendorContext);
155
+ * host.fireInit(appContext);
156
+ * host.fireShow();
157
+ * host.fireStart();
158
+ * ```
159
+ */
160
+ export declare function createAppHost(options: CreateAppHostOptions): AppHost;
161
+ //# sourceMappingURL=app-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-host.d.ts","sourceRoot":"","sources":["../src/app-host.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,UAAU,EAEf,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAUrD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,OAAO;IACtB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAE/B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAEpC;;OAEG;IACH,QAAQ,IAAI,IAAI,CAAC;IAEjB;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;IAElB;;OAEG;IACH,QAAQ,IAAI,IAAI,CAAC;IAEjB;;OAEG;IACH,QAAQ,IAAI,IAAI,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IAEzC;;;;;OAKG;IACH,cAAc,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,QAAQ,EAAE,kBAAkB,CAAC;IAE7B;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,cAAc,EAAE,MAAM,IAAI,CAAC;IAE3B;;;;;;OAMG;IACH,kBAAkB,EAAE,CAAC,kBAAkB,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzD;;;;;;;OAOG;IACH,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAElF;;;;;;;OAOG;IACH,GAAG,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACjE;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CA6NT"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * AppHost - Host-side player controller.
3
+ *
4
+ * Encapsulates the SignagePlayer and player-side state such as the current AppContext and
5
+ * registeredlifecycle handlers.
6
+ * Provides fire methods for Players to trigger lifecycle events.
7
+ */
8
+ import { LifecyclePhase, createLogger, } from "@appstrata/core";
9
+ const logger = createLogger("AppHost");
10
+ import { MessageBridge, createPostMessageTransport, } from "@appstrata/protocol";
11
+ // ═══════════════════════════════════════════════════════════════════════════
12
+ // IMPLEMENTATION
13
+ // ═══════════════════════════════════════════════════════════════════════════
14
+ /**
15
+ * Create an AppHost for managing an app instance.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const host = createAppHost({
20
+ * services: { storage, proxy },
21
+ * target: iframe.contentWindow!,
22
+ * notifyComplete: () => { ... },
23
+ * log: (level, msg) => console.log(msg),
24
+ * });
25
+ *
26
+ * // Fire lifecycle events with AppContext
27
+ * const appContext = buildContextFromVendor(vendorContext);
28
+ * host.fireInit(appContext);
29
+ * host.fireShow();
30
+ * host.fireStart();
31
+ * ```
32
+ */
33
+ export function createAppHost(options) {
34
+ const { services, transport, target, targetOrigin = "*", retryInterval, maxRetries, notifyComplete, notifyEstimatedEnd, notifyNoContent, log, } = options;
35
+ // ═══════════════════════════════════════════════════════════════════════
36
+ // Internal state
37
+ // ═══════════════════════════════════════════════════════════════════════
38
+ let context = null;
39
+ let resolveReady;
40
+ const readyPromise = new Promise((r) => { resolveReady = r; });
41
+ // Lifecycle handlers (arrays for predictable ordering)
42
+ const handlers = {
43
+ onInit: [],
44
+ onShow: [],
45
+ onStart: [],
46
+ onHide: [],
47
+ onStop: [],
48
+ onContextChange: [],
49
+ };
50
+ // Determine capabilities from services
51
+ const capabilities = [];
52
+ if (services.storage)
53
+ capabilities.push("storage");
54
+ if (services.proxy)
55
+ capabilities.push("proxy");
56
+ if (services.mediaCache)
57
+ capabilities.push("mediaCache");
58
+ if (services.static)
59
+ capabilities.push("static");
60
+ // ═══════════════════════════════════════════════════════════════════════
61
+ // SignagePlayer (apps interface) - used by MessageBridge for RPC routing
62
+ // ═══════════════════════════════════════════════════════════════════════
63
+ const player = {
64
+ apiVersion: "1.0.0",
65
+ lifecyclePhase: LifecyclePhase.None,
66
+ async getContext() {
67
+ await readyPromise;
68
+ return context;
69
+ },
70
+ async hasCapability(cap) {
71
+ return capabilities.includes(cap);
72
+ },
73
+ onInit(handler) {
74
+ if (context)
75
+ handler(context); // Late subscriber
76
+ handlers.onInit.push(handler);
77
+ },
78
+ onShow(handler) { handlers.onShow.push(handler); },
79
+ onStart(handler) { handlers.onStart.push(handler); },
80
+ onHide(handler) { handlers.onHide.push(handler); },
81
+ onStop(handler) { handlers.onStop.push(handler); },
82
+ onContextChange(handler) { handlers.onContextChange.push(handler); },
83
+ notifyComplete() {
84
+ notifyComplete();
85
+ },
86
+ notifyEstimatedEnd(options) {
87
+ notifyEstimatedEnd(options?.expectedFinishTime ?? options);
88
+ },
89
+ notifyNoContent(options) {
90
+ notifyNoContent(options);
91
+ },
92
+ storage: services.storage,
93
+ proxy: services.proxy,
94
+ mediaCache: services.mediaCache,
95
+ static: services.static,
96
+ log(level, message, data) {
97
+ log(level, message, data);
98
+ },
99
+ };
100
+ // ═══════════════════════════════════════════════════════════════════════
101
+ // Message bridge setup
102
+ // ═══════════════════════════════════════════════════════════════════════
103
+ const ownsTransport = !transport;
104
+ const transportToUse = transport ?? createPostMessageTransport({
105
+ targetWindow: target,
106
+ targetOrigin: targetOrigin,
107
+ });
108
+ const bridge = new MessageBridge({
109
+ transport: transportToUse,
110
+ getContext: player.getContext, // we could probably drop this, since we are passing the player to the bridge
111
+ player,
112
+ ...(retryInterval !== undefined && { retryInterval }), // keep default values if not provided
113
+ ...(maxRetries !== undefined && { maxRetries }), // keep default values if not provided
114
+ });
115
+ // Forward lifecycle events through the message bridge
116
+ handlers.onShow.push(() => bridge.fireShow());
117
+ handlers.onStart.push(() => bridge.fireStart());
118
+ handlers.onHide.push(() => bridge.fireHide());
119
+ handlers.onStop.push(() => bridge.fireStop());
120
+ handlers.onContextChange.push((ctx) => bridge.fireContextChange(ctx));
121
+ // This will send a proactive READY
122
+ // as soon as the context is available.
123
+ bridge.start();
124
+ logger.info("AppHost created, message bridge started");
125
+ // ═══════════════════════════════════════════════════════════════════════
126
+ // Helper functions for safe handler execution
127
+ // ═══════════════════════════════════════════════════════════════════════
128
+ /**
129
+ * Safely execute lifecycle handlers.
130
+ * Catches and logs errors to prevent one handler from breaking the chain.
131
+ */
132
+ function fireLifecycleHandlers(handlerArray) {
133
+ for (const handler of handlerArray) {
134
+ try {
135
+ handler();
136
+ }
137
+ catch (error) {
138
+ logger.error("Error in lifecycle handler", error);
139
+ }
140
+ }
141
+ }
142
+ function setPhase(phase) {
143
+ player.lifecyclePhase = phase;
144
+ }
145
+ /**
146
+ * Safely execute context handlers.
147
+ * Catches and logs errors to prevent one handler from breaking the chain.
148
+ */
149
+ function fireContextHandlers(handlerArray, ctx) {
150
+ for (const handler of handlerArray) {
151
+ try {
152
+ handler(ctx);
153
+ }
154
+ catch (error) {
155
+ logger.error("Error in context handler", error);
156
+ }
157
+ }
158
+ }
159
+ // ═══════════════════════════════════════════════════════════════════════
160
+ // AppHost interface
161
+ // ═══════════════════════════════════════════════════════════════════════
162
+ return {
163
+ player,
164
+ fireInit(appContext) {
165
+ context = appContext;
166
+ setPhase(LifecyclePhase.Init);
167
+ resolveReady();
168
+ fireContextHandlers(handlers.onInit, context);
169
+ },
170
+ fireShow() {
171
+ setPhase(LifecyclePhase.Show);
172
+ fireLifecycleHandlers(handlers.onShow);
173
+ },
174
+ fireStart() {
175
+ setPhase(LifecyclePhase.Start);
176
+ fireLifecycleHandlers(handlers.onStart);
177
+ },
178
+ fireHide() {
179
+ setPhase(LifecyclePhase.Hide);
180
+ fireLifecycleHandlers(handlers.onHide);
181
+ },
182
+ fireStop() {
183
+ setPhase(LifecyclePhase.Stop);
184
+ fireLifecycleHandlers(handlers.onStop);
185
+ },
186
+ updateContext(appContext) {
187
+ if (!context) {
188
+ throw new Error("Cannot update context before context is initialized");
189
+ }
190
+ context = appContext;
191
+ fireContextHandlers(handlers.onContextChange, context);
192
+ },
193
+ updateServices(newServices) {
194
+ player.storage = newServices.storage;
195
+ player.proxy = newServices.proxy;
196
+ player.mediaCache = newServices.mediaCache;
197
+ player.static = newServices.static;
198
+ capabilities.length = 0;
199
+ if (newServices.storage)
200
+ capabilities.push("storage");
201
+ if (newServices.proxy)
202
+ capabilities.push("proxy");
203
+ if (newServices.mediaCache)
204
+ capabilities.push("mediaCache");
205
+ if (newServices.static)
206
+ capabilities.push("static");
207
+ },
208
+ destroy() {
209
+ bridge.destroy();
210
+ // Close the transport only if we created it internally.
211
+ // When the caller passes their own transport, they own its lifecycle.
212
+ if (ownsTransport) {
213
+ transportToUse.close();
214
+ }
215
+ // remove all registered lifecycle handlers
216
+ Object.values(handlers).forEach((arr) => (arr.length = 0));
217
+ },
218
+ };
219
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @appstrata/player-lib - Player implementation library
3
+ *
4
+ * Provides the createAppHost() function for platform vendors implementing
5
+ * AppStrata-compliant players. Creates an AppHost instance.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export * from "@appstrata/protocol";
10
+ export type { AppHost, CreateAppHostOptions, CapabilityServices } from "./app-host.js";
11
+ export { createAppHost } from "./app-host.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,cAAc,qBAAqB,CAAC;AAGpC,YAAY,EAAE,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @appstrata/player-lib - Player implementation library
3
+ *
4
+ * Provides the createAppHost() function for platform vendors implementing
5
+ * AppStrata-compliant players. Creates an AppHost instance.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ // Re-export everything from protocol for convenience
10
+ export * from "@appstrata/protocol";
11
+ export { createAppHost } from "./app-host.js";
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@appstrata/player-lib",
3
+ "version": "0.1.0",
4
+ "description": "AppStrata Player Library - Helpers for platform vendors implementing compliant players",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "keywords": [
15
+ "digital-signage",
16
+ "appstrata",
17
+ "player",
18
+ "cms"
19
+ ],
20
+ "author": "AppStrata",
21
+ "license": "MIT",
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "publishConfig": {
26
+ "access": "restricted"
27
+ },
28
+ "dependencies": {
29
+ "@appstrata/core": "0.1.0",
30
+ "@appstrata/protocol": "0.1.0"
31
+ },
32
+ "devDependencies": {
33
+ "@jest/globals": "^29.7.0",
34
+ "@types/jest": "^29.5.11",
35
+ "jest": "^29.7.0",
36
+ "jest-environment-jsdom": "^29.7.0",
37
+ "ts-jest": "^29.1.1",
38
+ "typescript": "^5.3.3"
39
+ },
40
+ "scripts": {
41
+ "build": "tsc --build tsconfig.build.json",
42
+ "clean": "rm -rf dist *.tsbuildinfo",
43
+ "dev": "tsc --build --watch",
44
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
45
+ }
46
+ }