Gathering detailed insights and metrics for codic
Gathering detailed insights and metrics for codic
Gathering detailed insights and metrics for codic
Gathering detailed insights and metrics for codic
Easy, intuitive database agnostic scheduler for node, JavaScript
npm install codic
Typescript
Module System
Min. Node Version
Node Version
NPM Version
74.8
Supply Chain
99
Quality
75.8
Maintenance
100
Vulnerability
99.6
License
TypeScript (97.17%)
JavaScript (2.83%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
NOASSERTION License
2 Stars
41 Commits
1 Forks
1 Watchers
1 Branches
1 Contributors
Updated on Nov 08, 2021
Latest Version
2.0.6
Package Id
codic@2.0.6
Unpacked Size
102.93 kB
Size
25.08 kB
File Count
113
NPM Version
5.6.0
Node Version
10.1.0
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
1
24
Fast, extensible queue manager for Node.
Typescript-enabled job scheduling with live update mechanism.
Made to be lightweight and fully customizable. Plug a database driver, write tasks and run. Same operation for different databases.
Since there are a few job queue solutions, here a table comparing them to help you use the one that better suits your needs.
Codic is recommended for its database variety, dynamic tasks support, and lightweight operations.
Feature | Codic | Bull | Kue | Bee | Agenda |
---|---|---|---|---|---|
Backend | any | redis | redis | redis | mongo |
Priorities | ✓ | ✓ | ✓ | ✓ | |
Concurrency | ✓ | ✓ | ✓ | ✓ | |
Delayed jobs | ✓ | ✓ | ✓ | ✓ | |
Global events | ✓ | ✓ | |||
Rate Limiter | ✓ | ||||
Pause/Resume | ✓ | ✓ | |||
Sandboxed worker | ✓ | ||||
Repeatable jobs | ✓ | ✓ | ✓ | ||
Atomic ops | ✓ | ✓ | ✓ | ||
Persistence | ✓ | ✓ | ✓ | ✓ | ✓ |
UI | ✓ | ✓ | ✓ | ||
Optimized for | Jobs | Jobs / Messages | Jobs | Messages | Jobs |
Kudos for making the comparison chart goes to Bull maintainers.
The inspiration comes from Agenda
Anyone can write a driver for any database or storage mechanism to work with Codic in managing schedules.
By default we support in-memory storage. Contributions are welcome. We will soon publish more details on how to contribute to codic itself.
Driver | Database |
---|---|
codic-memory | Memory |
codic-redis | Redis |
npm install --save codic
or
yarn add codic
Codic is easy to implement. In your code, do the following:
1import Codic from "codic"; 2 3//instatiate codic 4var codic = new Codic(); 5 6// define your tasks 7const simpleLogTask = (activity) => { 8 console.log("Simply saying "+activity.attrs.data.message); // data will be passed in 9} 10// wrap in an IIFE, for async operation 11(async function(){ 12 13 try { 14 // register task on Codic 15 await codic.assign("say hello",simpleLogTask); 16 17 //create the activities that run the tasks 18 await codic 19 .run("say hello") 20 .every("3 seconds") // or simply 3 21 .use({ message:"Hello" }) //pass data to the task(s) 22 .startAt("2018-12-12") // when to start from (optional) 23 .setName("some_activity_name") //optional 24 .save(); 25 26 //start codic 27 await codic.start(); 28 } catch (error) { 29 console.log(error); 30 } 31})();
Thats it. You are live!!
You can create many activities that run the same say hello
task(function) or different tasks for the same activity.
Install a driver library of your choice. Currently codic-redis is available. Anyone can write a driver and let us know to link it here.
npm install --save codic-redis
or
yarn add codic-redis
1import Codic from "codic"; 2//import external driver 3import RedisDriver from "codic-redis"; 4 5//instatiate driver 6var driver = new RedisDriver(); 7//instatiate codic and pass in the driver 8var codic = new Codic(driver); 9 10// ... continue as above
Codic uses Activities and Tasks to let you automate processes in your app.
A task is what you want to do at a particular time. It can be a simple function or a file exporting a function.
An activity can contain a number of tasks that will be performed. Tasks will be ranked in terms of priority
Activity specifies the time and how often one or more tasks are run. They can be executed repeatedly or once.
So when a scheduled activity is executed, it will run one or more tasks before it ends. This is a bit different from existing schedulers that only let you create jobs and pass in functions.
Assuming we have defined a task as follows:
1import mailer from "somepackage"; 2import getUsersByGroupId from "somepackage2"; 3 4await codic.assign("send notifications",async function(activity){ 5 let groupId = activity.attrs.data.groupId; 6 let users = await getUsersByGroupId(groupId); 7 let message="Report to headquarters"; 8 users.map(async user=>{ 9 await mailer.send(user.email,message); 10 }); 11})
1// pass isoString or human-interval or milliseconds to the at method 2await codic.run("send notifications") 3 .use({groupId:1}) 4 .at("2019-12-08T23:31:24.627Z") 5 .save(); 6 7await codic.start(); 8
1await codic.setName("someName").save(); 2
1// wait 5 minutes before executing activity 2await codic.run(["send notifications"]) 3 .every("30 minutes") 4 .startIn("5 minutes") 5 .save(); 6
You can pass the task list, repeat time and data to the .run
method
1await codic.run( 2 ["send notifications","task2"], //tasks 3 "30 minutes", //time, every("30 minutes") 4 {groupId:2} //data, use({groupId:2}) 5 ) 6 .save(); 7
Dynamic tasks can be created and executed at any point in your execution cycle. You will then be able to pass different data to the task at any point in your code.
To use dynamic tasks, define each task in a separate file and export it as default: lets say we have
src/
tasks/
email-sender-task.js
lib/
email-sender.js
Then, in email-sender-task.js,
1// tasks/email-sender-task.js 2 3// do your imports here if any 4require const emailSender = "../lib/email-sender"; 5 6function sendEmails(activity){ 7 // your content here 8 console.log("Sending emails"); 9 emailSender.sendMassEmails(); 10} 11 12module.exports=dynamicTask; //or 13export default dynamicTask;
Register your task with codic, in your app:
1const path = require("path"); 2//define full path to task file 3let taskPath = path.join(process.cwd(),"./tasks/dynamic-task.js"); 4//register full path 5await codic.define("send emails",taskPath); 6
Now you can use the task in your activities. The task content can be modified in the email-sender-task.js
file and codic will always read the latest changes.
You can also create several activities that use the same task, during runtime.
To update an activity, set a name for it during creation. You can then use the name to fetch, modify and then save the change.
1await codic.run("send emails") 2 .every("year") 3 .use({recipients:[ 4 "joe@gmail.com","doe@yahoo.com"] 5 }) 6 .setName("annualMailsActivity");
then somewhere else in your app,
1let annualMA = await codic.activities.get("annualMailsActivity"); 2//add another recipient 3let newRecipients=["joe@gmail.com","doe@yahoo.com","sam@live.com"]; 4annualMA.use({recipients:newRecipients}); 5await annualMA.save();
We have written codic to make it easy for anyone to use and build upon. Fully Typescript, in-built memory driver, and even more tests with mocha
Note: You don't have to know or use typescript to develop with codic, or to use codic. It works same way with regular javascript.
Codic is entirely written in typescript. This means you can implement the driver interface and create your own storage driver without knowing the internals of codic. We have included declarations for all methods and variables. More comments will come soon, but everything is mostly self-explanatory, we hope :).
Right on the start, you get a default memory driver. That means codic can work standalone if you do not supply external driver. Memory driver means your schedules won't survive a service restart. For production use, do opt for an external persistent storage driver.
Creating a codic storage driver is easy. Just implement the methods and properties on the driver interface and you are done.
The driver is just a plain object with two properties. Your driver instance should export an object as shown below.
1driver = { 2 tasks:{ //Tasks 3 //methods for handling tasks 4 }, 5 activities:{ // Activities 6 // methods for handling activities 7 } 8}
The driver.tasks
object implements the ITasks
interface which is as shown below. Your tasks object should export all the methods and return the data as specified. The implementation below is taken from the in-built memory driver which implements the same methods.
1//storage object. mode of communication between codic and driver.tasks 2interface TaskModel { 3 name: string; 4 id?: string | number; 5 config: TaskConfig; 6 definition: string | TaskDefinition; 7} 8//custom interface for your driver,(optional) 9//just to separate in-house implementations from basic codic stuff 10interface IATasks { 11 list?: Array<TaskModel>; 12} 13// driver.tasks interface 14interface ITasks extends IATasks { 15 getById?(id: string | number): Promise<TaskModel>; 16 save(activity: TaskModel): Promise<TaskModel>; 17 get(name: string): Promise<TaskModel>; 18 all(): Promise<Array<TaskModel>>; 19 clear(): number; 20}
The TaskModel
, TaskDefinition
, TaskConfig
interface can be found in lib/codic/task/constructor.ts
.
ITasks and IATasks interfaces can be found in lib/memory/tasks/constructor.ts
.
For JS developers, you only have to return an object similar to TaskModel when returning a task.
The activities interface is similar to the tasks and is as shown.
1//storage object. mode of communication between codic and driver.activities 2interface ActivityModel { 3 driver?: any; 4 id?: string | number; 5 status: ActivityStatus; 6 nextRun: number; 7 lastRun?: number; 8 failedAt?: Date; 9 failReason?: string; 10 startedAt?: Date; 11 type: ActivityType; 12 _name?: string; 13 attrs: IActivityAttr; 14 taskNames: Array<string>; 15} 16 17//custom stuff 18interface IAActivities { 19 list?: Array<ActivityModel>; 20} 21 22//driver.activities interface 23interface `IActivities` extends `IAActivities` { 24 getById?(id: string | number): Promise<ActivityModel>; 25 save(activity: ActivityModel): Promise<ActivityModel>; 26 getDueList(): Promise<Array<ActivityModel>>; 27 getActive(): Promise<Array<ActivityModel>>; 28 get(name: string): Promise<ActivityModel>; 29 all(): Promise<Array<ActivityModel>>; 30 getNextRunDelay(): Promise<number>; 31 clear(): Promise<number>; 32 skip():Activity; 33}
The ActivityModel
, IActivityAttr
, interface can be found in lib/codic/activity/constructor
.
IActivities
and IAActivities
can be found in lib/memory/activities/constructor
.
ActivityType and ActivityStatus can be found in lib/codic/activity/enums
.
You can follow lib/memory
as a sample implementation to create your driver.
Remember to manage copies of these declarations in your local project instead of referencing in codic.
Namespaces shall be introduced to put things in perspective in future updates.
Creating and managing record ids is left to you the creator of the driver. Codic mostly works with names of tasks and activities though ids are used in some cases.
Javascript developers should return objects that implement TaskModel and ActivityModel, as single items or array. The other interfaces should serve only as reference to know which methods to implement
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no SAST tool detected
Details
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
70 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More