polotno-node 3.10.0 → 3.11.0
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/assets/index-CpBN0dhf.js +660 -0
- package/dist/assets/{index.es-BRgisxmP.js → index.es-2ncnHwRp.js} +1 -1
- package/dist/assets/{jspdf.es.min-D1i2-kxU.js → jspdf.es.min-B1nUIUxR.js} +3 -3
- package/dist/assets/{lib-BAYK6Nbm.js → lib-qW6sgCha.js} +1 -1
- package/dist/index.html +1 -1
- package/lib/instance.d.ts +1 -10
- package/lib/instance.js +7 -45
- package/package.json +5 -5
- package/dist/assets/index-BB9RRitk.js +0 -649
package/lib/instance.d.ts
CHANGED
|
@@ -13,16 +13,7 @@ declare global {
|
|
|
13
13
|
__polotnoVideoHeartbeat?: () => Promise<void>;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
export
|
|
17
|
-
/**
|
|
18
|
-
* Visit every URL-holding field in a design: `visit(node, key, value)` for each
|
|
19
|
-
* string under one of `URL_FIELDS`, `custom` skipped whole.
|
|
20
|
-
*
|
|
21
|
-
* Exported because `@polotno/fidelity` inlines a fixture's local assets over
|
|
22
|
-
* the same fields — which subtrees a rewrite may enter is one rule, and two
|
|
23
|
-
* copies of it drift. Changing either one needs that package's `test:unit`.
|
|
24
|
-
*/
|
|
25
|
-
export declare const forEveryUrlField: (node: any, visit: any) => void;
|
|
16
|
+
export { URL_FIELDS, forEveryUrlField } from '@polotno/schema/asset-urls';
|
|
26
17
|
/**
|
|
27
18
|
* Rewrite every `file:` source in a design to a URL the client can load with
|
|
28
19
|
* any API. Designs without one — the common case — come back untouched, so this
|
package/lib/instance.js
CHANGED
|
@@ -7,6 +7,7 @@ import { pathToFileURL, fileURLToPath } from 'url';
|
|
|
7
7
|
import { Readable } from 'stream';
|
|
8
8
|
import { pipeline } from 'stream/promises';
|
|
9
9
|
import { assertValidDesign } from '@polotno/schema';
|
|
10
|
+
import { forEveryUrlField } from '@polotno/schema/asset-urls';
|
|
10
11
|
import * as fontCache from './font-cache.js';
|
|
11
12
|
import * as localMedia from './local-media.js';
|
|
12
13
|
import { polotnoError, rehydrateError } from './errors.js';
|
|
@@ -53,48 +54,8 @@ const collectMediaSourcePointers = (json) => {
|
|
|
53
54
|
}
|
|
54
55
|
return pointers;
|
|
55
56
|
};
|
|
56
|
-
//
|
|
57
|
-
|
|
58
|
-
// for why the browser must never see that scheme. Every other value is passed
|
|
59
|
-
// through exactly as the caller wrote it.
|
|
60
|
-
//
|
|
61
|
-
// A list, rather than "rewrite every `file:` string anywhere", because a design
|
|
62
|
-
// carries text: a text element whose content reads `file:///notes.txt` is
|
|
63
|
-
// content, and rewriting it corrupts the render. `custom` is arbitrary caller
|
|
64
|
-
// data with the same problem, so the walk does not enter it at all. And
|
|
65
|
-
// `test/unit/local-media.test.mjs` fails when the schema grows a field named
|
|
66
|
-
// like one that is missing here.
|
|
67
|
-
export const URL_FIELDS = ['src', 'clipSrc', 'maskSrc', 'background', 'url'];
|
|
68
|
-
const URL_FIELD_SET = new Set(URL_FIELDS);
|
|
69
|
-
/**
|
|
70
|
-
* Visit every URL-holding field in a design: `visit(node, key, value)` for each
|
|
71
|
-
* string under one of `URL_FIELDS`, `custom` skipped whole.
|
|
72
|
-
*
|
|
73
|
-
* Exported because `@polotno/fidelity` inlines a fixture's local assets over
|
|
74
|
-
* the same fields — which subtrees a rewrite may enter is one rule, and two
|
|
75
|
-
* copies of it drift. Changing either one needs that package's `test:unit`.
|
|
76
|
-
*/
|
|
77
|
-
export const forEveryUrlField = (node, visit) => {
|
|
78
|
-
if (!node || typeof node !== 'object')
|
|
79
|
-
return;
|
|
80
|
-
if (Array.isArray(node)) {
|
|
81
|
-
for (const item of node)
|
|
82
|
-
forEveryUrlField(item, visit);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
for (const key of Object.keys(node)) {
|
|
86
|
-
if (key === 'custom')
|
|
87
|
-
continue;
|
|
88
|
-
const value = node[key];
|
|
89
|
-
if (typeof value === 'string') {
|
|
90
|
-
if (URL_FIELD_SET.has(key))
|
|
91
|
-
visit(node, key, value);
|
|
92
|
-
}
|
|
93
|
-
else if (value && typeof value === 'object') {
|
|
94
|
-
forEveryUrlField(value, visit);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
};
|
|
57
|
+
// Keep the published deep-import API while schema owns the asset vocabulary.
|
|
58
|
+
export { URL_FIELDS, forEveryUrlField } from '@polotno/schema/asset-urls';
|
|
98
59
|
// Not `toLowerCase().startsWith`: a `src` is routinely a data URL of several
|
|
99
60
|
// MB, and that would copy every one of them on every render.
|
|
100
61
|
const isFileUrl = (value) => /^file:/i.test(value);
|
|
@@ -1160,11 +1121,12 @@ export const createInstance = async ({ key, url, useParallelPages = true, browse
|
|
|
1160
1121
|
});
|
|
1161
1122
|
const jsonToVideoDataURL = (json, attrs = {}) => renderVideoString(json, attrs, true);
|
|
1162
1123
|
const jsonToVideoBase64 = (json, attrs = {}) => renderVideoString(json, attrs, false);
|
|
1124
|
+
let closing;
|
|
1163
1125
|
const instance = {
|
|
1164
|
-
close: async () => {
|
|
1126
|
+
close: () => (closing ?? (closing = (async () => {
|
|
1165
1127
|
createdInstances.splice(createdInstances.indexOf(instance), 1);
|
|
1166
1128
|
await browser.close();
|
|
1167
|
-
},
|
|
1129
|
+
})())),
|
|
1168
1130
|
firstPage,
|
|
1169
1131
|
browser,
|
|
1170
1132
|
run,
|
|
@@ -1185,7 +1147,7 @@ export const createInstance = async ({ key, url, useParallelPages = true, browse
|
|
|
1185
1147
|
};
|
|
1186
1148
|
// Function to close all created instances in parallel
|
|
1187
1149
|
const closeAllInstances = async () => {
|
|
1188
|
-
await Promise.all(createdInstances.map((instance) => instance.close()));
|
|
1150
|
+
await Promise.all([...createdInstances].map((instance) => instance.close()));
|
|
1189
1151
|
};
|
|
1190
1152
|
// Also handle other termination signals
|
|
1191
1153
|
['SIGINT', 'SIGTERM', 'SIGQUIT', 'exit'].forEach((signal) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polotno-node",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.0",
|
|
4
4
|
"description": "Polotno workflow from NodeJS",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"type": "module",
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
"@types/node": "^26.6.1",
|
|
41
41
|
"dotenv": "^17.4.2",
|
|
42
42
|
"jspdf": "^4.2.1",
|
|
43
|
-
"konva": "^10.
|
|
43
|
+
"konva": "^10.7.0",
|
|
44
44
|
"mediabunny": "^1.56.3",
|
|
45
45
|
"pixelmatch": "^7.2.0",
|
|
46
46
|
"pngjs": "^7.0.0",
|
|
47
|
-
"polotno": "4.
|
|
47
|
+
"polotno": "4.14.0",
|
|
48
48
|
"react": "^19.3.0",
|
|
49
49
|
"react-dom": "^19.3.0",
|
|
50
50
|
"tmp": "^0.2.7",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
"author": "Anton Lavrenov",
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@polotno/schema": "0.
|
|
64
|
+
"@polotno/schema": "0.7.0",
|
|
65
65
|
"@sparticuz/chromium": "^153.0.0",
|
|
66
66
|
"puppeteer": "25.11.0",
|
|
67
67
|
"puppeteer-core": "25.11.0"
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
77
77
|
"test": "if [ -z \"$TURBO_HASH\" ]; then pnpm exec turbo run build --filter=polotno-node --output-logs=new-only --log-order=stream; fi && vitest run test/unit test/static",
|
|
78
78
|
"test:update-goldens": "rm -f test/static/goldens/*.png test/static/goldens/matrix/*.png && pnpm run test",
|
|
79
|
-
"test:video": "pnpm exec turbo run build --filter=polotno-node &&
|
|
79
|
+
"test:video": "if [ -z \"$TURBO_HASH\" ]; then pnpm exec turbo run build --filter=polotno-node --output-logs=new-only; fi && vitest run test/video/video.test.mjs",
|
|
80
80
|
"test:all": "pnpm exec turbo run build --filter=polotno-node && vitest run test/unit test/static test/video",
|
|
81
81
|
"dev": "vite ./client.html"
|
|
82
82
|
}
|