Class

IconService

IconService()

Constructor

# new IconService()

Icon domain service with full mixin composition.

Manages icon assets including CRUD operations, caching, event emission, soft deletes, and activation state. Extends BaseService with additional mixins for production-ready features.

Mixin Stack (bottom to top):

  1. BaseService (with withObservable) - Core CRUD + automatic observability
  2. withPluggableCacheableAndSoftDeletable - Event emission, caching, soft deletes
  3. withActivatable - Activation state management

Custom Business Logic: In addition to inherited CRUD methods, IconService provides domain-specific queries via IconRepository (getIconByUniqueId, getIconsBySetId, etc.).

View Source src/products/icons/IconService.js, line 67

Examples
// Basic CRUD (inherited from BaseService)
const iconService = new IconService();

const icon = await iconService.create({
  name: 'home',
  svgPath: 'M3 9l9-7...',
  setId: 10,
  isActive: true
});

const found = await iconService.getById(icon.id); // Cached
const updated = await iconService.update(icon.id, { name: 'home-alt' });
await iconService.softDelete(icon.id); // Soft delete
// Custom queries (domain-specific)
const iconsBySet = await iconService.getIconsBySetId(10);
const activeIcons = await iconService.getAllActiveIcons();
const iconByUid = await iconService.getIconByUniqueId('home-123');
// Activation management (from withActivatable)
await iconService.activate(icon.id);   // is_active=true
await iconService.deactivate(icon.id); // is_active=false
await iconService.toggleActive(icon.id); // Toggle state
// Pagination (inherited from BaseService)
const result = await iconService.paginate(
  { setId: 10, isActive: true },
  1,    // page
  20    // pageSize
);
// Returns: { results: IconEntity[], total, page, pageSize, totalPages }

Extends

Methods

# async cursorPaginate(filters, cursor, limitopt, sortByopt, sortOrderopt, optionsopt) → {Promise.<Object>}

Paginate icons using cursor-based keyset pagination.

Provides efficient pagination for large icon datasets (750K+ icons) with support for complex search facets including:

  • Price filtering (free, premium, all)
  • Tag filtering (multiple tags)
  • Style filtering
  • User/creator filtering
  • Set and family filtering
  • Text search
  • Elasticsearch result IDs

Performance:

  • O(log n + limit) vs O(n) for offset pagination
  • Consistent results even when data changes
  • No "page drift" from concurrent modifications

Cursor Format: Cursors are base64-encoded tokens containing the last seen item's sort fields. Use pageInfo.endCursor from one page as the cursor parameter for the next page.

Parameters:
Name Type Attributes Default Description
filters Object

Search facets and filter criteria

price string <optional>

'free', 'premium', or 'all'

tagIds Array.<number> <optional>

Array of tag IDs to filter by

styleId number <optional>

Style ID to filter by

userId number <optional>

Creator user ID to filter by

setId number <optional>

Set ID to filter by

familyId number <optional>

Family ID to filter by

searchTerm string <optional>

Text search on icon name

iconIds Array.<number> <optional>

Specific icon IDs (e.g., from Elasticsearch)

isActive boolean <optional>

Filter by active status

isDeleted boolean <optional>

Filter by deleted status

cursor string | null

Cursor token from previous page (null for first page)

limit number <optional>
20

Page size (max 100)

sortBy string <optional>
'createdAt'

Field to sort by

sortOrder string <optional>
'desc'

'asc' or 'desc'

options Object <optional>
{}

Additional options

includeTotalCount boolean <optional>
false

Whether to include total count (expensive!)

trx Object <optional>

Knex transaction

View Source src/products/icons/IconService.js, line 292

Pagination result with results and metadata

Promise.<Object>
Examples
// First page (newest free icons)
const page1 = await iconService.cursorPaginate({
  price: 'free'
}, null, 20, 'createdAt', 'desc');

console.log(page1.results);           // IconEntity[]
console.log(page1.pageInfo.hasNextPage); // true
console.log(page1.pageInfo.endCursor);   // 'eyJpZC...'
// Next page (using cursor from page1)
const page2 = await iconService.cursorPaginate({
  price: 'free'
}, page1.pageInfo.endCursor, 20);
// Complex search with multiple facets
const results = await iconService.cursorPaginate({
  price: 'free',
  tagIds: [1, 2, 3],      // Icons with these tags
  styleId: 5,              // Specific design style
  searchTerm: 'home',      // Text search
  userId: 123              // From specific creator
}, null, 20);
// With Elasticsearch integration
const elasticResults = await elasticsearchService.search('home icon');
const iconIds = elasticResults.hits.map(h => h.id);

const results = await iconService.cursorPaginate({
  iconIds: iconIds,  // Only these icon IDs
  price: 'free'
}, null, 20);
// Oldest icons first (ascending sort)
const oldestIcons = await iconService.cursorPaginate({
  price: 'all'
}, null, 20, 'createdAt', 'asc');

# async getAllActiveIcons(optionsopt) → {Promise.<Array.<IconEntity>>}

Get all active (published) icons across all sets.

Returns only icons where is_active=true and is_deleted=false. Useful for public-facing endpoints that should only show published content.

Warning: This can return 750,000+ icons. Consider using pagination instead:

await iconService.paginate({ isActive: true, isDeleted: false }, page, pageSize);
Parameters:
Name Type Attributes Default Description
options Object <optional>
{}

Query options

trx Object <optional>

Knex transaction

View Source src/products/icons/IconService.js, line 203

Array of active icon entities

Promise.<Array.<IconEntity>>
Example
const activeIcons = await iconService.getAllActiveIcons();
console.log(activeIcons.length); // 750,000+
console.log(activeIcons.every(icon => icon.isActive)); // true

# async getIconByUniqueId(uniqueId, optionsopt) → {Promise.<(IconEntity|null)>}

Get icon by unique identifier.

Domain-specific query delegating to IconRepository. The unique ID is a combination of set identifier and icon name for human-readable URLs.

Parameters:
Name Type Attributes Default Description
uniqueId string

Unique identifier (e.g., "material-design-home")

options Object <optional>
{}

Query options

trx Object <optional>

Knex transaction

View Source src/products/icons/IconService.js, line 159

Icon entity or null if not found

Promise.<(IconEntity|null)>
Example
const icon = await iconService.getIconByUniqueId('material-design-home');
console.log(icon.name); // 'home'
console.log(icon.setId); // 10 (Material Design set)

# async getIconsBySetId(setId, optionsopt) → {Promise.<Array.<IconEntity>>}

Get all icons in a specific set.

Domain-specific query for fetching all icons that belong to a set (e.g., all icons in "Material Design Icons" set).

Parameters:
Name Type Attributes Default Description
setId number

Set ID to filter by

options Object <optional>
{}

Query options

trx Object <optional>

Knex transaction

View Source src/products/icons/IconService.js, line 179

Array of icon entities

Promise.<Array.<IconEntity>>
Example
const materialIcons = await iconService.getIconsBySetId(10);
console.log(materialIcons.length); // 2500+ icons
console.log(materialIcons[0].setId); // 10

# async searchIcons(params, optionsopt) → {Promise.<Object>}

Paginate icons with search facets (convenience method).

Simplified interface for cursor pagination with common search facets. Delegates to cursorPaginate() with pre-configured defaults.

Sorting Options:

  • 'newest' - Sort by created_at DESC (PostgreSQL)
  • 'bestseller' - Sort by popularity DESC (PostgreSQL)
  • 'relevance' - Sort by Elasticsearch relevance (requires iconIds)
Parameters:
Name Type Attributes Default Description
params Object

Search parameters

price string <optional>
'all'

Price filter

tagIds Array.<number> <optional>
[]

Tag IDs

styleId number <optional>

Style ID

searchTerm string <optional>

Text search

iconIds Array.<number> <optional>

Icon IDs from Elasticsearch (for relevance sort)

cursor string <optional>

Cursor token

limit number <optional>
20

Page size

sort string <optional>
'newest'

Sort type ('newest', 'bestseller', or 'relevance')

options Object <optional>
{}

Additional options

View Source src/products/icons/IconService.js, line 376

Pagination result

Promise.<Object>
Examples
// Simple search (newest first)
const results = await iconService.searchIcons({
  price: 'free',
  searchTerm: 'home',
  sort: 'newest',
  limit: 20
});
// Bestsellers
const bestsellers = await iconService.searchIcons({
  price: 'all',
  sort: 'bestseller',
  limit: 20
});
// Elasticsearch relevance sorting
const esResults = await elasticsearchService.search('home icon');
const iconIds = esResults.hits.map(h => h.id);

const results = await iconService.searchIcons({
  iconIds: iconIds,      // Ranked IDs from Elasticsearch
  price: 'free',
  sort: 'relevance',     // Preserves Elasticsearch ranking
  limit: 20
});
// Next page (same sort and filters)
const page2 = await iconService.searchIcons({
  iconIds: iconIds,      // SAME IDs for consistency
  price: 'free',
  sort: 'relevance',
  cursor: results.pageInfo.endCursor,
  limit: 20
});

IconService(optionsopt)

Constructor

# new IconService(optionsopt)

Construct IconService with repository and entity class.

Parameters:
Name Type Attributes Default Description
options Object <optional>
{}

Service configuration

repository IconRepository <optional>

Icon repository instance

entityClass function <optional>

Icon entity class

View Source src/products/icons/IconService.js, line 139

Examples
// Default construction
const iconService = new IconService();
// Custom repository (e.g., for testing)
const mockRepo = new IconRepository({ DB: mockDB });
const iconService = new IconService({ repository: mockRepo });

Methods

# async cursorPaginate(filters, cursor, limitopt, sortByopt, sortOrderopt, optionsopt) → {Promise.<Object>}

Paginate icons using cursor-based keyset pagination.

Provides efficient pagination for large icon datasets (750K+ icons) with support for complex search facets including:

  • Price filtering (free, premium, all)
  • Tag filtering (multiple tags)
  • Style filtering
  • User/creator filtering
  • Set and family filtering
  • Text search
  • Elasticsearch result IDs

Performance:

  • O(log n + limit) vs O(n) for offset pagination
  • Consistent results even when data changes
  • No "page drift" from concurrent modifications

Cursor Format: Cursors are base64-encoded tokens containing the last seen item's sort fields. Use pageInfo.endCursor from one page as the cursor parameter for the next page.

Parameters:
Name Type Attributes Default Description
filters Object

Search facets and filter criteria

price string <optional>

'free', 'premium', or 'all'

tagIds Array.<number> <optional>

Array of tag IDs to filter by

styleId number <optional>

Style ID to filter by

userId number <optional>

Creator user ID to filter by

setId number <optional>

Set ID to filter by

familyId number <optional>

Family ID to filter by

searchTerm string <optional>

Text search on icon name

iconIds Array.<number> <optional>

Specific icon IDs (e.g., from Elasticsearch)

isActive boolean <optional>

Filter by active status

isDeleted boolean <optional>

Filter by deleted status

cursor string | null

Cursor token from previous page (null for first page)

limit number <optional>
20

Page size (max 100)

sortBy string <optional>
'createdAt'

Field to sort by

sortOrder string <optional>
'desc'

'asc' or 'desc'

options Object <optional>
{}

Additional options

includeTotalCount boolean <optional>
false

Whether to include total count (expensive!)

trx Object <optional>

Knex transaction

View Source src/products/icons/IconService.js, line 292

Pagination result with results and metadata

Promise.<Object>
Examples
// First page (newest free icons)
const page1 = await iconService.cursorPaginate({
  price: 'free'
}, null, 20, 'createdAt', 'desc');

console.log(page1.results);           // IconEntity[]
console.log(page1.pageInfo.hasNextPage); // true
console.log(page1.pageInfo.endCursor);   // 'eyJpZC...'
// Next page (using cursor from page1)
const page2 = await iconService.cursorPaginate({
  price: 'free'
}, page1.pageInfo.endCursor, 20);
// Complex search with multiple facets
const results = await iconService.cursorPaginate({
  price: 'free',
  tagIds: [1, 2, 3],      // Icons with these tags
  styleId: 5,              // Specific design style
  searchTerm: 'home',      // Text search
  userId: 123              // From specific creator
}, null, 20);
// With Elasticsearch integration
const elasticResults = await elasticsearchService.search('home icon');
const iconIds = elasticResults.hits.map(h => h.id);

const results = await iconService.cursorPaginate({
  iconIds: iconIds,  // Only these icon IDs
  price: 'free'
}, null, 20);
// Oldest icons first (ascending sort)
const oldestIcons = await iconService.cursorPaginate({
  price: 'all'
}, null, 20, 'createdAt', 'asc');

# async getAllActiveIcons(optionsopt) → {Promise.<Array.<IconEntity>>}

Get all active (published) icons across all sets.

Returns only icons where is_active=true and is_deleted=false. Useful for public-facing endpoints that should only show published content.

Warning: This can return 750,000+ icons. Consider using pagination instead:

await iconService.paginate({ isActive: true, isDeleted: false }, page, pageSize);
Parameters:
Name Type Attributes Default Description
options Object <optional>
{}

Query options

trx Object <optional>

Knex transaction

View Source src/products/icons/IconService.js, line 203

Array of active icon entities

Promise.<Array.<IconEntity>>
Example
const activeIcons = await iconService.getAllActiveIcons();
console.log(activeIcons.length); // 750,000+
console.log(activeIcons.every(icon => icon.isActive)); // true

# async getIconByUniqueId(uniqueId, optionsopt) → {Promise.<(IconEntity|null)>}

Get icon by unique identifier.

Domain-specific query delegating to IconRepository. The unique ID is a combination of set identifier and icon name for human-readable URLs.

Parameters:
Name Type Attributes Default Description
uniqueId string

Unique identifier (e.g., "material-design-home")

options Object <optional>
{}

Query options

trx Object <optional>

Knex transaction

View Source src/products/icons/IconService.js, line 159

Icon entity or null if not found

Promise.<(IconEntity|null)>
Example
const icon = await iconService.getIconByUniqueId('material-design-home');
console.log(icon.name); // 'home'
console.log(icon.setId); // 10 (Material Design set)

# async getIconsBySetId(setId, optionsopt) → {Promise.<Array.<IconEntity>>}

Get all icons in a specific set.

Domain-specific query for fetching all icons that belong to a set (e.g., all icons in "Material Design Icons" set).

Parameters:
Name Type Attributes Default Description
setId number

Set ID to filter by

options Object <optional>
{}

Query options

trx Object <optional>

Knex transaction

View Source src/products/icons/IconService.js, line 179

Array of icon entities

Promise.<Array.<IconEntity>>
Example
const materialIcons = await iconService.getIconsBySetId(10);
console.log(materialIcons.length); // 2500+ icons
console.log(materialIcons[0].setId); // 10

# async searchIcons(params, optionsopt) → {Promise.<Object>}

Paginate icons with search facets (convenience method).

Simplified interface for cursor pagination with common search facets. Delegates to cursorPaginate() with pre-configured defaults.

Sorting Options:

  • 'newest' - Sort by created_at DESC (PostgreSQL)
  • 'bestseller' - Sort by popularity DESC (PostgreSQL)
  • 'relevance' - Sort by Elasticsearch relevance (requires iconIds)
Parameters:
Name Type Attributes Default Description
params Object

Search parameters

price string <optional>
'all'

Price filter

tagIds Array.<number> <optional>
[]

Tag IDs

styleId number <optional>

Style ID

searchTerm string <optional>

Text search

iconIds Array.<number> <optional>

Icon IDs from Elasticsearch (for relevance sort)

cursor string <optional>

Cursor token

limit number <optional>
20

Page size

sort string <optional>
'newest'

Sort type ('newest', 'bestseller', or 'relevance')

options Object <optional>
{}

Additional options

View Source src/products/icons/IconService.js, line 376

Pagination result

Promise.<Object>
Examples
// Simple search (newest first)
const results = await iconService.searchIcons({
  price: 'free',
  searchTerm: 'home',
  sort: 'newest',
  limit: 20
});
// Bestsellers
const bestsellers = await iconService.searchIcons({
  price: 'all',
  sort: 'bestseller',
  limit: 20
});
// Elasticsearch relevance sorting
const esResults = await elasticsearchService.search('home icon');
const iconIds = esResults.hits.map(h => h.id);

const results = await iconService.searchIcons({
  iconIds: iconIds,      // Ranked IDs from Elasticsearch
  price: 'free',
  sort: 'relevance',     // Preserves Elasticsearch ranking
  limit: 20
});
// Next page (same sort and filters)
const page2 = await iconService.searchIcons({
  iconIds: iconIds,      // SAME IDs for consistency
  price: 'free',
  sort: 'relevance',
  cursor: results.pageInfo.endCursor,
  limit: 20
});