polotno-node 2.12.17 → 2.12.19

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
@@ -307,42 +307,6 @@ const url = await instance.run(async (json) => {
307
307
  }, json);
308
308
  ```
309
309
 
310
- ## Video export
311
-
312
- **Video export is deprecated on this package and not supported anymore.**
313
-
314
- You may need to have ffmpeg available in your system to make it work.
315
- Also you need to manually dependencies:
316
-
317
- ```bash
318
- npm install fluent-ffmpeg axios
319
- ```
320
-
321
- ```js
322
- import { createInstance } from 'polotno-node';
323
- import { jsonToVideo } from 'polotno-node/video-parallel';
324
-
325
- // load sample json
326
- const json = JSON.parse(fs.readFileSync('./test-data/video.json'));
327
-
328
- await jsonToVideo(
329
- // first argument is a function that returns an instance
330
- // it can be a new instance on every call (useful for parallel rendering on local machine)
331
- // or it can be a single instance (useful for cloud functions)
332
- () =>
333
- createInstance({
334
- key: '...key...',
335
- }),
336
- json,
337
- {
338
- out: 'out.mp4', // output file name
339
- parallel: 4, // number of parallel rendering processes
340
- fps: 15, // frames per second
341
- keepInstance: false, // keep instance open after rendering, make sure to use true if use just one instance
342
- }
343
- );
344
- ```
345
-
346
310
  ## Your own client
347
311
 
348
312
  By default `polotno-node` ships with the default Polotno Editor with its (hopefully) last version. If you use experimental API such as `unstable_registerShapeModel` and `unstable_registerShapeComponent`, the rendering may fail if you use unknown elements types.
@@ -364,8 +328,6 @@ const instance = await createInstance({
364
328
 
365
329
  ## Usage on the cloud
366
330
 
367
- `polotno-node` should work by default on AWS Lambda. But in some cloud providers you may need to do extra steps to reduce function size.
368
-
369
331
  ### AWS EC2
370
332
 
371
333
  EC2 has some troubles with loading fonts. To fix the issue install Google Chrome, it will load all required libraries.
@@ -383,6 +345,7 @@ You can speed up your function execution a lot, if instead of using full browser
383
345
  Using browserless.io you can also make your function much smaller in size, so it will be possible to deploy to cloud provider with smaller limits, like Vercel.
384
346
 
385
347
  ```js
348
+ // (!) loading from polotno-node/instance will not import puppeteer and chromium-min dependencies
386
349
  const { createInstance } = require('polotno-node/instance');
387
350
  const puppeteer = require('puppeteer');
388
351
 
@@ -461,10 +424,12 @@ How to create a configuration layer with a dependency on `chronium` ?
461
424
 
462
425
  1. Create a `.zip` file from a chronium project. For example:
463
426
 
464
- ```
427
+ ```shell
465
428
  mkdir chronium-112 && cd chronium-112
429
+
466
430
  npm init -y
467
431
  npm install @sparticuz/chromium@112.0
432
+
468
433
  zip -r chronium.zip ./*
469
434
  ```
470
435
 
@@ -477,19 +442,26 @@ zip -r chronium.zip ./*
477
442
 
478
443
  How to run the full example with aws-cli ?
479
444
 
480
- - Create a Lambda configuration layer, and upload a **.zip** archive which stores a **chronium** npm or git package.
445
+ ### 1. Create a Lambda configuration layer
481
446
 
482
- ```
447
+ Create a Lambda configuration layer, and upload a **.zip** archive which stores a **chronium** npm or git package.
448
+
449
+ ```shell
483
450
  export CH_VERSION=112.0
484
451
  export BUCKET=example-bucket
485
452
  export AWS_ACC_ID=000000000000
486
- // create a chronium project for Layer
453
+
454
+ # create a chronium project for Layer
487
455
  mkdir chronium-layer
488
456
  cd chronium-layer
489
457
  npm init -y
490
458
  npm install @sparticuz/chromium@${CH_VERSION}
491
459
  zip -r chronium.zip ./*
460
+
461
+ # upload a Layer to S3
492
462
  aws s3 cp chronium.zip s3://${BUCKET}/lambda-layers/chronium-${CH_VERSION}.zip
463
+
464
+ # publish a Layer so it can be used in Lambda
493
465
  aws lambda publish-layer-version \
494
466
  --layer-name chronium-polotno \
495
467
  --content "S3Bucket=${BUCKET},S3Key=lambda-layers/chronium-{CH_VERSION}.zip" \
@@ -498,18 +470,28 @@ aws lambda publish-layer-version \
498
470
  --compatible-runtimes nodejs18.x
499
471
  ```
500
472
 
501
- - Create a JS file for a Lambda's handler
473
+ ### 2. Create a JS file for a Lambda's handler
502
474
 
503
- ```
504
- // create a folder
475
+ #### Init a node project
476
+
477
+ ```shell
478
+ # create a folder
505
479
  mkdir handler && cd handler
506
- // init a node project
480
+
481
+ # init a node project
507
482
  npm init -y
508
- // install dependencies
483
+
484
+ # install dependencies
509
485
  npm install --save polotno-node puppeteer-core@19.8.0
510
- // create a file handler
486
+ ```
487
+
488
+ #### Create a handler
489
+
490
+ ```shell
491
+ # create a file handler
511
492
  touch index.mjs
512
- // add code example
493
+
494
+ # add code example
513
495
  echo "
514
496
  import chromium from "@sparticuz/chromium";
515
497
  import puppeteer from "puppeteer-core";
@@ -544,18 +526,68 @@ export const handler = () => {
544
526
  }
545
527
  };
546
528
  " >> index.mjs
547
- // create file with variables
529
+ ```
530
+
531
+ <details>
532
+ <summary>Highlighted code example from the command above:</summary>
533
+
534
+ ```js
535
+ import chromium from "@sparticuz/chromium";
536
+ import puppeteer from "puppeteer-core";
537
+ import { createInstance } from "polotno-node";
538
+ export const handler = () => {
539
+ const browser = await puppeteer.launch({
540
+ args: [
541
+ ...chromium.args,
542
+ "--no-sandbox",
543
+ "--hide-scrollbars",
544
+ "--disable-web-security",
545
+ "--allow-file-access-from-files",
546
+ "--disable-dev-shm-usage",
547
+ ],
548
+ defaultViewport: chromium.defaultViewport,
549
+ executablePath: await chromium.executablePath(),
550
+ headless: true,
551
+ ignoreHTTPSErrors: true,
552
+ });
553
+ const polotnoInstance = await createInstance({
554
+ key: process.env.POLOTNO_API_KEY,
555
+ browser,
556
+ });
557
+ const body = polotnoInstance.jsonToImageBase64(event.json)
558
+
559
+ return {
560
+ StatusCode: 200,
561
+ headers: {
562
+ 'Content-Type': 'image/png'
563
+ },
564
+ body,
565
+ }
566
+ };
567
+ ```
568
+
569
+ </details>
570
+
571
+ #### Create file with variables
572
+
573
+ ```shell
548
574
  echo '{
549
575
  "Variables": {
550
576
  "POLOTNO_API_KEY": "your-api-key"
551
577
  }
552
578
  }
553
579
  ' >> vars.json
554
- // archive the folder
580
+
581
+ # archive the folder
555
582
  zip -r index.zip ./*
556
- // copy to S3
583
+
584
+ # copy to S3
557
585
  aws s3 cp index.zip s3://${BUCKET}/polotno-handler.zip
558
- // crete a trust policy
586
+ ```
587
+
588
+ #### Crete a trust policy
589
+
590
+ ```shell
559
591
  echo '{
560
592
  "Version": "2012-10-17",
561
593
  "Statement": [
@@ -569,7 +601,11 @@ echo '{
569
601
  ]
570
602
  }
571
603
  ' >> trustPolicy.json
572
- // create roles and policies
604
+ ```
605
+
606
+ #### Create roles and policies in AWS
607
+
608
+ ```shell
573
609
  aws iam create-role --role-name lambda-polotno-role --assume-role-policy-document file://trustPolicy.json
574
610
  aws iam attach-role-policy --role-name lambda-polotno-role --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
575
611
  aws lambda create-function --function-name lambda-polotno \
@@ -585,6 +621,44 @@ aws lambda create-function --function-name lambda-polotno \
585
621
  aws lambda invoke --function-name lambda-polotno --cli-binary-format raw-in-base64-out --payload file://polotno-project-json.json image
586
622
  ```
587
623
 
624
+ ### AWS Lambda fonts issue
625
+
626
+ If you have faced an issue `Timeout for loading font <font name>`, please proceed to the next solution.
627
+
628
+ Lambda functions does not include any fonts by default, so we need to provide basic fonts (Arial and Times or their analogs) to make sure Polotno fonts functionality is working correctly.
629
+
630
+ 1. Create a `fonts` folder in the root of your handler project.
631
+
632
+ ```shell
633
+ mkdir fonts
634
+ ```
635
+
636
+ 2. Put the `Arial.ttf` and `Times.ttf` files into the `fonts` folder. You can get them from your system fonts folder.
637
+ 3. Usage of fonts analogues is also possible:
638
+ 1. If you don't want to use system Arial and Times fonts, you can use [Liberation Fonts](https://github.com/liberationfonts/liberation-fonts) as free alternative. Download fonts from repository. Put `LiberationMono-Regular.ttf` and `LiberationSans-Regular.ttf` inside `fonts` folder.
639
+ 2. Create file `fonts.conf` inside `fonts` folder. It should contain the following lines:
640
+ ```xml
641
+ <?xml version="1.0"?>
642
+ <!DOCTYPE fontconfig SYSTEM "fonts.dtd">
643
+ <fontconfig>
644
+ <alias>
645
+ <family>Arial</family>
646
+ <prefer>
647
+ <family>Liberation Sans</family>
648
+ </prefer>
649
+ </alias>
650
+ <alias>
651
+ <family>Times New Roman</family>
652
+ <prefer>
653
+ <family>Liberation Serif</family>
654
+ </prefer>
655
+ </alias>
656
+
657
+ <dir>/var/task/fonts</dir>
658
+ </fontconfig>
659
+ ```
660
+ 4. Upload your Lambda function as usual, fonts will be loaded automatically.
661
+
588
662
  ## Troubleshooting
589
663
 
590
664
  If you have an error like this
@@ -598,9 +672,12 @@ Unhandled Promise Rejection {"errorType":"Runtime.UnhandledPromiseRejection","er
598
672
  It may mean that Polotno Client Editor was not loaded in `puppeteer` instance. It is possible that you are missing required files in `node_modules` folder. I got this error when I was trying to run `polotno-node` on Vercel. To fix the issue you need to add this config into `vercel.json`:
599
673
 
600
674
  ```json
601
- "functions": {
602
- "api/render.js": { // remember to replace this line with your function name
603
- "includeFiles": "node_modules/polotno-node/\*\*"
604
- },
675
+ {
676
+ "functions": {
677
+ "api/render.js": {
678
+ // remember to replace this line with your function name
679
+ "includeFiles": "node_modules/polotno-node/**"
680
+ }
681
+ }
605
682
  }
606
683
  ```