Socket
Book a DemoInstallSign in
Socket

@skedulo/pulse-solutions-framework

Package Overview
Dependencies
Maintainers
33
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@skedulo/pulse-solutions-framework

Pulse Solutions Framework

latest
npmnpm
Version
0.0.10
Version published
Weekly downloads
255
66.67%
Maintainers
33
Weekly downloads
 
Created
Source

Data Service

A comprehensive TypeScript service library for GraphQL-based data operations with support for complex object relationships, batch processing, and advanced querying capabilities.

Features

  • Dynamic Query Building: Automatically generates GraphQL queries based on object definitions
  • Relationship Handling: Supports nested references and related lists with configurable depth levels
  • Batch Processing: Efficiently handles large datasets with automatic chunking
  • Change Detection: Only sends modified fields during updates to optimize performance
  • Pagination Support: Automatic handling of paginated results
  • Flexible Filtering: Support for various operators and custom conditions

Installation

npm install @skedulo/pulse-solutions-framework

Object Definition

import { createObjectDefinition, MappingType, ObjectDefinition } from '@skedulo/pulse-solutions-framework'

export const JobsDefinition: ObjectDefinition = createObjectDefinition({
  objectName: 'Jobs',
  fieldConfigs: [
    { fieldName: 'UID' }, //mappingType: MappingType.string as default
    { fieldName: 'Name', readonly: true },
    { fieldName: 'Account', mappingType: MappingType.reference, referenceObject: 'Accounts' },
    {
      fieldName: 'JobAllocations',
      mappingType: MappingType.relatedList,
      referenceObject: 'JobAllocations',
      parentField: 'Job'
    },
    { fieldName: 'JobAllocationTimeSource', mappingType: MappingType.boolean },
    { fieldName: 'Quantity', mappingType: MappingType.number },
    { fieldName: 'Start', mappingType: MappingType.datetime }
  ]
})

Configuration

Service Settings

PropertyTypeDefaultDescription
objectNamestringRequiredName of the primary object
objectDefinitionsRecord<string, ObjectDefinition>RequiredCollection of object definitions

Basic Usage

Creating a Service Instance

import { createBaseService, ServiceSetting } from '@skedulo/pulse-solutions-framework'
import * as objectDefinitions from './my-object-definitions'

interface Jobs extends BaseModel {
  AccountId: string
  JobStatus: string
  // ... other fields
}

const settings: ServiceSetting = {
  objectName: 'Jobs',
  objectDefinitions: objectDefinitions
}

const jobsService = createBaseService<Jobs>(settings)

Querying Data

import { QueryModel, Operator } from '@skedulo/pulse-solutions-framework'

// Simple query
const queryModels: QueryModel[] = [
  {
    conditions: [
      ['AccountId', Operator.EQUAL, 'account-uid'],
      ['JobStatus', Operator.NOT_IN, ['Cancelled']]
    ],
    orderBy: 'CreatedDate DESC'
  }
]

const result = await jobsService.query(queryModels)

Saving Data

// Insert records
const recordsToInsert: Jobs[] = [
  { AccountId: 'account-uid-1', JobStatus: 'Queued' },
  { AccountId: 'account-uid-2', JobStatus: 'Queued' }
]

// Update records
const recordsToUpdate: Jobs[] = [{ UID: 'existing-id', AccountId: 'account-uid', JobStatus: 'Pending Dispatch' }]

// Delete records
const recordsToDelete: Jobs[] = [{ UID: 'existing-id', _IsDeleted: true }]

await jobsService.save([...recordsToInsert, ...recordsToUpdate, ...recordsToDelete])

Advanced Usage

Complex Queries with Custom Logic

const complexQuery: QueryModel[] = [
  {
    conditions: [
      ['Start', Operator.GREATER_OR_EQUAL, '2025-01-01T00:00:00.000Z'],
      ['End', Operator.LESS_OR_EQUAL, '2025-12-31T00:00:00.000Z'],
      ['JobStatus', Operator.IN, ['Pending Allocation', 'Pending Dispatch']]
    ],
    customLogic: '(1 AND 2) AND 3', // Reference conditions by index
    orderBy: 'CreatedDate DESC'
  }
]

Period-based Queries

const periodQuery: QueryModel[] = [
  {
    conditions: [[['Start', 'End'], Operator.PERIOD, ['2025-01-01T00:00:00.000Z', '2025-12-31T00:00:00.000Z']]]
  }
]

Custom Conditions

const customQuery: QueryModel[] = [
  {
    conditions: [['my_custom_query', Operator.CUSTOM, 'ContactId != null AND ContactId != ""']]
  }
]
const jobsWithJobAllocationsQuery: QueryModel[] = [
  {
    conditions: [['JobStatus', Operator.NOT_IN, ['Cancelled']]],
    orderBy: 'CreatedDate DESC'
  },
  {
    relatedList: 'JobAllocations',
    conditions: [['Status', Operator.NOT_IN, ['Deleted', 'Declined']]]
  }
]

Query Options

const options: QueryOptions = {
  readOnly: true // Optimize for read-only operations
}

const result = await jobsService.query(queryModels, options)

Save Options

const options: SaveOptions = {
  sourceRecords: [], // Original records for change detection
  bulkOperation: true, // Enable bulk operation mode
  suppressChangeEvents: true // Suppress change events
}

const result = await jobsService.save(records, options)

Supported Operators

OperatorGraphQL EquivalentDescription
EQUAL==Equality comparison
NOT_EQUAL!=Inequality comparison
ININValue in array
NOT_INNOTINValue not in array
GREATER>Greater than
GREATER_OR_EQUAL>=Greater than or equal
LESS<Less than
LESS_OR_EQUAL<=Less than or equal
INCLUDESINCLUDESString value included
EXCLUDESEXCLUDESString value excluded
INCLUDES_ALLCustomAll string values included
INCLUDES_ANYCustomAny string included
EXCLUDES_ALLCustomAll string values excluded
PERIODCustomDate range overlap
PERIOD_INCLUDE_NULLCustomDate range overlap including records have period fields value is null
CUSTOMCustomRaw GraphQL condition

API Reference

DataService Interface

interface DataService<T extends BaseModel> {
  newQueryBuilder(queryModels: QueryModel[]): GraphQLQueryBuilder
  query(queryModels: QueryModel[], options?: QueryOptions): Promise<GetListResponse<T>>
  save(objects: T[], options?: SaveOptions<T>): Promise<SaveResult[]>
}

QueryModel

interface QueryModel {
  conditions?: [string | string[], Operator, any][]
  customLogic?: string
  orderBy?: string
  limit?: number
  relatedList?: string
  overriddenFields?: string
}

Performance Considerations

  • Batch Processing: Large datasets are automatically chunked to respect API limits
  • Change Detection: Only modified fields are sent during updates
  • Circular Reference Prevention: Automatic detection and prevention of circular lookups
  • Pagination: Automatic handling of large result sets
  • Field Selection: Only predefined fields are queried based on object definitions

Best Practices

  • Use Change Detection: Provide sourceRecords for optimal update performance
  • Batch Operations: Consider bulkOperation: true for large datasets. This helps optimize large-scale mutations
  • Suppress Change Events: Consider suppressChangeEvents: true for large datasets. This disables change history tracking, helping to minimize delays.

Recurring Service

The recurring-service module provides utilities for generating recurring dates based on customizable patterns. It supports daily, weekly, monthly, and yearly recurrence rules with advanced options like skipping specific dates, handling timezones, and limiting occurrences.

Features

  • Flexible Recurrence Rules: Supports daily, weekly, monthly, and yearly recurrence modes.
  • Advanced Options:
    • Skip specific dates or weekdays.
    • Define end conditions (after a number of occurrences or on a specific date).
    • Handle leap years and months with fewer days.
  • Timezone Support: Generate dates in specific timezones using luxon.
  • Type Safety: Fully typed with TypeScript for robust development.

Generators

The following generators are available for creating recurring dates:

  • Daily Generator: daily-generator.ts
  • Weekly Generator: weekly-generator.ts
  • Monthly Generator: monthly-generator.ts
  • Yearly Generator: yearly-generator.ts

Each generator implements the RecurringGenerator interface and provides the following methods:

  • generateDates(pattern: RecurringPattern): DateTime[]
  • getRepeatMode(): RepeatMode

Types

The module defines the following key types in types.ts:

  • RecurringPattern: Configuration object for defining recurrence rules.
  • RecurringGenerator: Interface for generators.

Usage

Example: Daily Recurrence

import { dailyRecurringGenerator } from './generators/daily-generator'
import { RepeatMode, EndMode, RecurringPattern } from './types'

const generator = dailyRecurringGenerator()

const pattern: RecurringPattern = {
  startDate: '2024-01-01',
  timezoneSidId: 'UTC',
  repeatMode: RepeatMode.Daily,
  every: 1,
  endMode: EndMode.After,
  endAfterNumberOccurrences: 5
}

const dates = generator.generateDates(pattern)
console.log(dates.map(date => date.toISODate()))
// Output: ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05']

Example: Monthly Recurrence with Skipped Dates

import { monthlyRecurringGenerator } from './generators/monthly-generator'
import { RepeatMode, EndMode, RecurringPattern } from './types'

const generator = monthlyRecurringGenerator()

const pattern: RecurringPattern = {
  startDate: '2024-01-15',
  timezoneSidId: 'UTC',
  repeatMode: RepeatMode.Monthly,
  every: 1,
  endMode: EndMode.After,
  endAfterNumberOccurrences: 3,
  repeatOnDayOfMonth: 15,
  skippedDates: ['2024-02-15']
}

const dates = generator.generateDates(pattern)
console.log(dates.map(date => date.toISODate()))
// Output: ['2024-01-15', '2024-03-15', '2024-04-15']

Example: Yearly Recurrence with Leap Year Handling

import { yearlyRecurringGenerator } from './generators/yearly-generator'
import { RepeatMode, EndMode, RecurringPattern } from './types'

const generator = yearlyRecurringGenerator()

const pattern: RecurringPattern = {
  startDate: '2024-02-29',
  timezoneSidId: 'UTC',
  repeatMode: RepeatMode.Yearly,
  every: 1,
  endMode: EndMode.After,
  endAfterNumberOccurrences: 2
}

const dates = generator.generateDates(pattern)
console.log(dates.map(date => date.toISODate()))
// Output: ['2024-02-29', '2025-02-28']

Testing

Unit tests for the recurring service are located in the unit-test/recurring-service folder. Each generator and helper function is thoroughly tested with various edge cases.

File Structure

  • base-service.ts: Core service for generating recurring dates and summaries.
  • helper.ts: Utility functions for validating and preprocessing patterns.
  • types.ts: Type definitions and enums for recurring patterns.
  • generators/: Contains the daily, weekly, monthly, and yearly generators.

FAQs

Package last updated on 18 Aug 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts