npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@huz-com/game-developer-sdk

v1.0.29

Published

Score-board, data-bucket for game developers in Huz platform

Downloads

4

Readme

Huz.Com > SDK > Game Developer

  • Stores game x profile data, statistics, leaderboards etc
  • Serves stored data
  • Provide to filter/criteria in stored data for game
  • Provide to learn player status for game

For SDK Developers

Standards

  • Language: TS
  • Eslint: Yes
  • Static Code Analysis: Yes IntelliJ Code Inspections
  • DDD - Document Driven: Yes
  • EDD - Exception Driven: Yes
  • TDD - Test Driven: Yes go to test folder
  • NoSQL, Dynamic Entity: Yes
  • Standards Complied: Huz Standards

Commands

  • npm run clear // clears "dist" folder
  • npm run lint // runs eslint for static code analysis
  • npm run test // runs test files in "test" folder
  • npm run build // builds JS files at "dist" folder
  • npm publish or npm run publix // publishes "dist" folder to npm

For Game Developers

Install

npm i @huz-com/game-developer-sdk

Usage

Importing

Export Instances: connector

Export Builder Classes: AnalyzeBuilder, FilterBuilder, SetBuilder, IncrementBuilder

Export Enum Classes: PrimitiveTypeEnum, EqualityEnum, AggregationEnum

const {connector} = require('@huz-com/game-developer-sdk');

Initialization

// initializes api connection options
connector.init({
    apiUrl: 'given-api-url',
    project: 'given-project-id',
    secret: 'given-game-secret',
    silent: false // if false, prints console.log messages
});

Basic Operations

Get, Set, Delete

// get all data
connector.getAsync(
).then((content) => {}).catch((err) => {});

// get partial data
connector.partialAsync(
    // returns only given fields
    'field1', 'field2', 'field3'
).then((content) => {}).catch((err) => {});

// set multiple data
connector.setAsync({
    // set point value, if existing them overwrite else create field    
    point: 101,
    // set level value, if existing them overwrite else create field
    level: 2,
    // set is favorited value, if existing them overwrite else create field
    isFavorited: false,
    // set level-1 date value, if existing them overwrite else create field, ISO Datetime format
    level1Date: '2020-01-03T13:35:00.000Z'
}).then((content) => {}).catch((err) => {});

// set one data
connector.setAsync({
    // set point value, if existing them overwrite else create field    
    point: 104,
}).then((content) => {}).catch((err) => {});

// set array data
connector.setAsync({
    // sets favorite colors as array, ie: you can use $intersects in where    
    favoriteColors: ['red', 'blue', 'black'],
}).then((content) => {}).catch((err) => {});

// increment multiple data
connector.incrementAsync({
    // increments level 2 point value if exists, else it evaluates old value is zero and increments again    
    level2Point: 10,
    // increments gold count value if exists, else it evaluates old value is zero and increments again    
    goldCount: 2,
}).then((content) => {}).catch((err) => {});

// increment one data
connector.incrementAsync({
    // increments level 2 point value if exists, else it evaluates old value is zero and increments again    
    level2Point: 10,
}).then((content) => {}).catch((err) => {});

// decrement one data
connector.incrementAsync({
    // decrements (because negative) gold value if exists, else it evaluates old value is zero and decrements again    
    gold: -1
}).then((content) => {}).catch((err) => {});

// decrement multiple data
connector.incrementAsync({
    // decrements (because negative) gold value if exists, else it evaluates old value is zero and decrements again    
    gold: -1,
    // decrements (because negative) point value if exists, else it evaluates old value is zero and decrements again    
    point: -10,
}).then((content) => {}).catch((err) => {});

// delete partial data
connector.deleteAsync(
    // deletes field1, field2 and field3 if any of them is existing
    'field1', 'field2', 'field3'
).then((content) => {}).catch((err) => {});

Filter Operations (Native)

Top-n Lists, ScoreBoard, LeaderBoard etc

// list top-20 players by track 1 point if player is;
// - "at level 3"
connector.filterAsync({
    select: [
        // get track 1 point and type is integer
        {field: 'track1Point', type: 'integer'},
    ],
    where: [
        // Players are at level 3
        {field: 'level', values: [3], type: 'integer', equation: '$eq'},
    ],
    orderBy: [
        // sort players by track 1 point desc (9 > 0)
        {field: 'track1Point', type: 'integer', desc: true},
    ],
    // top 20 players
    limit: 20,
}).then((content) => {}).catch((err) => {});

// list top-20 players by track 1 point if player is;
// - "at level 3" and "male"
connector.filterAsync({
    select: [
        // get track 1 point and type is integer
        {field: 'track1Point', type: 'integer'},
    ],
    where: [
        // Players are at level 3
        {field: 'level', values: [3], type: 'integer', equation: '$eq'},
        // Players are male or boy
        {field: 'gender', values: ['male'], type: 'string', equation: '$eq'},
    ],
    orderBy: [
        // sort players by track 1 point desc (9 > 0)
        {field: 'track1Point', type: 'integer', desc: true},
    ],
    // top 20 players
    limit: 20,
}).then((content) => {}).catch((err) => {});

// list top-20 players by track 1 point if player is;
// - "at level 3" and "male" and "clicked before 2020-09-01"
connector.filterAsync({
    select: [
        // get track 1 point and type is integer
        {field: 'track1Point', type: 'integer'},
    ],
    where: [
        // Players are at level 3
        {field: 'level', values: [3], type: 'integer', equation: '$eq'},
        // Players are male or boy
        {field: 'gender', values: ['male'], type: 'string', equation: '$eq'},
        // Players are clicked before 2020-09-01
        {field: 'firstClickDate', values: ['2020-09-01'], type: 'date', equation: '$lt'},
    ],
    orderBy: [
        // sort players by track 1 point desc (9 > 0)
        {field: 'track1Point', type: 'integer', desc: true},
    ],
    // top 20 players
    limit: 20,
}).then((content) => {}).catch((err) => {});

// list top-20 players by track 1 point if player is;
// - "at level 3" and "male" and "clicked before 2020-09-01" and "favorite color is red"
connector.filterAsync({
    select: [
        // get track 1 point and type is integer
        {field: 'track1Point', type: 'integer'},
    ],
    where: [
        // Players are at level 3
        {field: 'level', values: [3], type: 'integer', equation: '$eq'},
        // Players are male or boy
        {field: 'gender', values: ['male'], type: 'string', equation: '$eq'},
        // Players are clicked before 2020-09-01
        {field: 'firstClickDate', values: ['2020-09-01'], type: 'date', equation: '$lt'},
        // Players who has favorite color is red, favoriteColors is array, so we used intersects
        {field: 'favoriteColors', values: ['red'], type: 'string', equation: '$intersects'},
    ],
    orderBy: [
        // sort players by track 1 point desc (9 > 0)
        {field: 'track1Point', type: 'integer', desc: true},
    ],
    // top 20 players
    limit: 20,
}).then((content) => {}).catch((err) => {});

Analyze Operations (Native)

Comparison current player to all players

// analyze current player by track 1 point with players who are;
// - "at level 3"
connector.analyzeAsync({
    // analyze by track 1 point and value is integer
    field: 'track1Point',
    type: 'integer',
    where: [
        // Players are at level 3
        {field: 'level', values: [3], type: 'integer', equation: '$eq'},
    ],
}).then((content) => {}).catch((err) => {});

// analyze current player by track 1 point with players who are;
// - "at level 3" and "male"
connector.analyzeAsync({
    // analyze by track 1 point and value is integer
    field: 'track1Point',
    type: 'integer',
    where: [
        // Players are at level 3
        {field: 'level', values: [3], type: 'integer', equation: '$eq'},
        // Players are male or boy
        {field: 'gender', values: ['male'], type: 'string', equation: '$eq'},
    ],
}).then((content) => {}).catch((err) => {});

// analyze current player by track 1 point with players who are;
// - "at level 3" and "male" and "clicked before 2020-09-01"
connector.analyzeAsync({
    // analyze by track 1 point and value is integer
    field: 'track1Point',
    type: 'integer',
    where: [
        // Players are at level 3
        {field: 'level', values: [3], type: 'integer', equation: '$eq'},
        // Players are male or boy
        {field: 'gender', values: ['male'], type: 'string', equation: '$eq'},
        // Players are clicked before 2020-09-01
        {field: 'firstClickDate', values: ['2020-09-01'], type: 'date', equation: '$lt'},
    ],
}).then((content) => {}).catch((err) => {});

// analyze current player by track 1 point with players who are;
// - "at level 3" and "male" and "clicked before 2020-09-01" and "favorite color is red"
connector.analyzeAsync({
    // analyze by track 1 point and value is integer
    field: 'track1Point',
    type: 'integer',
    where: [
        // Players are at level 3
        {field: 'level', values: [3], type: 'integer', equation: '$eq'},
        // Players are male or boy
        {field: 'gender', values: ['male'], type: 'string', equation: '$eq'},
        // Players are clicked before 2020-09-01
        {field: 'firstClickDate', values: ['2020-09-01'], type: 'date', equation: '$lt'},
        // Players who has favorite color is red, favoriteColors is array, so we used intersects
        {field: 'favoriteColors', values: ['red'], type: 'string', equation: '$intersects'},
    ],
}).then((content) => {}).catch((err) => {});

Basic Operations (Builder)

Set Builder is same with "connector.setAsync" method

Increment Builder is same with "connector.incrementAsync" method

Implemented to provide clean-code and easy-usage

// sets level and point values, if they are not existing create them
new SetBuilder()
    // set level as 6
    .field('level', 6)
    // set point as 3
    .field('point', 3)
    // trigger setAsync
    .runAsync()
    .then((content) => {}).catch((err) => {});

// increments level and point values if exist, else it evaluates old values are zero and increments again
new IncrementBuilder()
    // increment level with 6
    .field('level', 6)
    // increment point with 3
    .field('point', 3)
    // trigger incrementAsync
    .runAsync()
    .then((content) => {}).catch((err) => {});

Filter Operations (Builder)

Filter Builder is same with "connector.filterAsync" method

Implemented to provide clean-code and easy-usage

// list top-20 players by track 1 point if player is;
// - "at level 3"
new FilterBuilder()
    // get track 1 point and type is integer
    .select('track1Point', PrimitiveTypeEnum.INTEGER)
    // Players are at level 3
    .where('level', [3], EqualityEnum.EQUALS, PrimitiveTypeEnum.INTEGER)
    // sort players by track 1 point desc (9 > 0)
    .orderBy('track1Point', true, PrimitiveTypeEnum.INTEGER)
    // top 20 players
    .limit(20)
    // trigger filterAsync with collected payload above
    .runAsync()
    .then((content) => {}).catch((err) => {});

// list top-20 players by track 1 point if player is;
// - "at level 3" and "male"
new FilterBuilder()
    // get track 1 point and type is integer
    .select('track1Point', PrimitiveTypeEnum.INTEGER)
    // Players are at level 3
    .where('level', [3], EqualityEnum.EQUALS, PrimitiveTypeEnum.INTEGER)
    // Players are male or boy
    .where('gender', ['male'], EqualityEnum.EQUALS, PrimitiveTypeEnum.STRING)
    // sort players by track 1 point desc (9 > 0)
    .orderBy('track1Point', true, PrimitiveTypeEnum.INTEGER)
    // top 20 players
    .limit(20)
    // trigger filterAsync with collected payload above
    .runAsync()
    .then((content) => {}).catch((err) => {});

// list top-20 players by track 1 point if player is;
// - "at level 3" and "male" and "clicked before 2020-09-01"
new FilterBuilder()
    // get track 1 point and type is integer
    .select('track1Point', PrimitiveTypeEnum.INTEGER)
    // Players are at level 3
    .where('level', [3], EqualityEnum.EQUALS, PrimitiveTypeEnum.INTEGER)
    // Players are male or boy
    .where('gender', ['male'], EqualityEnum.EQUALS, PrimitiveTypeEnum.STRING)
    // Players are clicked before 2020-09-01
    .where('firstClickDate', ['2020-09-01'], EqualityEnum.LESS_THAN, PrimitiveTypeEnum.DATE)
    // sort players by track 1 point desc (9 > 0)
    .orderBy('track1Point', true, PrimitiveTypeEnum.INTEGER)
    // top 20 players
    .limit(20)
    // trigger filterAsync with collected payload above
    .runAsync()
    .then((content) => {}).catch((err) => {});

// list top-20 players by track 1 point if player is;
// - "at level 3" and "male" and "clicked before 2020-09-01" and "favorite color is red"
new FilterBuilder()
    // get track 1 point and type is integer
    .select('track1Point', PrimitiveTypeEnum.INTEGER)
    // Players are at level 3
    .where('level', [3], EqualityEnum.EQUALS, PrimitiveTypeEnum.INTEGER)
    // Players are male or boy
    .where('gender', ['male'], EqualityEnum.EQUALS, PrimitiveTypeEnum.STRING)
    // Players are clicked before 2020-09-01
    .where('firstClickDate', ['2020-09-01'], EqualityEnum.LESS_THAN, PrimitiveTypeEnum.DATE)
    // Players who has favorite color is red, favoriteColors is array, so we used intersects
    .where('favoriteColors', ['red'], EqualityEnum.INTERSECTS, PrimitiveTypeEnum.STRING)
    // sort players by track 1 point desc (9 > 0)
    .orderBy('track1Point', true, PrimitiveTypeEnum.INTEGER)
    // top 20 players
    .limit(20)
    // trigger filterAsync with collected payload above
    .runAsync()
    .then((content) => {}).catch((err) => {});

Analyze Operations (Builder)

Analyze Builder is same with "connector.analyzeAsync" method

Implemented to provide clean-code and easy-usage

// analyze current player by track 1 point with players who are;
// - "at level 3"
new AnalyzeBuilder()
    // analyze by track 1 point and value is integer
    .field('track1Point').type(PrimitiveTypeEnum.INTEGER)
    // Players are at level 3
    .where('level', [3], EqualityEnum.EQUALS, PrimitiveTypeEnum.INTEGER)
    // trigger analyzeAsync with collected payload above
    .runAsync()
    .then((content) => {}).catch((err) => {});

// analyze current player by track 1 point with players who are;
// - "at level 3" and "male"
new AnalyzeBuilder()
    // analyze by track 1 point and value is integer
    .field('track1Point').type(PrimitiveTypeEnum.INTEGER)
    // Players are at level 3
    .where('level', [3], EqualityEnum.EQUALS, PrimitiveTypeEnum.INTEGER)
    // Players are male or boy
    .where('gender', ['male'], EqualityEnum.EQUALS, PrimitiveTypeEnum.STRING)
    // trigger analyzeAsync with collected payload above
    .runAsync()
    .then((content) => {}).catch((err) => {});

// analyze current player by track 1 point with players who are;
// - "at level 3" and "male" and "clicked before 2020-09-01"
new AnalyzeBuilder()
    // analyze by track 1 point and value is integer
    .field('track1Point').type(PrimitiveTypeEnum.INTEGER)
    // Players are at level 3
    .where('level', [3], EqualityEnum.EQUALS, PrimitiveTypeEnum.INTEGER)
    // Players are male or boy
    .where('gender', ['male'], EqualityEnum.EQUALS, PrimitiveTypeEnum.STRING)
    // Players are clicked before 2020-09-01
    .where('firstClickDate', ['2020-09-01'], EqualityEnum.LESS_THAN, PrimitiveTypeEnum.DATE)
    // trigger analyzeAsync with collected payload above
    .runAsync()
    .then((content) => {}).catch((err) => {});

// analyze current player by track 1 point with players who are;
// - "at level 3" and "male" and "clicked before 2020-09-01" and "favorite color is red"
new AnalyzeBuilder()
    // analyze by track 1 point and value is integer
    .field('track1Point').type(PrimitiveTypeEnum.INTEGER)
    // Players are at level 3
    .where('level', [3], EqualityEnum.EQUALS, PrimitiveTypeEnum.INTEGER)
    // Players are male or boy
    .where('gender', ['male'], EqualityEnum.EQUALS, PrimitiveTypeEnum.STRING)
    // Players are clicked before 2020-09-01
    .where('firstClickDate', ['2020-09-01'], EqualityEnum.LESS_THAN, PrimitiveTypeEnum.DATE)
    // Players who has favorite color is red, favoriteColors is array, so we used intersects
    .where('favoriteColors', ['red'], EqualityEnum.INTERSECTS, PrimitiveTypeEnum.STRING)
    // trigger analyzeAsync with collected payload above
    .runAsync()
    .then((content) => {}).catch((err) => {});

Current Player

Fetch current player info

connector.meAsync({
}).then((content) => {}).catch((err) => {});

Types

Interfaces / Models

// setAsync, incrementAsync, deleteAsync response
interface UpdateResponse {
    changed: number; // changed value
    ignored: number; // ignored value for some reasons (not changed, readonly, invalid etc)
}
// getAsync response
interface GetResponse extends Record<string, unknown> {
    createdAt?: string; // default system field, it holds first activity time
    updatedAt?: string; // default system field, it holds latest updating activity time
    // record means, more keys can be responded, ie: dynamic entity
}
// analyzeAsync request
interface AnalyzeRequest {
    field: string; // which field will be analyzed
    type?: string | PrimitiveTypeEnum; // data type of field, default: string
    where?: Array<QueryWhereItem>; // criteria
}
// analyzeAsync response
interface AnalyzeResponse {
    aboveCount: number; // # of players who's value is greater then current player (by response.field)
    belowCount: number; // # of players who's value is less then current player (by response.field)
    sameCount: number; // # of players who's value is equal to current player (by response.field)
    noneCount: number; // # of players who have not any value (by response.field)
    selfValue: unknown; // current player's value (by response.field)
    minValue: unknown; // min value in all players (by response.field)
    maxValue: unknown; // max value in all players (by response.field)
}
// filterAsync request
interface FilterRequest {
    select: Array<QuerySelectItem>; // selected fields, at least one
    where?: Array<QueryWhereItem>; // where criteria
    groupBy?: Array<QueryGroupByItem>; // group by criteria, not implemented, reserved for future
    orderBy?: Array<QueryOrderByItem>; // order statements
    limit?: number; // limit, top-n value, default: 20
    offset?: number; // for pagination, offset value, default: 0
}
interface FilterResponse extends Record<string, unknown> {
    profile: ProfilePair; // profile info
    // record means, more keys can be responded, by response.select fields
}
// each select item in filterAsync
interface QuerySelectItem {
    field: string; // selected field
    type?: PrimitiveTypeEnum; // field type, default: string
    aggregate?: AggregationEnum; // reserved for future and group by
}
// each where item in filterAsync and analyzeAsync
interface QueryWhereItem {
    field: string; // criteria or filtered field
    values?: Array<unknown>; //value or values of criteria
    type?: PrimitiveTypeEnum; // field type, default: string
    equation?: EqualityEnum; // equation of criteria
}
// each group by item in filterAsync
interface QueryGroupByItem {
    field: string; // grouped field
    type?: PrimitiveTypeEnum; // field type, default: string
}
// each order by item in filterAsync
interface QueryOrderByItem {
    field: string; // ordered field
    type?: PrimitiveTypeEnum; // field type, default: string
    desc?: boolean; // is desc or asc, default: false ASC: A->Z, 0->0, DESC: Z-A, 9->0
}

Profile Models

interface ProfileEntity extends Record<string, unknown> {
    id: string;
    name: string; // nickname of player
    role: BasePair; // $.id can be [owner, kid, adult]
    kind: BasePair; // $.id can be [demo, anonymous, regular, subscribed]
    effectiveKind: BasePair; // $.id can be [demo, anonymous, regular, subscribed]
    avatar: BasePair; // $.id is global media in huz
    theme: string; // ui theme name
    pegi?: BasePair; // age group
    language: BasePair; // $.id is 2-letter language code, ie: en, nl, de, it
    country: BasePair; // $.id is 2-letter country code, ie: NL, DE, UK, US, TR
    timezone: string; // standart timezone text, ie: Europe/Amsterdam
    isKid: boolean; // shortcut for role==kid
    anonymous: boolean; // shortcut for kind==anonymous
}
// it is used filter.response[].profile
interface ProfilePair {
    id: string;
    name: string;
    avatar: AvatarPair;
}
interface BasePair {
    id: string;
    name: string;
}
interface AvatarPair {
    id: string;
}

Enumerations / Static Items

// primitive data type for db value casting
enum PrimitiveTypeEnum {
    STRING = 'string', // plain text
    INTEGER = 'integer', // D
    FLOAT = 'float', // D.D
    BOOLEAN = 'boolean', // true, false
    DATETIME = 'datetime', // yyyy-mm-ddThh::ii:ss.eeeZ
    DATE = 'date', // yyyy-mm-dd
}
// it is used in filter.where[].equation and analyze.where[].equation
enum EqualityEnum {
    EQUALS = '$eq', // a == b, if "a" is not array
    NOT_EQUALS = '$eq_not', // a != b, if "a" is not array
    TRUE = '$true', // a == true, if type is boolean
    FALSE = '$false', // a == false, if type is boolean
    NULL = '$null', // a == null, if "a" is not array
    NOT_NULL = '$null_not', // a != null, if "a" is not array
    GREATER_THAN = '$gt', // a > b, if "a" is not array
    NOT_GREATER_THAN = '$gt_not', // !(a > b), if "a" is not array
    GREATER_OR_EQUAL_THAN = '$gte', // a >= b, if "a" is not array
    NOT_GREATER_OR_EQUAL_THAN = '$gte_not', // !(a >= b), if "a" is not array
    LESS_THAN = '$lt', // a < b, if "a" is not array
    NOT_LESS_THAN = '$lt_not', // !(a < b), if "a" is not array
    LESS_OR_EQUAL_THAN = '$lte', // a <= b, if "a" is not array
    NOT_LESS_OR_EQUAL_THAN = '$lte_not', // !(a <= b), if "a" is not array
    BETWEEN = '$between', // (a >= b) && (a <= c), if "a" is not array
    NOT_BETWEEN = '$between_not', // !((a >= b) && (a <= c)), if "a" is not array
    IN = '$in', // a in [b,c,d,..], if "a" is not array
    NOT_IN = '$in_not', // !(a in [b,c,d,..]), if "a" is not array
    INTERSECTS = '$intersects', // (a intersects [b,c,d,...]), if "a" is array
    NOT_INTERSECTS = '$intersects_not', // !(a intersects [b,c,d,...]), if "a" is array
    STARTS_WITH = '$starts_with', // a.startsWith(b), if type is string
    NOT_STARTS_WITH = '$starts_with_not', // !a.startsWith(b), if type is string
    ENDS_WITH = '$ends_with', // a.endsWith(b), if type is string
    NOT_ENDS_WITH = '$ends_with_not', // !a.endsWith(b), if type is string
    CONTAINS = '$contains', // a.contains(b), if type is string
    NOT_CONTAINS = '$contains_not', // !a.contains(b), if type is string
}
// reserved for future
enum AggregationEnum {
    COUNT = 'count', // count of players, ie: # of players
    AVG = 'avg', // average of player' values, ie: average point
    SUM = 'sum', // sum of player' values, ie: total gold won
    MIN = 'min', // min value of player' values, ie: min point
    MAX = 'max', // max value of player' values, ie: max point
}

Prepared By

Mustafa Yelmer, 2021-02-06, v03