@vibrant/core
Advanced tools
Comparing version 3.2.1-alpha.1 to 4.0.0-alpha.1
{ | ||
"name": "@vibrant/core", | ||
"version": "3.2.1-alpha.1", | ||
"version": "4.0.0-alpha.1", | ||
"description": "Core vibrant classes", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "vitest run", | ||
"test:watch": "vitest watch", | ||
"build": "vite build" | ||
}, | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"type": "module", | ||
"types": "dist/esm/index.d.ts", | ||
"main": "dist/cjs/index.cjs", | ||
"module": "dist/esm/index.js", | ||
"exports": { | ||
".": { | ||
"import": { | ||
"types": "./dist/esm/index.d.ts", | ||
"default": "./dist/esm/index.js" | ||
}, | ||
"require": { | ||
"types": "./dist/cjs/index.d.cts", | ||
"default": "./dist/cjs/index.cjs" | ||
} | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"sideEffects": false, | ||
"files": [ | ||
"dist", | ||
"src" | ||
], | ||
"author": { | ||
@@ -20,11 +42,14 @@ "name": "akfish", | ||
"dependencies": { | ||
"@vibrant/color": "^3.2.1-alpha.1", | ||
"@vibrant/generator": "^3.2.1-alpha.1", | ||
"@vibrant/image": "^3.2.1-alpha.1", | ||
"@vibrant/quantizer": "^3.2.1-alpha.1", | ||
"@vibrant/types": "^3.2.1-alpha.1", | ||
"@vibrant/worker": "^3.2.1-alpha.1" | ||
"@vibrant/color": "^4.0.0-alpha.1", | ||
"@vibrant/generator": "^4.0.0-alpha.1", | ||
"@vibrant/image": "^4.0.0-alpha.1", | ||
"@vibrant/quantizer": "^4.0.0-alpha.1", | ||
"@vibrant/types": "^4.0.0-alpha.1", | ||
"@vibrant/worker": "^4.0.0-alpha.1" | ||
}, | ||
"devDependencies": { | ||
"typescript": "^3.7.2" | ||
"@tanstack/config": "^0.14.2", | ||
"typescript": "^4.5.2", | ||
"vite": "^6.0.3", | ||
"vitest": "^2.1.8" | ||
}, | ||
@@ -34,3 +59,3 @@ "publishConfig": { | ||
}, | ||
"gitHead": "e667d4c12e1de66e251d451710b093e9cb4630c2" | ||
"gitHead": "968ad565c625279b5d3e2baf3e5da7f764551ade" | ||
} |
@@ -1,90 +0,82 @@ | ||
import { | ||
Options | ||
} from './options' | ||
import { | ||
Callback | ||
} from '@vibrant/types' | ||
import { | ||
ImageClass, | ||
ImageSource | ||
} from '@vibrant/image' | ||
import { Options } from "./options"; | ||
import { Callback } from "@vibrant/types"; | ||
import { ImageClass, ImageSource } from "@vibrant/image"; | ||
import { | ||
Filter, | ||
Palette | ||
} from '@vibrant/color' | ||
import Vibrant from './' | ||
import { assignDeep } from './utils' | ||
import { Filter, Palette } from "@vibrant/color"; | ||
import Vibrant from "./"; | ||
import { assignDeep } from "./utils"; | ||
export default class Builder { | ||
private _src: ImageSource | ||
private _opts: Partial<Options> | ||
constructor (src: ImageSource, opts: Partial<Options> = {}) { | ||
this._src = src | ||
this._opts = assignDeep({}, Vibrant.DefaultOpts, opts) | ||
private _src: ImageSource; | ||
private _opts: Partial<Options>; | ||
constructor(src: ImageSource, opts: Partial<Options> = {}) { | ||
this._src = src; | ||
this._opts = assignDeep({}, Vibrant.DefaultOpts, opts); | ||
} | ||
maxColorCount (n: number): Builder { | ||
this._opts.colorCount = n | ||
return this | ||
maxColorCount(n: number): Builder { | ||
this._opts.colorCount = n; | ||
return this; | ||
} | ||
maxDimension (d: number): Builder { | ||
this._opts.maxDimension = d | ||
return this | ||
maxDimension(d: number): Builder { | ||
this._opts.maxDimension = d; | ||
return this; | ||
} | ||
addFilter (name: string): Builder { | ||
addFilter(name: string): Builder { | ||
if (!this._opts.filters) { | ||
this._opts.filters = [name] | ||
this._opts.filters = [name]; | ||
} else { | ||
this._opts.filters.push(name) | ||
this._opts.filters.push(name); | ||
} | ||
return this | ||
return this; | ||
} | ||
removeFilter (name: string): Builder { | ||
removeFilter(name: string): Builder { | ||
if (this._opts.filters) { | ||
let i = this._opts.filters.indexOf(name) | ||
if (i > 0) this._opts.filters.splice(i) | ||
const i = this._opts.filters.indexOf(name); | ||
if (i > 0) this._opts.filters.splice(i); | ||
} | ||
return this | ||
return this; | ||
} | ||
clearFilters (): Builder { | ||
this._opts.filters = [] | ||
return this | ||
clearFilters(): Builder { | ||
this._opts.filters = []; | ||
return this; | ||
} | ||
quality (q: number): Builder { | ||
this._opts.quality = q | ||
return this | ||
quality(q: number): Builder { | ||
this._opts.quality = q; | ||
return this; | ||
} | ||
useImageClass (imageClass: ImageClass): Builder { | ||
this._opts.ImageClass = imageClass | ||
return this | ||
useImageClass(imageClass: ImageClass): Builder { | ||
this._opts.ImageClass = imageClass; | ||
return this; | ||
} | ||
useGenerator (generator: string, options?: any): Builder { | ||
if (!this._opts.generators) this._opts.generators = [] | ||
this._opts.generators.push(options ? { name: generator, options } : generator) | ||
return this | ||
useGenerator(generator: string, options?: any): Builder { | ||
if (!this._opts.generators) this._opts.generators = []; | ||
this._opts.generators.push( | ||
options ? { name: generator, options } : generator | ||
); | ||
return this; | ||
} | ||
useQuantizer (quantizer: string, options?: any): Builder { | ||
this._opts.quantizer = options ? { name: quantizer, options } : quantizer | ||
return this | ||
useQuantizer(quantizer: string, options?: any): Builder { | ||
this._opts.quantizer = options ? { name: quantizer, options } : quantizer; | ||
return this; | ||
} | ||
build (): Vibrant { | ||
return new Vibrant(this._src, this._opts) | ||
build(): Vibrant { | ||
return new Vibrant(this._src, this._opts); | ||
} | ||
getPalette (cb?: Callback<Palette>): Promise<Palette> { | ||
return this.build().getPalette(cb) | ||
getPalette(cb?: Callback<Palette>): Promise<Palette> { | ||
return this.build().getPalette(cb); | ||
} | ||
getSwatches (cb?: Callback<Palette>): Promise<Palette> { | ||
return this.build().getPalette(cb) | ||
getSwatches(cb?: Callback<Palette>): Promise<Palette> { | ||
return this.build().getPalette(cb); | ||
} | ||
} |
162
src/index.ts
@@ -1,127 +0,139 @@ | ||
import { Options, buildProcessOptions } from './options' | ||
import { Callback } from '@vibrant/types' | ||
import { Image, ImageSource } from '@vibrant/image' | ||
import { buildProcessOptions, Options } from "./options"; | ||
import { Callback } from "@vibrant/types"; | ||
import { Image, ImageSource } from "@vibrant/image"; | ||
import { Filter, Palette, Swatch } from '@vibrant/color' | ||
import { Palette } from "@vibrant/color"; | ||
import Builder from './builder' | ||
import { Pipeline, ProcessOptions, ProcessResult } from './pipeline' | ||
import { assignDeep } from './utils' | ||
import Builder from "./builder"; | ||
import { Pipeline, ProcessOptions, ProcessResult } from "./pipeline"; | ||
import { assignDeep } from "./utils"; | ||
export interface VibrantStatic { | ||
from (src: ImageSource): Builder | ||
from(src: ImageSource): Builder; | ||
} | ||
export default class Vibrant { | ||
private _result: ProcessResult | ||
private static _pipeline: Pipeline | ||
static use (pipeline: Pipeline) { | ||
this._pipeline = pipeline | ||
private _result: ProcessResult; | ||
private static _pipeline: Pipeline; | ||
static use(pipeline: Pipeline) { | ||
this._pipeline = pipeline; | ||
} | ||
static DefaultOpts: Partial<Options> = { | ||
colorCount: 64, | ||
quality: 5, | ||
filters: [] | ||
filters: [], | ||
}; | ||
static from(src: ImageSource): Builder { | ||
return new Builder(src); | ||
} | ||
static from (src: ImageSource): Builder { | ||
return new Builder(src) | ||
get result() { | ||
return this._result; | ||
} | ||
get result () { | ||
return this._result | ||
opts: Options; | ||
constructor(private _src: ImageSource, opts?: Partial<Options>) { | ||
this.opts = assignDeep({}, Vibrant.DefaultOpts, opts); | ||
} | ||
opts: Options | ||
constructor (private _src: ImageSource, opts?: Partial<Options>) { | ||
this.opts = assignDeep({}, Vibrant.DefaultOpts, opts) | ||
} | ||
private _process ( | ||
private _process( | ||
image: Image, | ||
opts?: Partial<ProcessOptions> | ||
): Promise<ProcessResult> { | ||
let { quantizer } = this.opts | ||
const { quantizer } = this.opts; | ||
image.scaleDown(this.opts) | ||
image.scaleDown(this.opts); | ||
let processOpts = buildProcessOptions(this.opts, opts) | ||
const processOpts = buildProcessOptions(this.opts, opts); | ||
return Vibrant._pipeline.process(image.getImageData(), processOpts) | ||
return Vibrant._pipeline.process(image.getImageData(), processOpts); | ||
} | ||
palette (): Palette { | ||
return this.swatches() | ||
palette(): Palette { | ||
return this.swatches(); | ||
} | ||
swatches (): Palette { | ||
swatches(): Palette { | ||
throw new Error( | ||
'Method deprecated. Use `Vibrant.result.palettes[name]` instead' | ||
) | ||
"Method deprecated. Use `Vibrant.result.palettes[name]` instead" | ||
); | ||
} | ||
getPalette (name: string, cb?: Callback<Palette>): Promise<Palette> | ||
getPalette (cb?: Callback<Palette>): Promise<Palette> | ||
getPalette (): Promise<Palette> { | ||
const arg0 = arguments[0] | ||
const arg1 = arguments[1] | ||
const name = typeof arg0 === 'string' ? arg0 : 'default' | ||
const cb = typeof arg0 === 'string' ? arg1 : arg0 | ||
let image = new this.opts.ImageClass() | ||
getPalette(name: string, cb?: Callback<Palette>): Promise<Palette>; | ||
getPalette(cb?: Callback<Palette>): Promise<Palette>; | ||
getPalette(): Promise<Palette> { | ||
const arg0 = arguments[0]; | ||
const arg1 = arguments[1]; | ||
const name = typeof arg0 === "string" ? arg0 : "default"; | ||
const cb = typeof arg0 === "string" ? arg1 : arg0; | ||
const image = new this.opts.ImageClass(); | ||
return image | ||
.load(this._src) | ||
.then(image => this._process(image, { generators: [name] })) | ||
.then(result => { | ||
this._result = result | ||
return result.palettes[name] | ||
.then((image) => this._process(image, { generators: [name] })) | ||
.then((result) => { | ||
this._result = result; | ||
return result.palettes[name]; | ||
}) | ||
.then(res => { | ||
image.remove() | ||
.then((res) => { | ||
image.remove(); | ||
if (cb) { | ||
cb(undefined, res) | ||
cb(undefined, res); | ||
} | ||
return res | ||
return res; | ||
}) | ||
.catch(err => { | ||
image.remove() | ||
.catch((err) => { | ||
image.remove(); | ||
if (cb) { | ||
cb(err) | ||
cb(err); | ||
} | ||
return Promise.reject(err) | ||
}) | ||
return Promise.reject(err); | ||
}); | ||
} | ||
getPalettes ( | ||
getPalettes( | ||
names: string[], | ||
cb?: Callback<Palette> | ||
): Promise<{ [name: string]: Palette }> | ||
getPalettes (cb?: Callback<Palette>): Promise<{ [name: string]: Palette }> | ||
getPalettes (): Promise<{ [name: string]: Palette }> { | ||
const arg0 = arguments[0] | ||
const arg1 = arguments[1] | ||
const names = Array.isArray(arg0) ? arg0 : ['*'] | ||
const cb = Array.isArray(arg0) ? arg1 : arg0 | ||
let image = new this.opts.ImageClass() | ||
): Promise<{ [name: string]: Palette }>; | ||
getPalettes(cb?: Callback<Palette>): Promise<{ [name: string]: Palette }>; | ||
getPalettes(): Promise<{ [name: string]: Palette }> { | ||
const arg0 = arguments[0]; | ||
const arg1 = arguments[1]; | ||
const names = Array.isArray(arg0) ? arg0 : ["*"]; | ||
const cb = Array.isArray(arg0) ? arg1 : arg0; | ||
const image = new this.opts.ImageClass(); | ||
return image | ||
.load(this._src) | ||
.then(image => | ||
.then((image) => | ||
this._process(image, { | ||
generators: names | ||
generators: names, | ||
}) | ||
) | ||
.then(result => { | ||
this._result = result | ||
return result.palettes | ||
.then((result) => { | ||
this._result = result; | ||
return result.palettes; | ||
}) | ||
.then(res => { | ||
image.remove() | ||
.then((res) => { | ||
image.remove(); | ||
if (cb) { | ||
cb(undefined, res) | ||
cb(undefined, res); | ||
} | ||
return res | ||
return res; | ||
}) | ||
.catch(err => { | ||
image.remove() | ||
.catch((err) => { | ||
image.remove(); | ||
if (cb) { | ||
cb(err) | ||
cb(err); | ||
} | ||
return Promise.reject(err) | ||
}) | ||
return Promise.reject(err); | ||
}); | ||
} | ||
} | ||
export { BasicPipeline } from "./pipeline"; | ||
export { WorkerPipeline } from "./pipeline/worker/client"; | ||
export { runPipelineInWorker } from "./pipeline/worker/host"; | ||
export { Builder }; |
@@ -1,30 +0,38 @@ | ||
import { Palette, Swatch, Filter } from '@vibrant/color' | ||
import { Image, ImageClass, ImageSource, ImageOptions } from '@vibrant/image' | ||
import { Quantizer, QuantizerOptions } from '@vibrant/quantizer' | ||
import { Generator } from '@vibrant/generator' | ||
import { StageOptions, ProcessOptions } from './pipeline' | ||
import { assignDeep } from './utils' | ||
import { Palette, Swatch, Filter } from "@vibrant/color"; | ||
import { Image, ImageClass, ImageSource, ImageOptions } from "@vibrant/image"; | ||
import { Quantizer, QuantizerOptions } from "@vibrant/quantizer"; | ||
import { Generator } from "@vibrant/generator"; | ||
import { StageOptions, ProcessOptions } from "./pipeline"; | ||
import { assignDeep } from "./utils"; | ||
export interface Options extends ImageOptions, QuantizerOptions { | ||
useWorker: boolean | ||
ImageClass: ImageClass | ||
quantizer: string | StageOptions | ||
generators: (string | StageOptions)[] | ||
filters: string[] | ||
useWorker: boolean; | ||
ImageClass: ImageClass; | ||
quantizer: string | StageOptions; | ||
generators: (string | StageOptions)[]; | ||
filters: string[]; | ||
} | ||
export function buildProcessOptions (opts: Options, override?: Partial<ProcessOptions>): ProcessOptions { | ||
let { colorCount, quantizer, generators, filters } = opts | ||
export function buildProcessOptions( | ||
opts: Options, | ||
override?: Partial<ProcessOptions> | ||
): ProcessOptions { | ||
const { colorCount, quantizer, generators, filters } = opts; | ||
// Merge with common quantizer options | ||
let commonQuantizerOpts = { colorCount } | ||
let q = typeof quantizer === 'string' | ||
? { name: quantizer, options: {} } | ||
: quantizer | ||
q.options = assignDeep({}, commonQuantizerOpts, q.options) | ||
const commonQuantizerOpts = { colorCount }; | ||
const q = | ||
typeof quantizer === "string" | ||
? { name: quantizer, options: {} } | ||
: quantizer; | ||
q.options = assignDeep({}, commonQuantizerOpts, q.options); | ||
return assignDeep({}, { | ||
quantizer: q, | ||
generators, | ||
filters | ||
}, override) | ||
return assignDeep( | ||
{}, | ||
{ | ||
quantizer: q, | ||
generators, | ||
filters, | ||
}, | ||
override | ||
); | ||
} |
@@ -1,21 +0,21 @@ | ||
import { ImageData, applyFilters } from '@vibrant/image' | ||
import { Quantizer } from '@vibrant/quantizer' | ||
import { Generator } from '@vibrant/generator' | ||
import { Palette, Swatch, Filter } from '@vibrant/color' | ||
import { ImageData, applyFilters } from "@vibrant/image"; | ||
import { Quantizer } from "@vibrant/quantizer"; | ||
import { Generator } from "@vibrant/generator"; | ||
import { Palette, Swatch, Filter } from "@vibrant/color"; | ||
export class Stage<T> { | ||
private _map: { [name: string]: T } = {} | ||
constructor (protected pipeline: BasicPipeline) { } | ||
names () { | ||
return Object.keys(this._map) | ||
private _map: { [name: string]: T } = {}; | ||
constructor(protected pipeline: BasicPipeline) {} | ||
names() { | ||
return Object.keys(this._map); | ||
} | ||
has (name: string) { | ||
return !!this._map[name] | ||
has(name: string) { | ||
return !!this._map[name]; | ||
} | ||
get (name: string) { | ||
return this._map[name] | ||
get(name: string) { | ||
return this._map[name]; | ||
} | ||
register (name: string, stageFn: T) { | ||
this._map[name] = stageFn | ||
return this.pipeline | ||
register(name: string, stageFn: T) { | ||
this._map[name] = stageFn; | ||
return this.pipeline; | ||
} | ||
@@ -25,27 +25,27 @@ } | ||
export interface ProcessResult { | ||
colors: Swatch[] | ||
palettes: { [name: string]: Palette } | ||
colors: Swatch[]; | ||
palettes: { [name: string]: Palette }; | ||
} | ||
export interface StageOptions { | ||
name: string | ||
options?: any | ||
name: string; | ||
options?: any; | ||
} | ||
export interface ProcessOptions { | ||
filters: string[] | ||
quantizer: string | StageOptions | ||
generators: (string | StageOptions)[] | ||
filters: string[]; | ||
quantizer: string | StageOptions; | ||
generators: (string | StageOptions)[]; | ||
} | ||
interface StageTask<Q> { | ||
name: string | ||
fn: Q | ||
options?: any | ||
name: string; | ||
fn: Q; | ||
options?: any; | ||
} | ||
interface ProcessTasks { | ||
filters: StageTask<Filter>[] | ||
quantizer: StageTask<Quantizer> | ||
generators: StageTask<Generator>[] | ||
filters: StageTask<Filter>[]; | ||
quantizer: StageTask<Quantizer>; | ||
generators: StageTask<Generator>[]; | ||
} | ||
@@ -56,31 +56,31 @@ | ||
// generator: Stage<Generator> | ||
process (imageData: ImageData, opts: ProcessOptions): Promise<ProcessResult> | ||
process(imageData: ImageData, opts: ProcessOptions): Promise<ProcessResult>; | ||
} | ||
export class BasicPipeline implements Pipeline { | ||
private _buildProcessTasks ({ | ||
private _buildProcessTasks({ | ||
filters, | ||
quantizer, | ||
generators | ||
generators, | ||
}: ProcessOptions): ProcessTasks { | ||
// Support wildcard for generators | ||
if (generators.length === 1 && generators[0] === '*') { | ||
generators = this.generator.names() | ||
if (generators.length === 1 && generators[0] === "*") { | ||
generators = this.generator.names(); | ||
} | ||
return { | ||
filters: filters.map(f => createTask(this.filter, f)), | ||
filters: filters.map((f) => createTask(this.filter, f)), | ||
quantizer: createTask(this.quantizer, quantizer), | ||
generators: generators.map(g => createTask(this.generator, g)) | ||
} | ||
function createTask<Q> ( | ||
generators: generators.map((g) => createTask(this.generator, g)), | ||
}; | ||
function createTask<Q>( | ||
stage: Stage<Q>, | ||
o: string | StageOptions | ||
): StageTask<Q> { | ||
let name: string | ||
let options: any | ||
if (typeof o === 'string') { | ||
name = o | ||
let name: string; | ||
let options: any; | ||
if (typeof o === "string") { | ||
name = o; | ||
} else { | ||
name = o.name | ||
options = o.options | ||
name = o.name; | ||
options = o.options; | ||
} | ||
@@ -91,34 +91,37 @@ | ||
fn: stage.get(name), | ||
options | ||
} | ||
options, | ||
}; | ||
} | ||
} | ||
filter: Stage<Filter> = new Stage(this) | ||
quantizer: Stage<Quantizer> = new Stage(this) | ||
generator: Stage<Generator> = new Stage(this) | ||
async process ( | ||
filter: Stage<Filter> = new Stage(this); | ||
quantizer: Stage<Quantizer> = new Stage(this); | ||
generator: Stage<Generator> = new Stage(this); | ||
async process( | ||
imageData: ImageData, | ||
opts: ProcessOptions | ||
): Promise<ProcessResult> { | ||
let { filters, quantizer, generators } = this._buildProcessTasks(opts) | ||
const imageFilterData = await this._filterColors(filters, imageData) | ||
const colors = await this._generateColors(quantizer, imageFilterData) | ||
const palettes = await this._generatePalettes(generators, colors) | ||
const { filters, quantizer, generators } = this._buildProcessTasks(opts); | ||
const imageFilterData = await this._filterColors(filters, imageData); | ||
const colors = await this._generateColors(quantizer, imageFilterData); | ||
const palettes = await this._generatePalettes(generators, colors); | ||
return { | ||
colors, | ||
palettes | ||
} | ||
palettes, | ||
}; | ||
} | ||
private _filterColors (filters: StageTask<Filter>[], imageData: ImageData) { | ||
private _filterColors(filters: StageTask<Filter>[], imageData: ImageData) { | ||
return Promise.resolve( | ||
applyFilters(imageData, filters.map(({ fn }) => fn)) | ||
) | ||
applyFilters( | ||
imageData, | ||
filters.map(({ fn }) => fn) | ||
) | ||
); | ||
} | ||
private _generateColors ( | ||
private _generateColors( | ||
quantizer: StageTask<Quantizer>, | ||
imageData: ImageData | ||
) { | ||
return Promise.resolve(quantizer.fn(imageData.data, quantizer.options)) | ||
return Promise.resolve(quantizer.fn(imageData.data, quantizer.options)); | ||
} | ||
private async _generatePalettes ( | ||
private async _generatePalettes( | ||
generators: StageTask<Generator>[], | ||
@@ -130,14 +133,11 @@ colors: Swatch[] | ||
generators.map(({ fn, options }) => Promise.resolve(fn(colors, options))) | ||
) | ||
); | ||
// Map the values to the expected name | ||
return Promise.resolve( | ||
promiseArr.reduce( | ||
(promises, promiseVal, i) => { | ||
promises[generators[i].name] = promiseVal | ||
return promises | ||
}, | ||
{} as { [name: string]: Palette } | ||
) | ||
) | ||
promiseArr.reduce((promises, promiseVal, i) => { | ||
promises[generators[i].name] = promiseVal; | ||
return promises; | ||
}, {} as { [name: string]: Palette }) | ||
); | ||
} | ||
} |
@@ -1,5 +0,5 @@ | ||
import { Pipeline, ProcessOptions, ProcessResult } from '../index' | ||
import WorkerManager, { TaskWorkerClass } from '@vibrant/worker' | ||
import { Swatch, Palette } from '@vibrant/color' | ||
import { mapValues } from '../../utils' | ||
import { Pipeline, ProcessOptions, ProcessResult } from "../index"; | ||
import WorkerManager, { TaskWorkerClass } from "@vibrant/worker"; | ||
import { Swatch, Palette } from "@vibrant/color"; | ||
import { mapValues } from "../../utils"; | ||
@@ -10,17 +10,21 @@ /** | ||
export class WorkerPipeline implements Pipeline { | ||
private _manager = new WorkerManager() | ||
constructor (protected PipelineWorker: TaskWorkerClass) { | ||
this._manager.register('pipeline', PipelineWorker) | ||
private _manager = new WorkerManager(); | ||
constructor(protected PipelineWorker: TaskWorkerClass) { | ||
this._manager.register("pipeline", PipelineWorker); | ||
} | ||
private _rehydrate (result: ProcessResult) { | ||
let { colors, palettes } = result | ||
result.colors = colors.map((s) => Swatch.clone(s)) | ||
private _rehydrate(result: ProcessResult) { | ||
const { colors, palettes } = result; | ||
result.colors = colors.map((s) => Swatch.clone(s)); | ||
result.palettes = mapValues(palettes, (p) => mapValues(p, (c) => c ? Swatch.clone(c) : null) as Palette) | ||
return result | ||
result.palettes = mapValues( | ||
palettes, | ||
(p) => mapValues(p, (c) => (c ? Swatch.clone(c) : null)) as Palette | ||
); | ||
return result; | ||
} | ||
process (imageData: ImageData, opts: ProcessOptions): Promise<ProcessResult> { | ||
return this._manager.invokeWorker('pipeline', [imageData, opts], [imageData.data.buffer]) | ||
.then((result) => this._rehydrate(result as ProcessResult)) | ||
process(imageData: ImageData, opts: ProcessOptions): Promise<ProcessResult> { | ||
return this._manager | ||
.invokeWorker("pipeline", [imageData, opts], [imageData.data.buffer]) | ||
.then((result) => this._rehydrate(result as ProcessResult)); | ||
} | ||
} |
@@ -1,8 +0,6 @@ | ||
import runInWorker from '@vibrant/worker/lib/worker' | ||
import { Pipeline } from '../index' | ||
import { runInWorker } from "@vibrant/worker"; | ||
import { Pipeline } from "../index"; | ||
export default function runPipelineInWorker (self: Window, pipeline: Pipeline) { | ||
runInWorker(self, (imageData, opts) => | ||
pipeline.process(imageData, opts) | ||
) | ||
export function runPipelineInWorker(self: Window, pipeline: Pipeline) { | ||
runInWorker(self, (imageData, opts) => pipeline.process(imageData, opts)); | ||
} |
@@ -1,12 +0,15 @@ | ||
export function mapValues<T, R> (o: { [key: string]: T }, mapper: (v: T) => R): { [key: string]: R } { | ||
let result: { [key: string]: R } = {} | ||
export function mapValues<T, R>( | ||
o: { [key: string]: T }, | ||
mapper: (v: T) => R | ||
): { [key: string]: R } { | ||
const result: { [key: string]: R } = {}; | ||
for (const key in o) { | ||
if (o.hasOwnProperty(key)) { | ||
const v = o[key] | ||
result[key] = mapper(v) | ||
const v = o[key]; | ||
result[key] = mapper(v); | ||
} | ||
} | ||
return result | ||
return result; | ||
} | ||
@@ -18,21 +21,24 @@ | ||
*/ | ||
export function assignDeep<T> (target: Partial<T>, ...sources: (Partial<T> | undefined)[]): T { | ||
sources.forEach(s => { | ||
if (!s) return | ||
export function assignDeep<T>( | ||
target: Partial<T>, | ||
...sources: (Partial<T> | undefined)[] | ||
): T { | ||
sources.forEach((s) => { | ||
if (!s) return; | ||
for (const key in s) { | ||
if (s.hasOwnProperty(key)) { | ||
const v = s[key] as any | ||
const v = s[key] as any; | ||
if (Array.isArray(v)) { | ||
// Shallow copy | ||
target[key] = v.slice(0) as any | ||
} else if (typeof v === 'object') { | ||
if (!target[key]) target[key] = {} as any | ||
assignDeep<any>(target[key] as any, v) | ||
target[key] = v.slice(0) as any; | ||
} else if (typeof v === "object") { | ||
if (!target[key]) target[key] = {} as any; | ||
assignDeep<any>(target[key] as any, v); | ||
} else { | ||
target[key] = v | ||
target[key] = v; | ||
} | ||
} | ||
} | ||
}) | ||
return target as T | ||
}); | ||
return target as T; | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
83620
51
1252
1
Yes
4
+ Added@vibrant/color@4.0.0(transitive)
+ Added@vibrant/generator@4.0.0(transitive)
+ Added@vibrant/image@4.0.0(transitive)
+ Added@vibrant/quantizer@4.0.0(transitive)
+ Added@vibrant/types@4.0.0(transitive)
+ Added@vibrant/worker@4.0.0(transitive)
- Removed@vibrant/color@3.2.1-alpha.1(transitive)
- Removed@vibrant/generator@3.2.1-alpha.1(transitive)
- Removed@vibrant/image@3.2.1-alpha.1(transitive)
- Removed@vibrant/quantizer@3.2.1-alpha.1(transitive)
- Removed@vibrant/types@3.2.1-alpha.1(transitive)
- Removed@vibrant/worker@3.2.1-alpha.1(transitive)