@emasoft/svg-matrix 1.1.0 → 1.2.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/bin/svg-matrix.js +7 -6
- package/bin/svgm.js +109 -40
- package/dist/svg-matrix.min.js +7 -7
- package/dist/svg-toolbox.min.js +148 -228
- package/dist/svgm.min.js +152 -232
- package/dist/version.json +5 -5
- package/package.json +1 -1
- package/scripts/postinstall.js +72 -41
- package/scripts/test-postinstall.js +18 -16
- package/scripts/version-sync.js +78 -60
- package/src/animation-optimization.js +190 -98
- package/src/animation-references.js +11 -3
- package/src/arc-length.js +23 -20
- package/src/bezier-analysis.js +9 -13
- package/src/bezier-intersections.js +18 -4
- package/src/browser-verify.js +35 -8
- package/src/clip-path-resolver.js +285 -114
- package/src/convert-path-data.js +20 -8
- package/src/css-specificity.js +33 -9
- package/src/douglas-peucker.js +272 -141
- package/src/geometry-to-path.js +79 -22
- package/src/gjk-collision.js +287 -126
- package/src/index.js +56 -21
- package/src/inkscape-support.js +122 -101
- package/src/logger.js +43 -27
- package/src/marker-resolver.js +201 -121
- package/src/mask-resolver.js +231 -98
- package/src/matrix.js +9 -5
- package/src/mesh-gradient.js +22 -14
- package/src/off-canvas-detection.js +53 -17
- package/src/path-optimization.js +356 -171
- package/src/path-simplification.js +671 -256
- package/src/pattern-resolver.js +1 -3
- package/src/polygon-clip.js +396 -78
- package/src/svg-boolean-ops.js +90 -23
- package/src/svg-collections.js +1546 -667
- package/src/svg-flatten.js +152 -38
- package/src/svg-matrix-lib.js +2 -2
- package/src/svg-parser.js +5 -1
- package/src/svg-rendering-context.js +3 -1
- package/src/svg-toolbox-lib.js +2 -2
- package/src/svg-toolbox.js +99 -457
- package/src/svg-validation-data.js +513 -345
- package/src/svg2-polyfills.js +156 -93
- package/src/svgm-lib.js +8 -4
- package/src/transform-optimization.js +168 -51
- package/src/transforms2d.js +73 -40
- package/src/transforms3d.js +34 -27
- package/src/use-symbol-resolver.js +175 -76
- package/src/vector.js +80 -44
- package/src/vendor/inkscape-hatch-polyfill.js +143 -108
- package/src/vendor/inkscape-hatch-polyfill.min.js +291 -1
- package/src/vendor/inkscape-mesh-polyfill.js +953 -766
- package/src/vendor/inkscape-mesh-polyfill.min.js +896 -1
- package/src/verification.js +3 -4
package/src/logger.js
CHANGED
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
// Why: Only appendFileSync is needed - we use sync writes in flush() for reliability
|
|
35
35
|
// during shutdown or before critical operations. Async writes were considered but
|
|
36
36
|
// the complexity of handling async flush during process exit wasn't worth it.
|
|
37
|
-
import { appendFileSync } from
|
|
37
|
+
import { appendFileSync } from "fs";
|
|
38
38
|
|
|
39
39
|
// ============================================================================
|
|
40
40
|
// CONSTANTS
|
|
41
41
|
// ============================================================================
|
|
42
42
|
// Why: Centralize configuration values to make tuning easier
|
|
43
|
-
const LOG_BUFFER_SIZE = 100;
|
|
44
|
-
const LOG_FLUSH_INTERVAL_MS = 5000;
|
|
43
|
+
const LOG_BUFFER_SIZE = 100; // Flush after this many messages
|
|
44
|
+
const LOG_FLUSH_INTERVAL_MS = 5000; // Auto-flush every 5 seconds
|
|
45
45
|
|
|
46
46
|
// ============================================================================
|
|
47
47
|
// LOG LEVELS
|
|
@@ -125,8 +125,8 @@ export const Logger = {
|
|
|
125
125
|
*/
|
|
126
126
|
_safeStringify(value) {
|
|
127
127
|
// Why: Handle null/undefined explicitly to show their actual type
|
|
128
|
-
if (value === null) return
|
|
129
|
-
if (value === undefined) return
|
|
128
|
+
if (value === null) return "null";
|
|
129
|
+
if (value === undefined) return "undefined";
|
|
130
130
|
|
|
131
131
|
// Why: Error objects should include stack traces for debugging
|
|
132
132
|
if (value instanceof Error) {
|
|
@@ -134,7 +134,7 @@ export const Logger = {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
// Why: For primitives, use String() for simple conversion
|
|
137
|
-
if (typeof value !==
|
|
137
|
+
if (typeof value !== "object") {
|
|
138
138
|
return String(value);
|
|
139
139
|
}
|
|
140
140
|
|
|
@@ -143,9 +143,9 @@ export const Logger = {
|
|
|
143
143
|
const seen = new WeakSet();
|
|
144
144
|
return JSON.stringify(value, (key, val) => {
|
|
145
145
|
// Why: Handle circular references by replacing with placeholder
|
|
146
|
-
if (typeof val ===
|
|
146
|
+
if (typeof val === "object" && val !== null) {
|
|
147
147
|
if (seen.has(val)) {
|
|
148
|
-
return
|
|
148
|
+
return "[Circular]";
|
|
149
149
|
}
|
|
150
150
|
seen.add(val);
|
|
151
151
|
}
|
|
@@ -168,8 +168,8 @@ export const Logger = {
|
|
|
168
168
|
*/
|
|
169
169
|
_format(level, message) {
|
|
170
170
|
// Why: Validate parameters to prevent crashes from invalid inputs
|
|
171
|
-
if (typeof level !==
|
|
172
|
-
throw new Error(
|
|
171
|
+
if (typeof level !== "string" || !level) {
|
|
172
|
+
throw new Error("Logger._format: level must be a non-empty string");
|
|
173
173
|
}
|
|
174
174
|
// Why: Use safe stringify to handle all message types including errors and objects
|
|
175
175
|
const messageStr = this._safeStringify(message);
|
|
@@ -219,7 +219,7 @@ export const Logger = {
|
|
|
219
219
|
try {
|
|
220
220
|
// Why sync here: flush() is called when reliability matters more
|
|
221
221
|
// than performance (shutdown, before risky operation)
|
|
222
|
-
const content = this._buffer.join(
|
|
222
|
+
const content = this._buffer.join("\n") + "\n";
|
|
223
223
|
appendFileSync(this.logToFile, content);
|
|
224
224
|
this._buffer = [];
|
|
225
225
|
} catch {
|
|
@@ -240,9 +240,11 @@ export const Logger = {
|
|
|
240
240
|
// Why: Check level FIRST - avoid performance cost of validation when logging is disabled
|
|
241
241
|
if (this.level < LogLevel.ERROR) return;
|
|
242
242
|
|
|
243
|
-
const formatted = this._format(
|
|
243
|
+
const formatted = this._format("ERROR", message);
|
|
244
244
|
// Why: Safely stringify args to handle objects, errors, and circular refs
|
|
245
|
-
const argsStr = args.length
|
|
245
|
+
const argsStr = args.length
|
|
246
|
+
? " " + args.map((a) => this._safeStringify(a)).join(" ")
|
|
247
|
+
: "";
|
|
246
248
|
console.error(formatted, ...args);
|
|
247
249
|
this._bufferWrite(formatted + argsStr);
|
|
248
250
|
// Why: Errors are important enough to flush immediately
|
|
@@ -258,9 +260,11 @@ export const Logger = {
|
|
|
258
260
|
// Why: Check level FIRST - avoid performance cost when logging is disabled
|
|
259
261
|
if (this.level < LogLevel.WARN) return;
|
|
260
262
|
|
|
261
|
-
const formatted = this._format(
|
|
263
|
+
const formatted = this._format("WARN", message);
|
|
262
264
|
// Why: Safely stringify args to handle objects, errors, and circular refs
|
|
263
|
-
const argsStr = args.length
|
|
265
|
+
const argsStr = args.length
|
|
266
|
+
? " " + args.map((a) => this._safeStringify(a)).join(" ")
|
|
267
|
+
: "";
|
|
264
268
|
console.warn(formatted, ...args);
|
|
265
269
|
this._bufferWrite(formatted + argsStr);
|
|
266
270
|
},
|
|
@@ -274,9 +278,11 @@ export const Logger = {
|
|
|
274
278
|
// Why: Check level FIRST - avoid performance cost when logging is disabled
|
|
275
279
|
if (this.level < LogLevel.INFO) return;
|
|
276
280
|
|
|
277
|
-
const formatted = this._format(
|
|
281
|
+
const formatted = this._format("INFO", message);
|
|
278
282
|
// Why: Safely stringify args to handle objects, errors, and circular refs
|
|
279
|
-
const argsStr = args.length
|
|
283
|
+
const argsStr = args.length
|
|
284
|
+
? " " + args.map((a) => this._safeStringify(a)).join(" ")
|
|
285
|
+
: "";
|
|
280
286
|
console.log(formatted, ...args);
|
|
281
287
|
this._bufferWrite(formatted + argsStr);
|
|
282
288
|
},
|
|
@@ -290,9 +296,11 @@ export const Logger = {
|
|
|
290
296
|
// Why: Check level FIRST - avoid performance cost when logging is disabled
|
|
291
297
|
if (this.level < LogLevel.DEBUG) return;
|
|
292
298
|
|
|
293
|
-
const formatted = this._format(
|
|
299
|
+
const formatted = this._format("DEBUG", message);
|
|
294
300
|
// Why: Safely stringify args to handle objects, errors, and circular refs
|
|
295
|
-
const argsStr = args.length
|
|
301
|
+
const argsStr = args.length
|
|
302
|
+
? " " + args.map((a) => this._safeStringify(a)).join(" ")
|
|
303
|
+
: "";
|
|
296
304
|
console.log(formatted, ...args);
|
|
297
305
|
this._bufferWrite(formatted + argsStr);
|
|
298
306
|
},
|
|
@@ -319,12 +327,16 @@ export const Logger = {
|
|
|
319
327
|
*/
|
|
320
328
|
export function setLogLevel(level) {
|
|
321
329
|
// Why: Validate level is a number to catch type errors
|
|
322
|
-
if (typeof level !==
|
|
323
|
-
throw new Error(
|
|
330
|
+
if (typeof level !== "number" || !Number.isFinite(level)) {
|
|
331
|
+
throw new Error(
|
|
332
|
+
`setLogLevel: level must be a finite number, got ${typeof level}`,
|
|
333
|
+
);
|
|
324
334
|
}
|
|
325
335
|
// Why: Validate level is within valid range to catch typos
|
|
326
336
|
if (level < LogLevel.SILENT || level > LogLevel.DEBUG) {
|
|
327
|
-
throw new Error(
|
|
337
|
+
throw new Error(
|
|
338
|
+
`Invalid log level: ${level}. Use LogLevel.SILENT (0) through LogLevel.DEBUG (4)`,
|
|
339
|
+
);
|
|
328
340
|
}
|
|
329
341
|
Logger.level = level;
|
|
330
342
|
}
|
|
@@ -347,16 +359,20 @@ export function getLogLevel() {
|
|
|
347
359
|
*/
|
|
348
360
|
export function enableFileLogging(filePath, withTimestamps = true) {
|
|
349
361
|
// Why: Validate filePath type to catch type errors
|
|
350
|
-
if (typeof filePath !==
|
|
351
|
-
throw new Error(
|
|
362
|
+
if (typeof filePath !== "string") {
|
|
363
|
+
throw new Error(
|
|
364
|
+
`enableFileLogging: filePath must be a string, got ${typeof filePath}`,
|
|
365
|
+
);
|
|
352
366
|
}
|
|
353
367
|
// Why: Don't accept empty/null paths - would cause confusing errors later
|
|
354
368
|
if (!filePath) {
|
|
355
|
-
throw new Error(
|
|
369
|
+
throw new Error("File path required for enableFileLogging()");
|
|
356
370
|
}
|
|
357
371
|
// Why: Validate withTimestamps type to catch type errors
|
|
358
|
-
if (typeof withTimestamps !==
|
|
359
|
-
throw new Error(
|
|
372
|
+
if (typeof withTimestamps !== "boolean") {
|
|
373
|
+
throw new Error(
|
|
374
|
+
`enableFileLogging: withTimestamps must be a boolean, got ${typeof withTimestamps}`,
|
|
375
|
+
);
|
|
360
376
|
}
|
|
361
377
|
Logger.logToFile = filePath;
|
|
362
378
|
Logger.timestamps = withTimestamps;
|