@tomorrowos/sdk 0.5.0 → 0.5.2

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
@@ -51,8 +51,8 @@ DATABASE_SSL=true
51
51
  ```
52
52
 
53
53
  For throwaway demos/tests, set `TOMORROWOS_STORE=memory`. The generated starter
54
- also includes `template/databaseInterface/` with SQLite and Supabase examples
55
- for customers who want to build their own `TomorrowOSStore` implementation.
54
+ includes its own `README.md` beside `server.ts` with database selection,
55
+ migration, and custom `TomorrowOSStore` examples.
56
56
 
57
57
  Migrate database records between supported stores:
58
58
 
@@ -1 +1 @@
1
- {"version":3,"file":"tomorrowos.d.ts","sourceRoot":"","sources":["../src/tomorrowos.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tomorrowos.d.ts","sourceRoot":"","sources":["../src/tomorrowos.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,30 @@ import { MemoryStore } from "./store/memory-store.js";
10
10
  import { resolveBrandLogoPath, syncProjectAssetsToStaticRoot } from "./brand-assets.js";
11
11
  import { probeVideoDurationMs } from "./media-probe.js";
12
12
  import { storeUploadIfNeeded } from "./upload-storage.js";
13
+ function normalizeDevicePlatform(platform, system) {
14
+ const explicit = typeof platform === "string" ? platform.trim().toLowerCase() : "";
15
+ if (explicit)
16
+ return explicit;
17
+ const systemLabel = typeof system === "string" ? system.toLowerCase() : "";
18
+ if (systemLabel.includes("brightsign"))
19
+ return "brightsign";
20
+ if (systemLabel.includes("tizen"))
21
+ return "tizen";
22
+ return undefined;
23
+ }
24
+ function formatDeviceSystemForFirmware(platform, firmware, existingSystem) {
25
+ const fw = typeof firmware === "string" ? firmware.trim() : "";
26
+ if (!fw)
27
+ return existingSystem ?? undefined;
28
+ if (platform === "brightsign")
29
+ return `BrightSign OS (${fw})`;
30
+ if (platform === "tizen")
31
+ return `Tizen (${fw})`;
32
+ const base = typeof existingSystem === "string"
33
+ ? existingSystem.replace(/\s*\([^)]*\)\s*$/, "").trim()
34
+ : "";
35
+ return base ? `${base} (${fw})` : fw;
36
+ }
13
37
  function formatDurationMs(ms) {
14
38
  if (!Number.isFinite(ms) || ms < 0)
15
39
  return "0s";
@@ -433,13 +457,12 @@ export class TomorrowOS extends EventEmitter {
433
457
  const firmware = typeof result.data.firmware === "string"
434
458
  ? result.data.firmware
435
459
  : undefined;
460
+ const platform = normalizeDevicePlatform(existing.platform, existing.system);
436
461
  await this.store.setPairedDevice(deviceId, {
437
462
  ...existing,
438
463
  deviceName: model ?? existing.deviceName,
439
- system: firmware
440
- ? `Tizen (${firmware})`
441
- : existing.system,
442
- platform: existing.platform ?? "tizen"
464
+ system: formatDeviceSystemForFirmware(platform, firmware, existing.system),
465
+ platform: platform ?? existing.platform
443
466
  });
444
467
  }
445
468
  catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomorrowos/sdk",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "TomorrowOS CMS server SDK - WebSocket transport, pairing, device commands, optional static CMS UI. Includes CLI (tomorrowos init / build) and starter templates.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,192 @@
1
+ # TomorrowOS CMS Starter
2
+
3
+ This starter runs a TomorrowOS CMS server with a small built-in control panel.
4
+ The entry point is `server.ts`.
5
+
6
+ ## Start
7
+
8
+ ```bash
9
+ npm install
10
+ npm run dev
11
+ ```
12
+
13
+ By default, the starter uses SQLite at `data/tomorrowos.db`. The database is
14
+ created by `tomorrowos init` and the server will also create missing tables on
15
+ startup.
16
+
17
+ ## Choose A Database
18
+
19
+ Use `.env` to select the database.
20
+
21
+ Default local SQLite:
22
+
23
+ ```env
24
+ TOMORROWOS_STORE=sqlite
25
+ TOMORROWOS_DB_PATH=./data/tomorrowos.db
26
+ ```
27
+
28
+ Supabase/Postgres:
29
+
30
+ ```env
31
+ TOMORROWOS_STORE=supabase
32
+ DATABASE_URL=postgresql://postgres:[PASSWORD]@[HOST]:5432/postgres
33
+ DATABASE_SSL=true
34
+ ```
35
+
36
+ Throwaway in-memory store for tests only:
37
+
38
+ ```env
39
+ TOMORROWOS_STORE=memory
40
+ ```
41
+
42
+ The default `server.ts` uses `createTomorrowOSStore()`, so changing `.env` is
43
+ enough when you use the SDK's built-in SQLite or Supabase/Postgres schema.
44
+
45
+ ## Migrate Data
46
+
47
+ Move data from SQLite to Supabase:
48
+
49
+ ```bash
50
+ npx tomorrowos migrate \
51
+ --from sqlite \
52
+ --from-sqlite ./data/tomorrowos.db \
53
+ --to supabase \
54
+ --to-database-url "$DATABASE_URL"
55
+ ```
56
+
57
+ Move data from Supabase back to SQLite:
58
+
59
+ ```bash
60
+ npx tomorrowos migrate \
61
+ --from supabase \
62
+ --from-database-url "$DATABASE_URL" \
63
+ --to sqlite \
64
+ --to-sqlite ./data/tomorrowos.db
65
+ ```
66
+
67
+ The migration command copies TomorrowOS database records: pairing codes, device
68
+ registry records, paired devices, playlists, and device assignments. It does not
69
+ copy media files in `public/uploads` or object storage. Copy those separately.
70
+
71
+ ## Create Your Own Store
72
+
73
+ Use a custom store when you want your own table names, column names, or database
74
+ backend. Implement `TomorrowOSStore`; implement `TomorrowOSMigratableStore` too
75
+ if you want your custom store to participate in migrations.
76
+
77
+ Reference the SDK's built-in implementations for production-grade examples:
78
+
79
+ - `@tomorrowos/sdk/dist/store/sqlite-store.js`
80
+ - `@tomorrowos/sdk/dist/store/postgres-store.js`
81
+
82
+ In TypeScript projects or when working from the SDK source, the matching source
83
+ files are `src/store/sqlite-store.ts` and `src/store/postgres-store.ts`.
84
+
85
+ Example skeleton:
86
+
87
+ ```ts
88
+ import type {
89
+ DevicePlaylistAssignment,
90
+ DeviceRegistryEntry,
91
+ DeviceRegistryRecord,
92
+ PairedDeviceEntry,
93
+ PairedDeviceRecord,
94
+ PendingCodeEntry,
95
+ PendingCodeRecord,
96
+ StoredPlaylist,
97
+ TomorrowOSMigratableStore
98
+ } from "@tomorrowos/sdk";
99
+
100
+ export class MyDatabaseStore implements TomorrowOSMigratableStore {
101
+ constructor(private readonly connectionString: string) {}
102
+
103
+ async setPendingCode(code: string, record: PendingCodeRecord): Promise<void> {
104
+ // Write record.deviceId and record.createdAt into your schema.
105
+ }
106
+
107
+ async getPendingCode(code: string): Promise<PendingCodeRecord | undefined> {
108
+ // Read from your schema and map it back to { deviceId, createdAt }.
109
+ return undefined;
110
+ }
111
+
112
+ async deletePendingCode(code: string): Promise<void> {}
113
+
114
+ async listPendingCodes(): Promise<PendingCodeEntry[]> {
115
+ return [];
116
+ }
117
+
118
+ async getDeviceRegistry(deviceId: string): Promise<DeviceRegistryRecord | undefined> {
119
+ return undefined;
120
+ }
121
+
122
+ async setDeviceRegistry(deviceId: string, record: DeviceRegistryRecord): Promise<void> {}
123
+
124
+ async getDeviceRegistryByCode(
125
+ code: string
126
+ ): Promise<{ deviceId: string; record: DeviceRegistryRecord } | undefined> {
127
+ return undefined;
128
+ }
129
+
130
+ async listDeviceRegistry(): Promise<DeviceRegistryEntry[]> {
131
+ return [];
132
+ }
133
+
134
+ async setPairedDevice(deviceId: string, record: PairedDeviceRecord): Promise<void> {}
135
+
136
+ async getPairedDevice(deviceId: string): Promise<PairedDeviceRecord | undefined> {
137
+ return undefined;
138
+ }
139
+
140
+ async deletePairedDevice(deviceId: string): Promise<void> {}
141
+
142
+ async listPairedDevices(): Promise<PairedDeviceEntry[]> {
143
+ return [];
144
+ }
145
+
146
+ async listPlaylists(): Promise<StoredPlaylist[]> {
147
+ return [];
148
+ }
149
+
150
+ async getPlaylist(id: string): Promise<StoredPlaylist | undefined> {
151
+ return undefined;
152
+ }
153
+
154
+ async setPlaylist(record: StoredPlaylist): Promise<void> {}
155
+
156
+ async isPlaylistNameTaken(name: string, excludeId?: string): Promise<boolean> {
157
+ return false;
158
+ }
159
+
160
+ async getDeviceAssignments(deviceId: string): Promise<DevicePlaylistAssignment[]> {
161
+ return [];
162
+ }
163
+
164
+ async setDeviceAssignments(
165
+ deviceId: string,
166
+ assignments: DevicePlaylistAssignment[]
167
+ ): Promise<void> {}
168
+ }
169
+ ```
170
+
171
+ ## Use Your Store In server.ts
172
+
173
+ Replace the default store creation:
174
+
175
+ ```ts
176
+ const store = createTomorrowOSStore({
177
+ sqlitePath: join(__dirname, "data", "tomorrowos.db")
178
+ });
179
+ ```
180
+
181
+ with your custom store:
182
+
183
+ ```ts
184
+ import { TomorrowOS } from "@tomorrowos/sdk";
185
+ import { MyDatabaseStore } from "./stores/my-database-store.js";
186
+
187
+ const store = new MyDatabaseStore(process.env.DATABASE_URL!);
188
+ const tomorrowos = new TomorrowOS({ brand, store });
189
+ ```
190
+
191
+ Your store class name and file path can be anything. TomorrowOS only requires
192
+ that the object passed as `store` implements the required store methods.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-cms",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "CMS server on @tomorrowos/sdk. Add your UI (React, static files, etc.) alongside this server.",
5
5
  "private": true,
6
6
  "type": "module",
@@ -10,7 +10,7 @@
10
10
  "build-player": "tomorrowos build --platform tizen"
11
11
  },
12
12
  "dependencies": {
13
- "@tomorrowos/sdk": "^0.5.0",
13
+ "@tomorrowos/sdk": "^0.5.2",
14
14
  "dotenv": "^17.2.3"
15
15
  },
16
16
  "devDependencies": {
@@ -1,14 +0,0 @@
1
- # Database Interface Examples
2
-
3
- The starter server already switches databases from `.env`:
4
-
5
- - `TOMORROWOS_STORE=sqlite` uses `data/tomorrowos.db`.
6
- - `TOMORROWOS_STORE=supabase` plus `DATABASE_URL=...` uses Supabase/Postgres.
7
- - `TOMORROWOS_STORE=memory` is only for throwaway tests.
8
-
9
- These files are reference examples for customers who want to understand or build
10
- their own database interface. You do not need to import them for the starter to
11
- work.
12
-
13
- If you build a custom database backend, implement `TomorrowOSStore` and pass it
14
- to `new TomorrowOS({ brand, store })` in `server.ts`.
@@ -1,10 +0,0 @@
1
- /**
2
- * Reference only. The starter already uses this behavior by default.
3
- */
4
- import { SQLiteStore } from "@tomorrowos/sdk";
5
-
6
- export function createSQLiteInterface() {
7
- return new SQLiteStore({
8
- databasePath: process.env.TOMORROWOS_DB_PATH || "./data/tomorrowos.db"
9
- });
10
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * Reference only. Supabase exposes a Postgres connection string, so TomorrowOS
3
- * uses PostgresStore for Supabase-backed persistence.
4
- */
5
- import { PostgresStore } from "@tomorrowos/sdk";
6
-
7
- export function createSupabaseInterface() {
8
- const connectionString = process.env.DATABASE_URL;
9
- if (!connectionString) {
10
- throw new Error("DATABASE_URL is required for Supabase/Postgres.");
11
- }
12
-
13
- return new PostgresStore({
14
- connectionString,
15
- ssl: { rejectUnauthorized: false }
16
- });
17
- }