@tomorrowos/sdk 1.1.4 → 1.1.6
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/PLAYER_INSTALL.md +32 -4
- package/README.md +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/playlist-catalog.d.ts +5 -0
- package/dist/playlist-catalog.d.ts.map +1 -1
- package/dist/playlist-catalog.js +22 -1
- package/dist/screen-tags.d.ts +95 -0
- package/dist/screen-tags.d.ts.map +1 -0
- package/dist/screen-tags.js +835 -0
- package/dist/store/memory-store.d.ts +2 -0
- package/dist/store/memory-store.d.ts.map +1 -1
- package/dist/store/memory-store.js +11 -0
- package/dist/store/postgres-store.d.ts +2 -0
- package/dist/store/postgres-store.d.ts.map +1 -1
- package/dist/store/postgres-store.js +9 -0
- package/dist/store/sqlite-store.d.ts +2 -0
- package/dist/store/sqlite-store.d.ts.map +1 -1
- package/dist/store/sqlite-store.js +12 -0
- package/dist/store/types.d.ts +20 -0
- package/dist/store/types.d.ts.map +1 -1
- package/dist/tomorrowos.d.ts +6 -0
- package/dist/tomorrowos.d.ts.map +1 -1
- package/dist/tomorrowos.js +44 -1
- package/package.json +1 -1
- package/templates/cms-starter/package-lock.json +3 -3
- package/templates/cms-starter/package.json +2 -2
- package/templates/cms-starter/public/index.html +86 -1
- package/templates/cms-starter/public/methods.js +782 -11
- package/templates/cms-starter/public/panel.css +356 -0
- package/templates/cms-starter-v0/cms-panel/index.html +86 -1
- package/templates/cms-starter-v0/cms-panel/methods.js +782 -11
- package/templates/cms-starter-v0/cms-panel/panel.css +356 -0
- package/templates/cms-starter-v0/package-lock.json +3 -3
- package/templates/cms-starter-v0/package.json +2 -2
package/PLAYER_INSTALL.md
CHANGED
|
@@ -18,7 +18,7 @@ This guide covers the full path from a verified player package to a paired scree
|
|
|
18
18
|
|
|
19
19
|
- A running TomorrowOS CMS (Replit, Vercel, Railway, or self-hosted)
|
|
20
20
|
- A CMS URL the **panel** can reach (public HTTPS in production, or a tunnel / LAN IP for lab tests)
|
|
21
|
-
- A supported panel: **Samsung Tizen 6.5 and 7.0
|
|
21
|
+
- A supported panel: **Samsung Tizen 6.5 and 7.0**, **BrightSign Series 3-6**, or **Windows 11 Pro x64** (Windows Player V1)
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
@@ -28,6 +28,7 @@ This guide covers the full path from a verified player package to a paired scree
|
|
|
28
28
|
| --- | --- |
|
|
29
29
|
| **Samsung** | Install on a Samsung Tizen player via **Custom App** (`https://tmr.sh/tizen`), or download the player from the CMS and install it via USB. |
|
|
30
30
|
| **BrightSign** | Download the ZIP package from the CMS with `config.js` configured so that `cmsEndpoint` points to your CMS origin and install it via SD card. |
|
|
31
|
+
| **Windows** | Download **Windows Player V1** (`TomorrowOS-Windows-Setup.exe`) and run the installer on **Windows 11 Pro x64**. |
|
|
31
32
|
|
|
32
33
|
### Samsung (recommended path)
|
|
33
34
|
|
|
@@ -54,7 +55,21 @@ After install, enter your CMS URL on the on-device setup screen.
|
|
|
54
55
|
1. Control Panel → **Download Players → BrightSign** (`GET /players/brightsign.zip`).
|
|
55
56
|
2. That zip already has `cmsEndpoint` pointed at **this** CMS origin — usually you only confirm `orientation`.
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
### Windows
|
|
59
|
+
|
|
60
|
+
**Windows 11 Pro x64** — Windows Player V1. Download the installer from either:
|
|
61
|
+
|
|
62
|
+
- `https://tmr.sh/app/windows/TomorrowOS-Windows-Setup.exe`, **or**
|
|
63
|
+
- Control Panel → **Download Players → Windows**
|
|
64
|
+
|
|
65
|
+
Then install:
|
|
66
|
+
|
|
67
|
+
1. Run `TomorrowOS-Windows-Setup.exe`.
|
|
68
|
+
2. In the wizard, set the CMS endpoint, orientation, display, and maintenance passcode.
|
|
69
|
+
3. Finish the wizard and launch the player.
|
|
70
|
+
4. The screen shows a six-character pairing code. Enter it in the Control Panel to pair.
|
|
71
|
+
|
|
72
|
+
Caption in the Control Panel today: **Tizen 6.5 and 7.0**, **BrightSign Series 3-6**, **Windows 11 Pro x64**.
|
|
58
73
|
|
|
59
74
|
---
|
|
60
75
|
|
|
@@ -144,6 +159,18 @@ When you download via the CMS, `cmsEndpoint` is **filled automatically** with th
|
|
|
144
159
|
9. Wait through the initial black window (~10 seconds before `Show()` is normal).
|
|
145
160
|
10. Confirm the pairing / brand UI appears.
|
|
146
161
|
|
|
162
|
+
### Windows
|
|
163
|
+
|
|
164
|
+
**Windows 11 Pro x64** — Windows Player V1.
|
|
165
|
+
|
|
166
|
+
1. Download the installer from either:
|
|
167
|
+
- `https://tmr.sh/app/windows/TomorrowOS-Windows-Setup.exe`, **or**
|
|
168
|
+
- Control Panel → **Download Players → Windows**
|
|
169
|
+
2. Run `TomorrowOS-Windows-Setup.exe`.
|
|
170
|
+
3. In the wizard, set the CMS endpoint, orientation, display, and maintenance passcode.
|
|
171
|
+
4. Finish the wizard and launch the player.
|
|
172
|
+
5. The screen shows a six-character pairing code. Enter it in the Control Panel to pair.
|
|
173
|
+
|
|
147
174
|
---
|
|
148
175
|
|
|
149
176
|
## 4. Six-character pairing
|
|
@@ -191,7 +218,7 @@ Always record **model + firmware** from `device.info.get` before calling a fleet
|
|
|
191
218
|
|
|
192
219
|
### Not shipping yet
|
|
193
220
|
|
|
194
|
-
LG webOS
|
|
221
|
+
LG webOS and Android players are not in this SDK release.
|
|
195
222
|
|
|
196
223
|
---
|
|
197
224
|
|
|
@@ -225,6 +252,7 @@ await tomorrowos.pairing.unpair(deviceId);
|
|
|
225
252
|
2. Point the player at the **new** CMS endpoint:
|
|
226
253
|
- Tizen: re-enter CMS URL on the setup screen (clear / change stored URL if needed, then reboot).
|
|
227
254
|
- BrightSign: download a new zip from the **new** CMS (or edit `config.js` `cmsEndpoint`), copy to SD, power-cycle.
|
|
255
|
+
- Windows: re-run `TomorrowOS-Windows-Setup.exe` and set the new CMS endpoint, then launch the player.
|
|
228
256
|
3. Pair on the new CMS with the on-screen code.
|
|
229
257
|
|
|
230
258
|
---
|
|
@@ -245,7 +273,7 @@ await tomorrowos.pairing.unpair(deviceId);
|
|
|
245
273
|
|
|
246
274
|
## Coming soon
|
|
247
275
|
|
|
248
|
-
LG webOS
|
|
276
|
+
LG webOS and Android players.
|
|
249
277
|
|
|
250
278
|
---
|
|
251
279
|
|
package/README.md
CHANGED
|
@@ -106,9 +106,9 @@ Player install and pairing: `PLAYER_INSTALL.md`. Deep hosting and agent protocol
|
|
|
106
106
|
| Samsung Tizen 6.5 and 7.0 | Supported | Certified models and firmware only |
|
|
107
107
|
| BrightSign Series 3-6 | Supported | Series 3 requires firmware **9.1.140+** |
|
|
108
108
|
| BrightSign Series 3 4K H.264 | Not supported | Use certified **1080p H.264** media |
|
|
109
|
+
| Windows 11 Pro x64 | Supported | None |
|
|
109
110
|
| Android | Planned | Not available for production |
|
|
110
111
|
| LG webOS | Planned | Not available for production |
|
|
111
|
-
| Windows | Planned | Not available for production |
|
|
112
112
|
|
|
113
113
|
Treat a combination as production-ready only after you validate it on your panels.
|
|
114
114
|
|
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,10 @@ export type { DeviceListItem, DeviceScreenshotInfo, ListenOptions, TomorrowOSBra
|
|
|
3
3
|
export type { ConnectorState, ConnectorStatus, ServerStatusReport, StatusBlocker } from "./server-status.js";
|
|
4
4
|
export { buildServerStatus } from "./server-status.js";
|
|
5
5
|
export { getSdkPackageVersion } from "./sdk-version.js";
|
|
6
|
-
export type { DeviceOnOffTimer, DevicePlaylistAssignment, DeviceRegistryRecord, PairedDeviceRecord, PendingCodeEntry, PendingCodeRecord, DeviceRegistryEntry, PlaylistItemRecord, PlaylistSchedule, PublishedPlaylistSnapshot, StoredPlaylist, TomorrowOSDataSnapshot, TomorrowOSMigratableStore, TomorrowOSStore } from "./store/types.js";
|
|
6
|
+
export type { DeviceOnOffTimer, DevicePlaylistAssignment, DeviceRegistryRecord, PairedDeviceRecord, PendingCodeEntry, PendingCodeRecord, DeviceRegistryEntry, PlaylistItemRecord, PlaylistItemSchedule, PlaylistItemTagRule, PlaylistSchedule, PublishedPlaylistSnapshot, StoredPlaylist, TomorrowOSDataSnapshot, TomorrowOSMigratableStore, TomorrowOSStore } from "./store/types.js";
|
|
7
7
|
export { PlaylistCatalog } from "./playlist-catalog.js";
|
|
8
|
+
export { filterPolicyForScreen, itemMatchesScreen, itemScheduleActive, parseItemSchedule, parseTagRule, ScreenTagStore } from "./screen-tags.js";
|
|
9
|
+
export type { ItemSchedule, ScreenTagHost, ScreenTagHttpDeps, TagRule, TagRuleOp } from "./screen-tags.js";
|
|
8
10
|
export type { BuiltDevicePolicy, SavePlaylistInput } from "./playlist-catalog.js";
|
|
9
11
|
export { DEFAULT_PAIRING_CODE_SECRET, generateDeterministicPairingCode, generateRandomPairingCode, isValidPairingCodeFormat, normalizePairingCode, PAIRING_CODE_ALPHABET, PAIRING_CODE_LENGTH, resolvePairingCodeSecret } from "./pairing-code.js";
|
|
10
12
|
export { MemoryStore } from "./store/memory-store.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,YAAY,EACV,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EACL,2BAA2B,EAC3B,gCAAgC,EAChC,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,4BAA4B,EAC5B,qBAAqB,EACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,YAAY,EACV,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,OAAO,EACP,SAAS,EACV,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EACL,2BAA2B,EAC3B,gCAAgC,EAChC,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,4BAA4B,EAC5B,qBAAqB,EACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export { TomorrowOS } from "./tomorrowos.js";
|
|
|
2
2
|
export { buildServerStatus } from "./server-status.js";
|
|
3
3
|
export { getSdkPackageVersion } from "./sdk-version.js";
|
|
4
4
|
export { PlaylistCatalog } from "./playlist-catalog.js";
|
|
5
|
+
export { filterPolicyForScreen, itemMatchesScreen, itemScheduleActive, parseItemSchedule, parseTagRule, ScreenTagStore } from "./screen-tags.js";
|
|
5
6
|
export { DEFAULT_PAIRING_CODE_SECRET, generateDeterministicPairingCode, generateRandomPairingCode, isValidPairingCodeFormat, normalizePairingCode, PAIRING_CODE_ALPHABET, PAIRING_CODE_LENGTH, resolvePairingCodeSecret } from "./pairing-code.js";
|
|
6
7
|
export { MemoryStore } from "./store/memory-store.js";
|
|
7
8
|
export { PostgresStore } from "./store/postgres-store.js";
|
|
@@ -29,6 +29,11 @@ export declare class PlaylistCatalog {
|
|
|
29
29
|
removePlaylistFromDevice(deviceId: string, playlistId: string): Promise<BuiltDevicePolicy>;
|
|
30
30
|
/** Remove every playlist assignment from a device (CMS catalog + empty policy). */
|
|
31
31
|
clearAllAssignmentsFromDevice(deviceId: string): Promise<BuiltDevicePolicy>;
|
|
32
|
+
/**
|
|
33
|
+
* A retired playlist stays only while some device still has its published snapshot.
|
|
34
|
+
* Clear (or removing it from the last screen) drops that snapshot, so the row goes too.
|
|
35
|
+
*/
|
|
36
|
+
private deleteRetiredPlaylistsWithoutAssignments;
|
|
32
37
|
/**
|
|
33
38
|
* If the device has this playlist assigned, refresh its snapshot to latest
|
|
34
39
|
* and return a rebuilt snapshot policy for immediate push.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playlist-catalog.d.ts","sourceRoot":"","sources":["../src/playlist-catalog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,kBAAkB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,SAAS,EAAE,yBAAyB,EAAE,CAAC;QACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;KAClC,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAyDD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,eAAe;IAE7C,aAAa,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAK1C,6BAA6B,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAI1D,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAI5D,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IA8B/D,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"playlist-catalog.d.ts","sourceRoot":"","sources":["../src/playlist-catalog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,kBAAkB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,SAAS,EAAE,yBAAyB,EAAE,CAAC;QACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;KAClC,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAyDD,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,eAAe;IAE7C,aAAa,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAK1C,6BAA6B,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAI1D,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAI5D,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IA8B/D,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBnD,oBAAoB,CACxB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAIhC,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC;IAiEvB,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,iBAAiB,CAAC;IAQ7B,mFAAmF;IAC7E,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IASjF;;;OAGG;YACW,wCAAwC;IAStD;;;OAGG;IACG,+BAA+B,CACnC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,iBAAiB,CAAA;KAAE,CAAC;IA4BrD,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC;YAKf,0BAA0B;IA+BxC,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGpE"}
|
package/dist/playlist-catalog.js
CHANGED
|
@@ -100,7 +100,11 @@ export class PlaylistCatalog {
|
|
|
100
100
|
retired: true,
|
|
101
101
|
retiredAt: new Date().toISOString()
|
|
102
102
|
};
|
|
103
|
-
await this.store.
|
|
103
|
+
if (await this.store.isPlaylistAssigned(id)) {
|
|
104
|
+
await this.store.setPlaylist(record);
|
|
105
|
+
return record;
|
|
106
|
+
}
|
|
107
|
+
await this.store.deletePlaylist(id);
|
|
104
108
|
return record;
|
|
105
109
|
}
|
|
106
110
|
async getDeviceAssignments(deviceId) {
|
|
@@ -161,13 +165,30 @@ export class PlaylistCatalog {
|
|
|
161
165
|
const assignments = await this.store.getDeviceAssignments(deviceId);
|
|
162
166
|
const next = assignments.filter((a) => a.playlistId !== playlistId);
|
|
163
167
|
await this.store.setDeviceAssignments(deviceId, next);
|
|
168
|
+
await this.deleteRetiredPlaylistsWithoutAssignments([playlistId]);
|
|
164
169
|
return this.buildPolicyFromAssignments(next, { useLatest: false });
|
|
165
170
|
}
|
|
166
171
|
/** Remove every playlist assignment from a device (CMS catalog + empty policy). */
|
|
167
172
|
async clearAllAssignmentsFromDevice(deviceId) {
|
|
173
|
+
const removedIds = (await this.store.getDeviceAssignments(deviceId)).map((assignment) => assignment.playlistId);
|
|
168
174
|
await this.store.setDeviceAssignments(deviceId, []);
|
|
175
|
+
await this.deleteRetiredPlaylistsWithoutAssignments(removedIds);
|
|
169
176
|
return this.buildPolicyFromAssignments([], { useLatest: false });
|
|
170
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* A retired playlist stays only while some device still has its published snapshot.
|
|
180
|
+
* Clear (or removing it from the last screen) drops that snapshot, so the row goes too.
|
|
181
|
+
*/
|
|
182
|
+
async deleteRetiredPlaylistsWithoutAssignments(playlistIds) {
|
|
183
|
+
for (const playlistId of new Set(playlistIds)) {
|
|
184
|
+
const playlist = await this.store.getPlaylist(playlistId);
|
|
185
|
+
if (!playlist?.retired)
|
|
186
|
+
continue;
|
|
187
|
+
if (await this.store.isPlaylistAssigned(playlistId))
|
|
188
|
+
continue;
|
|
189
|
+
await this.store.deletePlaylist(playlistId);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
171
192
|
/**
|
|
172
193
|
* If the device has this playlist assigned, refresh its snapshot to latest
|
|
173
194
|
* and return a rebuilt snapshot policy for immediate push.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screen tags and per-item schedules.
|
|
3
|
+
*
|
|
4
|
+
* Screens store tags. Each playlist item may store a tagRule and a schedule.
|
|
5
|
+
* When a policy is pushed, items that do not match that screen right now are
|
|
6
|
+
* removed. Items with no rule play on every screen. Items with no schedule
|
|
7
|
+
* play all the time. tagRule and schedule are stripped before the player sees
|
|
8
|
+
* the policy.
|
|
9
|
+
*
|
|
10
|
+
* Screen tags live in screen-tags.json beside the SQLite database (or
|
|
11
|
+
* data/screen-tags.json). Playlist item rules ride along in items JSON.
|
|
12
|
+
*/
|
|
13
|
+
import type { IncomingMessage, ServerResponse } from "http";
|
|
14
|
+
import type { TomorrowOSStore } from "./store/types.js";
|
|
15
|
+
export interface ScreenTagHost {
|
|
16
|
+
listDevices(): Promise<Array<{
|
|
17
|
+
deviceId: string;
|
|
18
|
+
deviceName?: string | null;
|
|
19
|
+
connected: boolean;
|
|
20
|
+
}>>;
|
|
21
|
+
pushLatestPolicyToDevice(deviceId: string): Promise<{
|
|
22
|
+
pushed: boolean;
|
|
23
|
+
}>;
|
|
24
|
+
playlists: {
|
|
25
|
+
buildPolicyForDevice(deviceId: string, options: {
|
|
26
|
+
useLatest?: boolean;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
policy: unknown;
|
|
29
|
+
}>;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export type TagRuleOp = "any" | "all" | "notAny" | "notAll";
|
|
33
|
+
export interface TagRule {
|
|
34
|
+
op: TagRuleOp;
|
|
35
|
+
tags: string[];
|
|
36
|
+
}
|
|
37
|
+
export declare function normalizeTag(raw: unknown): string | null;
|
|
38
|
+
export declare function normalizeTagList(raw: unknown): string[];
|
|
39
|
+
/**
|
|
40
|
+
* Monday = 0 … Sunday = 6.
|
|
41
|
+
* [true, true, true, true, true, false, false] is Mon–Fri and does not play Sat or Sun.
|
|
42
|
+
* [false, false, false, false, false, true, true] is Sat and Sun.
|
|
43
|
+
*/
|
|
44
|
+
export declare function weekdayIndexMondayFirst(date: Date): number;
|
|
45
|
+
export interface ItemSchedule {
|
|
46
|
+
startDate?: string;
|
|
47
|
+
endDate?: string;
|
|
48
|
+
startTime?: string;
|
|
49
|
+
endTime?: string;
|
|
50
|
+
days?: boolean[];
|
|
51
|
+
}
|
|
52
|
+
/** Missing or empty schedule means the item plays all the time. */
|
|
53
|
+
export declare function parseItemSchedule(raw: unknown): ItemSchedule | null;
|
|
54
|
+
/**
|
|
55
|
+
* `now` is interpreted in its local timezone. End times are exclusive.
|
|
56
|
+
* A window whose end is earlier than its start continues past midnight,
|
|
57
|
+
* and that tail still belongs to the day the window started.
|
|
58
|
+
*/
|
|
59
|
+
export declare function itemScheduleActive(raw: unknown, now?: Date): boolean;
|
|
60
|
+
/** Missing, empty, or invalid rules mean the item plays on every screen. */
|
|
61
|
+
export declare function parseTagRule(raw: unknown): TagRule | null;
|
|
62
|
+
export declare function itemMatchesScreen(screenTags: readonly string[], item: unknown, now?: Date): boolean;
|
|
63
|
+
/** Returns a new policy. Does not mutate the SDK snapshot objects. */
|
|
64
|
+
export declare function filterPolicyForScreen(policy: unknown, screenTags: readonly string[], now?: Date): unknown;
|
|
65
|
+
/**
|
|
66
|
+
* Re-push a screen when a schedule window opens or closes.
|
|
67
|
+
* Current players ignore item schedules, so the CMS removes inactive items
|
|
68
|
+
* before the policy is sent. The check uses this computer's local clock.
|
|
69
|
+
*/
|
|
70
|
+
export declare function startItemScheduleRefresher(deps: ScreenTagHttpDeps): void;
|
|
71
|
+
export declare class ScreenTagStore {
|
|
72
|
+
private readonly filePath;
|
|
73
|
+
private chain;
|
|
74
|
+
constructor(filePath: string);
|
|
75
|
+
get(deviceId: string): Promise<string[]>;
|
|
76
|
+
all(): Promise<Record<string, string[]>>;
|
|
77
|
+
catalog(): Promise<string[]>;
|
|
78
|
+
remember(tag: string): Promise<string[]>;
|
|
79
|
+
rename(from: string, to: string): Promise<string[]>;
|
|
80
|
+
forget(tag: string): Promise<void>;
|
|
81
|
+
add(deviceId: string, tag: string): Promise<string[]>;
|
|
82
|
+
remove(deviceId: string, tag: string): Promise<string[]>;
|
|
83
|
+
deleteDevice(deviceId: string): Promise<void>;
|
|
84
|
+
private rememberOn;
|
|
85
|
+
private enqueue;
|
|
86
|
+
private read;
|
|
87
|
+
private write;
|
|
88
|
+
}
|
|
89
|
+
export interface ScreenTagHttpDeps {
|
|
90
|
+
host: ScreenTagHost;
|
|
91
|
+
store: TomorrowOSStore;
|
|
92
|
+
tags: ScreenTagStore;
|
|
93
|
+
}
|
|
94
|
+
export declare function handleScreenTagHttp(req: IncomingMessage, res: ServerResponse, deps: ScreenTagHttpDeps): Promise<boolean>;
|
|
95
|
+
//# sourceMappingURL=screen-tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen-tags.d.ts","sourceRoot":"","sources":["../src/screen-tags.ts"],"names":[],"mappings":"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"}
|