@camera.ui/browser 0.1.11 → 0.1.13

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/index.d.ts CHANGED
@@ -1389,9 +1389,11 @@ export declare type StreamStatus = 'idle' | 'connecting' | 'connected' | 'reconn
1389
1389
 
1390
1390
  export declare interface TerminalManagerInterface {
1391
1391
  createSession(options?: TerminalOptions): Promise<TerminalSessionInfo>;
1392
+ listSessions(): Promise<TerminalSessionInfo[]>;
1392
1393
  generateOutput(sessionId: string): AsyncGenerator<Uint8Array>;
1393
1394
  writeInput(sessionId: string, data: string): Promise<void>;
1394
1395
  resize(sessionId: string, dimensions: { cols: number; rows: number }): Promise<void>;
1396
+ updateSession(sessionId: string, update: TerminalSessionUpdate): Promise<void>;
1395
1397
  closeSession(sessionId: string): Promise<void>;
1396
1398
  }
1397
1399
 
@@ -1406,12 +1408,21 @@ export declare interface TerminalOptions {
1406
1408
  cwd?: string;
1407
1409
  shell?: string;
1408
1410
  env?: Record<string, string>;
1411
+ name?: string;
1412
+ persistent?: boolean;
1409
1413
  }
1410
1414
 
1411
1415
  export declare interface TerminalSessionInfo {
1412
1416
  sessionId: string;
1413
1417
  pid: number;
1414
1418
  dimensions: { cols: number; rows: number };
1419
+ name?: string;
1420
+ persistent: boolean;
1421
+ }
1422
+
1423
+ declare interface TerminalSessionUpdate {
1424
+ name?: string;
1425
+ persistent?: boolean;
1415
1426
  }
1416
1427
 
1417
1428
  declare type TrainingBoxSource = 'object' | 'static' | 'extra' | 'face' | 'plate' | 'suggestion' | 'drawn' | 'copied';
@@ -1632,7 +1643,10 @@ export declare interface UseTabVisibilityReturn {
1632
1643
  export declare function useTerminal(): UseTerminalReturn;
1633
1644
 
1634
1645
  export declare interface UseTerminalOptions extends TerminalOptions {
1646
+ sessionId?: string;
1635
1647
  onData?: (data: Uint8Array) => void;
1648
+ onReplay?: () => void;
1649
+ onSession?: (session: TerminalSessionInfo) => void;
1636
1650
  onClose?: () => void;
1637
1651
  onError?: (error: Error) => void;
1638
1652
  }
@@ -1647,13 +1661,23 @@ export declare interface UseTerminalReturn {
1647
1661
  cols: number;
1648
1662
  rows: number;
1649
1663
  }>>;
1664
+ persistent: Readonly<Ref<boolean>>;
1650
1665
  connect: (options?: UseTerminalOptions) => Promise<void>;
1651
1666
  write: (data: string) => Promise<void>;
1652
1667
  resize: (dimensions: {
1653
1668
  cols: number;
1654
1669
  rows: number;
1655
1670
  }) => Promise<void>;
1671
+ setPersistent: (persistent: boolean) => Promise<void>;
1672
+ rename: (name: string) => Promise<void>;
1656
1673
  close: () => Promise<void>;
1674
+ terminate: () => Promise<void>;
1675
+ }
1676
+
1677
+ export declare function useTerminalSessions(): UseTerminalSessionsReturn;
1678
+
1679
+ export declare interface UseTerminalSessionsReturn {
1680
+ list: () => Promise<TerminalSessionInfo[]>;
1657
1681
  }
1658
1682
 
1659
1683
  export declare function useTopmostFullscreenElement(): ComputedRef<HTMLElement | null>;
package/dist/index.js CHANGED
@@ -6729,7 +6729,6 @@ function useCoreManager() {
6729
6729
  function useTerminal() {
6730
6730
  const cameraUi = useCameraUi();
6731
6731
  const { rpc, isConnected: isClientConnected } = cameraUi;
6732
- const namespaces = NamespaceManager.terminalManagerNamespaces();
6733
6732
  const sessionId = shallowRef();
6734
6733
  const isConnected = ref(false);
6735
6734
  const isConnecting = ref(false);
@@ -6738,6 +6737,7 @@ function useTerminal() {
6738
6737
  cols: 80,
6739
6738
  rows: 24
6740
6739
  });
6740
+ const persistent = ref(false);
6741
6741
  let streamAbortController;
6742
6742
  let currentOptions;
6743
6743
  let streamGen = 0;
@@ -6745,28 +6745,28 @@ function useTerminal() {
6745
6745
  let streamClient;
6746
6746
  let wentOffline = false;
6747
6747
  let keptAcrossBlip = false;
6748
- const proxy = (r) => r.createProxy(namespaces.terminalManagerRpc);
6749
6748
  async function connect(options) {
6750
6749
  if (isConnecting.value || isConnected.value) return;
6751
6750
  isConnecting.value = true;
6752
6751
  error.value = void 0;
6753
6752
  currentOptions = options;
6754
6753
  try {
6755
- const session = await rpcCall(rpc, (r) => proxy(r).createSession({
6756
- cols: options?.cols ?? 80,
6757
- rows: options?.rows ?? 24,
6758
- cwd: options?.cwd,
6759
- shell: options?.shell,
6760
- env: options?.env
6761
- }), { maxRetries: 0 });
6754
+ const { session, attached } = await openSession(options);
6762
6755
  sessionId.value = session.sessionId;
6763
6756
  dimensions.value = session.dimensions;
6757
+ persistent.value = session.persistent;
6764
6758
  isConnected.value = true;
6759
+ options?.onSession?.(session);
6765
6760
  streamAbortController = new AbortController();
6766
6761
  wentOffline = false;
6767
6762
  keptAcrossBlip = false;
6768
6763
  const gen = ++streamGen;
6764
+ if (attached) options?.onReplay?.();
6769
6765
  consumeOutputStream(session.sessionId, options, gen);
6766
+ if (attached && options?.cols && options.rows) resize({
6767
+ cols: options.cols,
6768
+ rows: options.rows
6769
+ });
6770
6770
  } catch (err) {
6771
6771
  error.value = err instanceof Error ? err : new Error(String(err));
6772
6772
  options?.onError?.(error.value);
@@ -6774,11 +6774,32 @@ function useTerminal() {
6774
6774
  isConnecting.value = false;
6775
6775
  }
6776
6776
  }
6777
+ async function openSession(options) {
6778
+ if (options?.sessionId) {
6779
+ const session = (await rpcCall(rpc, (r) => terminalProxy(r).listSessions())).find((candidate) => candidate.sessionId === options.sessionId);
6780
+ if (session) return {
6781
+ session,
6782
+ attached: true
6783
+ };
6784
+ }
6785
+ return {
6786
+ session: await rpcCall(rpc, (r) => terminalProxy(r).createSession({
6787
+ cols: options?.cols ?? 80,
6788
+ rows: options?.rows ?? 24,
6789
+ cwd: options?.cwd,
6790
+ shell: options?.shell,
6791
+ env: options?.env,
6792
+ name: options?.name,
6793
+ persistent: options?.persistent
6794
+ }), { maxRetries: 0 }),
6795
+ attached: false
6796
+ };
6797
+ }
6777
6798
  async function consumeOutputStream(sid, options, gen) {
6778
6799
  try {
6779
6800
  const current = rpc.value;
6780
6801
  if (!current) return;
6781
- const output = proxy(current).generateOutput(sid);
6802
+ const output = terminalProxy(current).generateOutput(sid);
6782
6803
  stream = output;
6783
6804
  streamClient = current;
6784
6805
  for await (const chunk of output) {
@@ -6797,37 +6818,50 @@ function useTerminal() {
6797
6818
  } finally {
6798
6819
  if (gen === streamGen && !streamAbortController?.signal.aborted) {
6799
6820
  isConnected.value = false;
6800
- closeRemote(sid);
6821
+ if (!persistent.value) closeRemote(sid);
6801
6822
  options?.onClose?.();
6802
6823
  }
6803
6824
  }
6804
6825
  }
6805
6826
  async function write(data) {
6806
- if (!sessionId.value || !isConnected.value) return;
6807
- try {
6808
- await rpcCall(rpc, (r) => proxy(r).writeInput(sessionId.value, data));
6809
- } catch (err) {
6810
- error.value = err instanceof Error ? err : new Error(String(err));
6811
- currentOptions?.onError?.(error.value);
6812
- }
6827
+ await callSession((api, sid) => api.writeInput(sid, data));
6813
6828
  }
6814
6829
  async function resize(dims) {
6815
- if (!sessionId.value || !isConnected.value) return;
6830
+ if (await callSession((api, sid) => api.resize(sid, dims))) dimensions.value = dims;
6831
+ }
6832
+ async function setPersistent(value) {
6833
+ persistent.value = value;
6834
+ await update({ persistent: value });
6835
+ }
6836
+ async function rename(name) {
6837
+ await update({ name });
6838
+ }
6839
+ function update(change) {
6840
+ return callSession((api, sid) => api.updateSession(sid, change));
6841
+ }
6842
+ async function callSession(call) {
6843
+ const sid = sessionId.value;
6844
+ if (!sid || !isConnected.value) return false;
6816
6845
  try {
6817
- await rpcCall(rpc, (r) => proxy(r).resize(sessionId.value, dims));
6818
- dimensions.value = dims;
6846
+ await rpcCall(rpc, (r) => call(terminalProxy(r), sid));
6847
+ return true;
6819
6848
  } catch (err) {
6820
6849
  error.value = err instanceof Error ? err : new Error(String(err));
6821
6850
  currentOptions?.onError?.(error.value);
6851
+ return false;
6822
6852
  }
6823
6853
  }
6824
6854
  async function close() {
6825
6855
  stopStream();
6826
- if (sessionId.value) await closeRemote(sessionId.value);
6856
+ if (sessionId.value && !persistent.value) await closeRemote(sessionId.value);
6827
6857
  sessionId.value = void 0;
6828
6858
  isConnected.value = false;
6829
6859
  currentOptions = void 0;
6830
6860
  }
6861
+ async function terminate() {
6862
+ persistent.value = false;
6863
+ await close();
6864
+ }
6831
6865
  function stopStream() {
6832
6866
  streamAbortController?.abort();
6833
6867
  streamGen++;
@@ -6837,7 +6871,7 @@ function useTerminal() {
6837
6871
  keptAcrossBlip = false;
6838
6872
  }
6839
6873
  function closeRemote(sid) {
6840
- return rpcCall(rpc, (r) => proxy(r).closeSession(sid), {
6874
+ return rpcCall(rpc, (r) => terminalProxy(r).closeSession(sid), {
6841
6875
  awaitConnect: false,
6842
6876
  maxRetries: 0
6843
6877
  }).catch(() => void 0);
@@ -6845,13 +6879,18 @@ function useTerminal() {
6845
6879
  function restart() {
6846
6880
  const savedOptions = currentOptions;
6847
6881
  const sid = sessionId.value;
6882
+ const keep = persistent.value;
6848
6883
  stopStream();
6849
- if (sid) closeRemote(sid);
6884
+ if (sid && !keep) closeRemote(sid);
6850
6885
  sessionId.value = void 0;
6851
6886
  isConnected.value = false;
6852
6887
  currentOptions = void 0;
6853
6888
  savedOptions?.onClose?.();
6854
- if (savedOptions) connect(savedOptions);
6889
+ if (savedOptions) connect({
6890
+ ...savedOptions,
6891
+ sessionId: keep ? sid : void 0,
6892
+ persistent: keep
6893
+ });
6855
6894
  }
6856
6895
  function handleReconnected() {
6857
6896
  if (!sessionId.value && !isConnected.value) return;
@@ -6878,10 +6917,21 @@ function useTerminal() {
6878
6917
  isClientConnected: readonly(isClientConnected),
6879
6918
  error: readonly(error),
6880
6919
  dimensions: readonly(dimensions),
6920
+ persistent: readonly(persistent),
6881
6921
  connect,
6882
6922
  write,
6883
6923
  resize,
6884
- close
6924
+ setPersistent,
6925
+ rename,
6926
+ close,
6927
+ terminate
6885
6928
  };
6886
6929
  }
6887
- export { CAMERA_UI_INJECTION_KEY, NamespaceManager, STREAM_CONFIG, acquireSensorManager, clearCameraCache, clearOAuthCache, clearPluginCache, clearSensorCache, clearSnapshotCache, clearStorageCache, createActivityMode, createCameraUiPlugin, createReactiveCameraDevice, createSensorManager, getSnapshotUrl, isReactiveAudioSensor, isReactiveBatteryInfo, isReactiveCarbonDioxideInfo, isReactiveCarbonMonoxideSensor, isReactiveClassifierSensor, isReactiveColdSensor, isReactiveContactSensor, isReactiveDoorbellTrigger, isReactiveFaceSensor, isReactiveGarageControl, isReactiveGasSensor, isReactiveHeatSensor, isReactiveHumidityInfo, isReactiveIlluminanceInfo, isReactiveLeakSensor, isReactiveLicensePlateSensor, isReactiveLightControl, isReactiveLockControl, isReactiveMotionSensor, isReactiveObjectSensor, isReactiveOccupancySensor, isReactivePTZControl, isReactivePowerSensor, isReactiveProblemSensor, isReactiveSecuritySystem, isReactiveSirenControl, isReactiveSmokeSensor, isReactiveSwitchControl, isReactiveTamperSensor, isReactiveTemperatureInfo, isReactiveVibrationSensor, refreshClientSubscriptions, releaseSensorManager, resetClientState, restartConnectedStreams, rpcCall, setFullscreenRoot, useAllSensors, useAudioSensor, useCameraById, useCameraStorage, useCameraStream, useCameraUi, useClassifierSensors, useCoreManager, useCuiFullscreen, useDeviceManager, useFaceSensor, useLicensePlateSensor, useMotionSensor, useOAuth, useObjectSensor, usePTZControl, usePlugin, usePluginStorage, useRpcCall, useRpcSubscription, useSensorById, useSensorByType, useSensorStorage, useSensors, useSensorsByType, useSnapshot, useTabVisibility, useTerminal, useTopmostFullscreenElement };
6930
+ function useTerminalSessions() {
6931
+ const { rpc } = useCameraUi();
6932
+ return { list: () => rpcCall(rpc, (r) => terminalProxy(r).listSessions()) };
6933
+ }
6934
+ function terminalProxy(r) {
6935
+ return r.createProxy(NamespaceManager.terminalManagerNamespaces().terminalManagerRpc);
6936
+ }
6937
+ export { CAMERA_UI_INJECTION_KEY, NamespaceManager, STREAM_CONFIG, acquireSensorManager, clearCameraCache, clearOAuthCache, clearPluginCache, clearSensorCache, clearSnapshotCache, clearStorageCache, createActivityMode, createCameraUiPlugin, createReactiveCameraDevice, createSensorManager, getSnapshotUrl, isReactiveAudioSensor, isReactiveBatteryInfo, isReactiveCarbonDioxideInfo, isReactiveCarbonMonoxideSensor, isReactiveClassifierSensor, isReactiveColdSensor, isReactiveContactSensor, isReactiveDoorbellTrigger, isReactiveFaceSensor, isReactiveGarageControl, isReactiveGasSensor, isReactiveHeatSensor, isReactiveHumidityInfo, isReactiveIlluminanceInfo, isReactiveLeakSensor, isReactiveLicensePlateSensor, isReactiveLightControl, isReactiveLockControl, isReactiveMotionSensor, isReactiveObjectSensor, isReactiveOccupancySensor, isReactivePTZControl, isReactivePowerSensor, isReactiveProblemSensor, isReactiveSecuritySystem, isReactiveSirenControl, isReactiveSmokeSensor, isReactiveSwitchControl, isReactiveTamperSensor, isReactiveTemperatureInfo, isReactiveVibrationSensor, refreshClientSubscriptions, releaseSensorManager, resetClientState, restartConnectedStreams, rpcCall, setFullscreenRoot, useAllSensors, useAudioSensor, useCameraById, useCameraStorage, useCameraStream, useCameraUi, useClassifierSensors, useCoreManager, useCuiFullscreen, useDeviceManager, useFaceSensor, useLicensePlateSensor, useMotionSensor, useOAuth, useObjectSensor, usePTZControl, usePlugin, usePluginStorage, useRpcCall, useRpcSubscription, useSensorById, useSensorByType, useSensorStorage, useSensors, useSensorsByType, useSnapshot, useTabVisibility, useTerminal, useTerminalSessions, useTopmostFullscreenElement };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camera.ui/browser",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "camera.ui browser client",
5
5
  "author": "seydx (https://github.com/cameraui/clients)",
6
6
  "type": "module",
@@ -39,7 +39,7 @@
39
39
  "devDependencies": {
40
40
  "@camera.ui/logger": "file:../../packages/logger",
41
41
  "@camera.ui/rpc": "^1.1.2",
42
- "@camera.ui/sdk": "~1.4.6",
42
+ "@camera.ui/sdk": "~1.4.7",
43
43
  "@camera.ui/transport": "file:../../packages/transport",
44
44
  "@eneris/push-receiver": "^4.4.0",
45
45
  "@microsoft/api-extractor": "^7.60.1",
@@ -61,7 +61,7 @@
61
61
  "typescript": "5.9.3",
62
62
  "typescript-eslint": "^8.72.1",
63
63
  "unplugin-dts": "^1.1.2",
64
- "updates": "^20.0.0",
64
+ "updates": "^20.0.1",
65
65
  "vite": "^8.3.6",
66
66
  "vitest": "^5.1.0",
67
67
  "vue": "^3.5.45",