@ohos-ports/slides-grab 1.5.0-beta.2 → 1.5.0-beta.4

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 (32) hide show
  1. package/native/@img/sharp-libvips-openharmony-arm64/lib/libc++_shared.so +0 -0
  2. package/native/@img/sharp-libvips-openharmony-arm64/lib/libcairo.so.2.11804.4 +0 -0
  3. package/native/@img/sharp-libvips-openharmony-arm64/lib/libexpat.so.1 +0 -0
  4. package/native/@img/sharp-libvips-openharmony-arm64/lib/libffi.so +0 -0
  5. package/native/@img/sharp-libvips-openharmony-arm64/lib/libfontconfig.so.1 +0 -0
  6. package/native/@img/sharp-libvips-openharmony-arm64/lib/libfreetype.so.6 +0 -0
  7. package/native/@img/sharp-libvips-openharmony-arm64/lib/libfribidi.so.0.4.0 +0 -0
  8. package/native/@img/sharp-libvips-openharmony-arm64/lib/libgdk_pixbuf-2.0.so.0.4400.3 +0 -0
  9. package/native/@img/sharp-libvips-openharmony-arm64/lib/libgio-2.0.so.0 +0 -0
  10. package/native/@img/sharp-libvips-openharmony-arm64/lib/libglib-2.0.so.0.8800.3 +0 -0
  11. package/native/@img/sharp-libvips-openharmony-arm64/lib/libgobject-2.0.so.0.8800.3 +0 -0
  12. package/native/@img/sharp-libvips-openharmony-arm64/lib/libharfbuzz.so.0.61430.0 +0 -0
  13. package/native/@img/sharp-libvips-openharmony-arm64/lib/libintl.so.8 +0 -0
  14. package/native/@img/sharp-libvips-openharmony-arm64/lib/libpango-1.0.so.0.5600.3 +0 -0
  15. package/native/@img/sharp-libvips-openharmony-arm64/lib/libpangocairo-1.0.so.0.5600.3 +0 -0
  16. package/native/@img/sharp-libvips-openharmony-arm64/lib/libpangoft2-1.0.so.0.5600.3 +0 -0
  17. package/native/@img/sharp-libvips-openharmony-arm64/lib/libpcre2-8.so +0 -0
  18. package/native/@img/sharp-libvips-openharmony-arm64/lib/libpcre2-8.so.0 +0 -0
  19. package/native/@img/sharp-libvips-openharmony-arm64/lib/libpixman-1.so.0 +0 -0
  20. package/native/@img/sharp-libvips-openharmony-arm64/lib/libpng16.so.16 +0 -0
  21. package/native/@img/sharp-libvips-openharmony-arm64/lib/librsvg-2.so.2.60.0 +0 -0
  22. package/native/@img/sharp-libvips-openharmony-arm64/lib/libvips-cpp.so.42 +0 -0
  23. package/native/@img/sharp-libvips-openharmony-arm64/lib/libvips-cpp.so.42.20.3 +0 -0
  24. package/native/@img/sharp-libvips-openharmony-arm64/lib/libvips.so.42 +0 -0
  25. package/native/@img/sharp-libvips-openharmony-arm64/lib/libvips.so.42.20.3 +0 -0
  26. package/native/@img/sharp-libvips-openharmony-arm64/lib/libxml2.so.16 +0 -0
  27. package/native/@img/sharp-libvips-openharmony-arm64/lib/libz.so.1 +0 -0
  28. package/package.json +3 -3
  29. package/scripts/html2pdf.js +5 -2
  30. package/scripts/html2png.js +5 -2
  31. package/scripts/validate-slides.js +4 -1
  32. package/src/ohos-browser-bridge.cjs +65 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ohos-ports/slides-grab",
3
- "version": "1.5.0-beta.2",
3
+ "version": "1.5.0-beta.4",
4
4
  "description": "Agent-first presentation framework — plan, design, and visually edit HTML slides with Claude Code or Codex, then export to PDF or experimental/unstable PPTX/Figma formats. HarmonyOS adaptation: Playwright connects to system Haitai browser (Chromium M132) via CDP bridge.",
5
5
  "license": "MIT",
6
6
  "author": "vkehfdl1",
@@ -77,12 +77,12 @@
77
77
  "pptxgenjs": "^3.12.0",
78
78
  "react": "^19.2.4",
79
79
  "react-dom": "^19.2.4",
80
- "sharp": "npm:@ohos-ports/sharp@0.34.5-beta.2",
80
+ "sharp": "npm:@ohos-ports/sharp@0.34.5-beta.5",
81
81
  "tldraw": "^4.4.1"
82
82
  },
83
83
  "optionalDependencies": {
84
84
  "@ohos-ports/img-sharp-openharmony-arm64": "0.34.5-beta.0",
85
- "@ohos-ports/img-sharp-libvips-openharmony-arm64": "1.2.4-beta.0"
85
+ "@ohos-ports/img-sharp-libvips-openharmony-arm64": "1.2.4-beta.1"
86
86
  },
87
87
  "devDependencies": {
88
88
  "@types/node": "^25.5.0",
@@ -11,6 +11,7 @@ import sharp from 'sharp';
11
11
  import { ensureSlidesPassValidation } from './validate-slides.js';
12
12
 
13
13
  const require = createRequire(import.meta.url);
14
+ const { launchBrowserViaCdp, loadPageUrl } = require('../src/ohos-browser-bridge.cjs');
14
15
  const {
15
16
  getResolutionChoices,
16
17
  getResolutionSize,
@@ -667,7 +668,7 @@ export async function renderSlideToPdf(page, slideFile, slidesDir, options = {})
667
668
  const slideMode = normalizeSlideMode(options.slideMode ?? DEFAULT_SLIDE_MODE, { optionName: '--slide-mode' });
668
669
  const captureResolution = mode === 'capture' ? normalizeResolutionPreset(options.resolution ?? '') : '';
669
670
 
670
- await page.goto(slideUrl, { waitUntil: 'load' });
671
+ await loadPageUrl(page, slideUrl, { waitUntil: 'load' });
671
672
  await waitForSlideRenderReady(page, options);
672
673
 
673
674
  const slideFrame = await detectSlideFrame(page, slideMode);
@@ -773,7 +774,9 @@ async function main() {
773
774
  throw new Error(`No slide-*.html files found in: ${slidesDir}`);
774
775
  }
775
776
 
776
- const browser = await chromium.launch({ headless: true });
777
+ const browser = process.platform === 'openharmony'
778
+ ? await launchBrowserViaCdp()
779
+ : await chromium.launch({ headless: true });
777
780
  const page = await browser.newPage(buildPageOptions(options.mode, options.resolution, options.slideMode));
778
781
  const diagnostics = createSlideDiagnostics();
779
782
  diagnostics.attach(page);
@@ -9,6 +9,7 @@ import { chromium } from 'playwright';
9
9
  import { ensureSlidesPassValidation } from './validate-slides.js';
10
10
 
11
11
  const require = createRequire(import.meta.url);
12
+ const { launchBrowserViaCdp, loadPageUrl } = require('../src/ohos-browser-bridge.cjs');
12
13
  const {
13
14
  getResolutionChoices,
14
15
  getResolutionSize,
@@ -159,7 +160,7 @@ async function discoverSlideFiles(slidesDir) {
159
160
 
160
161
  async function renderSlideToPng(page, slidesDir, slideFile, outputPath) {
161
162
  const url = pathToFileURL(join(slidesDir, slideFile)).href;
162
- await page.goto(url, { waitUntil: 'load' });
163
+ await loadPageUrl(page, url, { waitUntil: 'load' });
163
164
  await page.evaluate(async () => {
164
165
  if (document.fonts?.ready) {
165
166
  await document.fonts.ready;
@@ -217,7 +218,9 @@ async function main() {
217
218
  `Rendering ${slideFiles.length} slide(s) at ${outputSize.width}x${outputSize.height} (${options.slideMode})\n`,
218
219
  );
219
220
 
220
- const browser = await chromium.launch({ headless: true });
221
+ const browser = process.platform === 'openharmony'
222
+ ? await launchBrowserViaCdp()
223
+ : await chromium.launch({ headless: true });
221
224
  try {
222
225
  const context = await browser.newContext({
223
226
  viewport: { width: framePx.width, height: framePx.height },
@@ -22,6 +22,7 @@ import {
22
22
  } from '../src/validation/core.js';
23
23
 
24
24
  const require = createRequire(import.meta.url);
25
+ const { launchBrowserViaCdp } = require('../src/ohos-browser-bridge.cjs');
25
26
  const { DEFAULT_SLIDE_MODE } = require('../src/slide-mode.cjs');
26
27
 
27
28
  export {
@@ -170,7 +171,9 @@ export async function validateSlides(slidesDir, { mode = DEFAULT_SLIDE_MODE, sel
170
171
  throw new Error(`No slide-*.html files found in: ${slidesDir}`);
171
172
  }
172
173
 
173
- const browser = await chromium.launch({ headless: true });
174
+ const browser = process.platform === 'openharmony'
175
+ ? await launchBrowserViaCdp()
176
+ : await chromium.launch({ headless: true });
174
177
  const context = await browser.newContext({ viewport: { width: 1920, height: 1080 } });
175
178
  const page = await context.newPage();
176
179
 
@@ -11,7 +11,6 @@
11
11
  * 4. chromium.connectOverCDP(wsEndpoint)
12
12
  */
13
13
 
14
- const { execFileSync } = require('child_process');
15
14
  const http = require('http');
16
15
 
17
16
  // ─── Browser registry ────────────────────────────────────────────────────
@@ -72,6 +71,8 @@ const DISABLED_FEATURES = [
72
71
  const OHOS_AA_PATH = '/system/bin/cli_tool/executable/ohos-aa';
73
72
  const OHOS_BM_PATH = '/system/bin/cli_tool/executable/ohos-bm';
74
73
 
74
+ const { execFileSync, execSync } = require('child_process');
75
+
75
76
  function execOhosAa(args, timeout = 30000) {
76
77
  return execFileSync(OHOS_AA_PATH, args, { timeout, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
77
78
  }
@@ -80,6 +81,66 @@ function execOhosBm(args, timeout = 30000) {
80
81
  return execFileSync(OHOS_BM_PATH, args, { timeout, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
81
82
  }
82
83
 
84
+ // ─── Process management ─────────────────────────────────────────────────
85
+ /**
86
+ * Kill a browser process by bundle name.
87
+ * ohos-aa force-stop can silently fail (returns status=failed without error).
88
+ * This function tries force-stop first, then falls back to killall.
89
+ */
90
+ function killBrowserProcess(pkg) {
91
+ // 1. Try ohos-aa force-stop
92
+ try {
93
+ const result = execOhosAa(['force-stop', '--bundlename', pkg]);
94
+ let parsed;
95
+ try { parsed = JSON.parse(result); } catch { parsed = null; }
96
+ if (parsed && parsed.status === 'success') return; // force-stop worked
97
+ } catch {}
98
+
99
+ // 2. Check if process is still alive
100
+ let stillAlive = false;
101
+ try {
102
+ const out = execSync(`ps -ef 2>/dev/null | grep "${pkg}" | grep -v grep`, {
103
+ encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'ignore']
104
+ });
105
+ stillAlive = out.trim().length > 0;
106
+ } catch {
107
+ // grep returns non-zero when no match — process is dead
108
+ stillAlive = false;
109
+ }
110
+
111
+ if (!stillAlive) return; // process already gone
112
+
113
+ // 3. Fallback: killall
114
+ try {
115
+ execSync(`killall ${pkg} 2>/dev/null`, { encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'ignore'] });
116
+ } catch {}
117
+
118
+ // 3b. Fallback: kill -9 by PID
119
+ try {
120
+ const out = execSync(`ps -ef 2>/dev/null | grep "${pkg}" | grep -v grep | awk '{print $2}'`, {
121
+ encoding: 'utf-8', timeout: 5000, stdio: ['pipe', 'pipe', 'ignore']
122
+ });
123
+ const pids = out.trim().split('\n').filter(Boolean);
124
+ for (const pid of pids) {
125
+ try { execSync(`kill -9 ${pid} 2>/dev/null`, { encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'ignore'] }); } catch {}
126
+ }
127
+ } catch {}
128
+
129
+ // 4. Wait for process to die (poll up to 5s)
130
+ const deadline = Date.now() + 5000;
131
+ while (Date.now() < deadline) {
132
+ try {
133
+ const out = execSync(`ps -ef 2>/dev/null | grep "${pkg}" | grep -v grep`, {
134
+ encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'ignore']
135
+ });
136
+ if (out.trim().length === 0) return; // dead
137
+ } catch {
138
+ return; // grep no match = dead
139
+ }
140
+ execSync('sleep 0.5', { timeout: 2000 });
141
+ }
142
+ }
143
+
83
144
  // ─── CDP ────────────────────────────────────────────────────────────────
84
145
  function buildCmdArgs(port, options = {}) {
85
146
  const args = [
@@ -151,8 +212,8 @@ async function launchBrowserViaCdp(options = {}) {
151
212
  }
152
213
 
153
214
  // 2. Stop stale browser process
154
- try { execOhosAa(['force-stop', '--bundlename', pkg]); } catch {}
155
- await new Promise(r => setTimeout(r, 2000));
215
+ killBrowserProcess(pkg);
216
+ await new Promise(r => setTimeout(r, 1000));
156
217
 
157
218
  // 3. Launch browser with CDP port
158
219
  const cmdArgs = buildCmdArgs(port, options);
@@ -174,7 +235,7 @@ async function launchBrowserViaCdp(options = {}) {
174
235
 
175
236
  // Real cleanup on process exit
176
237
  process.on('exit', () => {
177
- try { execOhosAa(['force-stop', '--bundlename', pkg]); } catch {}
238
+ try { killBrowserProcess(pkg); } catch {}
178
239
  });
179
240
 
180
241
  return browser;