@supraio/client-daemon-js 0.0.1 → 1.0.0-mzscreengeometry.447

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supraio/client-daemon-js",
3
- "version": "0.0.1",
3
+ "version": "1.0.0-mzscreengeometry.447",
4
4
  "description": "",
5
5
  "main": "sdk.js",
6
6
  "types": "sdk.d.ts",
@@ -14,8 +14,8 @@
14
14
  "lint": "eslint \"**/*.ts\""
15
15
  },
16
16
  "devDependencies": {
17
- "@signageos/nacl-decoder": "0.1.0",
18
- "@signageos/samsung-wasm-decoder": "0.1.0",
17
+ "@signageos/nacl-decoder": "0.1.1-mz-screen-geometry.9",
18
+ "@signageos/samsung-wasm-decoder": "0.1.1-mz-screen-geometry.7",
19
19
  "@types/dropboxjs": "0.0.29",
20
20
  "@types/filesystem": "0.0.29",
21
21
  "@types/node": "14.14.34",
@@ -4,6 +4,16 @@ declare global {
4
4
  __supra?: {
5
5
  setEncodingPreferences(json: string): void;
6
6
  getCurrentStats(): string | null;
7
+ stopScreen?(): void;
8
+ /** Set by the Go runtime when geometry was requested via screen options. */
9
+ geometry?: {
10
+ x: number;
11
+ y: number;
12
+ width: number;
13
+ height: number;
14
+ } | null;
15
+ /** Set to true by the Go runtime after stopScreen() was invoked. */
16
+ screenStopped?: boolean;
7
17
  };
8
18
  }
9
19
  }
@@ -55,6 +65,12 @@ export interface IScreenControl {
55
65
  getEncodingPreferences(): IEncodingPreferences;
56
66
  /** Returns a snapshot of client-daemon stats, or null if the bridge is not ready. */
57
67
  getCurrentStats(): IClientStats | null;
68
+ /**
69
+ * Stops local rendering of the screen. The server-side app keeps running;
70
+ * only the client screen process disconnects and exits. Returns false when
71
+ * the rendering bridge is not available (screen not started on this device).
72
+ */
73
+ stop(): boolean;
58
74
  }
59
75
  /**
60
76
  * Creates a screen control instance for runtime adjustments.
@@ -1,8 +1,9 @@
1
1
  import { createNaClDecoder } from '@signageos/nacl-decoder';
2
+ import { IScreenOptions } from './options';
2
3
  declare global {
3
4
  interface Window {
4
5
  /** Make it global accessible for x264/nacldecoder/nacldecoder.go */
5
6
  createNaClDecoder?: typeof createNaClDecoder;
6
7
  }
7
8
  }
8
- export declare function initNaCLDecoder(): void;
9
+ export declare function initNaCLDecoder(options?: Pick<IScreenOptions, 'geometry'>): void;
@@ -5,6 +5,16 @@ export interface IEncodingPreferences {
5
5
  preferredTune?: string;
6
6
  preferredProfile?: string;
7
7
  }
8
+ /**
9
+ * Position and size of the rendering surface on the physical screen, in CSS
10
+ * pixels. When omitted, the renderer covers the whole screen (legacy behavior).
11
+ */
12
+ export interface IScreenGeometry {
13
+ x: number;
14
+ y: number;
15
+ width: number;
16
+ height: number;
17
+ }
8
18
  export interface IScreenOptions {
9
19
  screenID: string;
10
20
  screenDriver: string;
@@ -18,6 +28,7 @@ export interface IScreenOptions {
18
28
  width: number;
19
29
  height: number;
20
30
  };
31
+ geometry?: IScreenGeometry;
21
32
  interactive: boolean;
22
33
  encodingPreferences?: IEncodingPreferences;
23
34
  control?: import('./control').IScreenControl;
package/screen/plain.d.ts CHANGED
@@ -1,2 +1,3 @@
1
+ import type { StartOptions } from "../sdk";
1
2
  import { IScreenOptions } from "./options";
2
- export declare function startPlainScreen(options?: IScreenOptions): Promise<void>;
3
+ export declare function startPlainScreen(options?: StartOptions & IScreenOptions): Promise<void>;
@@ -6,4 +6,4 @@ declare global {
6
6
  samsungWasmDecoder?: SamsungWasmDecoder;
7
7
  }
8
8
  }
9
- export declare function initSamsungWasmDecoder(options: Pick<IScreenOptions, 'interactive'>): Promise<void>;
9
+ export declare function initSamsungWasmDecoder(options: Pick<IScreenOptions, 'interactive' | 'geometry'>): Promise<void>;
@@ -1,3 +1,4 @@
1
+ import type { StartOptions } from "../sdk";
1
2
  import { IScreenOptions } from "./options";
2
- export declare function parseQueryOptions(): IScreenOptions;
3
+ export declare function parseQueryOptions(): StartOptions & IScreenOptions;
3
4
  export declare function getGoArgv(binFile: string, options: IScreenOptions): string[];
package/screen/wasm.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import '../go/go';
2
+ import type { StartOptions } from '../sdk';
2
3
  import { IScreenOptions } from './options';
3
- export declare function startWasmScreen(options?: IScreenOptions): Promise<void>;
4
+ export declare function startWasmScreen(options?: StartOptions & IScreenOptions): Promise<void>;
@@ -9,10 +9,11 @@ interface SupraFrameWorkerConnection {
9
9
  timestamp: number;
10
10
  length: number;
11
11
  data: ArrayBuffer;
12
+ firstPacketAt: number;
12
13
  }>;
13
14
  write(data: ArrayBuffer): Promise<number>;
14
15
  close(): Promise<void>;
15
16
  }
16
17
  /** Make it global accessible for netpacket/js_websocket.go */
17
- export declare function initWorkerFrameConnection(): void;
18
+ export declare function initWorkerFrameConnection(enabled: boolean): void;
18
19
  export {};
package/screen.html CHANGED
@@ -5,6 +5,6 @@
5
5
  <link rel="stylesheet" href="screen.css"></link>
6
6
  </head>
7
7
  <body>
8
- <script type="text/javascript" src="screen.js?v=0.0.1"></script>
8
+ <script type="text/javascript" src="screen.js?v=1.0.0-mzscreengeometry.447"></script>
9
9
  </body>
10
10
  </html>
package/screen.js CHANGED
@@ -17227,8 +17227,8 @@
17227
17227
  function handleCrash(event) {
17228
17228
  console.log("nacl crash", event);
17229
17229
  }
17230
- function createNaClModule(handleMessage) {
17231
- var _a, _b;
17230
+ function createNaClModule(handleMessage, geometry) {
17231
+ var _a, _b, _c, _d;
17232
17232
  var listenerEl = document.createElement("div");
17233
17233
  listenerEl.setAttribute("id", "listener");
17234
17234
  listenerEl.addEventListener("message", handleMessage, true);
@@ -17238,8 +17238,15 @@
17238
17238
  var baseHref = (_b = (_a = document.getElementsByTagName("base")[0]) === null || _a === void 0 ? void 0 : _a.href) !== null && _b !== void 0 ? _b : location.href;
17239
17239
  var nmpPath = new URL("nacl-decoder.nmf", baseHref).href;
17240
17240
  var naclModuleEl = document.createElement("embed");
17241
- naclModuleEl.setAttribute("width", "".concat(window.screen.width));
17242
- naclModuleEl.setAttribute("height", "".concat(window.screen.height));
17241
+ var width = (_c = geometry === null || geometry === void 0 ? void 0 : geometry.width) !== null && _c !== void 0 ? _c : window.screen.width;
17242
+ var height = (_d = geometry === null || geometry === void 0 ? void 0 : geometry.height) !== null && _d !== void 0 ? _d : window.screen.height;
17243
+ naclModuleEl.setAttribute("width", "".concat(width));
17244
+ naclModuleEl.setAttribute("height", "".concat(height));
17245
+ if (geometry) {
17246
+ naclModuleEl.style.position = "absolute";
17247
+ naclModuleEl.style.left = "".concat(geometry.x, "px");
17248
+ naclModuleEl.style.top = "".concat(geometry.y, "px");
17249
+ }
17243
17250
  naclModuleEl.setAttribute("src", nmpPath);
17244
17251
  naclModuleEl.setAttribute("type", "application/x-nacl");
17245
17252
  naclModuleEl.setAttribute("id", "nacl_module");
@@ -18338,20 +18345,20 @@
18338
18345
  if (!isNaClSupported3()) {
18339
18346
  throw new Error("NaCl is not supported in this browser.");
18340
18347
  }
18341
- var runtime = getNaClRuntime(requiredOptions.timeoutMs);
18348
+ var runtime = getNaClRuntime(requiredOptions.timeoutMs, options === null || options === void 0 ? void 0 : options.geometry);
18342
18349
  return new naclDecoder_1.NaClDecoder(runtime.messageSender, runtime.naclModuleEl);
18343
18350
  }
18344
18351
  function createNaClTCP2(options) {
18345
18352
  var decoder = createNaClDecoder2(options);
18346
18353
  return decoder.createTCP();
18347
18354
  }
18348
- function getNaClRuntime(timeoutMs) {
18355
+ function getNaClRuntime(timeoutMs, geometry) {
18349
18356
  if (naclRuntime) {
18350
18357
  return naclRuntime;
18351
18358
  }
18352
18359
  var messageListeners = (0, messageListeners_1.createMessageListeners)();
18353
18360
  var messageReceiver = new messageReceiver_1.MessageReceiver(messageListeners);
18354
- var naclModuleEl = (0, module_1.createNaClModule)(messageReceiver.handleMessage.bind(messageReceiver));
18361
+ var naclModuleEl = (0, module_1.createNaClModule)(messageReceiver.handleMessage.bind(messageReceiver), geometry);
18355
18362
  var messageSender = new messageSender_1.MessageSender(naclModuleEl, messageListeners, timeoutMs);
18356
18363
  naclRuntime = {
18357
18364
  messageSender,
@@ -19698,16 +19705,17 @@
19698
19705
  }
19699
19706
  return false;
19700
19707
  }
19701
- function ensureVideoElement(videoElementId) {
19708
+ function ensureVideoElement(videoElementId, geometry) {
19709
+ var _a, _b, _c, _d;
19702
19710
  var el = document.getElementById(videoElementId);
19703
19711
  if (!el) {
19704
19712
  el = document.createElement("video");
19705
19713
  el.id = videoElementId;
19706
19714
  el.style.position = "absolute";
19707
- el.style.top = "0";
19708
- el.style.left = "0";
19709
- el.style.width = "1920px";
19710
- el.style.height = "1080px";
19715
+ el.style.top = "".concat((_a = geometry === null || geometry === void 0 ? void 0 : geometry.y) !== null && _a !== void 0 ? _a : 0, "px");
19716
+ el.style.left = "".concat((_b = geometry === null || geometry === void 0 ? void 0 : geometry.x) !== null && _b !== void 0 ? _b : 0, "px");
19717
+ el.style.width = "".concat((_c = geometry === null || geometry === void 0 ? void 0 : geometry.width) !== null && _c !== void 0 ? _c : 1920, "px");
19718
+ el.style.height = "".concat((_d = geometry === null || geometry === void 0 ? void 0 : geometry.height) !== null && _d !== void 0 ? _d : 1080, "px");
19711
19719
  el.style.backgroundColor = "#000";
19712
19720
  document.body.appendChild(el);
19713
19721
  }
@@ -19719,14 +19727,14 @@
19719
19727
  var SamsungWasmDecoder2 = (
19720
19728
  /** @class */
19721
19729
  function() {
19722
- function SamsungWasmDecoder3(videoElementId) {
19730
+ function SamsungWasmDecoder3(videoElementId, geometry) {
19723
19731
  this.videoElementId = videoElementId;
19724
19732
  this.initialized = false;
19725
19733
  this.destroyed = false;
19726
19734
  this.decoderHandle = 0;
19727
19735
  this.ptsSeconds = 0;
19728
19736
  this.frameDurationSeconds = 0;
19729
- this.videoElement = ensureVideoElement(videoElementId);
19737
+ this.videoElement = ensureVideoElement(videoElementId, geometry);
19730
19738
  }
19731
19739
  SamsungWasmDecoder3.prototype.destroy = function() {
19732
19740
  return __awaiter(this, void 0, void 0, function() {
@@ -20099,7 +20107,7 @@
20099
20107
  return [4, (0, wasmLoader_1.loadWasmModule)()];
20100
20108
  case 1:
20101
20109
  _a.sent();
20102
- return [2, new wasmDecoder_1.SamsungWasmDecoder(options.videoElementId)];
20110
+ return [2, new wasmDecoder_1.SamsungWasmDecoder(options.videoElementId, options.geometry)];
20103
20111
  }
20104
20112
  });
20105
20113
  });
@@ -20636,9 +20644,10 @@
20636
20644
 
20637
20645
  // screen/nacldecoder.ts
20638
20646
  var import_nacl_decoder2 = __toESM(require_dist());
20639
- function initNaCLDecoder() {
20647
+ function initNaCLDecoder(options) {
20640
20648
  if ((0, import_nacl_decoder2.isNaClSupported)()) {
20641
- window.createNaClDecoder = import_nacl_decoder2.createNaClDecoder;
20649
+ const geometry = options == null ? void 0 : options.geometry;
20650
+ window.createNaClDecoder = (decoderOptions) => (0, import_nacl_decoder2.createNaClDecoder)({ geometry, ...decoderOptions });
20642
20651
  }
20643
20652
  }
20644
20653
 
@@ -20651,8 +20660,17 @@ var frames = {};
20651
20660
  var closed = false;
20652
20661
  var GENERAL_HEADER_SIZE = 6;
20653
20662
  var FIRST_HEADER_SIZE = GENERAL_HEADER_SIZE + 9;
20654
- var MAX_PACKET_SIZE = 32768;
20655
- var DATA_PART_SIZE = MAX_PACKET_SIZE - GENERAL_HEADER_SIZE;
20663
+
20664
+ function now() {
20665
+ if (
20666
+ typeof performance !== 'undefined' &&
20667
+ typeof performance.timeOrigin === 'number' &&
20668
+ typeof performance.now === 'function'
20669
+ ) {
20670
+ return performance.timeOrigin + performance.now();
20671
+ }
20672
+ return Date.now();
20673
+ }
20656
20674
 
20657
20675
  function postError(id, error) {
20658
20676
  self.postMessage({ type: 'error', id: id, error: error && error.message ? error.message : String(error) });
@@ -20672,7 +20690,8 @@ function resolveFrame() {
20672
20690
  frameType: frame.frameType,
20673
20691
  timestamp: frame.timestamp,
20674
20692
  length: frame.length,
20675
- data: frame.data
20693
+ data: frame.data,
20694
+ firstPacketAt: frame.firstPacketAt
20676
20695
  }, [frame.data]);
20677
20696
  }
20678
20697
 
@@ -20699,11 +20718,12 @@ function handlePacket(buffer) {
20699
20718
  var item = frames[frameID];
20700
20719
  if (!item || seq === 0 || item.total !== total) {
20701
20720
  item = {
20702
- buffer: new Uint8Array(total * DATA_PART_SIZE),
20721
+ packets: new Array(total),
20703
20722
  frameType: 0,
20704
20723
  timestamp: 0,
20705
20724
  total: total,
20706
- received: 0
20725
+ received: 0,
20726
+ firstPacketAt: now()
20707
20727
  };
20708
20728
  frames[frameID] = item;
20709
20729
  if (seq === 0) {
@@ -20717,25 +20737,39 @@ function handlePacket(buffer) {
20717
20737
  }
20718
20738
  }
20719
20739
 
20720
- var dataStartsAt = seq * DATA_PART_SIZE;
20721
- if (seq > 0) {
20722
- dataStartsAt -= FIRST_HEADER_SIZE - GENERAL_HEADER_SIZE;
20740
+ if (total === 0 || seq >= total) {
20741
+ delete frames[frameID];
20742
+ return;
20723
20743
  }
20724
20744
  var packetData = new Uint8Array(buffer, headerSize);
20725
- item.buffer.set(packetData, dataStartsAt);
20726
- item.received++;
20745
+ if (!item.packets[seq]) {
20746
+ item.received++;
20747
+ }
20748
+ item.packets[seq] = packetData;
20727
20749
 
20728
20750
  if (seq + 1 === total) {
20729
20751
  delete frames[frameID];
20730
20752
  if (item.received !== item.total) {
20731
20753
  return;
20732
20754
  }
20733
- var dataEndsAt = dataStartsAt + length - headerSize;
20755
+ var dataLength = 0;
20756
+ var packetIndex;
20757
+ for (packetIndex = 0; packetIndex < item.packets.length; packetIndex++) {
20758
+ dataLength += item.packets[packetIndex].byteLength;
20759
+ }
20760
+ var frameBuffer = new Uint8Array(dataLength);
20761
+ var dataStartsAt = 0;
20762
+ for (packetIndex = 0; packetIndex < item.packets.length; packetIndex++) {
20763
+ var completedPacket = item.packets[packetIndex];
20764
+ frameBuffer.set(completedPacket, dataStartsAt);
20765
+ dataStartsAt += completedPacket.byteLength;
20766
+ }
20734
20767
  latestFrame = {
20735
20768
  frameType: item.frameType,
20736
20769
  timestamp: item.timestamp,
20737
- length: dataEndsAt,
20738
- data: item.buffer.buffer
20770
+ length: dataLength,
20771
+ data: frameBuffer.buffer,
20772
+ firstPacketAt: item.firstPacketAt
20739
20773
  };
20740
20774
  resolveFrame();
20741
20775
  }
@@ -20822,7 +20856,8 @@ self.onmessage = function(event) {
20822
20856
  frameType: message.frameType,
20823
20857
  timestamp: message.timestamp,
20824
20858
  length: message.length,
20825
- data: message.data
20859
+ data: message.data,
20860
+ firstPacketAt: message.firstPacketAt
20826
20861
  });
20827
20862
  }
20828
20863
  };
@@ -20848,8 +20883,9 @@ self.onmessage = function(event) {
20848
20883
  }
20849
20884
  };
20850
20885
  };
20851
- function initWorkerFrameConnection() {
20852
- if (typeof Worker !== "undefined") {
20886
+ function initWorkerFrameConnection(enabled) {
20887
+ delete window.createSupraFrameWorkerConnection;
20888
+ if (enabled && typeof Worker !== "undefined") {
20853
20889
  window.createSupraFrameWorkerConnection = createSupraFrameWorkerConnection;
20854
20890
  }
20855
20891
  }
@@ -20860,7 +20896,8 @@ self.onmessage = function(event) {
20860
20896
  async function initSamsungWasmDecoder(options) {
20861
20897
  if ((0, import_samsung_wasm_decoder2.isSamsungWasmSupported)()) {
20862
20898
  window.samsungWasmDecoder = await (0, import_samsung_wasm_decoder2.createSamsungWasmDecoder)({
20863
- videoElementId: "samsung-wasm-video"
20899
+ videoElementId: "samsung-wasm-video",
20900
+ geometry: options.geometry
20864
20901
  });
20865
20902
  const latencyMode = options.interactive ? import_videoDecoder.LatencyMode.UltraLow : import_videoDecoder.LatencyMode.Low;
20866
20903
  await window.samsungWasmDecoder.initialize({ latencyMode });
@@ -20901,7 +20938,8 @@ self.onmessage = function(event) {
20901
20938
  clientID: params.clientID,
20902
20939
  clientSecret: params.clientSecret,
20903
20940
  secure: params.secure !== "false",
20904
- interactive: params.interactive === "true"
20941
+ interactive: params.interactive === "true",
20942
+ netInWorker: params.netInWorker === "true"
20905
20943
  };
20906
20944
  if (typeof params.forceScreenSize === "string") {
20907
20945
  const sizeParts = params.forceScreenSize.split("x");
@@ -20915,6 +20953,17 @@ self.onmessage = function(event) {
20915
20953
  }
20916
20954
  options.forceScreenSize = { width, height };
20917
20955
  }
20956
+ if (typeof params.geometry === "string" && params.geometry !== "") {
20957
+ const geometryParts = params.geometry.split(",");
20958
+ if (geometryParts.length !== 4) {
20959
+ throw new Error(`Invalid geometry query param, expected "x,y,width,height"`);
20960
+ }
20961
+ const [x, y, width, height] = geometryParts.map(Number);
20962
+ if ([x, y, width, height].some(isNaN) || width <= 0 || height <= 0) {
20963
+ throw new Error(`Invalid geometry query param`);
20964
+ }
20965
+ options.geometry = { x, y, width, height };
20966
+ }
20918
20967
  const encodingPreferences = {};
20919
20968
  if (params.preferredPreset) {
20920
20969
  encodingPreferences.preferredPreset = params.preferredPreset;
@@ -20949,16 +20998,17 @@ self.onmessage = function(event) {
20949
20998
  options.clientSecret,
20950
20999
  options.secure ? "1" : "0",
20951
21000
  options.forceScreenSize ? `${options.forceScreenSize.width}x${options.forceScreenSize.height}` : "",
20952
- encodingPrefsJson
21001
+ encodingPrefsJson,
21002
+ options.geometry ? JSON.stringify(options.geometry) : ""
20953
21003
  ];
20954
21004
  }
20955
21005
 
20956
21006
  // screen/plain.ts
20957
- var SCREEN_JS_URL = "supra-client-screen.js?v=0.0.1";
21007
+ var SCREEN_JS_URL = "supra-client-screen.js?v=1.0.0-mzscreengeometry.447";
20958
21008
  async function startPlainScreen(options) {
20959
21009
  options = options != null ? options : parseQueryOptions();
20960
- initNaCLDecoder();
20961
- initWorkerFrameConnection();
21010
+ initNaCLDecoder(options);
21011
+ initWorkerFrameConnection(options.netInWorker === true);
20962
21012
  await initNaClTCP();
20963
21013
  await initSamsungWasmTCP();
20964
21014
  await initSamsungWasmDecoder(options);
@@ -20967,7 +21017,15 @@ self.onmessage = function(event) {
20967
21017
  process.argv = ["go", ...getGoArgv(SCREEN_JS_URL, options)];
20968
21018
  Object.assign(process.env, getGoEnv());
20969
21019
  await injectScript(SCREEN_JS_URL);
20970
- await new Promise(() => void 0);
21020
+ await new Promise((resolve) => {
21021
+ const interval = setInterval(() => {
21022
+ var _a;
21023
+ if (((_a = window.__supra) == null ? void 0 : _a.screenStopped) === true) {
21024
+ clearInterval(interval);
21025
+ resolve();
21026
+ }
21027
+ }, 500);
21028
+ });
20971
21029
  }
20972
21030
 
20973
21031
  // screen/h264decoder.ts
@@ -20984,10 +21042,10 @@ self.onmessage = function(event) {
20984
21042
  }
20985
21043
 
20986
21044
  // screen/wasm.ts
20987
- var SCREEN_WASM_URL = "supra-client-screen.wasm?v=0.0.1";
21045
+ var SCREEN_WASM_URL = "supra-client-screen.wasm?v=1.0.0-mzscreengeometry.447";
20988
21046
  async function startWasmScreen(options) {
20989
21047
  options = options != null ? options : parseQueryOptions();
20990
- initWorkerFrameConnection();
21048
+ initWorkerFrameConnection(options.netInWorker === true);
20991
21049
  await initSamsungWasmTCP();
20992
21050
  await initSamsungWasmDecoder(options);
20993
21051
  await initH264Decoder();