corebasic 1.0.181 → 1.0.183

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/libs/dip.js CHANGED
@@ -8,10 +8,10 @@ export const query = Elabase.query
8
8
  export const update = Elabase.update
9
9
  export const remove = Elabase.remove
10
10
 
11
- export const transactionBegin = Elabase.transactionBegin
12
- export const transactionAbort = Elabase.transactionAbort
13
- export const transactionReset = Elabase.transactionReset
14
- export const transactionCommit = Elabase.transactionCommit
11
+ export const batchBegin = Elabase.batchBegin
12
+ export const batchAbort = Elabase.batchAbort
13
+ export const batchReset = Elabase.batchReset
14
+ export const batchSubmit = Elabase.batchSubmit
15
15
 
16
16
  export const shard_stats = Elabase.shard_stats
17
17
  export let config = Elabase.config
package/libs/elabase.js CHANGED
@@ -54,74 +54,84 @@ export function start(dbName) {
54
54
  }
55
55
  }
56
56
 
57
- function generate_suffix(meta) {
57
+ function validate_collection(collection, fn_name) {
58
+ if ((typeof collection === 'string' && collection.trim() === "") || (typeof collection !== 'string' && !Array.isArray(collection)) || (Array.isArray(collection) && (!collection.length || collection.some(item => typeof item !== "string" || item.trim() === "")))) {
59
+ throw {message: `Error: Invalid collection ${fn_name}`}
60
+ }
61
+ }
58
62
 
63
+ function validate_meta(meta, fn_name) {
59
64
  if (!meta || typeof meta !== 'object') {
60
- throw {message: "Dip Error. Invalid meta"}
65
+ throw {message: `Error: Invalid meta ${fn_name}`}
61
66
  }
62
67
  if ((typeof meta.company === 'string' && meta.company.trim() === "") || (typeof meta.company !== 'string' && !Array.isArray(meta.company)) || (Array.isArray(meta.company) && (!meta.company.length || meta.company.some(item => typeof item !== "string"|| item.trim() === "")))) {
63
- throw {message: "Dip Error. Invalid meta.company"}
68
+ throw {message: `Error: Invalid meta.company ${fn_name}`}
64
69
  }
65
70
  if ((typeof meta.outlet === 'string' && meta.outlet.trim() === "") || (typeof meta.outlet !== 'string' && !Array.isArray(meta.outlet)) || (Array.isArray(meta.outlet) && (!meta.outlet.length || meta.outlet.some(item => typeof item !== "string" || item.trim() === "")))) {
66
- throw {message: "Dip Error. Invalid meta.outlet"}
71
+ throw {message: `Error: Invalid meta.outlet ${fn_name}`}
67
72
  }
68
73
  if ((meta.suffix !== undefined && typeof meta.suffix !== 'string' && !Array.isArray(meta.suffix)) || (Array.isArray(meta.suffix) && meta.suffix.some(item => typeof item !== "string" || item.trim() === ""))) {
69
- throw {message: "Dip Error. Invalid meta.suffix"}
74
+ throw {message: `Error: Invalid meta.suffix ${fn_name}`}
70
75
  } else if (typeof meta.suffix === 'string' && meta.suffix.trim() === "")
71
- throw {message: "Dip Error. Invalid meta.suffix"}
72
-
73
-
74
- let company = typeof meta.company == 'string' ? [meta.company] : (meta.company?.length ? meta.company : [])
75
- let outlet = typeof meta.outlet == 'string' ? [meta.outlet] : (meta.outlet?.length ? meta.outlet : [])
76
- let suffix = typeof meta.suffix == 'string' ? [meta.suffix] : (meta.suffix?.length ? meta.suffix : [])
77
-
78
- company = company.filter(item => item.trim() !== "")
79
- outlet = outlet.filter(item => item.trim() !== "")
80
- suffix = suffix.filter(item => item.trim() !== "")
81
-
82
- company = company.length ? company : [""]
83
- outlet = outlet.length ? outlet : [""]
84
- suffix = suffix.length ? suffix : [""]
85
-
86
- company = new Set(company)
87
- outlet = new Set(outlet)
88
- suffix = new Set(suffix)
89
-
90
- // console.log(company, outlet, suffix)
91
- let suffixes = []
92
- for (let c of company) {
93
- for (let o of outlet) {
94
- for (let s of suffix) {
95
- let pathSegments = [c, o, s].filter(segment => segment !== "");
96
- if (pathSegments.length > 0) {
97
- suffixes.push(pathSegments.join('/'));
98
- }
76
+ throw {message: `Error: Invalid meta.suffix ${fn_name}`}
77
+ }
78
+
79
+ function generate_suffix(meta) {
80
+
81
+ // Assuming validate_meta() is called before reaching here. If not then this is intentional validation bypass
82
+
83
+ let company = typeof meta.company == 'string' ? [meta.company] : (meta.company?.length ? meta.company : [])
84
+ let outlet = typeof meta.outlet == 'string' ? [meta.outlet] : (meta.outlet?.length ? meta.outlet : [])
85
+ let suffix = typeof meta.suffix == 'string' ? [meta.suffix] : (meta.suffix?.length ? meta.suffix : [])
86
+
87
+ company = company.filter(item => item.trim() !== "")
88
+ outlet = outlet.filter(item => item.trim() !== "")
89
+ suffix = suffix.filter(item => item.trim() !== "")
90
+
91
+ company = company.length ? company : [""]
92
+ outlet = outlet.length ? outlet : [""]
93
+ suffix = suffix.length ? suffix : [""]
94
+
95
+ company = new Set(company)
96
+ outlet = new Set(outlet)
97
+ suffix = new Set(suffix)
98
+
99
+ // console.log(company, outlet, suffix)
100
+ let suffixes = []
101
+ for (let c of company) {
102
+ for (let o of outlet) {
103
+ for (let s of suffix) {
104
+ let pathSegments = [c, o, s].filter(segment => segment !== "");
105
+ if (pathSegments.length > 0) {
106
+ suffixes.push(pathSegments.join('/'));
99
107
  }
100
108
  }
101
109
  }
110
+ }
102
111
 
103
- return suffixes
112
+ return suffixes
104
113
  }
105
114
 
106
- let isBranch = false
107
- let batches = []
115
+ let BATCH_COUNTER = 0n;
116
+ let batches = {}
108
117
 
109
118
  export function batchBegin() {
110
- isBranch = true
111
- batches = []
119
+ const uid = ++BATCH_COUNTER; // Safe. No skew in async ++BATCH_COUNTER as single thread and ++COUNTER is atomic in event loop sense. ⚠️ Only breaks on worker_threads or cluster (multi-process)
120
+ batches[uid] = []
121
+ return uid
112
122
  }
113
- export function batchAbort() {
114
- isBranch = false
115
- batches = []
123
+ export function batchAbort(batch_id) {
124
+ delete batches[batch_id]
116
125
  }
117
126
  export function batchReset() {
118
127
  batchAbort()
119
128
  }
120
- export function batchSubmit(arg) {
121
- let txns = batches
122
- let mode = batches.some(txn => txn.insert || txn.update || txn.delete) ? "command" : "query"
123
- isBranch = false
124
- batches = []
129
+ export function batchSubmit(batch_id, arg) {
130
+ if (!batch_id || !batches[batch_id] || !batches[batch_id].length)
131
+ throw {message: `Error: Invalid batch in Dip.batchSubmit()`}
132
+ let txns = batches[batch_id]
133
+ let mode = batches[batch_id].some(txn => txn.insert || txn.update || txn.delete) ? "command" : "query"
134
+ delete batches[batch_id]
125
135
  return new Promise((resolve, reject) => resolve())
126
136
  .then(() => execute({ "batch": txns, mode, version: arg?.version, compression: arg?.compression }))
127
137
  .then (result => {
@@ -136,16 +146,10 @@ export const operation = async (name, extras) => {
136
146
 
137
147
 
138
148
  export const insert = async (meta, collection, value, _id, extras) => {
139
- if (typeof collection !== "string") throw {message: "Error: collection type is not string in Dip.insert()"}
140
- // Multi Company Support
141
- if (Utils.isEmpty(meta?.company)) throw {message: "Error: meta argument not provided in Dip.insert()"}
142
- collection = `${meta.company}.${collection}`
143
- if (meta.company !== "GLOBAL") {
144
- if (typeof value === "object" && !Array.isArray(value))
145
- value.company = meta.company
146
- }
147
- value.outlet = value.outlet ?? meta.outlet
148
- // ---------------------
149
+
150
+ validate_collection(collection, 'in Dip.insert()')
151
+
152
+ validate_meta(meta, 'in Dip.insert()')
149
153
 
150
154
  var arg = {
151
155
  collection: collection,
@@ -164,8 +168,10 @@ export const insert = async (meta, collection, value, _id, extras) => {
164
168
  throw {message: "Error: invalid _id in Dip.insert()"}
165
169
 
166
170
 
167
- if (isBranch) {
168
- batches.push(arg)
171
+ if (meta.batch) {
172
+ if (!batches[meta.batch])
173
+ throw {message: 'Error: Invalid batch in Dip.insert()'}
174
+ batches[meta.batch].push(arg)
169
175
  return
170
176
  }
171
177
  arg.mode = "command"
@@ -178,18 +184,10 @@ export const insert = async (meta, collection, value, _id, extras) => {
178
184
  }
179
185
 
180
186
  export const query = async (meta, collection, query, options, extras) => {
181
- if (typeof collection !== "string") throw {message: "Error: collection type is not string in Dip.query()"}
182
- if (meta?.USE_EMPTY_COMPANY) {
183
-
184
- } else {
185
- // Multi Company Support
186
- if (Utils.isEmpty(meta?.company)) throw {message: "Error: meta argument not provided in Dip.query()"}
187
- collection = `${meta.company}.${collection}`
188
- if (meta.company !== "GLOBAL")
189
- query.company = meta.company
190
- }
191
- // ---------------------
192
187
 
188
+ validate_collection(collection, 'in Dip.query()')
189
+
190
+ validate_meta(meta, 'in Dip.query()')
193
191
 
194
192
  var arg = {
195
193
  collection: collection,
@@ -200,8 +198,10 @@ export const query = async (meta, collection, query, options, extras) => {
200
198
  ...(meta.DIP_DB ? {db: meta.DIP_DB} : {}),
201
199
  }
202
200
  arg = Object.assign(arg, extras)
203
- if (isBranch) {
204
- batches.push(arg)
201
+ if (meta.batch) {
202
+ if (!batches[meta.batch])
203
+ throw {message: 'Error: Invalid batch in Dip.query()'}
204
+ batches[meta.batch].push(arg)
205
205
  return
206
206
  }
207
207
  arg.mode = "query"
@@ -228,27 +228,10 @@ function collectionArray(col) {
228
228
 
229
229
 
230
230
  export const update = async (meta, collection, query, update, options, extras) => {
231
- // Multi Company Support
232
- if (Utils.isEmpty(meta?.company)) throw {message: "Error: meta argument not provided in Dip.update()"}
233
- if (typeof collection !== "string") throw {message: "Error: collection type is not string in Dip.update()"}
234
- collection = `${meta.company}.${collection}`
235
- if (meta.company !== "GLOBAL") {
236
- query.company = meta.company
237
- update.$set = update.$set ?? {}
238
- update.$set.company = meta.company
239
- if (options?.upsert) {
240
- update.$setOnInsert = update.$setOnInsert ?? {}
241
- update.$setOnInsert.company = meta.company
242
- update.$setOnInsert.outlet = update.$setOnInsert.outlet ?? update.$set?.outlet ?? meta.outlet
243
-
244
- let _id = update.$setOnInsert._id ?? update.$set?._id ?? query?._id
245
- if (!(["string", "number"].includes(typeof _id)))
246
- throw {message: "Error: invalid _id in Dip.update() with upsert"}
247
- if (typeof _id === "string" && _id.trim().length === 0)
248
- throw {message: "Error: invalid _id in Dip.update() with upsert"}
249
- }
250
- }
251
- // ---------------------
231
+
232
+ validate_collection(collection, 'in Dip.update()')
233
+
234
+ validate_meta(meta, 'in Dip.update()')
252
235
 
253
236
  var arg = {
254
237
  collection: collection,
@@ -260,8 +243,10 @@ export const update = async (meta, collection, query, update, options, extras) =
260
243
  ...(meta.DIP_DB ? {db: meta.DIP_DB} : {}),
261
244
  }
262
245
  arg = Object.assign(arg, extras)
263
- if (isBranch) {
264
- batches.push(arg)
246
+ if (meta.batch) {
247
+ if (!batches[meta.batch])
248
+ throw {message: 'Error: Invalid batch in Dip.update()'}
249
+ batches[meta.batch].push(arg)
265
250
  return
266
251
  }
267
252
  arg.mode = "command"
@@ -274,17 +259,13 @@ export const update = async (meta, collection, query, update, options, extras) =
274
259
  }
275
260
 
276
261
  export const remove = async (meta, collection, query, options, extras) => {
277
- // Multi Company Support
278
- if (Utils.isEmpty(meta?.company)) throw {message: "Error: meta argument not provided in Dip.remove()"}
279
- if (typeof collection !== "string") throw {message: "Error: collection type is not string in Dip.remove()"}
280
- collection = `${meta.company}.${collection}`
281
- if (meta.company !== "GLOBAL")
282
- query.company = meta.company
283
- // ---------------------
284
- if (Utils.isEmpty(query._id) && !meta.allowDangerousRemove) {
285
- throw { message: "Error: Dip.remove() without _id blocked by default (Dangerous Operation). Set allowDangerousRemove key if intentional." }
286
- return
287
- }
262
+
263
+ validate_collection(collection, 'in Dip.remove()')
264
+
265
+ if (Utils.isEmpty(query._id) && !meta.allowDangerousRemove)
266
+ throw { message: "Error: Dip.remove() without _id blocked by default (Dangerous Operation). Set meta.allowDangerousRemove if intentional." }
267
+
268
+ validate_meta(meta, 'in Dip.remove()')
288
269
 
289
270
  var arg = {
290
271
  collection: collection,
@@ -296,8 +277,10 @@ export const remove = async (meta, collection, query, options, extras) => {
296
277
  ...(meta.DIP_DB ? {db: meta.DIP_DB} : {}),
297
278
  }
298
279
  arg = Object.assign(arg, extras)
299
- if (isBranch) {
300
- batches.push(arg)
280
+ if (meta.batch) {
281
+ if (!batches[meta.batch])
282
+ throw {message: 'Error: Invalid batch in Dip.query()'}
283
+ batches[meta.batch].push(arg)
301
284
  return
302
285
  }
303
286
  arg.mode = "command"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "corebasic",
3
3
  "type": "module",
4
- "version": "1.0.181",
4
+ "version": "1.0.183",
5
5
  "description": "",
6
6
  "main": "index.js",
7
7
  "scripts": {