@smart-cloud/publisher-exporter 1.1.61 → 1.1.62

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/README.md CHANGED
@@ -179,17 +179,19 @@ functions. Large payloads do not travel in the Lambda response: workers write
179
179
  HTML and detailed results below a configured S3 workspace prefix and return a
180
180
  small `resultKey` pointer. Reusing the same job/task ID is idempotent.
181
181
 
182
- The companion CDK application is in the repository `infrastructure/`
182
+ The companion CDK application is maintained separately at
183
+ [`smartcloudsol/static-publisher-lambda-workers`](https://github.com/smartcloudsol/static-publisher-lambda-workers).
183
184
  directory. Its deploy script emits a `remote-workers.json` containing the
184
185
  versioned Lambda alias ARNs, workspace bucket/prefix, region, and generated
185
186
  assumable role. The file contains no static AWS access keys.
186
187
 
187
- Copy that output to the exporter host with owner-only permissions and validate
188
- the role, aliases, and function runtimes:
188
+ Install that output with owner-only permissions at
189
+ `<site-runtime>/remote-workers.json`, then validate the role, aliases, and
190
+ function runtimes:
189
191
 
190
192
  ```bash
191
193
  publisher-exporter remote-worker-health \
192
- --config /etc/wpsuite/remote-workers.json
194
+ --runtime-dir /srv/site/runtime
193
195
  ```
194
196
 
195
197
  Protocol v1 accepts 1-20 same-origin URLs per render task. Start with one URL
@@ -197,11 +199,56 @@ per invocation so retries stay small and Lambda concurrency supplies the
197
199
  parallelism. The Lambda response is not the rendered body; read the returned
198
200
  S3 result object using the same temporary role credentials.
199
201
 
200
- This change establishes the deployable workers, client, health check, and S3
201
- contract. The normal `crawl`, `rewrite`, and `deploy` commands retain their
202
- local behavior until their coordinator paths are explicitly configured to
203
- delegate work. There is deliberately no automatic local fallback after a
204
- remote worker error.
202
+ Enable the desired Lambda phases in the Static Publisher WordPress admin. The saved
203
+ runtime configuration contains only the operational settings:
204
+
205
+ ```json
206
+ {
207
+ "remoteWorkers": {
208
+ "render": {
209
+ "enabled": true,
210
+ "concurrency": 4,
211
+ "maxAttempts": 2
212
+ },
213
+ "rewrite": {
214
+ "enabled": true,
215
+ "concurrency": 8,
216
+ "batchSize": 25,
217
+ "maxAttempts": 2
218
+ },
219
+ "deploy": {
220
+ "enabled": true,
221
+ "concurrency": 8,
222
+ "batchSize": 50,
223
+ "maxAttempts": 2
224
+ }
225
+ }
226
+ }
227
+ ```
228
+
229
+ The normal queue runner already supplies the runtime directory, so cron needs
230
+ no Lambda-specific environment variables. A one-off diagnostic crawl can still
231
+ override the generated file explicitly:
232
+
233
+ ```bash
234
+ STATIC_PUBLISHER_RUNTIME_DIR=/srv/site/runtime \
235
+ publisher-exporter crawl --remote-render
236
+ ```
237
+
238
+ Use `--local-render` to override an enabled configuration for a diagnostic run.
239
+ The crawl coordinator keeps sitemap discovery, incremental decisions, asset
240
+ downloads, manifests, and deploy planning local. Each admitted
241
+ page is rendered by one Lambda task, and its HTML is read from S3 with length
242
+ and SHA-256 verification. Failed/deferred tasks receive a new task ID when
243
+ retried. Final text files are staged in the workspace, rewritten in bounded
244
+ Lambda batches, checksum-verified, and restored to the local export tree.
245
+ Deployment stages finalized objects with their cache and checksum metadata;
246
+ deploy workers then check or copy them directly from S3 to the allowlisted
247
+ target. Only explicit deploy-plan tombstones may be deleted. Each completed
248
+ batch updates phase-scoped runtime progress and adds a structured batch summary
249
+ to `deploy.log.jsonl`; debug logging also records each returned object result.
250
+ There is no silent local fallback for any
251
+ enabled remote phase.
205
252
 
206
253
  ## Troubleshooting
207
254
 
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import {spawn}from'child_process';import {existsSync,readFileSync}from'fs';import o from'path';import {fileURLToPath}from'url';var p=o.dirname(fileURLToPath(import.meta.url)),l=o.resolve(p,"..");function f(){try{let e=readFileSync(o.join(l,"package.json"),"utf8"),n=JSON.parse(e);if(typeof n.version=="string"&&n.version.trim())return n.version.trim()}catch{}return "unknown"}function g(){console.log(`publisher-exporter <command> [args]
2
+ import {spawn}from'child_process';import {existsSync,readFileSync}from'fs';import o from'path';import {fileURLToPath}from'url';var p=o.dirname(fileURLToPath(import.meta.url)),l=o.resolve(p,"..");function f(){try{let e=readFileSync(o.join(l,"package.json"),"utf8"),r=JSON.parse(e);if(typeof r.version=="string"&&r.version.trim())return r.version.trim()}catch{}return "unknown"}function g(){console.log(`publisher-exporter <command> [args]
3
3
 
4
4
  Commands:
5
5
  crawl Run the crawl phase
@@ -14,12 +14,18 @@ Commands:
14
14
  version Show the installed CLI version
15
15
  help Show this help
16
16
 
17
+ Crawl worker options:
18
+ --remote-render Delegate Playwright page rendering to Lambda
19
+ --local-render Force local Playwright rendering
20
+ --remote-worker-config <path> Diagnostic override for runtime/remote-workers.json
21
+
17
22
  Examples:
18
23
  publisher-exporter crawl --crawl-mode incremental
24
+ publisher-exporter crawl --remote-render
19
25
  publisher-exporter deploy --profile prod
20
26
  publisher-exporter queue-runner --runtime-dir /srv/site/runtime --max-jobs 1
21
27
  publisher-exporter prune-logs --runtime-dir /srv/site/runtime --older-than-days 30
22
- publisher-exporter remote-worker-health --config ./remote-workers.json
28
+ publisher-exporter remote-worker-health --runtime-dir /srv/site/runtime
23
29
  publisher-exporter install-browsers
24
30
  publisher-exporter --version
25
- `);}function v(){console.log(f());}function a(e){let n=o.join(p,`${e}.js`);if(!existsSync(n))throw new Error(`Missing CLI entrypoint: ${n}`);return n}function y(){let e=[o.join(l,"node_modules","playwright","cli.js"),o.join(l,"node_modules","playwright-core","cli.js")];for(let n of e)if(existsSync(n))return n;throw new Error("Playwright CLI was not found under this package. Run `npm install` first.")}function i(e,n){return new Promise((r,s)=>{let t=spawn(process.execPath,[e,...n],{cwd:l,env:process.env,stdio:"inherit"});t.on("error",s),t.on("close",(d,c)=>{if(c){s(new Error(`Command terminated by signal ${c}.`));return}r(d??1);});})}async function b(e){let n=`direct-publish-${Date.now()}`,r=await i(a("content-sync"),["--capture-baseline-cutoffs",n]);if(r!==0)return r;for(let s of ["crawl","deploy","invalidate"]){let t=await i(a(s),e);if(t!==0)return t}return i(a("content-sync"),["--establish-baselines",n])}async function x(){let[e="help",...n]=process.argv.slice(2);if(["version","--version","-v"].includes(e)){v();return}if(["help","--help","-h"].includes(e)){g();return}if(e==="publish"){process.exitCode=await b(n);return}if(e==="install-browsers"){let r=n.length>0?n:["install","chromium"];process.exitCode=await i(y(),r);return}if(e==="crawl"||e==="deploy"||e==="invalidate"||e==="queue-runner"||e==="prune-logs"||e==="remote-worker-health"||e==="content-sync"){process.exitCode=await i(a(e),n);return}throw new Error(`Unknown command: ${e}`)}x().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});
31
+ `);}function v(){console.log(f());}function a(e){let r=o.join(p,`${e}.js`);if(!existsSync(r))throw new Error(`Missing CLI entrypoint: ${r}`);return r}function y(){let e=[o.join(l,"node_modules","playwright","cli.js"),o.join(l,"node_modules","playwright-core","cli.js")];for(let r of e)if(existsSync(r))return r;throw new Error("Playwright CLI was not found under this package. Run `npm install` first.")}function i(e,r){return new Promise((n,s)=>{let t=spawn(process.execPath,[e,...r],{cwd:l,env:process.env,stdio:"inherit"});t.on("error",s),t.on("close",(d,c)=>{if(c){s(new Error(`Command terminated by signal ${c}.`));return}n(d??1);});})}async function b(e){let r=`direct-publish-${Date.now()}`,n=await i(a("content-sync"),["--capture-baseline-cutoffs",r]);if(n!==0)return n;for(let s of ["crawl","deploy","invalidate"]){let t=await i(a(s),e);if(t!==0)return t}return i(a("content-sync"),["--establish-baselines",r])}async function x(){let[e="help",...r]=process.argv.slice(2);if(["version","--version","-v"].includes(e)){v();return}if(["help","--help","-h"].includes(e)){g();return}if(e==="publish"){process.exitCode=await b(r);return}if(e==="install-browsers"){let n=r.length>0?r:["install","chromium"];process.exitCode=await i(y(),n);return}if(e==="crawl"||e==="deploy"||e==="invalidate"||e==="queue-runner"||e==="prune-logs"||e==="remote-worker-health"||e==="content-sync"){process.exitCode=await i(a(e),r);return}throw new Error(`Unknown command: ${e}`)}x().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1);});