@pixerate/editor 0.207.0 → 0.208.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.
Files changed (69) hide show
  1. package/dist/animation-editor/index.cjs +60 -59
  2. package/dist/animation-editor/index.js +6 -5
  3. package/dist/{brushstrokeRender-7LXCU7PD.js → brushstrokeRender-C3UU6GVC.js} +5 -4
  4. package/dist/{brushstrokeRender-VO4ZTWVA.cjs → brushstrokeRender-EAJNE6WP.cjs} +12 -11
  5. package/dist/canvas/index.cjs +8 -8
  6. package/dist/canvas/index.js +1 -1
  7. package/dist/{chunk-2N2QPO3H.js → chunk-2PBZBRP5.js} +9 -7
  8. package/dist/{chunk-7NW46N7I.cjs → chunk-3EHPLDFQ.cjs} +54 -52
  9. package/dist/{chunk-H367YTXI.js → chunk-42TWUPNJ.js} +13 -387
  10. package/dist/chunk-474IQG74.cjs +384 -0
  11. package/dist/{chunk-MLC7HUHO.js → chunk-BGOCAUXH.js} +1 -1
  12. package/dist/chunk-DWYQPL2A.js +2010 -0
  13. package/dist/{chunk-YXKLVD56.js → chunk-F7YA3MMC.js} +2 -2
  14. package/dist/{chunk-ZZGPYNS2.js → chunk-G4E6RUPC.js} +1 -1
  15. package/dist/chunk-HVVR5PZW.js +384 -0
  16. package/dist/{chunk-FR2Q2LVF.cjs → chunk-I7G3RSUJ.cjs} +35 -35
  17. package/dist/chunk-K6PXS6DO.cjs +102 -0
  18. package/dist/{chunk-ZIDUPSP4.js → chunk-KFIOEOCQ.js} +24 -761
  19. package/dist/{chunk-V7GWZIZK.cjs → chunk-KWNMBMKG.cjs} +23 -21
  20. package/dist/chunk-L3G23N5Y.js +763 -0
  21. package/dist/{chunk-GHCXLQ47.js → chunk-NDMXB4PR.js} +2 -2
  22. package/dist/{chunk-CWM3CUUX.cjs → chunk-OLNIPTB3.cjs} +39 -413
  23. package/dist/{chunk-EBDCRTZI.cjs → chunk-PQ3H2AAN.cjs} +92 -90
  24. package/dist/{chunk-BRKVNXDZ.cjs → chunk-QAUIZPYI.cjs} +7 -7
  25. package/dist/{chunk-UYXL6ZWQ.cjs → chunk-QE7D7TZR.cjs} +494 -1231
  26. package/dist/chunk-QYLWG22N.cjs +763 -0
  27. package/dist/{chunk-YQ5C5BVK.cjs → chunk-ROVK6AXX.cjs} +60 -60
  28. package/dist/{chunk-HGTDMKNE.cjs → chunk-UOGKSVRQ.cjs} +126 -221
  29. package/dist/{chunk-EL5PAHNP.js → chunk-USQCKRZG.js} +6 -4
  30. package/dist/{chunk-36OKQDCF.js → chunk-WJ2RBZMM.js} +5 -3
  31. package/dist/chunk-X4LUGTQX.cjs +2010 -0
  32. package/dist/{chunk-NQMP3CWF.js → chunk-YBJXCQTR.js} +15 -110
  33. package/dist/chunk-ZIF4UJJ6.js +102 -0
  34. package/dist/{chunk-WTW7QRTS.cjs → chunk-ZMHPQ6HP.cjs} +1 -1
  35. package/dist/image-editor/controller.d.cts +28 -3
  36. package/dist/image-editor/controller.d.ts +28 -3
  37. package/dist/image-editor/index.cjs +1726 -3359
  38. package/dist/image-editor/index.js +241 -1874
  39. package/dist/image-editor/selection/index.d.cts +1 -0
  40. package/dist/image-editor/selection/index.d.ts +1 -0
  41. package/dist/image-editor/selection/segment/focus.d.cts +2 -0
  42. package/dist/image-editor/selection/segment/focus.d.ts +2 -0
  43. package/dist/image-editor/selection/segment/grabcut.d.cts +4 -2
  44. package/dist/image-editor/selection/segment/grabcut.d.ts +4 -2
  45. package/dist/image-editor/selection/segment/sky.d.cts +2 -0
  46. package/dist/image-editor/selection/segment/sky.d.ts +2 -0
  47. package/dist/image-editor/selection/segment/subject.d.cts +2 -1
  48. package/dist/image-editor/selection/segment/subject.d.ts +2 -1
  49. package/dist/image-editor/selection/segment/work.d.cts +5 -0
  50. package/dist/image-editor/selection/segment/work.d.ts +5 -0
  51. package/dist/image-editor/selection/select-and-mask.d.cts +12 -2
  52. package/dist/image-editor/selection/select-and-mask.d.ts +12 -2
  53. package/dist/image-editor/selection/worker.d.cts +126 -0
  54. package/dist/image-editor/selection/worker.d.ts +126 -0
  55. package/dist/image-editor/selection-worker.cjs +14 -0
  56. package/dist/image-editor/selection-worker.d.cts +12 -0
  57. package/dist/image-editor/selection-worker.d.ts +12 -0
  58. package/dist/image-editor/selection-worker.js +14 -0
  59. package/dist/image-editor/types.d.cts +8 -0
  60. package/dist/image-editor/types.d.ts +8 -0
  61. package/dist/paint/index.cjs +6 -5
  62. package/dist/paint/index.js +5 -4
  63. package/dist/paint-editor/index.cjs +394 -390
  64. package/dist/paint-editor/index.js +18 -14
  65. package/dist/raster/index.cjs +22 -18
  66. package/dist/raster/index.js +29 -25
  67. package/dist/vector/index.cjs +986 -985
  68. package/dist/vector/index.js +6 -5
  69. package/package.json +11 -1
@@ -16,3 +16,4 @@ export * from './magnetic.cjs';
16
16
  export * from './segment/index.cjs';
17
17
  export * from './refine-edits.cjs';
18
18
  export * from './select-and-mask.cjs';
19
+ export * from './worker.cjs';
@@ -16,3 +16,4 @@ export * from './magnetic.js';
16
16
  export * from './segment/index.js';
17
17
  export * from './refine-edits.js';
18
18
  export * from './select-and-mask.js';
19
+ export * from './worker.js';
@@ -5,6 +5,7 @@
5
5
  * and fitted to the image's edges with a guided filter.
6
6
  */
7
7
  import type { PixelBuffer, SelectionMask } from '../mask.cjs';
8
+ import { type SelectionProgress } from './work.cjs';
8
9
  export interface FocusAreaOptions {
9
10
  /** In-Focus Range 0..100 (default 50): higher takes in less sharp areas too. */
10
11
  range?: number;
@@ -12,6 +13,7 @@ export interface FocusAreaOptions {
12
13
  noise?: number;
13
14
  /** Soften the edge over this many natural pixels (default 4; 0 for a hard edge). */
14
15
  softness?: number;
16
+ onProgress?: SelectionProgress;
15
17
  }
16
18
  export interface FocusAreaResult {
17
19
  selection: SelectionMask;
@@ -5,6 +5,7 @@
5
5
  * and fitted to the image's edges with a guided filter.
6
6
  */
7
7
  import type { PixelBuffer, SelectionMask } from '../mask.js';
8
+ import { type SelectionProgress } from './work.js';
8
9
  export interface FocusAreaOptions {
9
10
  /** In-Focus Range 0..100 (default 50): higher takes in less sharp areas too. */
10
11
  range?: number;
@@ -12,6 +13,7 @@ export interface FocusAreaOptions {
12
13
  noise?: number;
13
14
  /** Soften the edge over this many natural pixels (default 4; 0 for a hard edge). */
14
15
  softness?: number;
16
+ onProgress?: SelectionProgress;
15
17
  }
16
18
  export interface FocusAreaResult {
17
19
  selection: SelectionMask;
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import type { CropBox, ImagePoint } from '../../types.cjs';
9
9
  import { type PixelBuffer, type SelectionMask } from '../mask.cjs';
10
- import { type Rect, type WorkImage } from './work.cjs';
10
+ import { type Rect, type SelectionProgress, type WorkImage } from './work.cjs';
11
11
  /** A mixture of {@link K} full-covariance Gaussians over RGB. */
12
12
  export declare class ColorGmm {
13
13
  private readonly logWeight;
@@ -36,7 +36,8 @@ export interface GrabCutSetup {
36
36
  hardFg: Uint8Array | null;
37
37
  }
38
38
  /** GrabCut over the setup's window; returns 1 for the object per window pixel. */
39
- export declare function grabCutLabels(work: WorkImage, setup: GrabCutSetup, iterations: number): Uint8Array;
39
+ /** GrabCut over the setup's window; `onRound` is called after each round with the share done. */
40
+ export declare function grabCutLabels(work: WorkImage, setup: GrabCutSetup, iterations: number, onRound?: (fraction: number) => void): Uint8Array;
40
41
  /**
41
42
  * Keeps the object's main parts: the pieces (4-connected) holding `seed` (window index), or
42
43
  * without one, every piece at least a fifth the size of the largest.
@@ -47,6 +48,7 @@ export interface ObjectSelectionOptions {
47
48
  enhanceEdge?: boolean;
48
49
  /** Most rounds of fitting and cutting (default 5; it stops early once the labels settle). */
49
50
  iterations?: number;
51
+ onProgress?: SelectionProgress;
50
52
  }
51
53
  /** What to select: a box around the object, or a point on it (natural pixels). */
52
54
  export type ObjectTarget = {
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import type { CropBox, ImagePoint } from '../../types.js';
9
9
  import { type PixelBuffer, type SelectionMask } from '../mask.js';
10
- import { type Rect, type WorkImage } from './work.js';
10
+ import { type Rect, type SelectionProgress, type WorkImage } from './work.js';
11
11
  /** A mixture of {@link K} full-covariance Gaussians over RGB. */
12
12
  export declare class ColorGmm {
13
13
  private readonly logWeight;
@@ -36,7 +36,8 @@ export interface GrabCutSetup {
36
36
  hardFg: Uint8Array | null;
37
37
  }
38
38
  /** GrabCut over the setup's window; returns 1 for the object per window pixel. */
39
- export declare function grabCutLabels(work: WorkImage, setup: GrabCutSetup, iterations: number): Uint8Array;
39
+ /** GrabCut over the setup's window; `onRound` is called after each round with the share done. */
40
+ export declare function grabCutLabels(work: WorkImage, setup: GrabCutSetup, iterations: number, onRound?: (fraction: number) => void): Uint8Array;
40
41
  /**
41
42
  * Keeps the object's main parts: the pieces (4-connected) holding `seed` (window index), or
42
43
  * without one, every piece at least a fifth the size of the largest.
@@ -47,6 +48,7 @@ export interface ObjectSelectionOptions {
47
48
  enhanceEdge?: boolean;
48
49
  /** Most rounds of fitting and cutting (default 5; it stops early once the labels settle). */
49
50
  iterations?: number;
51
+ onProgress?: SelectionProgress;
50
52
  }
51
53
  /** What to select: a box around the object, or a point on it (natural pixels). */
52
54
  export type ObjectTarget = {
@@ -6,11 +6,13 @@
6
6
  * with the colour guided filter.
7
7
  */
8
8
  import { type PixelBuffer, type SelectionMask } from '../mask.cjs';
9
+ import { type SelectionProgress } from './work.cjs';
9
10
  export interface SkyOptions {
10
11
  /** 0..100 (default 50): higher takes in less sky-like pixels (haze, a sunset glow). */
11
12
  threshold?: number;
12
13
  /** Soften the edge over this many natural pixels (default 4; 0 for a hard edge). */
13
14
  softness?: number;
15
+ onProgress?: SelectionProgress;
14
16
  }
15
17
  export interface FoundSky {
16
18
  selection: SelectionMask;
@@ -6,11 +6,13 @@
6
6
  * with the colour guided filter.
7
7
  */
8
8
  import { type PixelBuffer, type SelectionMask } from '../mask.js';
9
+ import { type SelectionProgress } from './work.js';
9
10
  export interface SkyOptions {
10
11
  /** 0..100 (default 50): higher takes in less sky-like pixels (haze, a sunset glow). */
11
12
  threshold?: number;
12
13
  /** Soften the edge over this many natural pixels (default 4; 0 for a hard edge). */
13
14
  softness?: number;
15
+ onProgress?: SelectionProgress;
14
16
  }
15
17
  export interface FoundSky {
16
18
  selection: SelectionMask;
@@ -12,7 +12,7 @@
12
12
  * It cannot tell which object a description names: it selects what stands out.
13
13
  */
14
14
  import type { PixelBuffer, SelectionMask } from '../mask.cjs';
15
- import { type WorkImage } from './work.cjs';
15
+ import { type SelectionProgress, type WorkImage } from './work.cjs';
16
16
  export interface Superpixels {
17
17
  /** Superpixel of each work pixel. */
18
18
  label: Int32Array;
@@ -41,4 +41,5 @@ export interface FoundSubject {
41
41
  */
42
42
  export declare function findSubject(pixels: PixelBuffer, options?: {
43
43
  enhanceEdge?: boolean;
44
+ onProgress?: SelectionProgress;
44
45
  }): FoundSubject;
@@ -12,7 +12,7 @@
12
12
  * It cannot tell which object a description names: it selects what stands out.
13
13
  */
14
14
  import type { PixelBuffer, SelectionMask } from '../mask.js';
15
- import { type WorkImage } from './work.js';
15
+ import { type SelectionProgress, type WorkImage } from './work.js';
16
16
  export interface Superpixels {
17
17
  /** Superpixel of each work pixel. */
18
18
  label: Int32Array;
@@ -41,4 +41,5 @@ export interface FoundSubject {
41
41
  */
42
42
  export declare function findSubject(pixels: PixelBuffer, options?: {
43
43
  enhanceEdge?: boolean;
44
+ onProgress?: SelectionProgress;
44
45
  }): FoundSubject;
@@ -3,6 +3,11 @@
3
3
  * Area) work on, and scaling their result back up to the image.
4
4
  */
5
5
  import { type PixelBuffer, type SelectionMask } from '../mask.cjs';
6
+ /**
7
+ * Progress of a long selection: `fraction` 0..1 done and what it is doing. The segmentations call
8
+ * it between their stages; in a worker it is posted back to the page.
9
+ */
10
+ export type SelectionProgress = (fraction: number, stage: string) => void;
6
11
  /** The reduced image the segmentations work on (sRGB, 0..255 per channel). */
7
12
  export interface WorkImage {
8
13
  /** Natural size of the image it was made from. */
@@ -3,6 +3,11 @@
3
3
  * Area) work on, and scaling their result back up to the image.
4
4
  */
5
5
  import { type PixelBuffer, type SelectionMask } from '../mask.js';
6
+ /**
7
+ * Progress of a long selection: `fraction` 0..1 done and what it is doing. The segmentations call
8
+ * it between their stages; in a worker it is posted back to the page.
9
+ */
10
+ export type SelectionProgress = (fraction: number, stage: string) => void;
6
11
  /** The reduced image the segmentations work on (sRGB, 0..255 per channel). */
7
12
  export interface WorkImage {
8
13
  /** Natural size of the image it was made from. */
@@ -5,7 +5,8 @@
5
5
  * the workspace and an agent produce the same result in one undo step.
6
6
  *
7
7
  * The preview is computed on a copy reduced to {@link PREVIEW_SIZE} px (or at full size with High
8
- * Quality Preview) and drawn as RGBA in the chosen view mode.
8
+ * Quality Preview), in the controller's selection worker when it has one, and drawn as RGBA in
9
+ * the chosen view mode.
9
10
  */
10
11
  import type { ImageEditorController, RefineOutput, RefineOutputResult } from '../controller.cjs';
11
12
  import type { ImagePoint } from '../types.cjs';
@@ -72,6 +73,9 @@ export declare class SelectAndMaskSession {
72
73
  note: string | null;
73
74
  /** Bumped each time the preview changes, so a UI can redraw. */
74
75
  revision: number;
76
+ /** True while the worker computes a preview. */
77
+ computing: boolean;
78
+ private dirty;
75
79
  constructor(controller: ImageEditorController);
76
80
  get settings(): SelectAndMaskSettings;
77
81
  get edits(): readonly RefineEdit[];
@@ -88,8 +92,14 @@ export declare class SelectAndMaskSession {
88
92
  /** Changes settings; the preview follows. Choosing a view also sets its usual opacity. */
89
93
  update(changes: Partial<SelectAndMaskSettings>): void;
90
94
  private rescale;
91
- /** Recomputes the preview mask from the base selection, the strokes and the settings. */
95
+ /**
96
+ * Recomputes the preview mask from the base selection, the strokes and the settings: at once on
97
+ * the page, or in the worker, where one job runs at a time and the newest state follows it.
98
+ */
92
99
  recompute(): void;
100
+ private recomputeInWorker;
101
+ /** Resolves once no preview is being computed (immediately without a worker). */
102
+ idle(): Promise<void>;
93
103
  /** Coverage 0..1 of the preview at (x, y) in preview pixels (for tests and hover readouts). */
94
104
  coverageAt(x: number, y: number): number;
95
105
  /** The preview drawn in the current view mode: RGBA at {@link previewSize}. */
@@ -5,7 +5,8 @@
5
5
  * the workspace and an agent produce the same result in one undo step.
6
6
  *
7
7
  * The preview is computed on a copy reduced to {@link PREVIEW_SIZE} px (or at full size with High
8
- * Quality Preview) and drawn as RGBA in the chosen view mode.
8
+ * Quality Preview), in the controller's selection worker when it has one, and drawn as RGBA in
9
+ * the chosen view mode.
9
10
  */
10
11
  import type { ImageEditorController, RefineOutput, RefineOutputResult } from '../controller.js';
11
12
  import type { ImagePoint } from '../types.js';
@@ -72,6 +73,9 @@ export declare class SelectAndMaskSession {
72
73
  note: string | null;
73
74
  /** Bumped each time the preview changes, so a UI can redraw. */
74
75
  revision: number;
76
+ /** True while the worker computes a preview. */
77
+ computing: boolean;
78
+ private dirty;
75
79
  constructor(controller: ImageEditorController);
76
80
  get settings(): SelectAndMaskSettings;
77
81
  get edits(): readonly RefineEdit[];
@@ -88,8 +92,14 @@ export declare class SelectAndMaskSession {
88
92
  /** Changes settings; the preview follows. Choosing a view also sets its usual opacity. */
89
93
  update(changes: Partial<SelectAndMaskSettings>): void;
90
94
  private rescale;
91
- /** Recomputes the preview mask from the base selection, the strokes and the settings. */
95
+ /**
96
+ * Recomputes the preview mask from the base selection, the strokes and the settings: at once on
97
+ * the page, or in the worker, where one job runs at a time and the newest state follows it.
98
+ */
92
99
  recompute(): void;
100
+ private recomputeInWorker;
101
+ /** Resolves once no preview is being computed (immediately without a worker). */
102
+ idle(): Promise<void>;
93
103
  /** Coverage 0..1 of the preview at (x, y) in preview pixels (for tests and hover readouts). */
94
104
  coverageAt(x: number, y: number): number;
95
105
  /** The preview drawn in the current view mode: RGBA at {@link previewSize}. */
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Running the long selections (Select Subject, Object Selection, Focus Area, Select Sky, Quick
3
+ * Selection strokes and the Select and Mask preview) off the page in a Web Worker, with progress
4
+ * and cancelling.
5
+ *
6
+ * - `runSelectionJob` does one job synchronously; the worker and the page's fallback both use it.
7
+ * - `startSelectionWorker` answers jobs inside a worker (the `selection-worker` entry calls it).
8
+ * - `SelectionWorkerClient` sends jobs from the page. The image is sent once per pixel buffer and
9
+ * kept in the worker; masks travel as their bounds and bytes. Cancelling terminates the worker
10
+ * (a running job can't be interrupted otherwise) and the next job starts a fresh one.
11
+ */
12
+ import type { CropBox, ImagePoint } from '../types.cjs';
13
+ import { type PixelBuffer, type SelectionMask } from './mask.cjs';
14
+ import { type RefineEdgeParams } from './refine.cjs';
15
+ import { type RefineEdit } from './refine-edits.cjs';
16
+ import { type FocusAreaOptions } from './segment/focus.cjs';
17
+ import { type ObjectTarget } from './segment/grabcut.cjs';
18
+ import { type SkyOptions } from './segment/sky.cjs';
19
+ import type { SelectionProgress } from './segment/work.cjs';
20
+ /** A selection as plain data: its size, bounds and the bytes inside the bounds. */
21
+ export interface SerializedMask {
22
+ width: number;
23
+ height: number;
24
+ bounds: CropBox | null;
25
+ bytes: Uint8Array;
26
+ }
27
+ export declare function serializeMask(mask: SelectionMask): SerializedMask;
28
+ export declare function deserializeMask(s: SerializedMask): SelectionMask;
29
+ /** One long selection, as data. */
30
+ export type SelectionJob = {
31
+ op: 'subject';
32
+ enhanceEdge?: boolean;
33
+ } | {
34
+ op: 'object';
35
+ target: ObjectTarget;
36
+ enhanceEdge?: boolean;
37
+ } | {
38
+ op: 'focus';
39
+ options?: Omit<FocusAreaOptions, 'onProgress'>;
40
+ } | {
41
+ op: 'sky';
42
+ options?: Omit<SkyOptions, 'onProgress'>;
43
+ } | {
44
+ op: 'quick';
45
+ stroke: ImagePoint[];
46
+ size?: number;
47
+ grow?: boolean;
48
+ enhanceEdge?: boolean;
49
+ selection?: SerializedMask | null;
50
+ } | {
51
+ op: 'refine-preview';
52
+ base: SerializedMask | null;
53
+ edits: RefineEdit[];
54
+ params: RefineEdgeParams;
55
+ };
56
+ /** What a job found: a selection of the whole image, and the job's notes. */
57
+ export interface SelectionJobResult {
58
+ mask: SelectionMask;
59
+ /** Why nothing was selected (subject, sky). */
60
+ reason?: string;
61
+ /** Focus Area: the noise level it measured. */
62
+ noiseLevel?: number;
63
+ }
64
+ /** Runs `job` on `pixels` here and now. */
65
+ export declare function runSelectionJob(job: SelectionJob, pixels: PixelBuffer, onProgress?: SelectionProgress): SelectionJobResult;
66
+ /** Messages from the page to the worker. */
67
+ export type SelectionWorkerRequest = {
68
+ type: 'pixels';
69
+ key: number;
70
+ pixels: PixelBuffer;
71
+ } | {
72
+ type: 'job';
73
+ id: number;
74
+ key: number;
75
+ job: SelectionJob;
76
+ };
77
+ /** Messages from the worker to the page. */
78
+ export type SelectionWorkerResponse = {
79
+ type: 'progress';
80
+ id: number;
81
+ fraction: number;
82
+ stage: string;
83
+ } | {
84
+ type: 'done';
85
+ id: number;
86
+ mask: SerializedMask;
87
+ reason?: string;
88
+ noiseLevel?: number;
89
+ } | {
90
+ type: 'error';
91
+ id: number;
92
+ message: string;
93
+ };
94
+ /**
95
+ * The part of a worker (or its global scope) the protocol uses; a DOM `Worker` is one. The event
96
+ * parameters are loose so a `Worker`'s `MessageEvent` / `ErrorEvent` handlers fit.
97
+ */
98
+ export interface SelectionWorkerLike {
99
+ postMessage(message: unknown, transfer?: Transferable[]): void;
100
+ onmessage: ((event: any) => void) | null;
101
+ onerror?: ((event: any) => void) | null;
102
+ terminate?(): void;
103
+ }
104
+ /** Makes a fresh selection worker, e.g. `() => new SelectionWorker()` with Vite's `?worker`. */
105
+ export type SelectionWorkerFactory = () => SelectionWorkerLike;
106
+ /** Answers selection jobs inside a worker: `scope` is the worker's global (`self`). */
107
+ export declare function startSelectionWorker(scope: SelectionWorkerLike): void;
108
+ /** Sends selection jobs to a worker made by `factory`, one worker at a time. */
109
+ export declare class SelectionWorkerClient {
110
+ private readonly factory;
111
+ private worker;
112
+ /** Pixel buffers this worker already has, by their data array. */
113
+ private sent;
114
+ private nextKey;
115
+ private nextId;
116
+ private readonly pending;
117
+ constructor(factory: SelectionWorkerFactory);
118
+ /** Runs `job` on `pixels` in the worker. Aborting `signal` terminates the worker and rejects with an `AbortError`. */
119
+ run(job: SelectionJob, pixels: PixelBuffer, options?: {
120
+ signal?: AbortSignal;
121
+ onProgress?: SelectionProgress;
122
+ }): Promise<SelectionJobResult>;
123
+ /** Stops the worker; jobs still running reject with `reason` (default an `AbortError`). */
124
+ terminate(reason?: unknown): void;
125
+ private ensure;
126
+ }
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Running the long selections (Select Subject, Object Selection, Focus Area, Select Sky, Quick
3
+ * Selection strokes and the Select and Mask preview) off the page in a Web Worker, with progress
4
+ * and cancelling.
5
+ *
6
+ * - `runSelectionJob` does one job synchronously; the worker and the page's fallback both use it.
7
+ * - `startSelectionWorker` answers jobs inside a worker (the `selection-worker` entry calls it).
8
+ * - `SelectionWorkerClient` sends jobs from the page. The image is sent once per pixel buffer and
9
+ * kept in the worker; masks travel as their bounds and bytes. Cancelling terminates the worker
10
+ * (a running job can't be interrupted otherwise) and the next job starts a fresh one.
11
+ */
12
+ import type { CropBox, ImagePoint } from '../types.js';
13
+ import { type PixelBuffer, type SelectionMask } from './mask.js';
14
+ import { type RefineEdgeParams } from './refine.js';
15
+ import { type RefineEdit } from './refine-edits.js';
16
+ import { type FocusAreaOptions } from './segment/focus.js';
17
+ import { type ObjectTarget } from './segment/grabcut.js';
18
+ import { type SkyOptions } from './segment/sky.js';
19
+ import type { SelectionProgress } from './segment/work.js';
20
+ /** A selection as plain data: its size, bounds and the bytes inside the bounds. */
21
+ export interface SerializedMask {
22
+ width: number;
23
+ height: number;
24
+ bounds: CropBox | null;
25
+ bytes: Uint8Array;
26
+ }
27
+ export declare function serializeMask(mask: SelectionMask): SerializedMask;
28
+ export declare function deserializeMask(s: SerializedMask): SelectionMask;
29
+ /** One long selection, as data. */
30
+ export type SelectionJob = {
31
+ op: 'subject';
32
+ enhanceEdge?: boolean;
33
+ } | {
34
+ op: 'object';
35
+ target: ObjectTarget;
36
+ enhanceEdge?: boolean;
37
+ } | {
38
+ op: 'focus';
39
+ options?: Omit<FocusAreaOptions, 'onProgress'>;
40
+ } | {
41
+ op: 'sky';
42
+ options?: Omit<SkyOptions, 'onProgress'>;
43
+ } | {
44
+ op: 'quick';
45
+ stroke: ImagePoint[];
46
+ size?: number;
47
+ grow?: boolean;
48
+ enhanceEdge?: boolean;
49
+ selection?: SerializedMask | null;
50
+ } | {
51
+ op: 'refine-preview';
52
+ base: SerializedMask | null;
53
+ edits: RefineEdit[];
54
+ params: RefineEdgeParams;
55
+ };
56
+ /** What a job found: a selection of the whole image, and the job's notes. */
57
+ export interface SelectionJobResult {
58
+ mask: SelectionMask;
59
+ /** Why nothing was selected (subject, sky). */
60
+ reason?: string;
61
+ /** Focus Area: the noise level it measured. */
62
+ noiseLevel?: number;
63
+ }
64
+ /** Runs `job` on `pixels` here and now. */
65
+ export declare function runSelectionJob(job: SelectionJob, pixels: PixelBuffer, onProgress?: SelectionProgress): SelectionJobResult;
66
+ /** Messages from the page to the worker. */
67
+ export type SelectionWorkerRequest = {
68
+ type: 'pixels';
69
+ key: number;
70
+ pixels: PixelBuffer;
71
+ } | {
72
+ type: 'job';
73
+ id: number;
74
+ key: number;
75
+ job: SelectionJob;
76
+ };
77
+ /** Messages from the worker to the page. */
78
+ export type SelectionWorkerResponse = {
79
+ type: 'progress';
80
+ id: number;
81
+ fraction: number;
82
+ stage: string;
83
+ } | {
84
+ type: 'done';
85
+ id: number;
86
+ mask: SerializedMask;
87
+ reason?: string;
88
+ noiseLevel?: number;
89
+ } | {
90
+ type: 'error';
91
+ id: number;
92
+ message: string;
93
+ };
94
+ /**
95
+ * The part of a worker (or its global scope) the protocol uses; a DOM `Worker` is one. The event
96
+ * parameters are loose so a `Worker`'s `MessageEvent` / `ErrorEvent` handlers fit.
97
+ */
98
+ export interface SelectionWorkerLike {
99
+ postMessage(message: unknown, transfer?: Transferable[]): void;
100
+ onmessage: ((event: any) => void) | null;
101
+ onerror?: ((event: any) => void) | null;
102
+ terminate?(): void;
103
+ }
104
+ /** Makes a fresh selection worker, e.g. `() => new SelectionWorker()` with Vite's `?worker`. */
105
+ export type SelectionWorkerFactory = () => SelectionWorkerLike;
106
+ /** Answers selection jobs inside a worker: `scope` is the worker's global (`self`). */
107
+ export declare function startSelectionWorker(scope: SelectionWorkerLike): void;
108
+ /** Sends selection jobs to a worker made by `factory`, one worker at a time. */
109
+ export declare class SelectionWorkerClient {
110
+ private readonly factory;
111
+ private worker;
112
+ /** Pixel buffers this worker already has, by their data array. */
113
+ private sent;
114
+ private nextKey;
115
+ private nextId;
116
+ private readonly pending;
117
+ constructor(factory: SelectionWorkerFactory);
118
+ /** Runs `job` on `pixels` in the worker. Aborting `signal` terminates the worker and rejects with an `AbortError`. */
119
+ run(job: SelectionJob, pixels: PixelBuffer, options?: {
120
+ signal?: AbortSignal;
121
+ onProgress?: SelectionProgress;
122
+ }): Promise<SelectionJobResult>;
123
+ /** Stops the worker; jobs still running reject with `reason` (default an `AbortError`). */
124
+ terminate(reason?: unknown): void;
125
+ private ensure;
126
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+ var _chunkX4LUGTQXcjs = require('../chunk-X4LUGTQX.cjs');
4
+ require('../chunk-QYLWG22N.cjs');
5
+ require('../chunk-K6PXS6DO.cjs');
6
+ require('../chunk-474IQG74.cjs');
7
+
8
+ // src/image-editor/selection-worker.ts
9
+ if (typeof self !== "undefined" && typeof window === "undefined" && typeof self.postMessage === "function") {
10
+ _chunkX4LUGTQXcjs.startSelectionWorker.call(void 0, self);
11
+ }
12
+
13
+
14
+ exports.startSelectionWorker = _chunkX4LUGTQXcjs.startSelectionWorker;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The selection worker's entry: load it as a module worker and give the controller a factory, e.g.
3
+ * with Vite
4
+ *
5
+ * import SelectionWorker from '@pixerate/editor/image-editor/selection-worker?worker';
6
+ * controller.setSelectionWorker(() => new SelectionWorker());
7
+ *
8
+ * Outside a worker (Node, a page importing it by mistake) it does nothing. It also exports
9
+ * `startSelectionWorker`, for a host that writes its own worker file.
10
+ */
11
+ import { startSelectionWorker } from './selection/worker.cjs';
12
+ export { startSelectionWorker };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The selection worker's entry: load it as a module worker and give the controller a factory, e.g.
3
+ * with Vite
4
+ *
5
+ * import SelectionWorker from '@pixerate/editor/image-editor/selection-worker?worker';
6
+ * controller.setSelectionWorker(() => new SelectionWorker());
7
+ *
8
+ * Outside a worker (Node, a page importing it by mistake) it does nothing. It also exports
9
+ * `startSelectionWorker`, for a host that writes its own worker file.
10
+ */
11
+ import { startSelectionWorker } from './selection/worker.js';
12
+ export { startSelectionWorker };
@@ -0,0 +1,14 @@
1
+ import {
2
+ startSelectionWorker
3
+ } from "../chunk-DWYQPL2A.js";
4
+ import "../chunk-L3G23N5Y.js";
5
+ import "../chunk-ZIF4UJJ6.js";
6
+ import "../chunk-HVVR5PZW.js";
7
+
8
+ // src/image-editor/selection-worker.ts
9
+ if (typeof self !== "undefined" && typeof window === "undefined" && typeof self.postMessage === "function") {
10
+ startSelectionWorker(self);
11
+ }
12
+ export {
13
+ startSelectionWorker
14
+ };
@@ -1,3 +1,4 @@
1
+ import type { SelectionWorkerFactory } from './selection/worker.cjs';
1
2
  import type { GlobalLight } from '../raster/effects/model.cjs';
2
3
  import type { EffectPattern } from '../raster/effects/patterns.cjs';
3
4
  import type { BlendMode } from './blend.cjs';
@@ -448,6 +449,13 @@ export interface ImageEditorOptions {
448
449
  * `setSegmentationProvider`.
449
450
  */
450
451
  segmentation?: SegmentationProvider | null;
452
+ /**
453
+ * Makes the Web Worker the long selections run in (Select Subject, Object Selection, Focus
454
+ * Area, Select Sky, Quick Selection, the Select and Mask preview), e.g. with Vite
455
+ * `() => new SelectionWorker()` from `@pixerate/editor/image-editor/selection-worker?worker`.
456
+ * Without one they run on the page. Change it later with `setSelectionWorker`.
457
+ */
458
+ selectionWorker?: SelectionWorkerFactory | null;
451
459
  }
452
460
  export interface InpaintOptions {
453
461
  prompt: string;
@@ -1,3 +1,4 @@
1
+ import type { SelectionWorkerFactory } from './selection/worker.js';
1
2
  import type { GlobalLight } from '../raster/effects/model.js';
2
3
  import type { EffectPattern } from '../raster/effects/patterns.js';
3
4
  import type { BlendMode } from './blend.js';
@@ -448,6 +449,13 @@ export interface ImageEditorOptions {
448
449
  * `setSegmentationProvider`.
449
450
  */
450
451
  segmentation?: SegmentationProvider | null;
452
+ /**
453
+ * Makes the Web Worker the long selections run in (Select Subject, Object Selection, Focus
454
+ * Area, Select Sky, Quick Selection, the Select and Mask preview), e.g. with Vite
455
+ * `() => new SelectionWorker()` from `@pixerate/editor/image-editor/selection-worker?worker`.
456
+ * Without one they run on the page. Change it later with `setSelectionWorker`.
457
+ */
458
+ selectionWorker?: SelectionWorkerFactory | null;
451
459
  }
452
460
  export interface InpaintOptions {
453
461
  prompt: string;