@superhero/eventflow-db 4.8.0 → 4.8.2-rc.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/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ---
2
+ #### v4.8.1
3
+ ---\n\nVersion alignment...
4
+
1
5
  ---
2
6
  ## Version: 4.8.0
3
7
  ---
package/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
 
2
2
  import Gateway from '@superhero/db'
3
3
  import AdapterFactory from '@superhero/db/adapter/mysql2/factory.js'
4
+ import Serde from './serde.js'
4
5
  import mysql2 from 'mysql2'
5
6
  import path from 'node:path'
6
7
  import { fileURLToPath } from 'node:url'
@@ -16,6 +17,8 @@ export function locate(locator)
16
17
  */
17
18
  export default class DB
18
19
  {
20
+ serde = new Serde()
21
+
19
22
  escape = mysql2.escape
20
23
 
21
24
  constructor(config)
@@ -177,13 +180,18 @@ export default class DB
177
180
  return Date.now().toString(36) + '-' + Math.random().toString(36).slice(2)
178
181
  }
179
182
 
180
- async persistEvent(event)
183
+ async persistEvent(event, serialize = false)
181
184
  {
182
185
  try
183
186
  {
184
- const
185
- id = event.id ?? this.#generateEventId(),
186
- data = JSON.stringify(event.data ?? {})
187
+ const id = event.id ?? this.#generateEventId()
188
+
189
+ let data = event.data ?? {}
190
+
191
+ if(serialize)
192
+ {
193
+ data = this.serde.serialize(data)
194
+ }
187
195
 
188
196
  await this.gateway.query('event/persist', { ...event, id, data })
189
197
 
@@ -231,7 +239,7 @@ export default class DB
231
239
  }
232
240
  }
233
241
 
234
- async readEvent(id)
242
+ async readEvent(id, deserialize = false)
235
243
  {
236
244
  let result
237
245
 
@@ -255,10 +263,12 @@ export default class DB
255
263
  }
256
264
 
257
265
  const event = result[0]
258
- return event
266
+ return deserialize
267
+ ? this.serde.deserialize(event)
268
+ : event
259
269
  }
260
270
 
261
- async readEventsByDomainAndPid(domain, pid)
271
+ async readEventsByDomainAndPid(domain, pid, deserialize = false)
262
272
  {
263
273
  let result
264
274
 
@@ -274,10 +284,12 @@ export default class DB
274
284
  throw error
275
285
  }
276
286
 
277
- return result
287
+ return deserialize
288
+ ? result.map(event => this.serde.deserialize(event))
289
+ : result
278
290
  }
279
291
 
280
- async readEventsByDomainAndPidBetweenTimestamps(domain, pid, timestampMin, timestampMax)
292
+ async readEventsByDomainAndPidBetweenTimestamps(domain, pid, timestampMin, timestampMax, deserialize = false)
281
293
  {
282
294
  let result
283
295
 
@@ -293,10 +305,12 @@ export default class DB
293
305
  throw error
294
306
  }
295
307
 
296
- return result
308
+ return deserialize
309
+ ? result.map(event => this.serde.deserialize(event))
310
+ : result
297
311
  }
298
312
 
299
- async readEventsByDomainAndPidAndNames(domain, pid, names)
313
+ async readEventsByDomainAndPidAndNames(domain, pid, names, deserialize = false)
300
314
  {
301
315
  let result
302
316
 
@@ -313,7 +327,9 @@ export default class DB
313
327
  throw error
314
328
  }
315
329
 
316
- return result
330
+ return deserialize
331
+ ? result.map(event => this.serde.deserialize(event))
332
+ : result
317
333
  }
318
334
 
319
335
  async readDistinctPidByDomain(domain)
@@ -386,11 +402,13 @@ export default class DB
386
402
  return result.map(({ domain, cpid }) => ({ domain, cpid }))
387
403
  }
388
404
 
389
- async readEventsByDomainAndCpid(domain, cpid)
405
+ async readEventsByDomainAndCpid(domain, cpid, deserialize = false)
390
406
  {
407
+ let result
408
+
391
409
  try
392
410
  {
393
- return await this.gateway.query('event_cpid/read-by-cpid-domain', cpid, domain)
411
+ result = await this.gateway.query('event_cpid/read-by-cpid-domain', cpid, domain)
394
412
  }
395
413
  catch(reason)
396
414
  {
@@ -399,6 +417,10 @@ export default class DB
399
417
  error.cause = reason
400
418
  throw error
401
419
  }
420
+
421
+ return deserialize
422
+ ? result.map(event => this.serde.deserialize(event))
423
+ : result
402
424
  }
403
425
 
404
426
  async persistEventEid(event_id, eid)
@@ -452,11 +474,13 @@ export default class DB
452
474
  return result.map((row) => row.eid)
453
475
  }
454
476
 
455
- async readEventsByEid(eid)
477
+ async readEventsByEid(eid, deserialize = false)
456
478
  {
479
+ let result
480
+
457
481
  try
458
482
  {
459
- return await this.gateway.query('event_eid/read-by-eid', eid)
483
+ result = await this.gateway.query('event_eid/read-by-eid', eid)
460
484
  }
461
485
  catch(reason)
462
486
  {
@@ -465,13 +489,19 @@ export default class DB
465
489
  error.cause = reason
466
490
  throw error
467
491
  }
492
+
493
+ return deserialize
494
+ ? result.map(event => this.serde.deserialize(event))
495
+ : result
468
496
  }
469
497
 
470
- async readEventsByDomainAndEid(domain, eid)
498
+ async readEventsByDomainAndEid(domain, eid, deserialize = false)
471
499
  {
500
+ let result
501
+
472
502
  try
473
503
  {
474
- return await this.gateway.query('event_eid/read-by-eid-domain', eid, domain)
504
+ result = await this.gateway.query('event_eid/read-by-eid-domain', eid, domain)
475
505
  }
476
506
  catch(reason)
477
507
  {
@@ -479,7 +509,11 @@ export default class DB
479
509
  error.code = 'E_EVENTFLOW_DB_EVENTS_READ_BY_DOMAIN_AND_EID'
480
510
  error.cause = reason
481
511
  throw error
482
- }
512
+ }
513
+
514
+ return deserialize
515
+ ? result.map(event => this.serde.deserialize(event))
516
+ : result
483
517
  }
484
518
 
485
519
  async persistEventPublished(publishedEvent)
@@ -727,7 +761,7 @@ export default class DB
727
761
  {
728
762
  try
729
763
  {
730
- log.error = JSON.stringify(log.error ?? {})
764
+ log.error = log.error ? this.serde.serialize(log.error) : {}
731
765
  await this.gateway.query('log/persist', log)
732
766
  }
733
767
  catch(reason)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superhero/eventflow-db",
3
- "version": "4.8.0",
3
+ "version": "4.8.2-rc.0.0",
4
4
  "description": "Eventflow db is a set of common database logic in the eventflow ecosystem.",
5
5
  "keywords": [
6
6
  "eventflow"
@@ -21,9 +21,9 @@
21
21
  "@superhero/db": "1.0.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@superhero/audit": "4.8.0",
24
+ "@superhero/audit": "4.8.1",
25
25
  "@superhero/syntax-check": "0.0.2",
26
- "@superhero/locator": "4.8.0"
26
+ "@superhero/locator": "4.8.1"
27
27
  },
28
28
  "author": {
29
29
  "name": "Erik Landvall",
package/serde.js ADDED
@@ -0,0 +1,122 @@
1
+ import util from 'node:util'
2
+
3
+ export default class Serde
4
+ {
5
+ transformers = new Map(
6
+ [
7
+ [
8
+ 'Date',
9
+ {
10
+ type : Date,
11
+ serializer : (input) => input.toJSON(),
12
+ deserializer : (input) => new Date(input)
13
+ }
14
+ ],
15
+ [
16
+ 'Error',
17
+ {
18
+ type : Error,
19
+ serializer : (input) =>
20
+ {
21
+ const json = { name: input.name }
22
+
23
+ Object.getOwnPropertyNames(input)
24
+ .forEach((key) => json[key] = this.serialize(input[key]))
25
+
26
+ return json
27
+ },
28
+ deserializer : (input) =>
29
+ {
30
+ const error = new Error
31
+
32
+ Object.getOwnPropertyNames(input)
33
+ .forEach((key) => error[key] = this.deserialize(input[key]))
34
+
35
+ return error
36
+ }
37
+ }
38
+ ],
39
+ [
40
+ 'Map',
41
+ {
42
+ type : Map,
43
+ serializer : (input) => [...input.entries()].map(([key, value]) => [ this.serialize(key), this.serialize(value) ]),
44
+ deserializer : (input) => new Map(input.map(([key, value]) => [ this.deserialize(key), this.deserialize(value) ]))
45
+ }
46
+ ],
47
+ [
48
+ 'Set',
49
+ {
50
+ type : Set,
51
+ serializer : (input) => [...input.values()].map(value => this.serialize(value)),
52
+ deserializer : (input) => new Set(input.map(value => this.deserialize(value)))
53
+ }
54
+ ],
55
+ ])
56
+
57
+ constructor(typeAttribute = '$type', valueAttribute = '$value')
58
+ {
59
+ this.typeAttribute = typeAttribute
60
+ this.valueAttribute = valueAttribute
61
+ }
62
+
63
+ serialize(input)
64
+ {
65
+ for(const [key, { type, serializer }] of this.transformers)
66
+ {
67
+ if(input instanceof type)
68
+ {
69
+ return { [this.typeAttribute] : key,
70
+ [this.valueAttribute] : serializer(input) }
71
+ }
72
+ }
73
+
74
+ if(Array.isArray(input))
75
+ {
76
+ return input.map(this.serialize.bind(this))
77
+ }
78
+
79
+ if('object' === typeof input && null !== input)
80
+ {
81
+ const serialized = {}
82
+ for (const [key, value] of Object.entries(input))
83
+ {
84
+ serialized[key] = this.serialize(value)
85
+ }
86
+ return serialized
87
+ }
88
+
89
+ return input
90
+ }
91
+
92
+ deserialize(input)
93
+ {
94
+ if(input)
95
+ {
96
+ for(const [key, { deserializer }] of this.transformers)
97
+ {
98
+ if(key === input[this.typeAttribute])
99
+ {
100
+ return deserializer(input[this.valueAttribute])
101
+ }
102
+ }
103
+
104
+ if (Array.isArray(input))
105
+ {
106
+ return input.map(this.deserialize.bind(this))
107
+ }
108
+
109
+ if (typeof input === 'object')
110
+ {
111
+ const deserialized = {}
112
+ for (const [key, value] of Object.entries(input))
113
+ {
114
+ deserialized[key] = this.deserialize(value)
115
+ }
116
+ return deserialized
117
+ }
118
+ }
119
+
120
+ return input
121
+ }
122
+ }