channel-worker 1.3.3 → 1.3.5

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.
Files changed (2) hide show
  1. package/lib/nst-manager.js +54 -80
  2. package/package.json +1 -2
@@ -1,29 +1,36 @@
1
- let NstBrowserV2;
2
- try {
3
- NstBrowserV2 = require('nstbrowser-sdk-node').NstBrowserV2;
4
- } catch {
5
- // SDK not installed
6
- }
7
-
8
1
  class NstManager {
9
2
  constructor(apiKey, options = {}) {
10
- if (!NstBrowserV2) {
11
- throw new Error('nstbrowser-sdk-node not installed. Run: npm install -g nstbrowser-sdk-node');
12
- }
13
3
  this.apiKey = apiKey;
14
- this.client = new NstBrowserV2(apiKey, {
15
- timeout: options.timeout || 60000,
16
- apiAddress: options.apiAddress || 'http://localhost:8848/api/v2',
4
+ this.baseUrl = options.apiAddress || 'http://localhost:8848/api/v2';
5
+ }
6
+
7
+ async api(path, options = {}) {
8
+ const url = path.startsWith('http') ? path : `${this.baseUrl}${path}`;
9
+ const res = await fetch(url, {
10
+ ...options,
11
+ headers: {
12
+ 'x-api-key': this.apiKey,
13
+ 'Content-Type': 'application/json',
14
+ ...options.headers,
15
+ },
17
16
  });
17
+ return res.json();
18
18
  }
19
19
 
20
20
  // Get all running browsers
21
21
  async getRunningBrowsers() {
22
22
  try {
23
- const res = await this.client.browsers().getBrowsers('running');
24
- return res?.data || [];
25
- } catch (err) {
26
- console.error(`[nst] Error getting running browsers:`, err.message);
23
+ const rawRes = await fetch(`${this.baseUrl}/browsers/running`, {
24
+ headers: { 'x-api-key': this.apiKey },
25
+ });
26
+ const text = await rawRes.text();
27
+ try {
28
+ const data = JSON.parse(text);
29
+ return data?.data || [];
30
+ } catch {
31
+ return [];
32
+ }
33
+ } catch {
27
34
  return [];
28
35
  }
29
36
  }
@@ -37,36 +44,19 @@ class NstManager {
37
44
  // Find profile by name, return profileId
38
45
  async findProfile(name) {
39
46
  try {
40
- // Try SDK first
41
- const res = await this.client.profiles().getProfiles({ keyword: name });
42
- let profiles = [];
43
- if (res?.data?.docs && Array.isArray(res.data.docs)) {
44
- profiles = res.data.docs;
45
- } else if (Array.isArray(res?.data)) {
46
- profiles = res.data;
47
- }
48
-
49
- const match = profiles.find(p => p.name?.toLowerCase() === name.toLowerCase());
50
- if (match) return match.profileId || match._id;
51
-
52
- // Fallback: fetch ALL profiles via local API (paginate if needed)
53
47
  let allProfiles = [];
54
48
  let page = 1;
55
49
  while (true) {
56
- const rawRes = await fetch(`http://localhost:8848/api/v2/profiles/?keyword=${encodeURIComponent(name)}&page=${page}&limit=100`, {
57
- headers: { 'x-api-key': this.apiKey },
58
- });
59
- const rawData = await rawRes.json();
60
- const docs = rawData?.data?.docs || rawData?.data || [];
50
+ const res = await this.api(`/profiles/?keyword=${encodeURIComponent(name)}&page=${page}&limit=100`);
51
+ const docs = res?.data?.docs || res?.data || [];
61
52
  allProfiles = allProfiles.concat(docs);
62
- const totalPages = rawData?.data?.totalPage || rawData?.data?.totalPages || 1;
53
+ const totalPages = res?.data?.totalPage || res?.data?.totalPages || 1;
63
54
  if (page >= totalPages || docs.length === 0) break;
64
55
  page++;
65
56
  }
66
- console.log(`[nst] Fallback search for "${name}": found ${allProfiles.length} profiles, names: [${allProfiles.map(p => p.name).join(', ')}]`);
67
- const fallback = allProfiles.find(p => p.name?.toLowerCase() === name.toLowerCase());
68
- if (fallback) return fallback.profileId || fallback._id;
69
-
57
+ console.log(`[nst] Search for "${name}": found ${allProfiles.length} profiles [${allProfiles.map(p => p.name).join(', ')}]`);
58
+ const match = allProfiles.find(p => p.name?.toLowerCase() === name.toLowerCase());
59
+ if (match) return match.profileId || match._id;
70
60
  return null;
71
61
  } catch (err) {
72
62
  console.error(`[nst] Error finding profile "${name}":`, err.message);
@@ -83,22 +73,19 @@ class NstManager {
83
73
  }
84
74
 
85
75
  console.log(`[nst] WARNING: Profile "${name}" NOT FOUND — creating new profile...`);
86
- const res = await this.client.profiles().createProfile({
87
- name,
88
- platform: 'Windows',
89
- kernelMilestone: '132',
90
- fingerprint: {
91
- flags: {
92
- audio: 'Noise',
93
- canvas: 'Noise',
94
- fonts: 'Masked',
95
- gpu: 'Allow',
96
- webgl: 'Noise',
76
+ const res = await this.api('/profiles', {
77
+ method: 'POST',
78
+ body: JSON.stringify({
79
+ name,
80
+ platform: 'Windows',
81
+ kernelMilestone: '132',
82
+ fingerprint: {
83
+ flags: { audio: 'Noise', canvas: 'Noise', fonts: 'Masked', gpu: 'Allow', webgl: 'Noise' },
84
+ hardwareConcurrency: 8,
85
+ deviceMemory: 8,
86
+ language: 'en-US',
97
87
  },
98
- hardwareConcurrency: 8,
99
- deviceMemory: 8,
100
- language: 'en-US',
101
- },
88
+ }),
102
89
  });
103
90
 
104
91
  const profileId = res?.data?.profileId || res?.data?._id;
@@ -112,7 +99,10 @@ class NstManager {
112
99
  async setProxy(profileId, proxyUrl) {
113
100
  if (!proxyUrl) return;
114
101
  console.log(`[nst] Setting proxy for ${profileId}: ${proxyUrl}`);
115
- await this.client.profiles().updateProfileProxy(profileId, { url: proxyUrl });
102
+ await this.api(`/profiles/${profileId}/proxy`, {
103
+ method: 'PATCH',
104
+ body: JSON.stringify({ url: proxyUrl }),
105
+ });
116
106
  console.log(`[nst] Proxy set`);
117
107
  }
118
108
 
@@ -123,23 +113,13 @@ class NstManager {
123
113
  profileId = await this.ensureProfile(profileIdOrName);
124
114
  }
125
115
 
126
- // If already running, skip — don't restart
116
+ // If already running, skip
127
117
  if (await this.isProfileRunning(profileId)) {
128
118
  console.log(`[nst] Profile ${profileId} already running — skipping`);
129
119
  return { profileId, alreadyRunning: true };
130
120
  }
131
121
 
132
- // Ensure profile language is en-US to prevent auto-translate
133
- try {
134
- const res = await fetch(`http://localhost:8848/api/v2/profiles/${profileId}`, {
135
- method: 'PATCH',
136
- headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey },
137
- body: JSON.stringify({ fingerprint: { language: 'en-US' } }),
138
- });
139
- if (!res.ok) console.warn(`[nst] Could not update profile language: ${res.status}`);
140
- } catch (err) {
141
- console.warn(`[nst] Could not update profile language:`, err.message);
142
- }
122
+ // Language set via --lang arg in connectConfig, no need to update profile
143
123
 
144
124
  // Set proxy before launch
145
125
  if (options.proxy) {
@@ -149,12 +129,10 @@ class NstManager {
149
129
  const connectConfig = {
150
130
  headless: false,
151
131
  autoClose: false,
152
- };
153
-
154
- // Disable Chrome auto-translate
155
- connectConfig.args = {
156
- '--lang': 'en-US',
157
- '--disable-features': 'Translate',
132
+ args: {
133
+ '--lang': 'en-US',
134
+ '--disable-features': 'Translate',
135
+ },
158
136
  };
159
137
 
160
138
  if (options.extensionPath) {
@@ -164,11 +142,7 @@ class NstManager {
164
142
  }
165
143
 
166
144
  console.log(`[nst] Connecting browser for profile: ${profileId}`);
167
-
168
- // SDK uses axios which serializes nested objects as config[key]=value
169
- // But Nstbrowser API expects ?config=<JSON-string>
170
- // Workaround: call the API directly with fetch instead of SDK
171
- const apiUrl = `http://localhost:8848/api/v2/connect/${profileId}?config=${encodeURIComponent(JSON.stringify(connectConfig))}`;
145
+ const apiUrl = `${this.baseUrl}/connect/${profileId}?config=${encodeURIComponent(JSON.stringify(connectConfig))}`;
172
146
  const rawRes = await fetch(apiUrl, { headers: { 'x-api-key': this.apiKey } });
173
147
  const res = await rawRes.json();
174
148
  if (res.err) throw new Error(res.msg || 'Failed to connect browser');
@@ -186,7 +160,7 @@ class NstManager {
186
160
  }
187
161
 
188
162
  console.log(`[nst] Stopping browser for profile: ${profileId}`);
189
- await this.client.browsers().stopBrowser(profileId);
163
+ await this.api(`/browsers/${profileId}/stop`, { method: 'PUT' });
190
164
  console.log(`[nst] Browser stopped`);
191
165
  }
192
166
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "channel-worker",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "description": "Channel Manager worker daemon — runs on remote machines to execute video pipeline jobs",
5
5
  "main": "lib/daemon.js",
6
6
  "bin": {
@@ -16,7 +16,6 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "node-fetch": "^3.3.2",
19
- "nstbrowser-sdk-node": "^0.1.1",
20
19
  "ws": "^8.18.0"
21
20
  },
22
21
  "engines": {