corebasic 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +2 -0
- package/libs/ObjectId.js +127 -0
- package/libs/app.js +11 -0
- package/libs/elabase.js +174 -0
- package/libs/kafka.js +142 -0
- package/libs/utils.js +55 -0
- package/package.json +11 -0
package/index.js
ADDED
package/libs/ObjectId.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* Copyright (c) 2011-2014- Justin Dearing (zippy1981@gmail.com)
|
|
4
|
+
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
|
5
|
+
* and GPL (http://www.opensource.org/licenses/gpl-license.php) version 2 licenses.
|
|
6
|
+
* This software is not distributed under version 3 or later of the GPL.
|
|
7
|
+
*
|
|
8
|
+
* Version 1.0.2
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if (!document) var document = { cookie: '' }; // fix crashes on node
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Javascript class that mimics how WCF serializes a object of type MongoDB.Bson.ObjectId
|
|
18
|
+
* and converts between that format and the standard 24 character representation.
|
|
19
|
+
*/
|
|
20
|
+
var ObjectId = (function () {
|
|
21
|
+
var increment = Math.floor(Math.random() * (16777216));
|
|
22
|
+
var pid = Math.floor(Math.random() * (65536));
|
|
23
|
+
var machine = Math.floor(Math.random() * (16777216));
|
|
24
|
+
|
|
25
|
+
var setMachineCookie = function() {
|
|
26
|
+
var cookieList = document.cookie.split('; ');
|
|
27
|
+
for (var i in cookieList) {
|
|
28
|
+
var cookie = cookieList[i].split('=');
|
|
29
|
+
var cookieMachineId = parseInt(cookie[1], 10);
|
|
30
|
+
if (cookie[0] == 'mongoMachineId' && cookieMachineId && cookieMachineId >= 0 && cookieMachineId <= 16777215) {
|
|
31
|
+
machine = cookieMachineId;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
document.cookie = 'mongoMachineId=' + machine + ';expires=Tue, 19 Jan 2038 05:00:00 GMT;path=/';
|
|
36
|
+
};
|
|
37
|
+
if (typeof (localStorage) != 'undefined') {
|
|
38
|
+
try {
|
|
39
|
+
var mongoMachineId = parseInt(localStorage['mongoMachineId']);
|
|
40
|
+
if (mongoMachineId >= 0 && mongoMachineId <= 16777215) {
|
|
41
|
+
machine = Math.floor(localStorage['mongoMachineId']);
|
|
42
|
+
}
|
|
43
|
+
// Just always stick the value in.
|
|
44
|
+
localStorage['mongoMachineId'] = machine;
|
|
45
|
+
} catch (e) {
|
|
46
|
+
setMachineCookie();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
setMachineCookie();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function ObjId() {
|
|
54
|
+
if (!(this instanceof ObjectId)) {
|
|
55
|
+
return new ObjectId(arguments[0], arguments[1], arguments[2], arguments[3]).toString();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (typeof (arguments[0]) == 'object') {
|
|
59
|
+
this.timestamp = arguments[0].timestamp;
|
|
60
|
+
this.machine = arguments[0].machine;
|
|
61
|
+
this.pid = arguments[0].pid;
|
|
62
|
+
this.increment = arguments[0].increment;
|
|
63
|
+
}
|
|
64
|
+
else if (typeof (arguments[0]) == 'string' && arguments[0].length == 24) {
|
|
65
|
+
this.timestamp = Number('0x' + arguments[0].substr(0, 8)),
|
|
66
|
+
this.machine = Number('0x' + arguments[0].substr(8, 6)),
|
|
67
|
+
this.pid = Number('0x' + arguments[0].substr(14, 4)),
|
|
68
|
+
this.increment = Number('0x' + arguments[0].substr(18, 6))
|
|
69
|
+
}
|
|
70
|
+
else if (arguments.length == 4 && arguments[0] != null) {
|
|
71
|
+
this.timestamp = arguments[0];
|
|
72
|
+
this.machine = arguments[1];
|
|
73
|
+
this.pid = arguments[2];
|
|
74
|
+
this.increment = arguments[3];
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.timestamp = Math.floor(new Date().valueOf() / 1000);
|
|
78
|
+
this.machine = machine;
|
|
79
|
+
this.pid = pid;
|
|
80
|
+
this.increment = increment++;
|
|
81
|
+
if (increment > 0xffffff) {
|
|
82
|
+
increment = 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
return ObjId;
|
|
87
|
+
})();
|
|
88
|
+
|
|
89
|
+
ObjectId.prototype.getDate = function () {
|
|
90
|
+
return new Date(this.timestamp * 1000);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
ObjectId.prototype.toArray = function () {
|
|
94
|
+
var strOid = this.toString();
|
|
95
|
+
var array = [];
|
|
96
|
+
var i;
|
|
97
|
+
for(i = 0; i < 12; i++) {
|
|
98
|
+
array[i] = parseInt(strOid.slice(i*2, i*2+2), 16);
|
|
99
|
+
}
|
|
100
|
+
return array;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Turns a WCF representation of a BSON ObjectId into a 24 character string representation.
|
|
105
|
+
*/
|
|
106
|
+
ObjectId.prototype.toString = function () {
|
|
107
|
+
if (this.timestamp === undefined
|
|
108
|
+
|| this.machine === undefined
|
|
109
|
+
|| this.pid === undefined
|
|
110
|
+
|| this.increment === undefined) {
|
|
111
|
+
return 'Invalid ObjectId';
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
var timestamp = this.timestamp.toString(16);
|
|
115
|
+
var machine = this.machine.toString(16);
|
|
116
|
+
var pid = this.pid.toString(16);
|
|
117
|
+
var increment = this.increment.toString(16);
|
|
118
|
+
return '00000000'.substr(0, 8 - timestamp.length) + timestamp +
|
|
119
|
+
'000000'.substr(0, 6 - machine.length) + machine +
|
|
120
|
+
'0000'.substr(0, 4 - pid.length) + pid +
|
|
121
|
+
'000000'.substr(0, 6 - increment.length) + increment;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
module.exports = {
|
|
126
|
+
ObjectId,
|
|
127
|
+
}
|
package/libs/app.js
ADDED
package/libs/elabase.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
const axios = require('axios')
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
start,
|
|
6
|
+
insert,
|
|
7
|
+
update,
|
|
8
|
+
query,
|
|
9
|
+
remove
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
let Utils = {
|
|
24
|
+
isEmpty: function(arg) { return arg === "" || arg == undefined || !arg ? true : false },
|
|
25
|
+
requisites: { startElabase: function () { } }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let Events = {
|
|
29
|
+
send: function() { }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
let url = "http://127.0.0.1"
|
|
36
|
+
let port = 9401
|
|
37
|
+
let api = 'execute'
|
|
38
|
+
let fullurl = `${url}:${port}/${api}`
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
let Elabase = {
|
|
42
|
+
Engine: {
|
|
43
|
+
Lmdb: 1,
|
|
44
|
+
Sled: 2,
|
|
45
|
+
Sanakirja: 3,
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let engine = Elabase.Engine.Lmdb
|
|
50
|
+
let internal = {
|
|
51
|
+
db: undefined,
|
|
52
|
+
engineName: engine === Elabase.Engine.Lmdb ? "lmdb" : (engine === Elabase.Engine.Sled ? "sled" : engine === Elabase.Engine.Sanakirja ? "sanakirja" : "lmdb")
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let db = internal.db // default database
|
|
56
|
+
|
|
57
|
+
function start(dbName) {
|
|
58
|
+
if (!Utils.isEmpty(dbName) && Utils.isEmpty(db)) {
|
|
59
|
+
internal.db = dbName
|
|
60
|
+
db = dbName
|
|
61
|
+
Utils.requisites.startElabase()
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
function insert(collection, value, _id) {
|
|
67
|
+
var arg = {
|
|
68
|
+
collection: collection,
|
|
69
|
+
insert: value
|
|
70
|
+
}
|
|
71
|
+
if (_id)
|
|
72
|
+
arg._id = _id
|
|
73
|
+
|
|
74
|
+
return new Promise((resolve, reject) => resolve())
|
|
75
|
+
.then(() => execute(arg))
|
|
76
|
+
.then(result => {
|
|
77
|
+
Events.send("Elabase.insert", { collection: collectionArray(collection), response: result })
|
|
78
|
+
return result
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function query(collection, query) {
|
|
83
|
+
var arg = {
|
|
84
|
+
collection: collection,
|
|
85
|
+
query: query
|
|
86
|
+
}
|
|
87
|
+
return new Promise((resolve, reject) => resolve())
|
|
88
|
+
.then(() => execute(arg))
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function collectionArray(col) {
|
|
92
|
+
var type = Object.prototype.toString.call(col)
|
|
93
|
+
if (type === '[object Array]') {
|
|
94
|
+
var newcol = []
|
|
95
|
+
for (var i in col) {
|
|
96
|
+
if (!Utils.isEmpty(col[i]))
|
|
97
|
+
newcol.push(col[i])
|
|
98
|
+
}
|
|
99
|
+
return newcol
|
|
100
|
+
} else if (type === '[object String]') {
|
|
101
|
+
if (!Utils.isEmpty(col))
|
|
102
|
+
return [col]
|
|
103
|
+
}
|
|
104
|
+
return []
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
function update(collection, query, update) {
|
|
109
|
+
var arg = {
|
|
110
|
+
collection: collection,
|
|
111
|
+
query: query,
|
|
112
|
+
update: update,
|
|
113
|
+
}
|
|
114
|
+
return new Promise((resolve, reject) => resolve())
|
|
115
|
+
.then(() => execute(arg))
|
|
116
|
+
.then (result => {
|
|
117
|
+
Events.send("Elabase.update", { collection: collectionArray(collection), response: result })
|
|
118
|
+
return result
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function remove(collection, query) {
|
|
123
|
+
var arg = {
|
|
124
|
+
collection: collection,
|
|
125
|
+
query: query,
|
|
126
|
+
delete: true,
|
|
127
|
+
}
|
|
128
|
+
return new Promise((resolve, reject) => resolve())
|
|
129
|
+
.then(() => execute(arg))
|
|
130
|
+
.then(result => {
|
|
131
|
+
Events.send("Elabase.remove", { collection: collectionArray(collection), response: result })
|
|
132
|
+
return result
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function execute(arg) {
|
|
137
|
+
// arg example
|
|
138
|
+
// {
|
|
139
|
+
// db: "sled-sandhra",
|
|
140
|
+
// collection: "staff",
|
|
141
|
+
// query: "[@][?name == 'Bilbo'] | [0]",
|
|
142
|
+
// insert: { "name": "Bilbo" },
|
|
143
|
+
// query: { "name": "Frodo"},
|
|
144
|
+
// update: { "$set": { "age": 21 } }
|
|
145
|
+
|
|
146
|
+
// _id: 1 // Optional. Used with insert
|
|
147
|
+
// }
|
|
148
|
+
arg.db = arg.db ?? db
|
|
149
|
+
arg.engine = arg.engine ?? internal.engineName
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
return axios
|
|
153
|
+
.post(fullurl, arg)
|
|
154
|
+
// .timeout(5000)
|
|
155
|
+
.then(result => {
|
|
156
|
+
// console.log(res.status);
|
|
157
|
+
// console.log(JSON.stringify(res.header, null, 4));
|
|
158
|
+
// console.log(JSON.stringify(res.body, null, 4));
|
|
159
|
+
|
|
160
|
+
return result.data
|
|
161
|
+
})
|
|
162
|
+
// .catch(err => { console.log(err.message); console.log(err.response); return err});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
// Axios usage
|
|
172
|
+
//--------------
|
|
173
|
+
// const axios = require('axios')
|
|
174
|
+
// axios.get('http://www.floatrates.com/daily/usd.json').then(data => console.log(data)).catch(error=> console.log(error))
|
package/libs/kafka.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
const { Kafka } = require('kafkajs')
|
|
2
|
+
|
|
3
|
+
let kafka, producer, admin
|
|
4
|
+
|
|
5
|
+
let topicPrefix = ''
|
|
6
|
+
|
|
7
|
+
function start(arg) {
|
|
8
|
+
topicPrefix = process.env.APP_DEPLOYMENT_NAME + '.'
|
|
9
|
+
kafka = new Kafka({
|
|
10
|
+
clientId: arg?.clientId ?? process.env.APP_DEPLOYMENT_NAME,
|
|
11
|
+
brokers: arg?.brokers ?? ['redpanda-0.redpanda.redpanda.svc.cluster.local:9093'], // ['107.155.108.78:9092'] ['127.0.0.1:29092']
|
|
12
|
+
sasl: {
|
|
13
|
+
mechanism: 'SCRAM-SHA-512',
|
|
14
|
+
username: process.env.KAFKA_USERNAME,
|
|
15
|
+
password: process.env.KAFKA_PASSWORD
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
producer = kafka.producer({allowAutoTopicCreation: true})
|
|
19
|
+
admin = kafka.admin();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async function createTopic(topic, partition, replicas) {
|
|
24
|
+
topic = topicPrefix + topic
|
|
25
|
+
return await admin.createTopics({ topics: [{topic, numPartitions: partition ?? 1, replicationFactor: replicas ?? 1}] })
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ===========
|
|
29
|
+
// Consumer
|
|
30
|
+
// ===========
|
|
31
|
+
|
|
32
|
+
let consumers = []
|
|
33
|
+
|
|
34
|
+
const start_consumer = async function (topic, groupId, callback) {
|
|
35
|
+
const consumer = kafka.consumer({ groupId: groupId ? groupId : "" })
|
|
36
|
+
consumers.push(consumer)
|
|
37
|
+
|
|
38
|
+
await consumer.connect()
|
|
39
|
+
await consumer.subscribe({ topic: topic, fromBeginning: true })
|
|
40
|
+
|
|
41
|
+
await consumer.run({
|
|
42
|
+
eachMessage: async ({ topic, partition, message }) => {
|
|
43
|
+
// callback(topic, message.value.toString(), partition) // toString() returns array so won't parse if json.
|
|
44
|
+
callback(topic, JSON.parse(message.value), partition)
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
// ===========
|
|
51
|
+
// Producer
|
|
52
|
+
// ===========
|
|
53
|
+
let producerInvoked = false
|
|
54
|
+
const start_producer = async function (topic, message, key) {
|
|
55
|
+
|
|
56
|
+
let isJson = Object.prototype.toString.call(message) === '[object Object]' || Object.prototype.toString.call(message) === '[object Array]'
|
|
57
|
+
|
|
58
|
+
if (!producerInvoked) {
|
|
59
|
+
await producer.connect()
|
|
60
|
+
producerInvoked = true
|
|
61
|
+
}
|
|
62
|
+
let value = isJson ? JSON.stringify(message) : message
|
|
63
|
+
await producer.send({
|
|
64
|
+
topic: topic,
|
|
65
|
+
messages: [
|
|
66
|
+
key ? { key, value} : {value},
|
|
67
|
+
],
|
|
68
|
+
})
|
|
69
|
+
// .then(console.log)
|
|
70
|
+
// .catch(e => console.error("[example/producer] " + e.message, e))
|
|
71
|
+
// await producer.disconnect()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
// start_consumer('quickstart-events')
|
|
77
|
+
// start_producer('quickstart-events', 'Hello KafkaJS user! Little')
|
|
78
|
+
|
|
79
|
+
const receive = async function(topic, groupId, callback) {
|
|
80
|
+
topic = topicPrefix + topic
|
|
81
|
+
await start_consumer(topic, groupId, callback)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
const send = async function(topic, message, key) {
|
|
86
|
+
topic = topicPrefix + topic
|
|
87
|
+
await start_producer(topic, message, key)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = {
|
|
91
|
+
start,
|
|
92
|
+
createTopic,
|
|
93
|
+
send,
|
|
94
|
+
receive,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
// Usage
|
|
100
|
+
// -------
|
|
101
|
+
// send('quickstart-events', { name: 'Muneer', age: 30 })
|
|
102
|
+
|
|
103
|
+
// receive('quickstart-events', function (topic, message) {
|
|
104
|
+
// console.log(message)
|
|
105
|
+
// })
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
const errorTypes = ['unhandledRejection', 'uncaughtException']
|
|
114
|
+
const signalTraps = ['SIGTERM', 'SIGINT', 'SIGUSR2']
|
|
115
|
+
|
|
116
|
+
errorTypes.forEach(type => {
|
|
117
|
+
process.on(type, async () => {
|
|
118
|
+
try {
|
|
119
|
+
console.log(`process.on ${type}`)
|
|
120
|
+
if (producer)
|
|
121
|
+
await producer.disconnect()
|
|
122
|
+
for (let i = 0; i < consumers.length; i++)
|
|
123
|
+
await consumers[i].disconnect()
|
|
124
|
+
process.exit(0)
|
|
125
|
+
} catch (_) {
|
|
126
|
+
process.exit(1)
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
signalTraps.forEach(type => {
|
|
132
|
+
process.once(type, async () => {
|
|
133
|
+
try {
|
|
134
|
+
if (producer)
|
|
135
|
+
await producer.disconnect()
|
|
136
|
+
for (let i = 0; i < consumers.length; i++)
|
|
137
|
+
await consumers[i].disconnect()
|
|
138
|
+
} finally {
|
|
139
|
+
process.kill(process.pid, type)
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
})
|
package/libs/utils.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
let ObjectId = require('./ObjectId')
|
|
2
|
+
|
|
3
|
+
let pipeline = { execute: execute }
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
uid,
|
|
7
|
+
isEmpty,
|
|
8
|
+
parseFloatValue,
|
|
9
|
+
parseIntValue,
|
|
10
|
+
now,
|
|
11
|
+
pipeline,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function uid() {
|
|
15
|
+
return ObjectId.ObjectId()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isEmpty(str) { // returns true for undefined
|
|
19
|
+
if(!str)
|
|
20
|
+
return true
|
|
21
|
+
return str.match(/\S/) ? false : true // matches a non space character
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// --------------
|
|
25
|
+
// Parse Numbers
|
|
26
|
+
// --------------
|
|
27
|
+
|
|
28
|
+
function parseFloatValue(val) {
|
|
29
|
+
return parseFloat(val) ? parseFloat(val) : 0
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function parseIntValue(val) {
|
|
33
|
+
return parseInt(val) ? parseInt(val) : 0
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function now() {
|
|
37
|
+
return new Date()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
// ----------------
|
|
42
|
+
// Pipeline Execute
|
|
43
|
+
// ----------------
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
function execute(pipeline, errfn) {
|
|
47
|
+
startPipeline(pipeline, 0, undefined, errfn)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function startPipeline(pipeline, index, data, errfn) {
|
|
51
|
+
index = index == undefined ? 0 : index
|
|
52
|
+
if (index == pipeline.length)
|
|
53
|
+
return
|
|
54
|
+
pipeline[index](data).then(data => startPipeline(pipeline, index + 1, data)).catch(err => { if (errfn) errfn(err) } )
|
|
55
|
+
}
|