@tomorrowos/sdk 0.1.9 → 0.1.10
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/dist/store/memory-store.d.ts +1 -0
- package/dist/store/memory-store.d.ts.map +1 -1
- package/dist/store/memory-store.js +3 -0
- package/dist/store/types.d.ts +1 -0
- package/dist/store/types.d.ts.map +1 -1
- package/dist/tomorrowos.d.ts +9 -0
- package/dist/tomorrowos.d.ts.map +1 -1
- package/dist/tomorrowos.js +37 -1
- package/package.json +1 -1
- package/templates/cms-starter/package.json +2 -2
- package/templates/cms-starter/public/index.html +1 -0
- package/templates/cms-starter/public/methods.js +54 -3
|
@@ -11,5 +11,6 @@ export declare class MemoryStore implements TomorrowOSStore {
|
|
|
11
11
|
deletePendingCode(code: string): Promise<void>;
|
|
12
12
|
setPairedDevice(deviceId: string, record: PairedDeviceRecord): Promise<void>;
|
|
13
13
|
getPairedDevice(deviceId: string): Promise<PairedDeviceRecord | undefined>;
|
|
14
|
+
deletePairedDevice(deviceId: string): Promise<void>;
|
|
14
15
|
}
|
|
15
16
|
//# sourceMappingURL=memory-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../src/store/memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,qBAAa,WAAY,YAAW,eAAe;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;IACrE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyC;IAEjE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAIpE,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9C,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,IAAI,CAAC;IAIV,eAAe,CACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../src/store/memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,qBAAa,WAAY,YAAW,eAAe;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwC;IACrE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyC;IAEjE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAIpE,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9C,eAAe,CACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,IAAI,CAAC;IAIV,eAAe,CACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;IAIpC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1D"}
|
package/dist/store/types.d.ts
CHANGED
|
@@ -20,5 +20,6 @@ export interface TomorrowOSStore {
|
|
|
20
20
|
deletePendingCode(code: string): Promise<void>;
|
|
21
21
|
setPairedDevice(deviceId: string, record: PairedDeviceRecord): Promise<void>;
|
|
22
22
|
getPairedDevice(deviceId: string): Promise<PairedDeviceRecord | undefined>;
|
|
23
|
+
deletePairedDevice(deviceId: string): Promise<void>;
|
|
23
24
|
}
|
|
24
25
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IACrE,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IACrE,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;IAC3E,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD"}
|
package/dist/tomorrowos.d.ts
CHANGED
|
@@ -40,10 +40,19 @@ export declare class TomorrowOS extends EventEmitter {
|
|
|
40
40
|
pairingVerify(code: string): Promise<{
|
|
41
41
|
deviceId: string;
|
|
42
42
|
}>;
|
|
43
|
+
/** Remove pairing for a device and notify it over WebSocket if connected. */
|
|
44
|
+
pairingUnpair(deviceId: string): Promise<{
|
|
45
|
+
deviceId: string;
|
|
46
|
+
notified: boolean;
|
|
47
|
+
}>;
|
|
43
48
|
pairing: {
|
|
44
49
|
verify: (code: string) => Promise<{
|
|
45
50
|
deviceId: string;
|
|
46
51
|
}>;
|
|
52
|
+
unpair: (deviceId: string) => Promise<{
|
|
53
|
+
deviceId: string;
|
|
54
|
+
notified: boolean;
|
|
55
|
+
}>;
|
|
47
56
|
};
|
|
48
57
|
device(deviceId: string): {
|
|
49
58
|
sendCommand<T = unknown>(method: string, params?: Record<string, unknown>): Promise<{
|
package/dist/tomorrowos.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tomorrowos.d.ts","sourceRoot":"","sources":["../src/tomorrowos.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,IAAI,MAAM,MAAM,CAAC;AAKxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,eAAe,CAAC;IACvB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"tomorrowos.d.ts","sourceRoot":"","sources":["../src/tomorrowos.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,IAAI,MAAM,MAAM,CAAC;AAKxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,eAAe,CAAC;IACvB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAyED,qBAAa,UAAW,SAAQ,YAAY;IAC1C,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,eAAe,CAAgB;gBAE3B,OAAO,EAAE,iBAAiB;IAMtC,oEAAoE;IAC9D,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAiChE,6EAA6E;IACvE,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IA2BvF,OAAO;uBACU,MAAM;sBA9DgC,MAAM;;2BA+DxC,MAAM;sBA7BgC,MAAM;sBAAY,OAAO;;MA8BlF;IAEF,MAAM,CAAC,QAAQ,EAAE,MAAM;oBAGD,CAAC,oBACT,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;;IAU5E,OAAO,CAAC,mBAAmB;IA6D3B,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC,MAAM;YAkD7B,iBAAiB;YAqCjB,cAAc;YAmCd,UAAU;YAkEV,gBAAgB;IAgE9B,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,gBAAgB;CAgFzB"}
|
package/dist/tomorrowos.js
CHANGED
|
@@ -90,8 +90,31 @@ export class TomorrowOS extends EventEmitter {
|
|
|
90
90
|
this.emit("device.paired", { deviceId: record.deviceId });
|
|
91
91
|
return { deviceId: record.deviceId };
|
|
92
92
|
}
|
|
93
|
+
/** Remove pairing for a device and notify it over WebSocket if connected. */
|
|
94
|
+
async pairingUnpair(deviceId) {
|
|
95
|
+
const id = String(deviceId || "").trim();
|
|
96
|
+
if (!id) {
|
|
97
|
+
const err = new Error("deviceId is required");
|
|
98
|
+
err.code = "PAIRING_INVALID";
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
await this.store.deletePairedDevice(id);
|
|
102
|
+
const ws = this.devices.get(id);
|
|
103
|
+
let notified = false;
|
|
104
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
105
|
+
ws.send(JSON.stringify({
|
|
106
|
+
type: "pairing.unpaired",
|
|
107
|
+
method: "tomorrowos.pairing.unpair",
|
|
108
|
+
deviceId: id
|
|
109
|
+
}));
|
|
110
|
+
notified = true;
|
|
111
|
+
}
|
|
112
|
+
this.emit("device.unpaired", { deviceId: id });
|
|
113
|
+
return { deviceId: id, notified };
|
|
114
|
+
}
|
|
93
115
|
pairing = {
|
|
94
|
-
verify: (code) => this.pairingVerify(code)
|
|
116
|
+
verify: (code) => this.pairingVerify(code),
|
|
117
|
+
unpair: (deviceId) => this.pairingUnpair(deviceId)
|
|
95
118
|
};
|
|
96
119
|
device(deviceId) {
|
|
97
120
|
const self = this;
|
|
@@ -291,6 +314,19 @@ export class TomorrowOS extends EventEmitter {
|
|
|
291
314
|
}
|
|
292
315
|
return;
|
|
293
316
|
}
|
|
317
|
+
if (req.method === "POST" && pathname === "/pairing/unpair") {
|
|
318
|
+
const body = (await readJsonBody(req));
|
|
319
|
+
const deviceId = typeof body.deviceId === "string" ? body.deviceId : "";
|
|
320
|
+
try {
|
|
321
|
+
const result = await this.pairingUnpair(deviceId);
|
|
322
|
+
sendJson(res, 200, { status: "success", ...result });
|
|
323
|
+
}
|
|
324
|
+
catch (e) {
|
|
325
|
+
const msg = e instanceof Error ? e.message : "Unpair failed";
|
|
326
|
+
sendJson(res, 400, { status: "failed", error: msg });
|
|
327
|
+
}
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
294
330
|
if (req.method === "POST") {
|
|
295
331
|
const parsed = parseDevicePath(pathname);
|
|
296
332
|
if (parsed) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomorrowos/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
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",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "my-cms",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
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.1.
|
|
13
|
+
"@tomorrowos/sdk": "^0.1.10"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@types/node": "^20.0.0",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
<div class="row">
|
|
20
20
|
<input id="code" maxlength="6" placeholder="6-digit code" />
|
|
21
21
|
<button type="button" onclick="verify()">Verify</button>
|
|
22
|
+
<button type="button" class="danger" onclick="unpair()">Unpair</button>
|
|
22
23
|
</div>
|
|
23
24
|
<input type="hidden" id="deviceId" />
|
|
24
25
|
</section>
|
|
@@ -104,6 +104,19 @@ function defaultDurationMs(type) {
|
|
|
104
104
|
return 10000;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
function normalizeDurationMs(item) {
|
|
108
|
+
const maxMs = 3600 * 1000;
|
|
109
|
+
const minMs = 1000;
|
|
110
|
+
let ms = Number(item?.durationMs);
|
|
111
|
+
if (!Number.isFinite(ms) || ms < minMs) {
|
|
112
|
+
return defaultDurationMs(item?.type);
|
|
113
|
+
}
|
|
114
|
+
if (ms === 1000000) {
|
|
115
|
+
return defaultDurationMs(item?.type);
|
|
116
|
+
}
|
|
117
|
+
return Math.min(maxMs, ms);
|
|
118
|
+
}
|
|
119
|
+
|
|
107
120
|
function savePlaylistDraft() {
|
|
108
121
|
localStorage.setItem(PANEL_PLAYLIST_KEY, JSON.stringify(playlistItems));
|
|
109
122
|
}
|
|
@@ -142,7 +155,11 @@ function loadPlaylistDraft() {
|
|
|
142
155
|
if (!raw) return;
|
|
143
156
|
const parsed = JSON.parse(raw);
|
|
144
157
|
if (Array.isArray(parsed)) {
|
|
145
|
-
playlistItems = parsed
|
|
158
|
+
playlistItems = parsed.map((item) => ({
|
|
159
|
+
...item,
|
|
160
|
+
durationMs: normalizeDurationMs(item)
|
|
161
|
+
}));
|
|
162
|
+
savePlaylistDraft();
|
|
146
163
|
renderPlaylist();
|
|
147
164
|
}
|
|
148
165
|
} catch {
|
|
@@ -200,9 +217,10 @@ function renderPlaylist() {
|
|
|
200
217
|
durInput.max = "3600";
|
|
201
218
|
durInput.value = String(Math.round(item.durationMs / 1000));
|
|
202
219
|
durInput.addEventListener("change", () => {
|
|
203
|
-
|
|
220
|
+
const seconds = Math.min(3600, Math.max(1, Number(durInput.value) || 10));
|
|
221
|
+
item.durationMs = seconds * 1000;
|
|
222
|
+
meta.textContent = `${item.type} · ${seconds}s`;
|
|
204
223
|
savePlaylistDraft();
|
|
205
|
-
renderPlaylist();
|
|
206
224
|
});
|
|
207
225
|
|
|
208
226
|
const removeBtn = document.createElement("button");
|
|
@@ -313,6 +331,39 @@ async function verify() {
|
|
|
313
331
|
}
|
|
314
332
|
}
|
|
315
333
|
|
|
334
|
+
async function unpair() {
|
|
335
|
+
const deviceId = getPanelDeviceId();
|
|
336
|
+
if (!deviceId) {
|
|
337
|
+
alert("No paired device in this panel.");
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (
|
|
342
|
+
!confirm(
|
|
343
|
+
"Unpair this device? The screen will show a new 6-digit code and this panel will forget the device."
|
|
344
|
+
)
|
|
345
|
+
) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const res = await fetch("/pairing/unpair", {
|
|
350
|
+
method: "POST",
|
|
351
|
+
headers: { "Content-Type": "application/json" },
|
|
352
|
+
body: JSON.stringify({ deviceId })
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
const data = await res.json();
|
|
356
|
+
showResult(data);
|
|
357
|
+
|
|
358
|
+
if (res.ok) {
|
|
359
|
+
setPanelDeviceId("");
|
|
360
|
+
const codeInput = document.getElementById("code");
|
|
361
|
+
if (codeInput) codeInput.value = "";
|
|
362
|
+
} else {
|
|
363
|
+
alert(data.error || "Unpair failed");
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
316
367
|
async function publish() {
|
|
317
368
|
const deviceId = getPanelDeviceId();
|
|
318
369
|
|